Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
+31 -31
View File
@@ -38,7 +38,7 @@
#include "G4VoxelLimits.hh"
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
#include "Randomize.hh"
#include "G4QuickRand.hh"
#include "G4VPVParameterisation.hh"
@@ -140,13 +140,13 @@ void G4Box::SetXHalfLength(G4double dx)
fCubicVolume = 0.;
fSurfaceArea = 0.;
fRebuildPolyhedron = true;
}
}
//////////////////////////////////////////////////////////////////////////
//
// Set Y dimension
void G4Box::SetYHalfLength(G4double dy)
void G4Box::SetYHalfLength(G4double dy)
{
if(dy > 2*kCarTolerance) // limit to thickness of surfaces
{
@@ -163,7 +163,7 @@ void G4Box::SetYHalfLength(G4double dy)
fCubicVolume = 0.;
fSurfaceArea = 0.;
fRebuildPolyhedron = true;
}
}
//////////////////////////////////////////////////////////////////////////
//
@@ -186,7 +186,7 @@ void G4Box::SetZHalfLength(G4double dz)
fCubicVolume = 0.;
fSurfaceArea = 0.;
fRebuildPolyhedron = true;
}
}
//////////////////////////////////////////////////////////////////////////
//
@@ -252,8 +252,8 @@ EInside G4Box::Inside(const G4ThreeVector& p) const
std::abs(p.x())-fDx,
std::abs(p.y())-fDy),
std::abs(p.z())-fDz);
if (dist > delta) return kOutside;
return (dist > -delta) ? kSurface : kInside;
return (dist > delta) ? kOutside :
((dist > -delta) ? kSurface : kInside);
}
//////////////////////////////////////////////////////////////////////////
@@ -278,7 +278,7 @@ G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
else
{
// Point is not on the surface
//
//
#ifdef G4CSGDEBUG
std::ostringstream message;
G4int oldprc = message.precision(16);
@@ -353,7 +353,7 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,
}
//////////////////////////////////////////////////////////////////////////
//
//
// Appoximate distance to box.
// Returns largest perpendicular distance to the closest x/y/z sides of
// the box, which is the most fast estimation of the shortest distance to box
@@ -361,9 +361,10 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,
G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
{
G4double dist = std::max(std::max(std::abs(p.x())-fDx,
std::abs(p.y())-fDy),
std::abs(p.z())-fDz);
G4double dist = std::max(std::max(
std::abs(p.x())-fDx,
std::abs(p.y())-fDy),
std::abs(p.z())-fDz);
return (dist > 0) ? dist : 0.;
}
@@ -456,9 +457,10 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
DumpInfo();
}
#endif
G4double dist = std::min(std::min(fDx-std::abs(p.x()),
fDy-std::abs(p.y())),
fDz-std::abs(p.z()));
G4double dist = std::min(std::min(
fDx-std::abs(p.x()),
fDy-std::abs(p.y())),
fDz-std::abs(p.z()));
return (dist > 0) ? dist : 0.;
}
@@ -493,29 +495,27 @@ std::ostream& G4Box::StreamInfo(std::ostream& os) const
//////////////////////////////////////////////////////////////////////////
//
// GetPointOnSurface
//
// Return a point (G4ThreeVector) randomly and uniformly selected
// on the solid surface
// Return a point randomly and uniformly selected on the surface
G4ThreeVector G4Box::GetPointOnSurface() const
{
G4double sxy = fDx*fDy, sxz = fDx*fDz, syz = fDy*fDz;
G4double select = (sxy + sxz + syz)*G4UniformRand();
G4double select = (sxy + sxz + syz)*G4QuickRand();
G4double u = 2.*G4QuickRand() - 1.;
G4double v = 2.*G4QuickRand() - 1.;
if (select < sxy)
return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
(2.*G4UniformRand() - 1.)*fDy,
(select < 0.5*sxy) ? -fDz : fDz);
if (select < sxy + sxz)
return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
(select < sxy + 0.5*sxz) ? -fDy : fDy,
(2.*G4UniformRand() - 1.)*fDz);
return G4ThreeVector(u*fDx,
v*fDy,
((select < 0.5*sxy) ? -fDz : fDz));
else if (select < sxy + sxz)
return G4ThreeVector(u*fDx,
((select < sxy + 0.5*sxz) ? -fDy : fDy),
v*fDz);
else
return G4ThreeVector((select < sxy + sxz + 0.5*syz) ? -fDx : fDx,
(2.*G4UniformRand() - 1.)*fDy,
(2.*G4UniformRand() - 1.)*fDz);
return G4ThreeVector(((select < sxy + sxz + 0.5*syz) ? -fDx : fDx),
u*fDy,
v*fDz);
}
//////////////////////////////////////////////////////////////////////////
+8 -7
View File
@@ -31,8 +31,7 @@
#include <cmath>
#include "G4CSGSolid.hh"
#include "Randomize.hh"
#include "G4RandomTools.hh"
#include "G4QuickRand.hh"
#include "G4Polyhedron.hh"
#include "G4AutoLock.hh"
@@ -45,7 +44,7 @@ namespace
//////////////////////////////////////////////////////////////////////////
//
// Constructor
// - Base class constructor
// - Base class constructor
G4CSGSolid::G4CSGSolid(const G4String& name) :
G4VSolid(name)
@@ -67,7 +66,7 @@ G4CSGSolid::G4CSGSolid( __void__& a )
// Destructor
//
G4CSGSolid::~G4CSGSolid()
G4CSGSolid::~G4CSGSolid()
{
delete fpPolyhedron; fpPolyhedron = nullptr;
}
@@ -87,7 +86,7 @@ G4CSGSolid::G4CSGSolid(const G4CSGSolid& rhs)
//
// Assignment operator
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
{
// Check assignment to self
//
@@ -105,11 +104,13 @@ G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
delete fpPolyhedron; fpPolyhedron = nullptr;
return *this;
}
}
G4double G4CSGSolid::GetRadiusInRing(G4double rmin, G4double rmax) const
{
return G4RandomRadiusInRing(rmin, rmax);
G4double k = G4QuickRand();
return (rmin <= 0) ? rmax*std::sqrt(k)
: std::sqrt(k*rmax*rmax + (1. - k)*rmin*rmin);
}
std::ostream& G4CSGSolid::StreamInfo(std::ostream& os) const
File diff suppressed because it is too large Load Diff
+115 -95
View File
@@ -28,7 +28,7 @@
// 21.03.95 P.Kent: Modified for `tolerant' geometry
// 09.09.96 V.Grichine: Final modifications before to commit
// 08.12.97 J.Allison: Added "nominal" constructor and method SetAllParameters
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
// 18.04.17 E.Tcherniaev: complete revision, speed-up
// --------------------------------------------------------------------
@@ -45,7 +45,7 @@
#include "G4VPVParameterisation.hh"
#include "Randomize.hh"
#include "G4QuickRand.hh"
#include "G4VGraphicsScene.hh"
#include "G4Polyhedron.hh"
@@ -54,7 +54,7 @@ using namespace CLHEP;
//////////////////////////////////////////////////////////////////////////
//
// Constructor - check and set half-widths as well as angles:
// Constructor - check and set half-widths as well as angles:
// final check of coplanarity
G4Trap::G4Trap( const G4String& pName,
@@ -79,8 +79,8 @@ G4Trap::G4Trap( const G4String& pName,
//////////////////////////////////////////////////////////////////////////
//
// Constructor - Design of trapezoid based on 8 G4ThreeVector parameters,
// which are its vertices. Checking of planarity with preparation of
// Constructor - Design of trapezoid based on 8 G4ThreeVector parameters,
// which are its vertices. Checking of planarity with preparation of
// fPlanes[] and than calculation of other members
G4Trap::G4Trap( const G4String& pName,
@@ -116,11 +116,11 @@ G4Trap::G4Trap( const G4String& pName,
G4Exception("G4Trap::G4Trap()", "GeomSolids0002",
FatalException, message);
}
// Set parameters
//
fDz = (pt[7]).z();
fDy1 = ((pt[2]).y()-(pt[1]).y())*0.5;
fDx1 = ((pt[1]).x()-(pt[0]).x())*0.5;
fDx2 = ((pt[3]).x()-(pt[2]).x())*0.5;
@@ -244,6 +244,7 @@ G4Trap::G4Trap(const G4Trap& rhs)
fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.fDx4), fTalpha2(rhs.fTalpha2)
{
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
for (G4int i=0; i<6; ++i) { fAreas[i] = rhs.fAreas[i]; }
fTrapType = rhs.fTrapType;
}
@@ -251,7 +252,7 @@ G4Trap::G4Trap(const G4Trap& rhs)
//
// Assignment operator
G4Trap& G4Trap::operator = (const G4Trap& rhs)
G4Trap& G4Trap::operator = (const G4Trap& rhs)
{
// Check assignment to self
//
@@ -268,6 +269,7 @@ G4Trap& G4Trap::operator = (const G4Trap& rhs)
fDy1 = rhs.fDy1; fDx1 = rhs.fDx1; fDx2 = rhs.fDx2; fTalpha1 = rhs.fTalpha1;
fDy2 = rhs.fDy2; fDx3 = rhs.fDx3; fDx4 = rhs.fDx4; fTalpha2 = rhs.fTalpha2;
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
for (G4int i=0; i<6; ++i) { fAreas[i] = rhs.fAreas[i]; }
fTrapType = rhs.fTrapType;
return *this;
}
@@ -358,8 +360,8 @@ void G4Trap::MakePlanes()
void G4Trap::MakePlanes(const G4ThreeVector pt[8])
{
G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
constexpr G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
const static G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
for (G4int i=0; i<4; ++i)
{
@@ -385,6 +387,70 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
FatalException, message);
}
// Re-compute parameters
SetCachedValues();
}
//////////////////////////////////////////////////////////////////////////
//
// Calculate the coef's of the plane p1->p2->p3->p4->p1
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed
// from infront of the plane (i.e. from normal direction).
//
// Return true if the points are coplanar, false otherwise
G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
const G4ThreeVector& p2,
const G4ThreeVector& p3,
const G4ThreeVector& p4,
TrapSidePlane& plane )
{
G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0);
if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0);
if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0);
normal = normal.unit();
G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
plane.a = normal.x();
plane.b = normal.y();
plane.c = normal.z();
plane.d = -normal.dot(centre);
// compute distances and check planarity
G4double d1 = std::abs(normal.dot(p1) + plane.d);
G4double d2 = std::abs(normal.dot(p2) + plane.d);
G4double d3 = std::abs(normal.dot(p3) + plane.d);
G4double d4 = std::abs(normal.dot(p4) + plane.d);
G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
return (dmax > 1000 * kCarTolerance) ? false : true;
}
//////////////////////////////////////////////////////////////////////////
//
// Recompute parameters using planes
void G4Trap::SetCachedValues()
{
// Set indeces
constexpr G4int iface[6][4] =
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
// Get vertices
G4ThreeVector pt[8];
GetVertices(pt);
// Set face areas
for (G4int i=0; i<6; ++i)
{
fAreas[i] = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
pt[iface[i][1]],
pt[iface[i][2]],
pt[iface[i][3]]).mag();
}
for (G4int i=1; i<6; ++i) { fAreas[i] += fAreas[i - 1]; }
// Define type of trapezoid
fTrapType = 0;
if (fPlanes[0].b == -1 && fPlanes[1].b == 1 &&
@@ -415,43 +481,7 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
}
}
///////////////////////////////////////////////////////////////////////
//
// Calculate the coef's of the plane p1->p2->p3->p4->p1
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed
// from infront of the plane (i.e. from normal direction).
//
// Return true if the points are coplanar, false otherwise
G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
const G4ThreeVector& p2,
const G4ThreeVector& p3,
const G4ThreeVector& p4,
TrapSidePlane& plane )
{
G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0);
if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0);
if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0);
normal = normal.unit();
G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
plane.a = normal.x();
plane.b = normal.y();
plane.c = normal.z();
plane.d = -normal.dot(centre);
// compute distances and check planarity
G4double d1 = std::abs(normal.dot(p1) + plane.d);
G4double d2 = std::abs(normal.dot(p2) + plane.d);
G4double d3 = std::abs(normal.dot(p3) + plane.d);
G4double d4 = std::abs(normal.dot(p4) + plane.d);
G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
return (dmax > 1000 * kCarTolerance) ? false : true;
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Get volume
@@ -461,7 +491,7 @@ G4double G4Trap::GetCubicVolume()
{
G4ThreeVector pt[8];
GetVertices(pt);
G4double dz = pt[4].z() - pt[0].z();
G4double dy1 = pt[2].y() - pt[0].y();
G4double dx1 = pt[1].x() - pt[0].x();
@@ -476,7 +506,7 @@ G4double G4Trap::GetCubicVolume()
return fCubicVolume;
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Get surface area
@@ -500,7 +530,7 @@ G4double G4Trap::GetSurfaceArea()
return fSurfaceArea;
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
// computation & modification.
@@ -512,7 +542,7 @@ void G4Trap::ComputeDimensions( G4VPVParameterisation* p,
p->ComputeDimensions(*this,n,pRep);
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Get bounding box
@@ -552,7 +582,7 @@ void G4Trap::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
}
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate extent under transform and specified limit
@@ -601,7 +631,7 @@ G4bool G4Trap::CalculateExtent( const EAxis pAxis,
return exist;
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Return whether point is inside/outside/on_surface
@@ -661,10 +691,10 @@ EInside G4Trap::Inside( const G4ThreeVector& p ) const
((dist > -halfCarTolerance) ? kSurface : kInside);
}
}
return kOutside;
return kOutside;
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Determine side, and return corresponding normal
@@ -765,7 +795,7 @@ G4ThreeVector G4Trap::SurfaceNormal( const G4ThreeVector& p ) const
}
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Algorithm for SurfaceNormal() following the original specification
// for points not on the surface
@@ -789,7 +819,7 @@ G4ThreeVector G4Trap::ApproxSurfaceNormal( const G4ThreeVector& p ) const
return G4ThreeVector(0, 0, (p.z() < 0) ? -1 : 1);
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate distance to shape from outside
// - return kInfinity if no intersection
@@ -802,7 +832,7 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
return kInfinity;
G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
G4double dz = (invz < 0) ? fDz : -fDz;
G4double dz = (invz < 0) ? fDz : -fDz;
G4double tzmin = (p.z() + dz)*invz;
G4double tzmax = (p.z() - dz)*invz;
@@ -811,7 +841,7 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
G4double tymin = 0, tymax = DBL_MAX;
G4int i = 0;
for ( ; i<2; ++i)
{
{
G4double cosa = fPlanes[i].b*v.y() + fPlanes[i].c*v.z();
G4double dist = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
if (dist >= -halfCarTolerance)
@@ -824,14 +854,14 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
{
G4double tmp = -dist/cosa;
if (tymax > tmp) tymax = tmp;
}
}
}
// Z intersections
//
G4double txmin = 0, txmax = DBL_MAX;
for ( ; i<4; ++i)
{
{
G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y()+fPlanes[i].c*v.z();
G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].c*p.z() +
fPlanes[i].d;
@@ -845,19 +875,19 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
{
G4double tmp = -dist/cosa;
if (txmax > tmp) txmax = tmp;
}
}
}
// Find distance
//
G4double tmin = std::max(std::max(txmin,tymin),tzmin);
G4double tmax = std::min(std::min(txmax,tymax),tzmax);
if (tmax <= tmin + halfCarTolerance) return kInfinity; // touch or no hit
return (tmin < halfCarTolerance ) ? 0. : tmin;
}
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate exact shortest distance to any boundary from outside
// This is the best fast estimation of the shortest distance to trap
@@ -914,7 +944,7 @@ G4double G4Trap::DistanceToIn( const G4ThreeVector& p ) const
return 0.;
}
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate distance to surface of shape from inside and
// find normal at exit point, if required
@@ -987,7 +1017,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
// Set normal, if required, and return distance
//
if (calcNorm)
if (calcNorm)
{
*validNorm = true;
if (iside < 0)
@@ -998,7 +1028,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
return tmax;
}
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate exact shortest distance to any boundary from inside
// - Returns 0 is ThreeVector outside
@@ -1015,7 +1045,7 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
message << " p.x() = " << p.x()/mm << " mm\n";
message << " p.y() = " << p.y()/mm << " mm\n";
message << " p.z() = " << p.z()/mm << " mm";
G4cout.precision(oldprc) ;
G4cout.precision(oldprc);
G4Exception("G4Trap::DistanceToOut(p)", "GeomSolids1002",
JustWarning, message );
DumpInfo();
@@ -1070,7 +1100,7 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
return 0.;
}
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// GetEntityType
@@ -1099,7 +1129,7 @@ std::ostream& G4Trap::StreamInfo( std::ostream& os ) const
+fTthetaSphi*fTthetaSphi));
G4double alpha1 = std::atan(fTalpha1);
G4double alpha2 = std::atan(fTalpha2);
G4String signDegree = "\u00B0";
G4String signDegree = "\u00B0";
G4int oldprc = os.precision(16);
os << "-----------------------------------------------------------\n"
@@ -1142,38 +1172,29 @@ void G4Trap::GetVertices(G4ThreeVector pt[8]) const
}
}
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Generate random point on the surface
G4ThreeVector G4Trap::GetPointOnSurface() const
{
G4ThreeVector pt[8];
G4int iface [6][4] =
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
G4double sface[6];
// Set indeces
constexpr G4int iface [6][4] =
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
// Set vertices
G4ThreeVector pt[8];
GetVertices(pt);
G4double stotal = 0;
for (G4int i=0; i<6; ++i)
{
G4double ss = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
pt[iface[i][1]],
pt[iface[i][2]],
pt[iface[i][3]]).mag();
stotal += ss;
sface[i] = stotal;
}
// Select face
//
G4double select = stotal*G4UniformRand();
G4double select = fAreas[5]*G4QuickRand();
G4int k = 5;
if (select <= sface[4]) k = 4;
if (select <= sface[3]) k = 3;
if (select <= sface[2]) k = 2;
if (select <= sface[1]) k = 1;
if (select <= sface[0]) k = 0;
k -= (select <= fAreas[4]);
k -= (select <= fAreas[3]);
k -= (select <= fAreas[2]);
k -= (select <= fAreas[1]);
k -= (select <= fAreas[0]);
// Select sub-triangle
//
@@ -1181,14 +1202,13 @@ G4ThreeVector G4Trap::GetPointOnSurface() const
G4int i1 = iface[k][1];
G4int i2 = iface[k][2];
G4int i3 = iface[k][3];
G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
if (select > fAreas[k] - s2) i0 = i2;
// Generate point
//
G4double u = G4UniformRand();
G4double v = G4UniformRand();
G4double u = G4QuickRand();
G4double v = G4QuickRand();
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
}
+87 -64
View File
@@ -26,7 +26,7 @@
// Implementation for G4Trd class
//
// 12.01.95 P.Kent: First version
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
// 25.05.17 E.Tcherniaev: complete revision, speed-up
// --------------------------------------------------------------------
@@ -39,7 +39,7 @@
#include "G4VoxelLimits.hh"
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
#include "Randomize.hh"
#include "G4QuickRand.hh"
#include "G4VPVParameterisation.hh"
@@ -89,7 +89,8 @@ G4Trd::~G4Trd()
G4Trd::G4Trd(const G4Trd& rhs)
: G4CSGSolid(rhs), halfCarTolerance(rhs.halfCarTolerance),
fDx1(rhs.fDx1), fDx2(rhs.fDx2),
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz),
fHx(rhs.fHx), fHy(rhs.fHy)
{
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
}
@@ -114,6 +115,7 @@ G4Trd& G4Trd::operator = (const G4Trd& rhs)
fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
fDz = rhs.fDz;
fHx = rhs.fHx; fHy = rhs.fHy;
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
return *this;
@@ -171,14 +173,14 @@ void G4Trd::MakePlanes()
G4double dx = fDx1 - fDx2;
G4double dy = fDy1 - fDy2;
G4double dz = 2*fDz;
G4double magx = std::sqrt(dx*dx + dz*dz);
G4double magy = std::sqrt(dy*dy + dz*dz);
fHx = std::sqrt(dy*dy + dz*dz);
fHy = std::sqrt(dx*dx + dz*dz);
// Set -Y & +Y planes
// Set X planes at -Y & +Y
//
fPlanes[0].a = 0.;
fPlanes[0].b = -dz/magy;
fPlanes[0].c = dy/magy;
fPlanes[0].b = -dz/fHx;
fPlanes[0].c = dy/fHx;
fPlanes[0].d = fPlanes[0].b*fDy1 + fPlanes[0].c*fDz;
fPlanes[1].a = fPlanes[0].a;
@@ -186,11 +188,11 @@ void G4Trd::MakePlanes()
fPlanes[1].c = fPlanes[0].c;
fPlanes[1].d = fPlanes[0].d;
// Set -X & +X planes
// Set Y planes at -X & +X
//
fPlanes[2].a = -dz/magx;
fPlanes[2].a = -dz/fHy;
fPlanes[2].b = 0.;
fPlanes[2].c = dx/magx;
fPlanes[2].c = dx/fHy;
fPlanes[2].d = fPlanes[2].a*fDx1 + fPlanes[2].c*fDz;
fPlanes[3].a = -fPlanes[2].a;
@@ -222,9 +224,7 @@ G4double G4Trd::GetSurfaceArea()
if (fSurfaceArea == 0.)
{
fSurfaceArea =
4*(fDx1*fDy1+fDx2*fDy2) +
2*(fDy1+fDy2)*std::hypot(fDx1-fDx2,2*fDz) +
2*(fDx1+fDx2)*std::hypot(fDy1-fDy2,2*fDz);
4*(fDx1*fDy1 + fDx2*fDy2) + 2*(fDx1+fDx2)*fHx + 2*(fDy1+fDy2)*fHy;
}
return fSurfaceArea;
}
@@ -328,7 +328,7 @@ G4bool G4Trd::CalculateExtent( const EAxis pAxis,
// Return whether point inside/outside/on surface, using tolerance
EInside G4Trd::Inside( const G4ThreeVector& p ) const
{
{
G4double dx = fPlanes[3].a*std::abs(p.x())+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dy = fPlanes[1].b*std::abs(p.y())+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dxy = std::max(dx,dy);
@@ -336,8 +336,8 @@ EInside G4Trd::Inside( const G4ThreeVector& p ) const
G4double dz = std::abs(p.z())-fDz;
G4double dist = std::max(dz,dxy);
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
return (dist > halfCarTolerance) ? kOutside :
((dist > -halfCarTolerance) ? kSurface : kInside);
}
//////////////////////////////////////////////////////////////////////////
@@ -457,7 +457,7 @@ G4double G4Trd::DistanceToIn(const G4ThreeVector& p,
if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
return kInfinity;
G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
G4double dz = (invz < 0) ? fDz : -fDz;
G4double dz = (invz < 0) ? fDz : -fDz;
G4double tzmin = (p.z() + dz)*invz;
G4double tzmax = (p.z() - dz)*invz;
@@ -626,7 +626,7 @@ G4double G4Trd::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
// Set normal, if required, and return distance
//
if (calcNorm)
if (calcNorm)
{
*validNorm = true;
if (iside < 0)
@@ -654,7 +654,7 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
message << " p.x() = " << p.x()/mm << " mm\n";
message << " p.y() = " << p.y()/mm << " mm\n";
message << " p.z() = " << p.z()/mm << " mm";
G4cout.precision(oldprc) ;
G4cout.precision(oldprc);
G4Exception("G4Trd::DistanceToOut(p)", "GeomSolids1002",
JustWarning, message );
DumpInfo();
@@ -666,7 +666,7 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
G4double dz = std::abs(p.z())-fDz;
G4double dist = std::max(dz,dxy);
return (dist < 0) ? -dist : 0.;
}
@@ -717,56 +717,79 @@ std::ostream& G4Trd::StreamInfo( std::ostream& os ) const
G4ThreeVector G4Trd::GetPointOnSurface() const
{
// Set vertices
//
G4ThreeVector pt[8];
pt[0].set(-fDx1,-fDy1,-fDz);
pt[1].set( fDx1,-fDy1,-fDz);
pt[2].set(-fDx1, fDy1,-fDz);
pt[3].set( fDx1, fDy1,-fDz);
pt[4].set(-fDx2,-fDy2, fDz);
pt[5].set( fDx2,-fDy2, fDz);
pt[6].set(-fDx2, fDy2, fDz);
pt[7].set( fDx2, fDy2, fDz);
// Set faces (-Z, -Y, +Y, -X, +X, +Z)
//
G4int iface [6][4] =
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
// Set areas
//
G4double sxz = (fDy1 + fDy2)*std::hypot(fDx1 - fDx2, 2*fDz);
G4double syz = (fDx1 + fDx2)*std::hypot(fDy1 - fDy2, 2*fDz);
G4double sface[6] = { 4*fDx1*fDy1, syz, syz, sxz, sxz, 4*fDx2*fDy2 };
for (G4int i=1; i<6; ++i) { sface[i] += sface[i-1]; }
//
G4double sxz = (fDx1 + fDx2)*fHx;
G4double syz = (fDy1 + fDy2)*fHy;
G4double ssurf[6] = { 4.*fDx1*fDy1, sxz, sxz, syz, syz, 4.*fDx2*fDy2 };
ssurf[1] += ssurf[0];
ssurf[2] += ssurf[1];
ssurf[3] += ssurf[2];
ssurf[4] += ssurf[3];
ssurf[5] += ssurf[4];
// Select face
//
G4double select = sface[5]*G4UniformRand();
G4double select = ssurf[5]*G4QuickRand();
G4int k = 5;
if (select <= sface[4]) k = 4;
if (select <= sface[3]) k = 3;
if (select <= sface[2]) k = 2;
if (select <= sface[1]) k = 1;
if (select <= sface[0]) k = 0;
k -= (select <= ssurf[4]);
k -= (select <= ssurf[3]);
k -= (select <= ssurf[2]);
k -= (select <= ssurf[1]);
k -= (select <= ssurf[0]);
// Select sub-triangle
// Generate point on selected surface
//
G4int i0 = iface[k][0];
G4int i1 = iface[k][1];
G4int i2 = iface[k][2];
G4int i3 = iface[k][3];
G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
// Generate point
//
G4double u = G4UniformRand();
G4double v = G4UniformRand();
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
G4double u = G4QuickRand();
G4double v = G4QuickRand();
switch(k)
{
case 0: // base at -Z
{
return G4ThreeVector((2.*u - 1.)*fDx1, (2.*v - 1.)*fDy1, -fDz);
}
case 1: // X face at -Y
{
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
G4ThreeVector p0(-fDx1,-fDy1,-fDz);
G4ThreeVector p1( fDx2,-fDy2, fDz);
return (select <= ssurf[0] + fDx1*fHx) ?
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx1,-fDy1,-fDz) :
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx2,-fDy2, fDz);
}
case 2: // X face at +Y
{
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
G4ThreeVector p0( fDx1, fDy1,-fDz);
G4ThreeVector p1(-fDx2, fDy2, fDz);
return (select <= ssurf[1] + fDx1*fHx) ?
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx1, fDy1,-fDz) :
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx2, fDy2, fDz);
}
case 3: // Y face at -X
{
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
G4ThreeVector p0(-fDx1, fDy1,-fDz);
G4ThreeVector p1(-fDx2,-fDy2, fDz);
return (select <= ssurf[2] + fDy1*fHy) ?
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx1,-fDy1,-fDz) :
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx2, fDy2, fDz);
}
case 4: // Y face at +X
{
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
G4ThreeVector p0( fDx1,-fDy1,-fDz);
G4ThreeVector p1( fDx2, fDy2, fDz);
return (select <= ssurf[3] + fDy1*fHy) ?
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx1, fDy1,-fDz) :
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx2,-fDy2, fDz);
}
case 5: // base at +Z
{
return G4ThreeVector((2.*u - 1.)*fDx2, (2.*v - 1.)*fDy2, fDz);
}
}
return G4ThreeVector(0., 0., 0.);
}
//////////////////////////////////////////////////////////////////////////
+153 -144
View File
@@ -43,12 +43,10 @@
#include "G4BoundingEnvelope.hh"
#include "G4VPVParameterisation.hh"
#include "Randomize.hh"
#include "meshdefs.hh"
#include "G4QuickRand.hh"
#include "G4VGraphicsScene.hh"
#include "G4Polyhedron.hh"
using namespace CLHEP;
@@ -103,7 +101,7 @@ G4Tubs::G4Tubs( __void__& a )
fRMin(0.), fRMax(0.), fDz(0.), fSPhi(0.), fDPhi(0.),
sinCPhi(0.), cosCPhi(0.), cosHDPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
fPhiFullTube(false), fInvRmax(0.), fInvRmin(0.),
fPhiFullTube(false), fInvRmax(0.), fInvRmin(0.),
halfCarTolerance(0.), halfRadTolerance(0.),
halfAngTolerance(0.)
{
@@ -141,7 +139,7 @@ G4Tubs::G4Tubs(const G4Tubs& rhs)
//
// Assignment operator
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
{
// Check assignment to self
//
@@ -232,7 +230,7 @@ void G4Tubs::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
G4bool G4Tubs::CalculateExtent( const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin,
G4double& pMin,
G4double& pMax ) const
{
G4ThreeVector bmin, bmax;
@@ -352,7 +350,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
else { tolRMin = 0 ; }
tolRMax = fRMax - halfRadTolerance ;
if ((r2 >= tolRMin*tolRMin) && (r2 <= tolRMax*tolRMax))
{
if ( fPhiFullTube )
@@ -378,7 +376,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
{
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
if ( (pPhi >= fSPhi + halfAngTolerance)
@@ -406,7 +404,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
in = kInside ;
}
}
}
}
}
}
else // Try generous boundaries
@@ -431,7 +429,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
{
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
if ( (pPhi >= fSPhi - halfAngTolerance)
@@ -476,7 +474,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
{
if ( (std::fabs(pPhi) < halfAngTolerance)
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
{
{
pPhi += twopi ; // 0 <= pPhi < 2pi
}
if ( (pPhi >= fSPhi - halfAngTolerance)
@@ -493,7 +491,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
{
in = kSurface ;
}
}
}
}
}
}
@@ -523,22 +521,22 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
distRMax = std::fabs(rho - fRMax);
distZ = std::fabs(std::fabs(p.z()) - fDz);
if (!fPhiFullTube) // Protected against (0,0,z)
if (!fPhiFullTube) // Protected against (0,0,z)
{
if ( rho > halfCarTolerance )
{
pPhi = std::atan2(p.y(),p.x());
if (pPhi < fSPhi-halfCarTolerance) { pPhi += twopi; }
else if (pPhi > fSPhi+fDPhi+halfCarTolerance) { pPhi -= twopi; }
distSPhi = std::fabs( pPhi - fSPhi );
distEPhi = std::fabs( pPhi - fSPhi - fDPhi );
distSPhi = std::fabs( pPhi - fSPhi );
distEPhi = std::fabs( pPhi - fSPhi - fDPhi );
}
else if ( !fRMin )
{
distSPhi = 0.;
distEPhi = 0.;
distSPhi = 0.;
distEPhi = 0.;
}
nPs = G4ThreeVector( sinSPhi, -cosSPhi, 0 );
nPe = G4ThreeVector( -sinEPhi, cosEPhi, 0 );
@@ -555,20 +553,20 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
++noSurfaces;
sumnorm -= nR;
}
if( fDPhi < twopi )
if( fDPhi < twopi )
{
if (distSPhi <= halfAngTolerance)
if (distSPhi <= halfAngTolerance)
{
++noSurfaces;
sumnorm += nPs;
}
if (distEPhi <= halfAngTolerance)
if (distEPhi <= halfAngTolerance)
{
++noSurfaces;
sumnorm += nPe;
}
}
if (distZ <= halfCarTolerance)
if (distZ <= halfCarTolerance)
{
++noSurfaces;
if ( p.z() >= 0.) { sumnorm += nZ; }
@@ -583,7 +581,7 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
G4cout<< "G4Tubs::SN ( "<<p.x()<<", "<<p.y()<<", "<<p.z()<<" ); "
<< G4endl << G4endl;
G4cout.precision(oldprc) ;
#endif
#endif
norm = ApproxSurfaceNormal(p);
}
else if ( noSurfaces == 1 ) { norm = sumnorm; }
@@ -635,8 +633,8 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
distMin = distRMax ;
side = kNRMax ;
}
}
if (!fPhiFullTube && rho ) // Protected against (0,0,z)
}
if (!fPhiFullTube && rho ) // Protected against (0,0,z)
{
phi = std::atan2(p.y(),p.x()) ;
@@ -651,7 +649,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
distSPhi = std::fabs(phi - fSPhi)*rho ;
}
distEPhi = std::fabs(phi - fSPhi - fDPhi)*rho ;
if (distSPhi < distEPhi) // Find new minimum
{
if ( distSPhi < distMin )
@@ -666,21 +664,21 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
side = kNEPhi ;
}
}
}
}
switch ( side )
{
case kNRMin : // Inner radius
{
{
norm = G4ThreeVector(-p.x()/rho, -p.y()/rho, 0) ;
break ;
}
case kNRMax : // Outer radius
{
{
norm = G4ThreeVector(p.x()/rho, p.y()/rho, 0) ;
break ;
}
case kNZ : // + or - dz
{
{
if ( p.z() > 0 ) { norm = G4ThreeVector(0,0,1) ; }
else { norm = G4ThreeVector(0,0,-1); }
break ;
@@ -702,8 +700,8 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
"GeomSolids1002", JustWarning,
"Undefined side for valid surface normal to solid.");
break ;
}
}
}
}
return norm;
}
@@ -713,7 +711,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
// Calculate distance to shape from outside, along normalised vector
// - return kInfinity if no intersection, or intersection distance <= tolerance
//
// - Compute the intersection with the z planes
// - Compute the intersection with the z planes
// - if at valid r, phi, return
//
// -> If point is outer outer radius, compute intersection with rmax
@@ -740,8 +738,8 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
// Intersection point variables
//
G4double Dist, sd, xi, yi, zi, rho2, inum, iden, cosPsi, Comp ;
G4double t1, t2, t3, b, c, d ; // Quadratic solver variables
G4double t1, t2, t3, b, c, d ; // Quadratic solver variables
// Calculate tolerant rmin and rmax
if (fRMin > kRadTolerance)
@@ -837,7 +835,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
{ // 64 bits systems. Split long distances and recompute
G4double fTerm = sd-std::fmod(sd,dRmax);
sd = fTerm + DistanceToIn(p+fTerm*v,v);
}
}
// Check z intersection
//
zi = p.z() + sd*v.z() ;
@@ -860,7 +858,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
} // end if (sd>=0)
} // end if (d>=0)
} // end if (r>=fRMax)
else
else
{
// Inside outer radius :
// check not inside, and heading through tubs (-> 0 to in)
@@ -878,11 +876,11 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
{
// In the old version, the small negative tangent for the point
// on surface was not taken in account, and returning 0.0 ...
// New version: check the tangent for the point on surface and
// New version: check the tangent for the point on surface and
// if no intersection, return kInfinity, if intersection instead
// return sd.
//
c = t3-fRMax*fRMax;
c = t3-fRMax*fRMax;
if ( c<=0.0 )
{
return 0.0;
@@ -894,26 +892,26 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
if ( d>=0.0 )
{
snxt = c/(-b+std::sqrt(d)); // using safe solution
// for quadratic equation
// for quadratic equation
if ( snxt < halfCarTolerance ) { snxt=0; }
return snxt ;
}
}
else
{
return kInfinity;
}
}
}
}
}
else
{
{
// In the old version, the small negative tangent for the point
// on surface was not taken in account, and returning 0.0 ...
// New version: check the tangent for the point on surface and
// New version: check the tangent for the point on surface and
// if no intersection, return kInfinity, if intersection instead
// return sd.
//
c = t3 - fRMax*fRMax;
c = t3 - fRMax*fRMax;
if ( c<=0.0 )
{
return 0.0;
@@ -925,10 +923,10 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
if ( d>=0.0 )
{
snxt= c/(-b+std::sqrt(d)); // using safe solution
// for quadratic equation
// for quadratic equation
if ( snxt < halfCarTolerance ) { snxt=0; }
return snxt ;
}
}
else
{
return kInfinity;
@@ -936,7 +934,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
}
} // end if (!fPhiFullTube)
} // end if (t3>tolIRMin2)
} // end if (Inside Outer Radius)
} // end if (Inside Outer Radius)
if ( fRMin ) // Try inner cylinder intersection
{
c = (t3 - fRMin*fRMin)/t1 ;
@@ -956,7 +954,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
{ // 64 bits systems. Split long distances and recompute
G4double fTerm = sd-std::fmod(sd,dRmax);
sd = fTerm + DistanceToIn(p+fTerm*v,v);
}
}
zi = p.z() + sd*v.z() ;
if (std::fabs(zi) <= tolODz)
{
@@ -964,7 +962,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
//
if ( fPhiFullTube )
{
return sd ;
return sd ;
}
else
{
@@ -999,7 +997,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
// First phi surface (Starting phi)
//
Comp = v.x()*sinSPhi - v.y()*cosSPhi ;
if ( Comp < 0 ) // Component in outwards normal dirn
{
Dist = (p.y()*cosSPhi - p.x()*sinSPhi) ;
@@ -1033,13 +1031,13 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
}
}
}
}
}
}
// Second phi surface (Ending phi)
Comp = -(v.x()*sinEPhi - v.y()*cosEPhi) ;
if (Comp < 0 ) // Component in outwards normal dirn
{
Dist = -(p.y()*cosEPhi - p.x()*sinEPhi) ;
@@ -1074,17 +1072,17 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
}
}
} // Comp < 0
} // !fPhiFullTube
} // !fPhiFullTube
if ( snxt<halfCarTolerance ) { snxt=0; }
return snxt ;
}
//////////////////////////////////////////////////////////////////
//
// Calculate distance to shape from outside, along normalised vector
// - return kInfinity if no intersection, or intersection distance <= tolerance
//
// - Compute the intersection with the z planes
// - Compute the intersection with the z planes
// - if at valid r, phi, return
//
// -> If point is outer outer radius, compute intersection with rmax
@@ -1124,7 +1122,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p ) const
// Psi=angle from central phi to point
//
cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/rho ;
if ( cosPsi < cosHDPhi )
{
// Point lies outside phi range
@@ -1158,11 +1156,11 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
ESide side=kNull , sider=kNull, sidephi=kNull ;
G4double snxt, srd=kInfinity, sphi=kInfinity, pdist ;
G4double deltaR, t1, t2, t3, b, c, d2, roMin2 ;
// Vars for phi intersection:
G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, vphi, roi2 ;
// Z plane intersection
if (v.z() > 0 )
@@ -1229,7 +1227,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
if ( t1 > 0 ) // Check not parallel
{
// Calculate srd, r exit distance
if ( (t2 >= 0.0) && (roi2 > fRMax*(fRMax + kRadTolerance)) )
{
// Delta r not negative => leaving via rmax
@@ -1253,7 +1251,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
// On tolerant boundary & heading outwards (or perpendicular to)
// outer radial surface -> leaving immediately
if ( calcNorm )
if ( calcNorm )
{
G4double invRho = FastInverseRxy( p, fInvRmax, kNormTolerance );
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
@@ -1261,10 +1259,10 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
}
return snxt = 0 ; // Leaving by rmax immediately
}
}
}
else if ( t2 < 0. ) // i.e. t2 < 0; Possible rmin intersection
{
roMin2 = t3 - t2*t2/t1 ; // min ro2 of the plane of movement
roMin2 = t3 - t2*t2/t1 ; // min ro2 of the plane of movement
if ( fRMin && (roMin2 < fRMin*(fRMin - kRadTolerance)) )
{
@@ -1280,7 +1278,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
if (deltaR > kRadTolerance*fRMin)
{
srd = c/(-b+std::sqrt(d2));
srd = c/(-b+std::sqrt(d2));
sider = kRMin ;
}
else
@@ -1307,7 +1305,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
if (calcNorm)
{
G4double invRho = FastInverseRxy( p, fInvRmax, kNormTolerance );
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
*validNorm = true ;
}
return snxt = 0.0;
@@ -1339,16 +1337,16 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
}
}
}
// Phi Intersection
if ( !fPhiFullTube )
{
// add angle calculation with correction
// add angle calculation with correction
// of the difference in domain of atan2 and Sphi
//
vphi = std::atan2(v.y(),v.x()) ;
if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
else if ( vphi > fSPhi + fDPhi + halfAngTolerance ) { vphi -= twopi; }
@@ -1364,25 +1362,25 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
compS = -sinSPhi*v.x() + cosSPhi*v.y() ;
compE = sinEPhi*v.x() - cosEPhi*v.y() ;
sidephi = kNull;
if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
&& (pDistE <= halfCarTolerance) ) )
|| ( (fDPhi > pi) && !((pDistS > halfCarTolerance)
&& (pDistE > halfCarTolerance) ) ) )
{
// Inside both phi *full* planes
if ( compS < 0 )
{
sphi = pDistS/compS ;
if (sphi >= -halfCarTolerance)
{
xi = p.x() + sphi*v.x() ;
yi = p.y() + sphi*v.y() ;
// Check intersecting with correct half-plane
// (if not -> no intersect)
//
@@ -1405,8 +1403,8 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
if ( pDistS > -halfCarTolerance )
{
sphi = 0.0 ; // Leave by sphi immediately
}
}
}
}
}
else
{
@@ -1421,14 +1419,14 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
if ( compE < 0 )
{
sphi2 = pDistE/compE ;
// Only check further if < starting phi intersection
//
if ( (sphi2 > -halfCarTolerance) && (sphi2 < sphi) )
{
xi = p.x() + sphi2*v.x() ;
yi = p.y() + sphi2*v.y() ;
if((std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance))
{
// Leaving via ending phi
@@ -1440,8 +1438,8 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
if ( pDistE <= -halfCarTolerance ) { sphi = sphi2 ; }
else { sphi = 0.0 ; }
}
}
else // Check intersecting with correct half-plane
}
else // Check intersecting with correct half-plane
if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
{
@@ -1463,7 +1461,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
{
// On z axis + travel not || to z axis -> if phi of vector direction
// within phi of shape, Step limited by rmax, else Step =0
if ( (fSPhi - halfAngTolerance <= vphi)
&& (vphi <= fSPhi + fDPhi + halfAngTolerance ) )
{
@@ -1471,7 +1469,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
}
else
{
sidephi = kSPhi ; // arbitrary
sidephi = kSPhi ; // arbitrary
sphi = 0.0 ;
}
}
@@ -1596,7 +1594,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
{
safeR1 = rho - fRMin ;
safeR2 = fRMax - rho ;
if ( safeR1 < safeR2 ) { safe = safeR1 ; }
else { safe = safeR2 ; }
}
@@ -1624,7 +1622,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
}
if ( safe < 0 ) { safe = 0 ; }
return safe ;
return safe ;
}
//////////////////////////////////////////////////////////////////////////
@@ -1674,80 +1672,91 @@ std::ostream& G4Tubs::StreamInfo( std::ostream& os ) const
G4ThreeVector G4Tubs::GetPointOnSurface() const
{
G4double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
aOne, aTwo, aThr, aFou;
G4double rRand;
G4double Rmax = fRMax;
G4double Rmin = fRMin;
G4double hz = 2.*fDz; // height
G4double lext = fDPhi*Rmax; // length of external circular arc
G4double lint = fDPhi*Rmin; // length of internal circular arc
aOne = 2.*fDz*fDPhi*fRMax;
aTwo = 2.*fDz*fDPhi*fRMin;
aThr = 0.5*fDPhi*(fRMax*fRMax-fRMin*fRMin);
aFou = 2.*fDz*(fRMax-fRMin);
// Set array of surface areas
//
G4double RRmax = Rmax * Rmax;
G4double RRmin = Rmin * Rmin;
G4double sbase = 0.5*fDPhi*(RRmax - RRmin);
G4double scut = (fDPhi == twopi) ? 0. : hz*(Rmax - Rmin);
G4double ssurf[6] = { scut, scut, sbase, sbase, hz*lext, hz*lint };
ssurf[1] += ssurf[0];
ssurf[2] += ssurf[1];
ssurf[3] += ssurf[2];
ssurf[4] += ssurf[3];
ssurf[5] += ssurf[4];
phi = G4RandFlat::shoot(fSPhi, fSPhi+fDPhi);
cosphi = std::cos(phi);
sinphi = std::sin(phi);
// Select surface
//
G4double select = ssurf[5]*G4QuickRand();
G4int k = 5;
k -= (select <= ssurf[4]);
k -= (select <= ssurf[3]);
k -= (select <= ssurf[2]);
k -= (select <= ssurf[1]);
k -= (select <= ssurf[0]);
rRand = GetRadiusInRing(fRMin,fRMax);
if( (fSPhi == 0) && (fDPhi == twopi) ) { aFou = 0; }
chose = G4RandFlat::shoot(0.,aOne+aTwo+2.*aThr+2.*aFou);
if( (chose >=0) && (chose < aOne) )
// Generate point on selected surface
//
switch(k)
{
xRand = fRMax*cosphi;
yRand = fRMax*sinphi;
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
return G4ThreeVector (xRand, yRand, zRand);
}
else if( (chose >= aOne) && (chose < aOne + aTwo) )
{
xRand = fRMin*cosphi;
yRand = fRMin*sinphi;
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
return G4ThreeVector (xRand, yRand, zRand);
}
else if( (chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr) )
{
xRand = rRand*cosphi;
yRand = rRand*sinphi;
zRand = fDz;
return G4ThreeVector (xRand, yRand, zRand);
}
else if( (chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + 2.*aThr) )
{
xRand = rRand*cosphi;
yRand = rRand*sinphi;
zRand = -1.*fDz;
return G4ThreeVector (xRand, yRand, zRand);
}
else if( (chose >= aOne + aTwo + 2.*aThr)
&& (chose < aOne + aTwo + 2.*aThr + aFou) )
{
xRand = rRand*cosSPhi;
yRand = rRand*sinSPhi;
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
return G4ThreeVector (xRand, yRand, zRand);
}
else
{
xRand = rRand*cosEPhi;
yRand = rRand*sinEPhi;
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
return G4ThreeVector (xRand, yRand, zRand);
case 0: // start phi cut
{
G4double r = Rmin + (Rmax - Rmin)*G4QuickRand();
return G4ThreeVector(r*cosSPhi, r*sinSPhi, hz*G4QuickRand() - fDz);
}
case 1: // end phi cut
{
G4double r = Rmin + (Rmax - Rmin)*G4QuickRand();
return G4ThreeVector(r*cosEPhi, r*sinEPhi, hz*G4QuickRand() - fDz);
}
case 2: // base at -dz
{
G4double r = std::sqrt(RRmin + (RRmax - RRmin)*G4QuickRand());
G4double phi = fSPhi + fDPhi*G4QuickRand();
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), -fDz);
}
case 3: // base at +dz
{
G4double r = std::sqrt(RRmin + (RRmax - RRmin)*G4QuickRand());
G4double phi = fSPhi + fDPhi*G4QuickRand();
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), fDz);
}
case 4: // external lateral surface
{
G4double phi = fSPhi + fDPhi*G4QuickRand();
G4double z = hz*G4QuickRand() - fDz;
G4double x = Rmax*std::cos(phi);
G4double y = Rmax*std::sin(phi);
return G4ThreeVector(x,y,z);
}
case 5: // internal lateral surface
{
G4double phi = fSPhi + fDPhi*G4QuickRand();
G4double z = hz*G4QuickRand() - fDz;
G4double x = Rmin*std::cos(phi);
G4double y = Rmin*std::sin(phi);
return G4ThreeVector(x,y,z);
}
}
return G4ThreeVector(0., 0., 0.);
}
///////////////////////////////////////////////////////////////////////////
//
// Methods for visualisation
void G4Tubs::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
void G4Tubs::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
{
scene.AddSolid (*this) ;
}
G4Polyhedron* G4Tubs::CreatePolyhedron () const
G4Polyhedron* G4Tubs::CreatePolyhedron () const
{
return new G4PolyhedronTubs (fRMin, fRMax, fDz, fSPhi, fDPhi) ;
}