75 const G4double currentProposedStepLength,
83 G4int& blockedReplicaNo)
90 G4double ourStep=currentProposedStepLength, ourSafety;
92 G4bool motherValidExitNormal =
false;
97 G4bool initialNode, noStep;
99 G4int curNoVolumes, contentNo;
111 motherSolid = motherLogical->
GetSolid();
118 ourSafety = motherSafety;
123 if( motherSafety < 0.0 )
126 std::ostringstream message;
127 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
128 <<
" Current solid " << motherSolid->
GetName()
129 <<
" gave negative safety: " << motherSafety <<
G4endl
130 <<
" for the current (local) point " << localPoint;
131 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
136 std::ostringstream message;
137 message <<
"Point is outside Current Volume !" <<
G4endl
138 <<
" Point " << localPoint
139 <<
" is outside current volume " << motherPhysical->
GetName()
142 G4cout <<
" Estimated isotropic distance to solid (distToIn)= "
144 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
147 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
149 "Point is far outside Current Volume !");
153 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
155 "Point is a little outside Current Volume.");
167 &motherValidExitNormal,
170 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
176 ourStep = motherStep = 0.0;
181 validExitNormal = motherValidExitNormal;
182 exitNormal = motherExitNormal;
184 *pBlockedPhysical =
nullptr;
185 blockedReplicaNo = 0;
206 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal)
208 if (localDirection.
dot(exitNormal)>=kMinExitingNormalCosine)
228 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
230 sampleNo = curVoxelNode->
GetVolume(contentNo);
237 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical,
245 if ( sampleSafety<ourSafety )
247 ourSafety = sampleSafety;
249 if ( sampleSafety<=ourStep )
253 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
254 if ( sampleStep<=ourStep )
256 ourStep = sampleStep;
259 *pBlockedPhysical = samplePhysical;
260 blockedReplicaNo = sampleNo;
266 if ( (
fCheck ) && ( sampleStep < kInfinity ) )
269 intersectionPoint = samplePoint + sampleStep * sampleDirection;
270 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
274 std::ostringstream message;
275 message <<
"Navigator gets conflicting response from Solid."
277 <<
" Inaccurate solid DistanceToIn"
279 <<
" Solid gave DistanceToIn = "
280 << sampleStep <<
" yet returns " ;
282 message <<
"-kInside-";
284 message <<
"-kOutside-";
286 message <<
"-kSurface-";
287 message <<
" for this point !" <<
G4endl
288 <<
" Point = " << intersectionPoint
291 message <<
" DistanceToIn(p) = "
294 message <<
" DistanceToOut(p) = "
296 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
298 G4cout.precision(oldcoutPrec);
310 voxelSafety = ComputeVoxelSafety(localPoint,axis);
311 if ( voxelSafety<ourSafety )
313 ourSafety = voxelSafety;
315 if ( currentProposedStepLength<ourSafety )
322 *pBlockedPhysical =
nullptr;
329 if ( motherSafety<=ourStep )
336 &motherValidExitNormal,
340 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
346 ourStep = motherStep = 0.0;
352 if( motherValidExitNormal && (
fCheck || (motherStep<=ourStep)) )
355 localPoint, localDirection,
356 motherStep, motherSolid,
357 "From motherSolid::DistanceToOut");
360 if ( motherStep<=ourStep )
362 ourStep = motherStep;
365 if ( validExitNormal )
376 validExitNormal =
false;
380 newSafety = ourSafety;
384 noStep = LocateNextVoxel(localPoint, localDirection, ourStep, axis);
403 G4VSolid *motherSolid, *sampleSolid;
405 G4int sampleNo, curVoxelNodeNo;
408 G4int curNoVolumes, contentNo;
420 motherSolid = motherLogical->
GetSolid();
427 ourSafety = motherSafety;
438 width, offset, consuming);
449 curVoxelNodeNo =
G4int((localPoint(fVoxelAxis)
452 fVoxelNodeNo = curVoxelNodeNo;
457 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
459 sampleNo = curVoxelNode->
GetVolume(contentNo);
463 sampleSolid= IdentifyAndPlaceSolid( sampleNo,samplePhysical,sampleParam );
470 if ( sampleSafety<ourSafety )
472 ourSafety = sampleSafety;
476 voxelSafety = ComputeVoxelSafety(localPoint,axis);
477 if ( voxelSafety<ourSafety )
479 ourSafety=voxelSafety;
494 const EAxis pAxis)
const
504 G4double voxelSafety, plusVoxelSafety, minusVoxelSafety;
505 G4double curNodeOffset, minCurCommonDelta, maxCurCommonDelta;
506 G4int minCurNodeNoDelta, maxCurNodeNoDelta;
511 curNodeOffset = fVoxelNodeNo*fVoxelSliceWidth;
512 minCurCommonDelta = localPoint(fVoxelAxis)
516 maxCurCommonDelta = fVoxelSliceWidth-minCurCommonDelta;
517 plusVoxelSafety = minCurNodeNoDelta*fVoxelSliceWidth+minCurCommonDelta;
518 minusVoxelSafety = maxCurNodeNoDelta*fVoxelSliceWidth+maxCurCommonDelta;
519 voxelSafety = std::min(plusVoxelSafety,minusVoxelSafety);
540G4bool G4ParameterisedNavigation::
558 G4double minVal, maxVal, curMinExtent, curCoord;
561 curCoord = localPoint(fVoxelAxis)+currentStep*localDirection(fVoxelAxis);
565 if ( minVal<=curCoord )
567 maxVal = curMinExtent
569 if ( maxVal<curCoord )
574 fVoxelNodeNo = newNodeNo;
589 fVoxelNodeNo = newNodeNo;
604 const G4int blockedNum,
607 const G4bool pLocatedOnEdge,
617 G4int voxelNoDaughters, replicaNo;
628 if ( voxelNoDaughters==0 ) {
return false; }
640 for (
auto sampleNo=voxelNoDaughters-1; sampleNo>=0; sampleNo-- )
642 replicaNo = motherVoxelNode->
GetVolume(sampleNo);
643 if ( (replicaNo!=blockedNum) || (pPhysical!=blockedVol) )
647 pSolid = IdentifyAndPlaceSolid( replicaNo, pPhysical, pParam );
662 localPoint = samplePoint;
673 pPhysical, &parentTouchable) );
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
HepRotation inverse() const
static G4bool CheckPointOnSurface(const G4VSolid *sampleSolid, const G4ThreeVector &localPoint, const G4ThreeVector *globalDirection, const G4AffineTransform &sampleTransform, const G4bool locatedOnEdge)
void BlockVolume(const G4int v)
void Enlarge(const G4int nv)
G4bool IsBlocked(const G4int v) const
G4VSolid * GetSolid() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
void SetSolid(G4VSolid *pSolid)
G4SmartVoxelHeader * GetVoxelHeader() const
void UpdateMaterial(G4Material *pMaterial)
void NewLevel(G4VPhysicalVolume *pNewMother, EVolume vType=kNormal, G4int nReplica=-1)
const G4AffineTransform & GetTopTransform() const
G4VPhysicalVolume * GetTopVolume() const
G4bool CheckAndReportBadNormal(const G4ThreeVector &unitNormal, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double step, const G4VSolid *solid, const char *msg) const
void ReportOutsideMother(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *motherPV, G4double tDist=30.0 *CLHEP::cm) const
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4SmartVoxelNode * ParamVoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
G4ParameterisedNavigation()
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
~G4ParameterisedNavigation()
G4int GetMaxEquivalentSliceNo() const
G4int GetVolume(G4int pVolumeNo) const
size_t GetNoContained() const
G4int GetMinEquivalentSliceNo() const
G4SmartVoxelNode * GetNode() const
virtual G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=nullptr)
const G4RotationMatrix * GetRotation() const
virtual void SetCopyNo(G4int CopyNo)=0
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
virtual G4VPVParameterisation * GetParameterisation() const =0
G4double GetTolerance() const
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 G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
G4NavigationLogger * fLogger
G4SmartVoxelNode * fVoxelNode
G4bool LocateNextVoxel(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentStep)
G4double ComputeVoxelSafety(const G4ThreeVector &localPoint) const