73 const G4double currentProposedStepLength,
81 G4int& blockedReplicaNo)
88 G4double ourStep=currentProposedStepLength, ourSafety;
90 G4bool motherValidExitNormal =
false;
95 G4bool initialNode, noStep;
97 G4long curNoVolumes, contentNo;
109 motherSolid = motherLogical->
GetSolid();
116 ourSafety = motherSafety;
121 if( motherSafety < 0.0 )
124 std::ostringstream message;
125 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
126 <<
" Current solid " << motherSolid->
GetName()
127 <<
" gave negative safety: " << motherSafety <<
G4endl
128 <<
" for the current (local) point " << localPoint;
129 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
134 std::ostringstream message;
135 message <<
"Point is outside Current Volume !" <<
G4endl
136 <<
" Point " << localPoint
137 <<
" is outside current volume " << motherPhysical->
GetName()
140 G4cout <<
" Estimated isotropic distance to solid (distToIn)= "
142 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
145 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
147 "Point is far outside Current Volume !");
151 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
153 "Point is a little outside Current Volume.");
165 &motherValidExitNormal,
168 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
174 ourStep = motherStep = 0.0;
179 validExitNormal = motherValidExitNormal;
180 exitNormal = motherExitNormal;
182 *pBlockedPhysical =
nullptr;
183 blockedReplicaNo = 0;
204 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal)
206 if (localDirection.
dot(exitNormal)>=kMinExitingNormalCosine)
226 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
235 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical,
243 if ( sampleSafety<ourSafety )
245 ourSafety = sampleSafety;
247 if ( sampleSafety<=ourStep )
251 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
252 if ( sampleStep<=ourStep )
254 ourStep = sampleStep;
257 *pBlockedPhysical = samplePhysical;
258 blockedReplicaNo = sampleNo;
264 if ( (
fCheck ) && ( sampleStep < kInfinity ) )
267 intersectionPoint = samplePoint + sampleStep * sampleDirection;
268 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
272 std::ostringstream message;
273 message <<
"Navigator gets conflicting response from Solid."
275 <<
" Inaccurate solid DistanceToIn"
277 <<
" Solid gave DistanceToIn = "
278 << sampleStep <<
" yet returns " ;
281 message <<
"-kInside-";
285 message <<
"-kOutside-";
289 message <<
"-kSurface-";
291 message <<
" for this point !" <<
G4endl
292 <<
" Point = " << intersectionPoint
296 message <<
" DistanceToIn(p) = "
301 message <<
" DistanceToOut(p) = "
304 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
306 G4cout.precision(oldcoutPrec);
318 voxelSafety = ComputeVoxelSafety(localPoint,axis);
319 if ( voxelSafety<ourSafety )
321 ourSafety = voxelSafety;
323 if ( currentProposedStepLength<ourSafety )
330 *pBlockedPhysical =
nullptr;
337 if ( motherSafety<=ourStep )
344 &motherValidExitNormal,
348 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
354 ourStep = motherStep = 0.0;
360 if( motherValidExitNormal && (
fCheck || (motherStep<=ourStep)) )
363 localPoint, localDirection,
364 motherStep, motherSolid,
365 "From motherSolid::DistanceToOut");
368 if ( motherStep<=ourStep )
370 ourStep = motherStep;
373 if ( validExitNormal )
384 validExitNormal =
false;
388 newSafety = ourSafety;
392 noStep = LocateNextVoxel(localPoint, localDirection, ourStep, axis);
411 G4VSolid *motherSolid, *sampleSolid;
413 G4int sampleNo, curVoxelNodeNo;
416 G4long curNoVolumes, contentNo;
428 motherSolid = motherLogical->
GetSolid();
435 ourSafety = motherSafety;
446 width, offset, consuming);
457 curVoxelNodeNo =
G4int((localPoint(fVoxelAxis)
460 fVoxelNodeNo = curVoxelNodeNo;
465 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
471 sampleSolid= IdentifyAndPlaceSolid( sampleNo,samplePhysical,sampleParam );
478 if ( sampleSafety<ourSafety )
480 ourSafety = sampleSafety;
484 voxelSafety = ComputeVoxelSafety(localPoint,axis);
485 if ( voxelSafety<ourSafety )
487 ourSafety=voxelSafety;
502 const EAxis pAxis)
const
512 G4double voxelSafety, plusVoxelSafety, minusVoxelSafety;
513 G4double curNodeOffset, minCurCommonDelta, maxCurCommonDelta;
514 G4long minCurNodeNoDelta, maxCurNodeNoDelta;
519 curNodeOffset = fVoxelNodeNo*fVoxelSliceWidth;
520 minCurCommonDelta = localPoint(fVoxelAxis)
524 maxCurCommonDelta = fVoxelSliceWidth-minCurCommonDelta;
525 plusVoxelSafety = minCurNodeNoDelta*fVoxelSliceWidth+minCurCommonDelta;
526 minusVoxelSafety = maxCurNodeNoDelta*fVoxelSliceWidth+maxCurCommonDelta;
527 voxelSafety = std::min(plusVoxelSafety,minusVoxelSafety);
548G4bool G4ParameterisedNavigation::
566 G4double minVal, maxVal, curMinExtent, curCoord;
569 curCoord = localPoint(fVoxelAxis)+currentStep*localDirection(fVoxelAxis);
573 if ( minVal<=curCoord )
575 maxVal = curMinExtent
577 if ( maxVal<curCoord )
582 fVoxelNodeNo = newNodeNo;
597 fVoxelNodeNo = newNodeNo;
612 const G4int blockedNum,
615 const G4bool pLocatedOnEdge,
625 G4int voxelNoDaughters, replicaNo;
636 if ( voxelNoDaughters==0 ) {
return false; }
648 for (
auto sampleNo=voxelNoDaughters-1; sampleNo>=0; sampleNo-- )
650 replicaNo = motherVoxelNode->
GetVolume(sampleNo);
651 if ( (replicaNo!=blockedNum) || (pPhysical!=blockedVol) )
655 pSolid = IdentifyAndPlaceSolid( replicaNo, pPhysical, pParam );
670 localPoint = samplePoint;
681 pPhysical, &parentTouchable) );
696 assert(motherLogical->GetNoDaughters() == 1);
698 if (
auto pVoxelHeader = motherLogical->GetVoxelHeader() )
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 std::size_t 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
G4SmartVoxelNode * ParamVoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
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) override
~G4ParameterisedNavigation() override
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX) override
G4ParameterisedNavigation()
void RelocateWithinVolume(G4VPhysicalVolume *motherPhysical, const G4ThreeVector &localPoint) override
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) override
G4int GetMaxEquivalentSliceNo() const
G4int GetVolume(G4int pVolumeNo) const
std::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 G4int GetRegularStructureId() const =0
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