58 halfkCarTolerance = kCarTolerance*0.5;
59 halfkRadTolerance = kRadTolerance*0.5;
60 halfkAngTolerance = kAngTolerance*0.5;
61 fMinStep = 0.05*kCarTolerance;
76 const G4int replicaNo,
88 G4double coord, rad2, rmin, tolRMax2, rmax, tolRMin2;
97 coord = std::fabs(localPoint(axis))-width*0.5;
98 if ( coord<=-halfkCarTolerance )
102 else if ( coord<=halfkCarTolerance )
108 if ( (localPoint.
y() != 0.0)||(localPoint.
x() != 0.0) )
110 coord = std::fabs(std::atan2(localPoint.
y(),localPoint.
x()))-width*0.5;
111 if ( coord<=-halfkAngTolerance )
115 else if ( coord<=halfkAngTolerance )
126 rad2 = localPoint.
perp2();
127 rmax = (replicaNo+1)*width+offset;
128 tolRMax2 = rmax-halfkRadTolerance;
129 tolRMax2 *= tolRMax2;
132 tolRMax2 = rmax+halfkRadTolerance;
133 tolRMax2 *= tolRMax2;
134 if ( rad2<=tolRMax2 )
143 if ( (replicaNo != 0)||(offset != 0.0) )
146 tolRMin2 = rmin-halfkRadTolerance;
147 tolRMin2 *= tolRMin2;
150 tolRMin2 = rmin+halfkRadTolerance;
151 tolRMin2 *= tolRMin2;
152 if ( rad2>=tolRMin2 )
169 G4Exception(
"G4ReplicaNavigation::Inside()",
"GeomNav0002",
182 const G4int replicaNo,
202 coord = localPoint(axis);
203 safe1 = width*0.5-coord;
204 safe2 = width*0.5+coord;
205 safety = (safe1<=safe2) ? safe1 : safe2;
208 if ( localPoint.
y()<=0 )
210 safety = localPoint.
x()*std::sin(width*0.5)
211 + localPoint.
y()*std::cos(width*0.5);
215 safety = localPoint.
x()*std::sin(width*0.5)
216 - localPoint.
y()*std::cos(width*0.5);
220 rho = localPoint.
perp();
221 rmax = width*(replicaNo+1)+offset;
222 if ( (replicaNo != 0)||(offset != 0.0) )
227 safety = (safe1<=safe2) ? safe1 : safe2;
235 G4Exception(
"G4ReplicaNavigation::DistanceToOut()",
"GeomNav0002",
239 return (safety >= halfkCarTolerance) ? safety : 0;
248 const G4int replicaNo,
271 coord = localPoint(axis);
272 Comp = localDirection(axis);
275 lindist = width*0.5-coord;
276 Dist = (lindist>0) ? lindist/Comp : 0;
281 lindist = width*0.5+coord;
282 Dist = (lindist>0) ? -lindist/Comp : 0;
290 candidateNormal.
exitNormal = ( signC * VecCartAxes[axis]);
294 (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis];
297 Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal);
301 Dist = DistanceToOutRad(localPoint,localDirection,width,offset,
302 replicaNo,candidateNormal);
306 G4Exception(
"G4ReplicaNavigation::DistanceToOut()",
"GeomNav0002",
311 arExitNormal= candidateNormal;
321G4ReplicaNavigation::DistanceToOutPhi(
const G4ThreeVector& localPoint,
329 G4double sinSPhi = -2.0, cosSPhi = -2.0;
330 G4double pDistS, pDistE, compS, compE, Dist, dist2, yi;
334 if ( (localPoint.
x()!=0.0) || (localPoint.
y()!=0.0) )
336 sinSPhi = std::sin(-width*0.5);
337 cosSPhi = std::cos(width*0.5);
341 pDistS = localPoint.
x()*sinSPhi-localPoint.
y()*cosSPhi;
343 pDistE = localPoint.
x()*sinSPhi+localPoint.
y()*cosSPhi;
348 compS = -sinSPhi*localDirection.
x()+cosSPhi*localDirection.
y();
349 compE = -sinSPhi*localDirection.
x()-cosSPhi*localDirection.
y();
351 if ( (pDistS<=halfkCarTolerance)&&(pDistE<=halfkCarTolerance) )
357 dist2 = pDistS/compS;
358 yi = localPoint.
y()+dist2*localDirection.
y();
364 Dist = (pDistS<=-halfkCarTolerance) ? dist2 : 0;
378 dist2 = pDistE/compE;
384 yi = localPoint.
y()+dist2*localDirection.
y();
392 Dist = (pDistE<=-halfkCarTolerance) ? dist2 : 0;
398 else if ( (pDistS>halfkCarTolerance)&&(pDistE>halfkCarTolerance) )
403 Dist = ((compS>=0)&&(compE>=0)) ? kInfinity : 0;
405 else if ( (pDistS>halfkCarTolerance)&&(pDistE<=halfkCarTolerance) )
411 dist2 = pDistE/compE;
412 yi = localPoint.
y()+dist2*localDirection.
y();
417 Dist = (yi>0) ? dist2 : kInfinity;
434 dist2 = pDistS/compS;
435 yi = localPoint.
y()+dist2*localDirection.
y();
440 Dist = (yi<0) ? dist2 : kInfinity;
461 if( (std::fabs(localDirection.
phi())<=width*0.5) )
495G4ReplicaNavigation::DistanceToOutRad(
const G4ThreeVector& localPoint,
499 const G4int replicaNo,
522 rmin = replicaNo*width+offset;
523 rmax = (replicaNo+1)*width+offset;
525 t1 = 1.0-localDirection.
z()*localDirection.
z();
526 t2 = localPoint.
x()*localDirection.
x()+localPoint.
y()*localDirection.
y();
527 t3 = localPoint.
x()*localPoint.
x()+localPoint.
y()*localPoint.
y();
542 if ( deltaR<-halfkRadTolerance )
546 srd = -b+std::sqrt(b*b-c);
574 srd = (
deltaR>halfkRadTolerance) ? -b-std::sqrt(d2) : 0.0;
586 srd = (d2 < 0.) ? 0.0 : -b+
std::sqrt(d2);
598 srd = (d2 < 0.) ? 0.0 : -b+
std::sqrt(d2);
615 xi = localPoint.
x() + srd*localDirection.
x();
616 yi = localPoint.
y() + srd*localDirection.
y();
625 normalR *= (-1.0)/rmin;
665 val = -width*0.5*(nReplicas-1)+width*replicaNo;
667 point.
setX(point.
x()-val);
670 val = -width*0.5*(nReplicas-1)+width*replicaNo;
672 point.
setY(point.
y()-val);
675 val = -width*0.5*(nReplicas-1)+width*replicaNo;
677 point.
setZ(point.
z()-val);
680 val = -(offset+width*(replicaNo+0.5));
681 SetPhiTransformation(val,pVol);
682 cosv = std::cos(val);
683 sinv = std::sin(val);
684 tmpx = point.
x()*cosv-point.
y()*sinv;
685 tmpy = point.
x()*sinv+point.
y()*cosv;
720 val = -width*0.5*(nReplicas-1)+width*replicaNo;
724 val = -width*0.5*(nReplicas-1)+width*replicaNo;
728 val = -width*0.5*(nReplicas-1)+width*replicaNo;
732 val = -(offset+width*(replicaNo+0.5));
733 SetPhiTransformation(val,pVol);
751 const G4double currentProposedStepLength,
756 G4bool& calculatedExitNormal,
761 G4int& blockedReplicaNo )
768 G4double ourStep=currentProposedStepLength;
770 G4double sampleStep, sampleSafety, motherStep, motherSafety;
771 G4long localNoDaughters, sampleNo;
776 calculatedExitNormal=
false;
780 if ( exiting&&validExitNormal )
782 if ( localDirection.
dot(exitNormalVector)>=kMinExitingNormalCosine )
786 blockedExitedVol = *pBlockedPhysical;
806 ourSafety = std::min( ourSafety, sampleSafety);
808 if ( sampleSafety<ourStep )
816 if ( sampleStep<ourStep )
818 ourStep = sampleStep;
822 exitNormalStc = normalOutStc;
825 calculatedExitNormal =
true;
828 const G4int secondDepth = topDepth;
841 if ( sampleSafety < ourSafety )
843 ourSafety = sampleSafety;
845 if ( sampleSafety < ourStep )
854 if ( sampleStep < ourStep )
856 ourStep = sampleStep;
865 exitNormalStc = normalOutStc;
867 calculatedExitNormal =
true;
876 G4bool exitConvex =
false;
880 motherPhysical = history.
GetVolume(depth);
885 motherStep = motherSolid->
DistanceToOut(repPoint,repDirection,
true,
886 &exitConvex,&exitVectorMother);
889 motherNormalStc =
G4ExitNormal( exitVectorMother,
true,
false,
891 calculatedExitNormal =
true;
895 G4bool motherDeterminedStep = (motherStep<ourStep);
897 if( (!exitConvex) && motherDeterminedStep )
900 motherNormalStc =
G4ExitNormal( exitVectorMother,
true,
false,
906 calculatedExitNormal =
true;
908 if( motherDeterminedStep )
913 exitNormalStc = motherNormalStc;
914 exitNormalStc.
exitNormal = globalExitNormalTop;
924 if( ourStep<fMinStep )
926 ourStep = 2*kCarTolerance;
929 if ( motherSafety<ourSafety )
931 ourSafety = motherSafety;
939 std::ostringstream message;
940 message <<
"Point outside volume !" <<
G4endl
941 <<
" Point " << localPoint
942 <<
" is outside current volume " << motherPhysical->
GetName()
945 message <<
" Estimated isotropic distance to solid (distToIn)= "
946 << estDistToSolid <<
G4endl;
947 if( estDistToSolid > 100.0 * kCarTolerance )
952 "Point is far outside Current Volume !" );
958 "Point is a little outside Current Volume.");
967 if( motherDeterminedStep )
969 ourStep = motherStep;
975 if ( calculatedExitNormal )
977 if ( motherDeterminedStep )
979 exitNormalVector = motherNormalStc.
exitNormal;
984 exitNormalVector = globalToLocalTop.
TransformAxis(exitNormalGlobal);
990 if ( rot !=
nullptr )
992 exitNormalVector *= rot->
inverse();
998 validExitNormal =
false;
1002 if ( motherSafety<=ourStep )
1004 if ( motherStep<=ourStep )
1006 ourStep = motherStep;
1008 if ( validExitNormal )
1019 validExitNormal =
false;
1026 G4bool daughterDeterminedStep =
false;
1035 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1038 if ( samplePhysical!=blockedExitedVol )
1050 const G4double sampleSafetyDistance =
1052 if ( sampleSafetyDistance<ourSafety )
1054 ourSafety = sampleSafetyDistance;
1056 if ( sampleSafetyDistance<=ourStep )
1059 const G4double sampleStepDistance =
1060 sampleSolid->
DistanceToIn(samplePoint,sampleDirection);
1061 if ( sampleStepDistance<=ourStep )
1063 daughterDeterminedStep =
true;
1065 ourStep = sampleStepDistance;
1068 *pBlockedPhysical = samplePhysical;
1069 blockedReplicaNo = (
G4int)sampleNo;
1071#ifdef DAUGHTER_NORMAL_ALSO
1081 if ( ( fCheck ) && ( sampleStepDistance < kInfinity ) )
1084 intersectionPoint = samplePoint
1085 + sampleStepDistance * sampleDirection;
1086 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
1090 std::ostringstream message;
1091 message <<
"Navigator gets conflicting response from Solid."
1093 <<
" Inaccurate DistanceToIn for solid "
1095 <<
" Solid gave DistanceToIn = "
1096 << sampleStepDistance <<
" yet returns " ;
1097 if ( insideIntPt ==
kInside ) {
1098 message <<
"-kInside-";
1099 }
else if ( insideIntPt ==
kOutside ) {
1100 message <<
"-kOutside-";
1102 message <<
"-kSurface-";
1104 message <<
" for this point !" <<
G4endl
1105 <<
" Point = " << intersectionPoint <<
G4endl;
1106 if ( insideIntPt !=
kInside ) {
1107 message <<
" DistanceToIn(p) = "
1112 message <<
" DistanceToOut(p) = "
1117 G4cout.precision(oldcoutPrec);
1126 calculatedExitNormal &= (!daughterDeterminedStep);
1128#ifdef DAUGHTER_NORMAL_ALSO
1129 if( daughterDeterminedStep )
1136 validExitNormal =
false;
1138 calculatedExitNormal =
true;
1143 newSafety = ourSafety;
1167 G4long localNoDaughters, sampleNo;
1180 if ( sampleSafety<ourSafety )
1182 ourSafety = sampleSafety;
1194 if ( sampleSafety<ourSafety )
1196 ourSafety = sampleSafety;
1204 motherPhysical = history.
GetVolume(depth);
1208 if ( sampleSafety<ourSafety )
1210 ourSafety = sampleSafety;
1216 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1219 if ( samplePhysical!=blockedExitedVol )
1228 const G4double sampleSafetyDistance =
1230 if ( sampleSafetyDistance<ourSafety )
1232 ourSafety = sampleSafetyDistance;
1248 G4bool& notKnownInside )
const
1253 G4int mdepth, depth, cdepth;
1260 for ( mdepth=cdepth-1; mdepth>=0; mdepth-- )
1269 if( pNRMother ==
nullptr )
1274 G4Exception(
"G4ReplicaNavigation::BackLocate()",
"GeomNav0002",
1281 insideCode = motherSolid->
Inside(goodPoint);
1293 notKnownInside =
false;
1298 for ( depth=mdepth+1; depth<cdepth; ++depth)
1306 localPoint = goodPoint;
1310 goodPoint = repPoint;
1322 localPoint = goodPoint;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
HepRotation inverse() const
G4double GetSurfaceTolerance() const
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
G4VSolid * GetSolid() const
std::size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
G4int GetReplicaNo(G4int n) const
const G4AffineTransform & GetTopTransform() const
G4int GetTopReplicaNo() const
G4VPhysicalVolume * GetVolume(G4int n) const
std::size_t GetDepth() const
G4VPhysicalVolume * GetTopVolume() const
EVolume GetVolumeType(G4int n) const
const G4AffineTransform & GetTransform(G4int n) const
G4double DistanceToOut(const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4bool &calculatedExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4double ComputeSafety(const G4ThreeVector &globalPoint, const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX) const
void ComputeTransformation(const G4int replicaNo, G4VPhysicalVolume *pVol, G4ThreeVector &point) const
EInside Inside(const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
EInside BackLocate(G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool ¬KnownInside) const
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
const G4String & GetName() const
void SetTranslation(const G4ThreeVector &v)
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0