Import Geant4 3.1.0 source tree
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Box.cc,v 1.10 2000/11/20 18:05:59 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// $Id: G4Box.cc,v 1.13 2001/02/01 08:22:19 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -17,8 +17,10 @@
|
||||
// 07.05.00 - V.Grichine: d= DistanceToIn(p,v), if d<e/2, d=0
|
||||
// 09.06.00 - V.Grichine: safety in DistanceToIn(p) against Inside(p)=kOutside
|
||||
// and information before exception in DistanceToOut(p,v,...)
|
||||
|
||||
|
||||
// 15.11.00 - D.Williams, V.Grichine: bug fixed in CalculateExtent - change
|
||||
// algorithm for rotated vertices
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4Box.hh"
|
||||
|
||||
@@ -37,10 +39,11 @@
|
||||
//
|
||||
// Constructor - check & set half widths
|
||||
|
||||
G4Box::G4Box(const G4String& pName, G4double pX,
|
||||
G4double pY, G4double pZ) : G4CSGSolid(pName)
|
||||
G4Box::G4Box(const G4String& pName,
|
||||
G4double pX, G4double pY, G4double pZ)
|
||||
: G4CSGSolid(pName)
|
||||
{
|
||||
if ( pX > 0 && pY > 0 && pZ > 0 )
|
||||
if ( pX > 2*kCarTolerance && pY > 2*kCarTolerance&& pZ > 2*kCarTolerance)
|
||||
{
|
||||
fDx = pX ;
|
||||
fDy = pY ;
|
||||
@@ -48,7 +51,7 @@ G4Box::G4Box(const G4String& pName, G4double pX,
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("Error in G4Box::Box - negative parameters");
|
||||
G4Exception("G4Box::G4Box(...) - invalid dimensions");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,6 +65,34 @@ G4Box::~G4Box()
|
||||
;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4Box::SetXHalfLength(G4double dx)
|
||||
{
|
||||
if(dx > 2*kCarTolerance)
|
||||
fDx = dx;
|
||||
else
|
||||
G4Exception("G4Box::SetXHalfLength(...) - invalid dimensions");
|
||||
}
|
||||
|
||||
void G4Box::SetYHalfLength(G4double dy)
|
||||
{
|
||||
if(dy > 2*kCarTolerance)
|
||||
fDy = dy;
|
||||
else
|
||||
G4Exception("G4Box::SetYHalfLength(...) - invalid dimensions");
|
||||
}
|
||||
|
||||
void G4Box::SetZHalfLength(G4double dz)
|
||||
{
|
||||
if(dz > 2*kCarTolerance)
|
||||
fDz = dz;
|
||||
else
|
||||
G4Exception("G4Box::SetZHalfLength(...) - invalid dimensions");
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dispatch to parameterisation for replication mechanism dimension
|
||||
@@ -189,39 +220,70 @@ G4bool G4Box::CalculateExtent(const EAxis pAxis,
|
||||
ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
|
||||
ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax) ;
|
||||
ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
|
||||
|
||||
if ( pMin != kInfinity || pMax != -kInfinity )
|
||||
{
|
||||
existsAfterClip = true ;
|
||||
|
||||
|
||||
if (pVoxelLimit.IsLimited(pAxis) == false)
|
||||
{
|
||||
if ( pMin != kInfinity || pMax != -kInfinity )
|
||||
{
|
||||
existsAfterClip = true ;
|
||||
|
||||
// Add 2*tolerance to avoid precision troubles
|
||||
|
||||
pMin -= kCarTolerance ;
|
||||
pMax += kCarTolerance ;
|
||||
}
|
||||
pMin -= kCarTolerance;
|
||||
pMax += kCarTolerance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ThreeVector clipCentre(
|
||||
( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
|
||||
( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
|
||||
( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
|
||||
|
||||
if ( pMin != kInfinity || pMax != -kInfinity )
|
||||
{
|
||||
existsAfterClip = true ;
|
||||
|
||||
|
||||
// Check to see if endpoints are in the solid
|
||||
|
||||
clipCentre(pAxis) = pVoxelLimit.GetMinExtent(pAxis);
|
||||
|
||||
if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
|
||||
{
|
||||
pMin = pVoxelLimit.GetMinExtent(pAxis);
|
||||
}
|
||||
else
|
||||
{
|
||||
pMin -= kCarTolerance;
|
||||
}
|
||||
clipCentre(pAxis) = pVoxelLimit.GetMaxExtent(pAxis);
|
||||
|
||||
if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
|
||||
{
|
||||
pMax = pVoxelLimit.GetMaxExtent(pAxis);
|
||||
}
|
||||
else
|
||||
{
|
||||
pMax += kCarTolerance;
|
||||
}
|
||||
}
|
||||
// Check for case where completely enveloping clipping volume
|
||||
// If point inside then we are confident that the solid completely
|
||||
// envelopes the clipping volume. Hence set min/max extents according
|
||||
// to clipping volume extents along the specified axis.
|
||||
|
||||
G4ThreeVector clipCentre(
|
||||
( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
|
||||
( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
|
||||
( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
|
||||
|
||||
if (Inside(pTransform.Inverse().TransformPoint(clipCentre))!=kOutside)
|
||||
else if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
|
||||
{
|
||||
existsAfterClip = true ;
|
||||
pMin = pVoxelLimit.GetMinExtent(pAxis) ;
|
||||
pMax = pVoxelLimit.GetMaxExtent(pAxis) ;
|
||||
existsAfterClip = true ;
|
||||
pMin = pVoxelLimit.GetMinExtent(pAxis) ;
|
||||
pMax = pVoxelLimit.GetMaxExtent(pAxis) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete vertices;
|
||||
return existsAfterClip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -646,8 +708,8 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
|
||||
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
|
||||
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
|
||||
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
|
||||
// G4Exception("Invalid call in G4Box::DistanceToOut(p), point p is outside") ;
|
||||
G4cout<<"G4Box::DistanceToOut(p),point p is outside ?!" << G4endl ;
|
||||
G4Exception("Invalid call in G4Box::DistanceToOut(p), point p is outside") ;
|
||||
// G4cout<<"G4Box::DistanceToOut(p),point p is outside ?!" << G4endl ;
|
||||
}
|
||||
safx1 = fDx - p.x() ;
|
||||
safx2 = fDx + p.x() ;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4CSGSolid.cc,v 1.2 1999/12/15 14:50:06 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
#include "G4CSGSolid.hh"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Cons.cc,v 1.16 2000/11/20 17:57:58 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
// class G4Cons
|
||||
//
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Para.cc,v 1.6 2000/11/20 17:57:59 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
// class G4Para
|
||||
//
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Sphere.cc,v 1.8 2000/11/20 17:57:59 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
// class G4Sphere
|
||||
//
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Torus.cc,v 1.20 2000/12/01 11:49:03 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// $Id: G4Torus.cc,v 1.23 2001/01/29 13:12:57 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
//
|
||||
// class G4Torus
|
||||
@@ -20,6 +20,7 @@
|
||||
// 26.05.00 V.Grichine, new fuctions developed by O.Cremonesi were added
|
||||
// 31.08.00 E.Medernach, numerical computation of roots with bounding volume technique
|
||||
// 03.10.00 E.Medernach, SafeNewton added
|
||||
// 11.01.01 E.Medernach, Use G4PolynomialSolver to find roots
|
||||
//
|
||||
|
||||
|
||||
@@ -38,6 +39,7 @@
|
||||
#include "G4NURBStube.hh"
|
||||
#include "G4NURBScylinder.hh"
|
||||
#include "G4NURBStubesector.hh"
|
||||
#include "G4PolynomialSolver.hh"
|
||||
|
||||
// #define DEBUGTORUS 1
|
||||
|
||||
@@ -1124,6 +1126,16 @@ G4double G4Torus::DistanceToIn(const G4ThreeVector& p,
|
||||
const G4ThreeVector& v) const
|
||||
{
|
||||
|
||||
/*
|
||||
On voudrait arriver a cela:
|
||||
return SolveNumeric(p, v, true);
|
||||
Mais des problemes avec la tolerance sur la section Phi
|
||||
ne le permet pas pour le moment
|
||||
*/
|
||||
|
||||
/*
|
||||
Le tore mathematique peut etre vu comme une equation implicite
|
||||
*/
|
||||
G4double snxt=kInfinity, sphi=kInfinity;// snxt = default return value
|
||||
|
||||
G4double c[5], s[4] ;
|
||||
@@ -2189,14 +2201,10 @@ G4NURBS* G4Torus::CreateNURBS () const
|
||||
|
||||
/** Important : the precision could be tuned by TORUSPRECISION **/
|
||||
|
||||
#define EPSILON 1e-12
|
||||
#define INFINITY 1e+12
|
||||
#define TORUSPRECISION 1.0 // or whatever you want for precision
|
||||
// (it is TorusEquation related)
|
||||
#define HOLEBVM 0
|
||||
#define NBPOINT 6
|
||||
#define ITERATION 12 // 20 But 8 is really enough for Newton with a good guess
|
||||
#define NOINTERSECTION kInfinity
|
||||
|
||||
|
||||
/*
|
||||
Torus implementation with Newton Method and Bounding volume
|
||||
@@ -2229,14 +2237,13 @@ G4double G4Torus::SolveNumeric(const G4ThreeVector& p,
|
||||
G4double Value = TorusEquation(p.x(),p.y(),p.z(),GetRtor(),GetRmax());
|
||||
EInside inside ;
|
||||
|
||||
/*** Check from only the exterior torus TORUSPRECISION ? ***/
|
||||
/** Note that we could be on the surface from the interior torus **/
|
||||
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::SolveNumeric " << p << ", " << v << G4endl ;
|
||||
G4cout << "G4Torus::SolveNumeric Value = " << Value << G4endl;
|
||||
#endif
|
||||
|
||||
|
||||
if (Value < -TORUSPRECISION) {
|
||||
inside = kInside ;
|
||||
} else {
|
||||
@@ -2255,7 +2262,7 @@ G4double G4Torus::SolveNumeric(const G4ThreeVector& p,
|
||||
<< " Rtor = " << GetRtor()
|
||||
<< " Rmax = " << GetRmax() << G4endl ;
|
||||
#endif
|
||||
if (fabs(GetRmin()) > EPSILON) {
|
||||
if (fabs(GetRmin()) > POLEPSILON) {
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::SolveNumeric Testing interior torus .." << G4endl ;
|
||||
#endif
|
||||
@@ -2420,7 +2427,10 @@ G4double G4Torus::SolveNumeric(const G4ThreeVector& p,
|
||||
/** Now check Phi .. **/
|
||||
|
||||
/* Eliminate the case of point (0,0,0) */
|
||||
if ((p.x()*p.x() + p.y()*p.y() + p.z()*p.z()) > EPSILON)
|
||||
// if ((p.x()*p.x() + p.y()*p.y() + p.z()*p.z()) > POLEPSILON)
|
||||
if (((p.x()+ lambda*v.x())*(p.x()+ lambda*v.x()) +
|
||||
(p.y()+ lambda*v.y())*(p.y()+ lambda*v.y()) +
|
||||
(p.z()+ lambda*v.z())*(p.z()+ lambda*v.z())) > POLEPSILON)
|
||||
{
|
||||
G4double theta ;
|
||||
|
||||
@@ -2436,11 +2446,14 @@ G4double G4Torus::SolveNumeric(const G4ThreeVector& p,
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::SolveNumeric theta = " << theta
|
||||
<< " Phi = " << fSPhi
|
||||
<< " Phi + dPhi = " << fSPhi + fDPhi << G4endl ;
|
||||
<< " Phi + dPhi = " << fSPhi + fDPhi
|
||||
<< " kAngTolerance = " << kAngTolerance << G4endl ;
|
||||
G4cout << " theta - Phi = " << theta - fSPhi << G4endl ;
|
||||
|
||||
#endif
|
||||
|
||||
if ((theta >= fSPhi - kAngTolerance*0.5) &&
|
||||
(theta <= (fSPhi + fDPhi + kAngTolerance*0.5))) {
|
||||
if ((theta - fSPhi >= - kAngTolerance*0.5) &&
|
||||
(theta - (fSPhi + fDPhi) <= kAngTolerance*0.5)) {
|
||||
/*** If this is the case we return this solution ***/
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::SolveNumeric Correct Phi section" << G4endl ;
|
||||
@@ -2511,7 +2524,12 @@ G4double G4Torus::SolveNumeric(const G4ThreeVector& p,
|
||||
v,IsDistanceToIn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::SolveNumeric Phi not checked because point is " << p + lambda*v << G4endl << G4endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return lambda;
|
||||
}
|
||||
@@ -2534,13 +2552,17 @@ void G4Torus::BVMIntersection(G4double x,G4double y,G4double z,
|
||||
DistToZ = (x+NewL[0]*dx)*(x+NewL[0]*dx) + (y+NewL[0]*dy)*(y+NewL[0]*dy);
|
||||
if (DistToZ - (Rmax + Rmin)*(Rmax + Rmin) > 0)
|
||||
valid[0] = 0;
|
||||
#if HOLEBVM
|
||||
if (DistToZ - (Rmax - Rmin)*(Rmax - Rmin) < 0)
|
||||
valid[0] = 0;
|
||||
#endif
|
||||
DistToZ = (x+NewL[1]*dx)*(x+NewL[1]*dx) + (y+NewL[1]*dy)*(y+NewL[1]*dy);
|
||||
if (DistToZ - (Rmax + Rmin)*(Rmax + Rmin) > 0)
|
||||
valid[1] = 0;
|
||||
#if HOLEBVM
|
||||
if (DistToZ - (Rmax - Rmin)*(Rmax - Rmin) < 0)
|
||||
valid[1] = 0;
|
||||
#endif
|
||||
} else {
|
||||
/* if dz == 0 we could know the exact solution */
|
||||
/* Well, this is true but we have not expected precision issue from sqrt .. */
|
||||
@@ -2564,63 +2586,65 @@ void G4Torus::BVMIntersection(G4double x,G4double y,G4double z,
|
||||
valid[3] = 0;
|
||||
NewL[2] = -1.0;
|
||||
NewL[3] = -1.0;
|
||||
} else {
|
||||
} else{
|
||||
d = sqrt(d) ;
|
||||
NewL[2] = (d - b)/(2*a);
|
||||
NewL[3] = (-d - b)/(2*a);
|
||||
if (NewL[2] < 0.0) valid[2] = 0;
|
||||
if (fabs(z + NewL[2]*dz) - Rmin > EPSILON) valid[2] = 0;
|
||||
if (fabs(z + NewL[2]*dz) - Rmin > POLEPSILON) valid[2] = 0;
|
||||
if (NewL[3] < 0.0) valid[3] = 0;
|
||||
if (fabs(z + NewL[3]*dz) - Rmin > EPSILON) valid[3] = 0;
|
||||
if (fabs(z + NewL[3]*dz) - Rmin > POLEPSILON) valid[3] = 0;
|
||||
}
|
||||
} else {
|
||||
/* only dz != 0 so we could know the exact solution */
|
||||
/* this depends only for the distance to Z axis */
|
||||
/* BUT big precision problem near the border.. */
|
||||
/* I like so much Newton to increase precision you know.. */
|
||||
} else
|
||||
{
|
||||
/* only dz != 0 so we could know the exact solution */
|
||||
/* this depends only for the distance to Z axis */
|
||||
/* BUT big precision problem near the border.. */
|
||||
/* I like so much Newton to increase precision you know.. */
|
||||
|
||||
NewL[2] = -1.0;
|
||||
NewL[3] = -1.0;
|
||||
valid[2] = 0;
|
||||
valid[3] = 0;
|
||||
NewL[2] = -1.0;
|
||||
NewL[3] = -1.0;
|
||||
valid[2] = 0;
|
||||
valid[3] = 0;
|
||||
|
||||
/*** Try This to see precision issue with sqrt(~ 0)
|
||||
G4double DistToZ ;
|
||||
G4double result;
|
||||
G4double guess;
|
||||
/*** Try This to see precision issue with sqrt(~ 0)
|
||||
G4double DistToZ ;
|
||||
G4double result;
|
||||
G4double guess;
|
||||
|
||||
DistToZ = sqrt(x*x + y*y) ;
|
||||
DistToZ = sqrt(x*x + y*y) ;
|
||||
|
||||
if ((DistToZ < (Rmax - Rmin)) || (DistToZ > (Rmax + Rmin))) {
|
||||
return -1.0 ;
|
||||
}
|
||||
if ((DistToZ < (Rmax - Rmin)) || (DistToZ > (Rmax + Rmin))) {
|
||||
return -1.0 ;
|
||||
}
|
||||
|
||||
result = sqrt((Rmin + Rmax - DistToZ)*(Rmin - Rmax + DistToZ));
|
||||
result = sqrt((Rmin + Rmax - DistToZ)*(Rmin - Rmax + DistToZ));
|
||||
|
||||
if (dz < 0) {
|
||||
if (z > result) {
|
||||
return (result - z)/dz;
|
||||
} else {
|
||||
if (z > -result) {
|
||||
return (-result - z)/dz;
|
||||
} else
|
||||
return -1.0;
|
||||
}
|
||||
} else {
|
||||
if (z < -result) {
|
||||
return (z + result)/dz;
|
||||
} else {
|
||||
if (z < result) {
|
||||
return (z - result)/dz;
|
||||
} else
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (dz < 0) {
|
||||
if (z > result) {
|
||||
return (result - z)/dz;
|
||||
} else {
|
||||
if (z > -result) {
|
||||
return (-result - z)/dz;
|
||||
} else
|
||||
return -1.0;
|
||||
}
|
||||
} else {
|
||||
if (z < -result) {
|
||||
return (z + result)/dz;
|
||||
} else {
|
||||
if (z < result) {
|
||||
return (z - result)/dz;
|
||||
} else
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* x² + y² = (Rmax - Rmin)² */
|
||||
#if HOLEBVM
|
||||
if ((dx != 0) || (dy != 0)) {
|
||||
G4double a,b,c,d;
|
||||
|
||||
@@ -2639,18 +2663,20 @@ void G4Torus::BVMIntersection(G4double x,G4double y,G4double z,
|
||||
NewL[4] = (d - b)/(2*a);
|
||||
NewL[5] = (-d - b)/(2*a);
|
||||
if (NewL[4] < 0.0) valid[4] = 0;
|
||||
if (fabs(z + NewL[4]*dz) - Rmin > EPSILON) valid[4] = 0;
|
||||
if (fabs(z + NewL[4]*dz) - Rmin > POLEPSILON) valid[4] = 0;
|
||||
if (NewL[5] < 0.0) valid[5] = 0;
|
||||
if (fabs(z + NewL[5]*dz) - Rmin > EPSILON) valid[5] = 0;
|
||||
if (fabs(z + NewL[5]*dz) - Rmin > POLEPSILON) valid[5] = 0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* only dz != 0 so we could know the exact solution */
|
||||
/* OK but same as above .. */
|
||||
valid[4] = 0;
|
||||
valid[5] = 0;
|
||||
NewL[4] = -1.0;
|
||||
NewL[5] = -1.0;
|
||||
}
|
||||
} else {
|
||||
/* only dz != 0 so we could know the exact solution */
|
||||
/* OK but same as above .. */
|
||||
valid[4] = 0;
|
||||
valid[5] = 0;
|
||||
NewL[4] = -1.0;
|
||||
NewL[5] = -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void G4Torus::SortIntervals (G4double *SortL, G4double *NewL,
|
||||
@@ -2660,7 +2686,7 @@ void G4Torus::SortIntervals (G4double *SortL, G4double *NewL,
|
||||
G4double swap;
|
||||
|
||||
(*NbIntersection) = 0;
|
||||
SortL[0] = -INFINITY;
|
||||
SortL[0] = -kInfinity;
|
||||
|
||||
for (i=0;i<6;i++) {
|
||||
if (valid[i] != 0) {
|
||||
@@ -2679,7 +2705,7 @@ void G4Torus::SortIntervals (G4double *SortL, G4double *NewL,
|
||||
/* Delete double values */
|
||||
/* When the ray hits a corner we have a double value */
|
||||
for (i=0;i<(*NbIntersection)-1;i++) {
|
||||
if (SortL[i+1] - SortL[i] < EPSILON) {
|
||||
if (SortL[i+1] - SortL[i] < POLEPSILON) {
|
||||
if (((*NbIntersection) & (1)) == 1) {
|
||||
/* If the NbIntersection is odd then we keep one value */
|
||||
for (j=i+1;j<(*NbIntersection);j++) {
|
||||
@@ -2706,7 +2732,8 @@ G4double G4Torus::DistanceToTorus (G4double x,G4double y,G4double z,
|
||||
G4double dx,G4double dy,G4double dz,
|
||||
G4double Rmax,G4double Rmin) const
|
||||
{
|
||||
G4double Lmin,Lmax;
|
||||
G4double Lmin=0.;
|
||||
G4double Lmax=0.;
|
||||
G4double guess;
|
||||
G4double SortL[4];
|
||||
|
||||
@@ -2733,16 +2760,16 @@ G4double G4Torus::DistanceToTorus (G4double x,G4double y,G4double z,
|
||||
SortIntervals(SortL,NewL,valid,&NbIntersection);
|
||||
|
||||
{
|
||||
/*** Length check ***/
|
||||
/*** Length check (Torus specific) ***/
|
||||
G4double LengthMin = 0.82842712*Rmin;
|
||||
|
||||
switch(NbIntersection) {
|
||||
case 1:
|
||||
if (SortL[0] < EPSILON) {
|
||||
if (SortL[0] < POLEPSILON) {
|
||||
if (fabs(TorusEquation(x,y,z,Rmax,Rmin)) < TORUSPRECISION) {
|
||||
return 0.0;
|
||||
} else {
|
||||
return NOINTERSECTION;
|
||||
return kInfinity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2750,7 +2777,7 @@ G4double G4Torus::DistanceToTorus (G4double x,G4double y,G4double z,
|
||||
if ((SortL[1] - SortL[0]) < LengthMin) NbIntersection = 0;
|
||||
break;
|
||||
case 3:
|
||||
if (SortL[0] < EPSILON) {
|
||||
if (SortL[0] < POLEPSILON) {
|
||||
if (fabs(TorusEquation(x,y,z,Rmax,Rmin)) < TORUSPRECISION) {
|
||||
return 0.0;
|
||||
} else {
|
||||
@@ -2785,454 +2812,93 @@ G4double G4Torus::DistanceToTorus (G4double x,G4double y,G4double z,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** If the ray intersects the torus it necessary intersects the BVMax ***/
|
||||
/*** So it is necessary into *an* interval from the BVM ***/
|
||||
|
||||
/** Note : In general there are only 2 intersections so computing the second
|
||||
interval could be done only if the first one does not contain any root */
|
||||
|
||||
/* NOW there is 2 possibilities */
|
||||
/* If inside the BVM (or Torus instead), take "0, SortL[0] .." */
|
||||
/* If outside the BVM, we have intervals where if there is an intersection
|
||||
the root must be */
|
||||
/* Now Lmin1 <= Lambda <= Lmax and there is a root */
|
||||
/* Newton Methods in this interval from the guess */
|
||||
|
||||
/*** Beware The first interval could be the bad one and we have to see other one ***/
|
||||
/*** We must have a way to decide if an interval contains root or not .. ***/
|
||||
|
||||
/***
|
||||
Beware: If the original point is near the torus (into the BVM not the torus)
|
||||
we have serious precision issue (bad guess value) try it with a big Rmin
|
||||
***/
|
||||
|
||||
/* We are Inside the BVM if the number of intersection is odd */
|
||||
/* Not necessary an intersection with Torus if point outside Torus and Inside BVM ! */
|
||||
|
||||
if (((NbIntersection) & (1)) != 0) {
|
||||
/*** If we are Inside the BVM Lmin = 0. Lmax is the point ***/
|
||||
/*** there is necessary an intersection if the point is inside the Torus ***/
|
||||
G4int InsideTorus = 0;
|
||||
|
||||
switch (NbIntersection) {
|
||||
case 0:
|
||||
return kInfinity ;
|
||||
break;
|
||||
case 1:
|
||||
Lmin = 0.0 ;
|
||||
Lmax = SortL[0] ;
|
||||
|
||||
if (TorusEquation(x,y,z,Rmax,Rmin) < 0.0) {
|
||||
|
||||
InsideTorus = 1;
|
||||
/* As we are inside the torus it must have an intersection */
|
||||
/* To have a good guess we take Lmax - Rmin/8.0 */
|
||||
/* If we are inside the torus the upper bound is better */
|
||||
guess = Lmax - Rmin*0.125;
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus Inside the torus" << G4endl ;
|
||||
G4cout << "G4Torus::DistanceToTorus Initial Guess is "
|
||||
<< guess << G4endl ;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
#if DEBUGTORUS
|
||||
G4cout.precision(16);
|
||||
G4cout << "G4Torus::DistanceToTorus point " << x << ", " << y
|
||||
<< ", " << z << ", " << " is outside the torus "
|
||||
<< " Rmax = " << Rmax << " Rmin = " << Rmin << " Teq = "
|
||||
<< TorusEquation(x,y,z,Rmax,Rmin) << G4endl ;
|
||||
#endif
|
||||
InsideTorus = 0;
|
||||
/* PROBLEMS what to choose ? */
|
||||
guess = 0.0; //0.0 ?
|
||||
}
|
||||
|
||||
|
||||
/* Ready to do Newton */
|
||||
guess = Newton(guess,x,y,z,dx,dy,dz,Rmax,Rmin,Lmin,Lmax);
|
||||
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus First Newton guess = "
|
||||
<< guess << G4endl ;
|
||||
G4cout << "G4Torus::DistanceToTorus Lmin = " << Lmin
|
||||
<< " Lmax = " << Lmax << G4endl ;
|
||||
#endif
|
||||
|
||||
/* In case the origin point is just in the surface
|
||||
the NbIntersection will be odd and guess will be zero
|
||||
Anyway, it is correct to say that distance is zero but
|
||||
we want to return +inf if we are exiting the solid
|
||||
So ..
|
||||
*/
|
||||
|
||||
/* Check here is the root found is into interval */
|
||||
|
||||
if ((guess >= (Lmin - EPSILON)) && (guess <= (Lmax + EPSILON))) {
|
||||
return guess ;
|
||||
} else {
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus Point does not appear to be in the interval guess = "
|
||||
<< guess
|
||||
<< " Lmin = " << Lmin - EPSILON << " Lmax = "
|
||||
<< Lmax + EPSILON << G4endl ;
|
||||
#endif
|
||||
|
||||
if (NbIntersection == 3) {
|
||||
/** OK we are in the small part around the BVM **/
|
||||
/** So we check the second interval **/
|
||||
Lmin = SortL[1];
|
||||
Lmax = SortL[2];
|
||||
guess = Lmin;
|
||||
|
||||
guess = Newton(guess,x,y,z,dx,dy,dz,Rmax,Rmin,Lmin,Lmax);
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus Second Newton guess = "
|
||||
<< guess << G4endl ;
|
||||
G4cout << "G4Torus::DistanceToTorus Lmin = " << Lmin
|
||||
<< " Lmax = " << Lmax << G4endl ;
|
||||
#endif
|
||||
if ((guess >= (Lmin - EPSILON)) && (guess <= (Lmax + EPSILON))) {
|
||||
return guess;
|
||||
} else {
|
||||
return NOINTERSECTION;
|
||||
}
|
||||
} else {
|
||||
if (InsideTorus == 1) {
|
||||
/* Incredible : sometimes precisions errors bring us here
|
||||
with guess = SortL[0]
|
||||
So we return guess ..
|
||||
*/
|
||||
|
||||
G4cout << "G4Torus: Root not found .." << G4endl ;
|
||||
G4cout << "Point: "<< x << " " << y << " " << z << G4endl ;
|
||||
G4cout << "Dir : "<< dx << " " << dy << " " << dz << G4endl ;
|
||||
return guess;
|
||||
}
|
||||
return NOINTERSECTION;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // Outside
|
||||
/*** If we are Out then we need more to know if intersection exists ***/
|
||||
/*** there is 2 intersection points at least (perhaps the same) with BVMax ***/
|
||||
|
||||
/*** Return if no intersection with BVMax ***/
|
||||
|
||||
if (NbIntersection == 0)
|
||||
return NOINTERSECTION ;
|
||||
|
||||
|
||||
break;
|
||||
case 2:
|
||||
Lmin = SortL[0] ;
|
||||
Lmax = SortL[1] ;
|
||||
/** Lmin because it is probably near the BVM entry point **/
|
||||
/** PROBLEM if the ray hits the top of BVM with a small angle
|
||||
then the interval is too big and the guess is bad **/
|
||||
guess = Lmin ;
|
||||
|
||||
break;
|
||||
#if HOLEBVM
|
||||
case 3:
|
||||
Lmin = 0.0 ;
|
||||
Lmax = SortL[0] ;
|
||||
|
||||
TorusEquationClass torus (Rmax,Rmin);
|
||||
torus.setPosition(x,y,z);
|
||||
torus.setDirection(dx,dy,dz);
|
||||
|
||||
G4PolynomialSolver<TorusEquationClass,G4double(TorusEquationClass::*)(G4double)>
|
||||
PolySolver(&torus,
|
||||
&TorusEquationClass::Function,
|
||||
&TorusEquationClass::Derivative,
|
||||
TORUSPRECISION) ;
|
||||
|
||||
/*** We know only that if there is a solution, it is between Lmin and Lmax ***/
|
||||
/*** But we are not sure that there is one ... ***/
|
||||
|
||||
/* Ready to do Newton */
|
||||
guess = Newton(guess,x,y,z,dx,dy,dz,Rmax,Rmin,Lmin,Lmax);
|
||||
guess = PolySolver.solve(Lmin,Lmax);
|
||||
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus Newton with 2 or 4 points : "
|
||||
<< guess << G4endl ;
|
||||
#endif
|
||||
|
||||
/* Check here is the root found is into interval */
|
||||
if ((guess >= (Lmin - EPSILON)) && (guess <= (Lmax + EPSILON))) {
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus Newton gives a point into interval (Ok)"
|
||||
<< G4endl ;
|
||||
#endif
|
||||
return guess;
|
||||
} else {
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus Newton does not give a point into interval (Ko)"
|
||||
<< G4endl ;
|
||||
#endif
|
||||
if (NbIntersection == 4) {
|
||||
/* Well if that does not converge with the first interval try with the other one */
|
||||
Lmin = SortL[2] ;
|
||||
Lmax = SortL[3] ;
|
||||
|
||||
guess = Lmin;
|
||||
guess = Newton(guess,x,y,z,dx,dy,dz,Rmax,Rmin,Lmin,Lmax);
|
||||
if ((guess >= (Lmin - EPSILON)) && (guess <= (Lmax + EPSILON))) {
|
||||
return guess;
|
||||
} else {
|
||||
return NOINTERSECTION;
|
||||
}
|
||||
} else {
|
||||
/* Certainly this is due to the BVM part that is not in Torus */
|
||||
|
||||
return NOINTERSECTION ;
|
||||
}
|
||||
if ((guess >= (Lmin - POLEPSILON)) && (guess <= (Lmax + POLEPSILON))) {
|
||||
return guess ;
|
||||
} else {
|
||||
Lmin = SortL[1] ;
|
||||
Lmax = SortL[2] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
Lmin = SortL[0] ;
|
||||
Lmax = SortL[1] ;
|
||||
|
||||
|
||||
G4int G4Torus::SafeNewton(G4double x, G4double y, G4double z,
|
||||
G4double dx, G4double dy, G4double dz,
|
||||
G4double Rmax, G4double Rmin,
|
||||
G4double *Lmin,G4double *Lmax) const
|
||||
{
|
||||
/** SafeNewton is a clipping interval Newton method **/
|
||||
/** This method is at least 3 times slower than Newton but is sure to work **/
|
||||
/** So it could be better to use it when Newton is not enough **/
|
||||
TorusEquationClass torus (Rmax,Rmin);
|
||||
torus.setPosition(x,y,z);
|
||||
torus.setDirection(dx,dy,dz);
|
||||
|
||||
G4double P[5][2],D[2] ;
|
||||
G4double Lx,Ly,Lz ;
|
||||
G4double NewMin,NewMax;
|
||||
|
||||
G4int IntervalIsVoid = 1;
|
||||
G4int NewtonIsSafe = 0;
|
||||
|
||||
/*** Calculating Control Points ***/
|
||||
|
||||
/*
|
||||
0 p0 = F((*Lmin))
|
||||
1/4 p1 = F((*Lmin)) + ((*Lmax) - (*Lmin))/4 * F'((*Lmin))
|
||||
2/4 p2 = 1/6 * (16*F(((*Lmax) + (*Lmin))/2) - (p0 + 4*p1 + 4*p3 + p4))
|
||||
3/4 p3 = F((*Lmax)) - ((*Lmax) - (*Lmin))/4 * F'((*Lmax))
|
||||
1 p4 = F((*Lmax))
|
||||
*/
|
||||
G4PolynomialSolver<TorusEquationClass,G4double(TorusEquationClass::*)(G4double)>
|
||||
PolySolver(&torus,
|
||||
&TorusEquationClass::Function,
|
||||
&TorusEquationClass::Derivative,
|
||||
TORUSPRECISION) ;
|
||||
|
||||
|
||||
Lx = x + (*Lmin)*dx;
|
||||
Ly = y + (*Lmin)*dy;
|
||||
Lz = z + (*Lmin)*dz;
|
||||
guess = PolySolver.solve(Lmin,Lmax);
|
||||
|
||||
D[0] = dx*TorusDerivativeX(Lx,Ly,Lz,Rmax,Rmin);
|
||||
D[0] += dy*TorusDerivativeY(Lx,Ly,Lz,Rmax,Rmin);
|
||||
D[0] += dz*TorusDerivativeZ(Lx,Ly,Lz,Rmax,Rmin);
|
||||
|
||||
P[0][0] = (*Lmin);
|
||||
P[0][1] = TorusEquation(Lx,Ly,Lz,Rmax,Rmin);
|
||||
|
||||
if (fabs(P[0][1]) < TORUSPRECISION) {
|
||||
NewtonIsSafe = 1;
|
||||
return NewtonIsSafe;
|
||||
}
|
||||
|
||||
if (((*Lmax) - (*Lmin)) < EPSILON) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
P[1][0] = (*Lmin) + ((*Lmax) - (*Lmin))/4;
|
||||
P[1][1] = P[0][1] + (((*Lmax) - (*Lmin))/4.0) * D[0];
|
||||
|
||||
Lx = x + (*Lmax)*dx;
|
||||
Ly = y + (*Lmax)*dy;
|
||||
Lz = z + (*Lmax)*dz;
|
||||
|
||||
D[1] = dx*TorusDerivativeX(Lx,Ly,Lz,Rmax,Rmin);
|
||||
D[1] += dy*TorusDerivativeY(Lx,Ly,Lz,Rmax,Rmin);
|
||||
D[1] += dz*TorusDerivativeZ(Lx,Ly,Lz,Rmax,Rmin);
|
||||
|
||||
P[4][0] = (*Lmax);
|
||||
P[4][1] = TorusEquation(Lx,Ly,Lz,Rmax,Rmin);
|
||||
P[3][0] = (*Lmax) - ((*Lmax) - (*Lmin))/4;
|
||||
P[3][1] = P[4][1] - ((*Lmax) - (*Lmin))/4 * D[1];
|
||||
|
||||
Lx = x + ((*Lmax)+(*Lmin))/2*dx;
|
||||
Ly = y + ((*Lmax)+(*Lmin))/2*dy;
|
||||
Lz = z + ((*Lmax)+(*Lmin))/2*dz;
|
||||
|
||||
P[2][0] = ((*Lmax) + (*Lmin))/2;
|
||||
P[2][1] = (16*TorusEquation(Lx,Ly,Lz,Rmax,Rmin)
|
||||
- (P[0][1] + 4*P[1][1] + 4*P[3][1] + P[4][1]))/6 ;
|
||||
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::SafeNewton Lmin = " << (*Lmin) << G4endl ;
|
||||
G4cout << "G4Torus::SafeNewton Lmax = " << (*Lmax) << G4endl ;
|
||||
G4cout << "G4Torus::SafeNewton P[0] = " << P[0][1] << G4endl ;
|
||||
G4cout << "G4Torus::SafeNewton P[1] = " << P[1][1] << G4endl ;
|
||||
G4cout << "G4Torus::SafeNewton P[2] = " << P[2][1] << G4endl ;
|
||||
G4cout << "G4Torus::SafeNewton P[3] = " << P[3][1] << G4endl ;
|
||||
G4cout << "G4Torus::SafeNewton P[4] = " << P[4][1] << G4endl ;
|
||||
#endif
|
||||
|
||||
/** Ok now we have all control points, we could compute the convex area **/
|
||||
/** Problems:
|
||||
- if there is one point with a ~ 0 coordinate and all the other the
|
||||
same sign we miss the value
|
||||
- if there are more than a root in the interval then the interval
|
||||
length does not decrease to 0. A solution may be to split intervals
|
||||
in the middle but how to know when we must split ?
|
||||
**/
|
||||
|
||||
/*** For each points make 2 sets. A set of positive points and a set
|
||||
of negative points ***/
|
||||
/*** Note: could be better done with scalar product .. ***/
|
||||
/**
|
||||
We have to compute convex area of the control point before
|
||||
applying intersection with y=0
|
||||
**/
|
||||
|
||||
/* there is an intersection only if each have different signs */
|
||||
/* PROBLEM : If a control point have a 0.00 value the sign check is wrong
|
||||
try to solve that with TORUSPRECISION ..
|
||||
*/
|
||||
{
|
||||
G4double Intersection ;
|
||||
G4int i,j;
|
||||
|
||||
NewMin = (*Lmax) ;
|
||||
NewMax = (*Lmin) ;
|
||||
|
||||
for (i=0;i<5;i++)
|
||||
for (j=i+1;j<5;j++)
|
||||
{
|
||||
/* there is an intersection only if each have different signs */
|
||||
if (((P[j][1] > -TORUSPRECISION) && (P[i][1] < TORUSPRECISION)) ||
|
||||
((P[j][1] < TORUSPRECISION) && (P[i][1] > -TORUSPRECISION))) {
|
||||
IntervalIsVoid = 0;
|
||||
Intersection = P[j][0] - P[j][1]*((P[i][0] - P[j][0])
|
||||
/(P[i][1] - P[j][1]));
|
||||
if (Intersection < NewMin) {
|
||||
NewMin = Intersection;
|
||||
}
|
||||
if (Intersection > NewMax) {
|
||||
NewMax = Intersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IntervalIsVoid != 1) {
|
||||
|
||||
(*Lmax) = NewMax;
|
||||
(*Lmin) = NewMin;
|
||||
if ((guess >= (Lmin - POLEPSILON)) && (guess <= (Lmax + POLEPSILON))) {
|
||||
return guess ;
|
||||
} else {
|
||||
Lmin = SortL[2] ;
|
||||
Lmax = SortL[3] ;
|
||||
}
|
||||
}
|
||||
|
||||
if (IntervalIsVoid == 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return NewtonIsSafe;
|
||||
}
|
||||
|
||||
|
||||
G4double G4Torus::Newton (G4double guess,
|
||||
G4double x, G4double y, G4double z,
|
||||
G4double dx, G4double dy, G4double dz,
|
||||
G4double Rmax, G4double Rmin,
|
||||
G4double Lmin,G4double Lmax) const
|
||||
{
|
||||
/* So now we have a good guess and an interval where
|
||||
if there are an intersection the root must be */
|
||||
|
||||
G4double Lx = 0;
|
||||
G4double Ly = 0;
|
||||
G4double Lz = 0;
|
||||
G4double Value = 0;
|
||||
G4double Gradient = 0;
|
||||
G4double Lambda ;
|
||||
|
||||
G4int i=0;
|
||||
|
||||
/* Reduce interval before applying Newton Method */
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::Newton Lmin = " << Lmin
|
||||
<< " Lmax = " << Lmax << G4endl ;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
G4cerr << "G4Torus::DistanceToTorus NbIntersection = " << NbIntersection << G4endl;
|
||||
break;
|
||||
}
|
||||
|
||||
TorusEquationClass torus (Rmax,Rmin);
|
||||
torus.setPosition(x,y,z);
|
||||
torus.setDirection(dx,dy,dz);
|
||||
|
||||
{
|
||||
G4int NewtonIsSafe ;
|
||||
G4int k;
|
||||
/*
|
||||
Here we stop to compute after ITERATION loop
|
||||
*/
|
||||
for (k=0;
|
||||
((k<ITERATION) &&
|
||||
((NewtonIsSafe = SafeNewton(x,y,z,dx,dy,dz,Rmax,Rmin,&Lmin,&Lmax))==0));
|
||||
k++);
|
||||
|
||||
G4PolynomialSolver<TorusEquationClass,G4double(TorusEquationClass::*)(G4double)>
|
||||
PolySolver(&torus,
|
||||
&TorusEquationClass::Function,
|
||||
&TorusEquationClass::Derivative,
|
||||
TORUSPRECISION) ;
|
||||
|
||||
/* But in fact it is safer to compute while this is safe
|
||||
while ((NewtonIsSafe = SafeNewton(x,y,z,dx,dy,dz,Rmax,Rmin,&Lmin,&Lmax)) == 0) ;
|
||||
guess = PolySolver.solve(Lmin,Lmax);
|
||||
|
||||
Problem: the mathematical algorithm is the one with the while loop
|
||||
but because of precision issue we could have TorusEquation(point) never equal to zero..
|
||||
But we see that all initial points are on the bounding volume. So there is a superior limit
|
||||
to the number of iteration in the while loop to reach the point with the given precision.
|
||||
|
||||
*/
|
||||
|
||||
guess = Lmin;
|
||||
}
|
||||
|
||||
/** So with SafeNewton we do not need a guess **/
|
||||
|
||||
Lambda = guess;
|
||||
Value = TorusEquation(x + Lambda*dx,y + Lambda*dy,z + Lambda*dz,Rmax,Rmin);
|
||||
|
||||
//If we want a gnuplot graphics af the function
|
||||
#if 0
|
||||
{
|
||||
FILE *fi;
|
||||
G4int i;
|
||||
fi = fopen("GNUplot.out","w+");
|
||||
fprintf(fi,"# Newton plot\n");
|
||||
|
||||
for (i = 0; i < 1000 ; i ++) {
|
||||
Lx = x + (Lmin + i*(Lmax - Lmin)/1000.0)*dx;
|
||||
Ly = y + (Lmin + i*(Lmax - Lmin)/1000.0)*dy;
|
||||
Lz = z + (Lmin + i*(Lmax - Lmin)/1000.0)*dz;
|
||||
Value = TorusEquation(Lx,Ly,Lz,Rmax,Rmin);
|
||||
fprintf(fi," %f %f\n",Lmin + i*(Lmax - Lmin)/1000.0,Value );
|
||||
}
|
||||
|
||||
fclose(fi);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* In fact The Torus Equation give big number
|
||||
so TORUS PRECISION is not EPSILON */
|
||||
while (fabs(Value) > TORUSPRECISION) {
|
||||
|
||||
Lx = x + Lambda*dx;
|
||||
Ly = y + Lambda*dy;
|
||||
Lz = z + Lambda*dz;
|
||||
Value = TorusEquation(Lx,Ly,Lz,Rmax,Rmin);
|
||||
|
||||
Gradient = dx*TorusDerivativeX(Lx,Ly,Lz,Rmax,Rmin);
|
||||
Gradient += dy*TorusDerivativeY(Lx,Ly,Lz,Rmax,Rmin);
|
||||
Gradient += dz*TorusDerivativeZ(Lx,Ly,Lz,Rmax,Rmin);
|
||||
|
||||
/**
|
||||
if (Gradient > -EPSILON) { // then the current point is repulsive
|
||||
and may not converge
|
||||
Seems to be solved by SafeNewton
|
||||
**/
|
||||
Lambda = Lambda - Value/Gradient ;
|
||||
|
||||
|
||||
if ((guess >= (Lmin - POLEPSILON)) && (guess <= (Lmax + POLEPSILON))) {
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::Newton Iteration " << i << G4endl ;
|
||||
G4cout << "G4Torus::Newton Lambda = " << Lambda
|
||||
<< " Value = " << Value << " Grad = " << Gradient << G4endl;
|
||||
G4cout << "G4Torus::Newton Lmin = " << Lmin
|
||||
<< " Lmax = " << Lmax << G4endl ;
|
||||
G4cout << "G4Torus::DistanceToTorus distance = " << guess << G4endl ;
|
||||
#endif
|
||||
|
||||
i ++;
|
||||
|
||||
if (i > ITERATION)
|
||||
return NOINTERSECTION; //no convergency ??
|
||||
|
||||
}
|
||||
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::Newton Exiting with Lambda = " << Lambda << G4endl ;
|
||||
G4cout << "G4Torus::Newton Exiting with Value = " << Value << G4endl ;
|
||||
if (Gradient > 0.0) {
|
||||
G4cout << "G4Torus::Newton Gradient: Exiting surface" << G4endl ;
|
||||
return guess ;
|
||||
} else {
|
||||
G4cout << "G4Torus::Newton Gradient: Entering surface" << G4endl ;
|
||||
}
|
||||
#if DEBUGTORUS
|
||||
G4cout << "G4Torus::DistanceToTorus : kInfinity" << G4endl ;
|
||||
#endif
|
||||
|
||||
|
||||
return Lambda ;
|
||||
return kInfinity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Trap.cc,v 1.8 2000/11/20 17:58:01 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
// class G4Trap
|
||||
//
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Trd.cc,v 1.7 2000/11/20 17:58:01 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
//
|
||||
// Implementation for G4Trd class
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Tubs.cc,v 1.23 2000/11/28 15:05:52 grichine Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
// $Id: G4Tubs.cc,v 1.28 2001/02/21 15:47:14 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-01 $
|
||||
//
|
||||
//
|
||||
// class G4Tubs
|
||||
@@ -28,6 +28,9 @@
|
||||
// 08.08.00 V.Grichine, more stable roots of 2-equation in Distance ToOut(p,v,...)
|
||||
// 31.10.00 V.Grichine, assign sr, sphi in Distance ToOut(p,v,...)
|
||||
// 28.11.00 V.Grichine, bug fixed in Inside(p)
|
||||
// 07.12.00 V.Grichine, phi-section algorithm was changed in Inside(p)
|
||||
// 20.02.01 V.Grichine, bug fixed in Inside(p) and CalculateExtent was
|
||||
// simplified base on G4Box::CalculateExtent
|
||||
|
||||
#include "G4Tubs.hh"
|
||||
|
||||
@@ -44,6 +47,7 @@
|
||||
#include "G4NURBStube.hh"
|
||||
#include "G4NURBScylinder.hh"
|
||||
#include "G4NURBStubesector.hh"
|
||||
#include "G4Box.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -139,6 +143,9 @@ G4bool G4Tubs::CalculateExtent( const EAxis pAxis,
|
||||
G4double& pMin,
|
||||
G4double& pMax ) const
|
||||
{
|
||||
G4Box box("box",fRMax,fRMax,fDz) ;
|
||||
return box.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax) ;
|
||||
/*
|
||||
if ( !pTransform.IsRotated() && fDPhi == 2.0*M_PI && fRMin == 0 )
|
||||
{
|
||||
// Special case handling for unrotated solid tubes
|
||||
@@ -324,8 +331,10 @@ G4bool G4Tubs::CalculateExtent( const EAxis pAxis,
|
||||
delete vertices;
|
||||
return existsAfterClip;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return whether point inside/outside/on surface
|
||||
@@ -354,25 +363,32 @@ EInside G4Tubs::Inside(const G4ThreeVector& p) const
|
||||
|
||||
pPhi = atan2(p.y(),p.x()) ;
|
||||
|
||||
if ( pPhi < 0 ) pPhi += 2*M_PI ; // 0<=pPhi<2pi
|
||||
if ( pPhi < -kAngTolerance*0.5 ) pPhi += 2*M_PI ; // 0<=pPhi<2pi
|
||||
|
||||
if ( fSPhi >= 0 )
|
||||
{
|
||||
if ( abs(pPhi) < kAngTolerance*0.5 &&
|
||||
abs(fSPhi + fDPhi - 2*M_PI) < kAngTolerance*0.5 )
|
||||
{
|
||||
pPhi += 2*M_PI ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( pPhi >= fSPhi + kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi + fDPhi-kAngTolerance*0.5 ) in = kInside ;
|
||||
pPhi <= fSPhi + fDPhi - kAngTolerance*0.5 ) in = kInside ;
|
||||
|
||||
else if ( pPhi >= fSPhi - kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi + fDPhi + kAngTolerance*0.5 ) in = kSurface ;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
else // fSPhi < 0
|
||||
{
|
||||
// if (pPhi < fSPhi + 2*M_PI) pPhi += 2*M_PI ;
|
||||
if ( pPhi <= fSPhi + 2*M_PI - kAngTolerance*0.5 &&
|
||||
pPhi >= fSPhi + fDPhi + kAngTolerance*0.5) ;
|
||||
|
||||
if ( pPhi >= fSPhi + 2*M_PI + kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi + fDPhi + 2*M_PI - kAngTolerance*0.5) in = kInside ;
|
||||
else if ( pPhi <= fSPhi + 2*M_PI + kAngTolerance*0.5 &&
|
||||
pPhi >= fSPhi + fDPhi - kAngTolerance*0.5) in = kSurface ;
|
||||
|
||||
else if (pPhi >= fSPhi+2*M_PI-kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi+fDPhi+2*M_PI+kAngTolerance*0.5) in = kSurface ;
|
||||
else in = kInside ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,25 +409,30 @@ EInside G4Tubs::Inside(const G4ThreeVector& p) const
|
||||
{
|
||||
pPhi = atan2(p.y(),p.x()) ;
|
||||
|
||||
if ( pPhi < 0 ) pPhi += 2*M_PI ; // 0<=pPhi<2pi
|
||||
if ( pPhi < -kAngTolerance*0.5 ) pPhi += 2*M_PI ; // 0<=pPhi<2pi
|
||||
|
||||
if ( fSPhi >= 0 )
|
||||
{
|
||||
if (pPhi >= fSPhi-kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi+fDPhi+kAngTolerance*0.5) in = kSurface ;
|
||||
if ( abs(pPhi) < kAngTolerance*0.5 &&
|
||||
abs(fSPhi + fDPhi - 2*M_PI) < kAngTolerance*0.5 )
|
||||
{
|
||||
pPhi += 2*M_PI ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( pPhi >= fSPhi - kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi + fDPhi + kAngTolerance*0.5) in = kSurface ;
|
||||
}
|
||||
else
|
||||
else // fSPhi < 0
|
||||
{
|
||||
// if (pPhi < fSPhi + 2*M_PI ) pPhi += 2*M_PI ;
|
||||
if ( pPhi <= fSPhi + 2*M_PI - kAngTolerance*0.5 &&
|
||||
pPhi >= fSPhi + fDPhi + kAngTolerance*0.5) ;
|
||||
|
||||
if (pPhi >= fSPhi+2*M_PI-kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi+fDPhi+2*M_PI+kAngTolerance*0.5) in=kSurface;
|
||||
else in = kSurface ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fabs(p.z()) <= fDz+kCarTolerance*0.5) // Check within tolerant r limits
|
||||
else if (fabs(p.z()) <= fDz + kCarTolerance*0.5) // Check within tolerant r limits
|
||||
{
|
||||
r2 = p.x()*p.x() + p.y()*p.y() ;
|
||||
tolRMin = fRMin - kRadTolerance*0.5 ;
|
||||
@@ -429,19 +450,23 @@ EInside G4Tubs::Inside(const G4ThreeVector& p) const
|
||||
{
|
||||
pPhi = atan2(p.y(),p.x()) ;
|
||||
|
||||
if ( pPhi < 0 ) pPhi += 2*M_PI ; // 0<=pPhi<2pi
|
||||
if ( pPhi < -kAngTolerance*0.5 ) pPhi += 2*M_PI ; // 0<=pPhi<2pi
|
||||
|
||||
if ( fSPhi >= 0 )
|
||||
{
|
||||
if (pPhi >= fSPhi-kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi+fDPhi+kAngTolerance*0.5) in=kSurface;
|
||||
if ( abs(pPhi) < kAngTolerance*0.5 &&
|
||||
abs(fSPhi + fDPhi - 2*M_PI) < kAngTolerance*0.5 )
|
||||
{
|
||||
pPhi += 2*M_PI ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( pPhi >= fSPhi - kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi + fDPhi + kAngTolerance*0.5) in = kSurface;
|
||||
}
|
||||
else
|
||||
else // fSPhi < 0
|
||||
{
|
||||
if ( pPhi < fSPhi + 2*M_PI ) pPhi += 2*M_PI ;
|
||||
|
||||
if ( pPhi >= fSPhi+2*M_PI-kAngTolerance*0.5 &&
|
||||
pPhi <= fSPhi+fDPhi+2*M_PI+kAngTolerance*0.5) in = kSurface ;
|
||||
if ( pPhi <= fSPhi + 2*M_PI - kAngTolerance*0.5 &&
|
||||
pPhi >= fSPhi + fDPhi + kAngTolerance*0.5) ;
|
||||
else in = kSurface ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,6 +474,8 @@ EInside G4Tubs::Inside(const G4ThreeVector& p) const
|
||||
return in ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return unit normal of surface closest to p
|
||||
|
||||
Reference in New Issue
Block a user