58 halfkCarTolerance = kCarTolerance*0.5;
59 halfkRadTolerance = kRadTolerance*0.5;
60 halfkAngTolerance = kAngTolerance*0.5;
61 fMinStep = 0.05*kCarTolerance;
78 const G4int replicaNo,
90 G4double coord, rad2, rmin, tolRMax2, rmax, tolRMin2;
99 coord = std::fabs(localPoint(axis))-width*0.5;
100 if ( coord<=-halfkCarTolerance )
104 else if ( coord<=halfkCarTolerance )
110 if ( localPoint.
y()||localPoint.
x() )
112 coord = std::fabs(std::atan2(localPoint.
y(),localPoint.
x()))-width*0.5;
113 if ( coord<=-halfkAngTolerance )
117 else if ( coord<=halfkAngTolerance )
128 rad2 = localPoint.
perp2();
129 rmax = (replicaNo+1)*width+offset;
130 tolRMax2 = rmax-halfkRadTolerance;
131 tolRMax2 *= tolRMax2;
134 tolRMax2 = rmax+halfkRadTolerance;
135 tolRMax2 *= tolRMax2;
136 if ( rad2<=tolRMax2 )
145 if ( replicaNo||offset )
148 tolRMin2 = rmin-halfkRadTolerance;
149 tolRMin2 *= tolRMin2;
152 tolRMin2 = rmin+halfkRadTolerance;
153 tolRMin2 *= tolRMin2;
154 if ( rad2>=tolRMin2 )
171 G4Exception(
"G4ReplicaNavigation::Inside()",
"GeomNav0002",
184 const G4int replicaNo,
204 coord = localPoint(axis);
205 safe1 = width*0.5-coord;
206 safe2 = width*0.5+coord;
207 safety = (safe1<=safe2) ? safe1 : safe2;
210 if ( localPoint.
y()<=0 )
212 safety = localPoint.
x()*std::sin(width*0.5)
213 + localPoint.
y()*std::cos(width*0.5);
217 safety = localPoint.
x()*std::sin(width*0.5)
218 - localPoint.
y()*std::cos(width*0.5);
222 rho = localPoint.
perp();
223 rmax = width*(replicaNo+1)+offset;
224 if ( replicaNo||offset )
229 safety = (safe1<=safe2) ? safe1 : safe2;
237 G4Exception(
"G4ReplicaNavigation::DistanceToOut()",
"GeomNav0002",
241 return (safety >= halfkCarTolerance) ? safety : 0;
250 const G4int replicaNo,
273 coord = localPoint(axis);
274 Comp = localDirection(axis);
277 lindist = width*0.5-coord;
278 Dist = (lindist>0) ? lindist/Comp : 0;
283 lindist = width*0.5+coord;
284 Dist = (lindist>0) ? -lindist/Comp : 0;
292 candidateNormal.
exitNormal = ( signC * VecCartAxes[axis]);
296 (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis];
299 Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal);
303 Dist = DistanceToOutRad(localPoint,localDirection,width,offset,
304 replicaNo,candidateNormal);
308 G4Exception(
"G4ReplicaNavigation::DistanceToOut()",
"GeomNav0002",
313 arExitNormal= candidateNormal;
323G4ReplicaNavigation::DistanceToOutPhi(
const G4ThreeVector& localPoint,
331 G4double sinSPhi = -2.0, cosSPhi = -2.0;
332 G4double pDistS, pDistE, compS, compE, Dist, dist2, yi;
336 if ( (localPoint.
x()!=0.0) || (localPoint.
y()!=0.0) )
338 sinSPhi = std::sin(-width*0.5);
339 cosSPhi = std::cos(width*0.5);
343 pDistS = localPoint.
x()*sinSPhi-localPoint.
y()*cosSPhi;
345 pDistE = localPoint.
x()*sinSPhi+localPoint.
y()*cosSPhi;
350 compS = -sinSPhi*localDirection.
x()+cosSPhi*localDirection.
y();
351 compE = -sinSPhi*localDirection.
x()-cosSPhi*localDirection.
y();
353 if ( (pDistS<=halfkCarTolerance)&&(pDistE<=halfkCarTolerance) )
359 dist2 = pDistS/compS;
360 yi = localPoint.
y()+dist2*localDirection.
y();
366 Dist = (pDistS<=-halfkCarTolerance) ? dist2 : 0;
380 dist2 = pDistE/compE;
386 yi = localPoint.
y()+dist2*localDirection.
y();
394 Dist = (pDistE<=-halfkCarTolerance) ? dist2 : 0;
400 else if ( (pDistS>halfkCarTolerance)&&(pDistE>halfkCarTolerance) )
405 Dist = ((compS>=0)&&(compE>=0)) ? kInfinity : 0;
407 else if ( (pDistS>halfkCarTolerance)&&(pDistE<=halfkCarTolerance) )
413 dist2 = pDistE/compE;
414 yi = localPoint.
y()+dist2*localDirection.
y();
419 Dist = (yi>0) ? dist2 : kInfinity;
436 dist2 = pDistS/compS;
437 yi = localPoint.
y()+dist2*localDirection.
y();
442 Dist = (yi<0) ? dist2 : kInfinity;
463 if( (std::fabs(localDirection.
phi())<=width*0.5) )
497G4ReplicaNavigation::DistanceToOutRad(
const G4ThreeVector& localPoint,
501 const G4int replicaNo,
504 G4double rmin, rmax, t1, t2, t3, deltaR;
524 rmin = replicaNo*width+offset;
525 rmax = (replicaNo+1)*width+offset;
527 t1 = 1.0-localDirection.
z()*localDirection.
z();
528 t2 = localPoint.
x()*localDirection.
x()+localPoint.
y()*localDirection.
y();
529 t3 = localPoint.
x()*localPoint.
x()+localPoint.
y()*localPoint.
y();
539 deltaR = t3-rmax*rmax;
544 if ( deltaR<-halfkRadTolerance )
548 srd = -b+std::sqrt(b*b-c);
566 deltaR = t3-rmin*rmin;
576 srd = (deltaR>halfkRadTolerance) ? -b-std::sqrt(d2) : 0.0;
585 deltaR = t3-rmax*rmax;
588 srd = (d2 < 0.) ? 0.0 : -b+std::sqrt(d2);
596 deltaR = t3-rmax*rmax;
600 srd = (d2 < 0.) ? 0.0 : -b+std::sqrt(d2);
617 xi = localPoint.
x() + srd*localDirection.
x();
618 yi = localPoint.
y() + srd*localDirection.
y();
627 normalR *= (-1.0)/rmin;
667 val = -width*0.5*(nReplicas-1)+width*replicaNo;
669 point.
setX(point.
x()-val);
672 val = -width*0.5*(nReplicas-1)+width*replicaNo;
674 point.
setY(point.
y()-val);
677 val = -width*0.5*(nReplicas-1)+width*replicaNo;
679 point.
setZ(point.
z()-val);
682 val = -(offset+width*(replicaNo+0.5));
683 SetPhiTransformation(val,pVol);
684 cosv = std::cos(val);
685 sinv = std::sin(val);
686 tmpx = point.
x()*cosv-point.
y()*sinv;
687 tmpy = point.
x()*sinv+point.
y()*cosv;
722 val = -width*0.5*(nReplicas-1)+width*replicaNo;
726 val = -width*0.5*(nReplicas-1)+width*replicaNo;
730 val = -width*0.5*(nReplicas-1)+width*replicaNo;
734 val = -(offset+width*(replicaNo+0.5));
735 SetPhiTransformation(val,pVol);
753 const G4double currentProposedStepLength,
758 G4bool& calculatedExitNormal,
763 G4int& blockedReplicaNo )
770 G4double ourStep=currentProposedStepLength;
772 G4double sampleStep, sampleSafety, motherStep, motherSafety;
773 G4long localNoDaughters, sampleNo;
778 calculatedExitNormal=
false;
782 if ( exiting&&validExitNormal )
784 if ( localDirection.
dot(exitNormalVector)>=kMinExitingNormalCosine )
788 blockedExitedVol = *pBlockedPhysical;
808 ourSafety = std::min( ourSafety, sampleSafety);
810 if ( sampleSafety<ourStep )
818 if ( sampleStep<ourStep )
820 ourStep = sampleStep;
824 exitNormalStc = normalOutStc;
827 calculatedExitNormal =
true;
830 const G4int secondDepth = topDepth;
843 if ( sampleSafety < ourSafety )
845 ourSafety = sampleSafety;
847 if ( sampleSafety < ourStep )
856 if ( sampleStep < ourStep )
858 ourStep = sampleStep;
867 exitNormalStc = normalOutStc;
869 calculatedExitNormal =
true;
878 G4bool exitConvex =
false;
882 motherPhysical = history.
GetVolume(depth);
887 motherStep = motherSolid->
DistanceToOut(repPoint,repDirection,
true,
888 &exitConvex,&exitVectorMother);
891 motherNormalStc =
G4ExitNormal( exitVectorMother,
true,
false,
893 calculatedExitNormal =
true;
897 G4bool motherDeterminedStep = (motherStep<ourStep);
899 if( (!exitConvex) && motherDeterminedStep )
902 motherNormalStc =
G4ExitNormal( exitVectorMother,
true,
false,
908 calculatedExitNormal =
true;
910 if( motherDeterminedStep )
915 exitNormalStc = motherNormalStc;
916 exitNormalStc.
exitNormal = globalExitNormalTop;
926 if( ourStep<fMinStep )
928 ourStep = 2*kCarTolerance;
931 if ( motherSafety<ourSafety )
933 ourSafety = motherSafety;
941 std::ostringstream message;
942 message <<
"Point outside volume !" <<
G4endl
943 <<
" Point " << localPoint
944 <<
" is outside current volume " << motherPhysical->
GetName()
947 message <<
" Estimated isotropic distance to solid (distToIn)= "
948 << estDistToSolid <<
G4endl;
949 if( estDistToSolid > 100.0 * kCarTolerance )
954 "Point is far outside Current Volume !" );
959 "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);
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 " ;
1098 message <<
"-kInside-";
1099 else if ( insideIntPt ==
kOutside )
1100 message <<
"-kOutside-";
1102 message <<
"-kSurface-";
1103 message <<
" for this point !" <<
G4endl
1104 <<
" Point = " << intersectionPoint <<
G4endl;
1106 message <<
" DistanceToIn(p) = "
1110 message <<
" DistanceToOut(p) = "
1114 G4cout.precision(oldcoutPrec);
1123 calculatedExitNormal &= (!daughterDeterminedStep);
1125#ifdef DAUGHTER_NORMAL_ALSO
1126 if( daughterDeterminedStep )
1133 validExitNormal =
false;
1135 calculatedExitNormal =
true;
1140 newSafety = ourSafety;
1164 G4long localNoDaughters, sampleNo;
1177 if ( sampleSafety<ourSafety )
1179 ourSafety = sampleSafety;
1191 if ( sampleSafety<ourSafety )
1193 ourSafety = sampleSafety;
1201 motherPhysical = history.
GetVolume(depth);
1205 if ( sampleSafety<ourSafety )
1207 ourSafety = sampleSafety;
1213 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1216 if ( samplePhysical!=blockedExitedVol )
1225 const G4double sampleSafetyDistance =
1227 if ( sampleSafetyDistance<ourSafety )
1229 ourSafety = sampleSafetyDistance;
1245 G4bool& notKnownInside )
const
1250 G4int mdepth, depth, cdepth;
1257 for ( mdepth=cdepth-1; mdepth>=0; mdepth-- )
1266 if( pNRMother ==
nullptr )
1271 G4Exception(
"G4ReplicaNavigation::BackLocate()",
"GeomNav0002",
1278 insideCode = motherSolid->
Inside(goodPoint);
1290 notKnownInside =
false;
1295 for ( depth=mdepth+1; depth<cdepth; ++depth)
1303 localPoint = goodPoint;
1309 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, G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
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