71 const G4double currentProposedStepLength,
79 G4int& blockedReplicaNo)
86 G4double ourStep=currentProposedStepLength, ourSafety;
88 G4bool motherValidExitNormal =
false;
93 G4bool initialNode, noStep;
95 G4long curNoVolumes, contentNo;
107 motherSolid = motherLogical->
GetSolid();
114 ourSafety = motherSafety;
119 if( motherSafety < 0.0 )
122 std::ostringstream message;
123 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
124 <<
" Current solid " << motherSolid->
GetName()
125 <<
" gave negative safety: " << motherSafety <<
G4endl
126 <<
" for the current (local) point " << localPoint;
127 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
132 std::ostringstream message;
133 message <<
"Point is outside Current Volume !" <<
G4endl
134 <<
" Point " << localPoint
135 <<
" is outside current volume " << motherPhysical->
GetName()
138 G4cout <<
" Estimated isotropic distance to solid (distToIn)= "
140 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
143 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
145 "Point is far outside Current Volume !");
149 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
151 "Point is a little outside Current Volume.");
163 &motherValidExitNormal,
166 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
170 fLogger->ReportOutsideMother(localPoint, localDirection, motherPhysical);
172 ourStep = motherStep = 0.0;
177 validExitNormal = motherValidExitNormal;
178 exitNormal = motherExitNormal;
180 *pBlockedPhysical =
nullptr;
181 blockedReplicaNo = 0;
197 fBList.Enlarge(nReplicas);
202 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal)
204 if (localDirection.
dot(exitNormal)>=kMinExitingNormalCosine)
208 fBList.BlockVolume(blockedReplicaNo);
224 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
227 if ( !
fBList.IsBlocked(sampleNo) )
229 fBList.BlockVolume(sampleNo);
233 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical,
241 if ( sampleSafety<ourSafety )
243 ourSafety = sampleSafety;
245 if ( sampleSafety<=ourStep )
249 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
250 if ( sampleStep<=ourStep )
252 ourStep = sampleStep;
255 *pBlockedPhysical = samplePhysical;
256 blockedReplicaNo = sampleNo;
262 if ( (
fCheck ) && ( sampleStep < kInfinity ) )
265 intersectionPoint = samplePoint + sampleStep * sampleDirection;
266 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
270 std::ostringstream message;
271 message <<
"Navigator gets conflicting response from Solid."
273 <<
" Inaccurate solid DistanceToIn"
275 <<
" Solid gave DistanceToIn = "
276 << sampleStep <<
" yet returns " ;
279 message <<
"-kInside-";
283 message <<
"-kOutside-";
287 message <<
"-kSurface-";
289 message <<
" for this point !" <<
G4endl
290 <<
" Point = " << intersectionPoint
294 message <<
" DistanceToIn(p) = "
299 message <<
" DistanceToOut(p) = "
302 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
304 G4cout.precision(oldcoutPrec);
316 voxelSafety = ComputeVoxelSafety(localPoint,
axis);
317 if ( voxelSafety<ourSafety )
319 ourSafety = voxelSafety;
321 if ( currentProposedStepLength<ourSafety )
328 *pBlockedPhysical =
nullptr;
335 if ( motherSafety<=ourStep )
342 &motherValidExitNormal,
346 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
349 fLogger->ReportOutsideMother(localPoint, localDirection,
352 ourStep = motherStep = 0.0;
358 if( motherValidExitNormal && (
fCheck || (motherStep<=ourStep)) )
360 fLogger->CheckAndReportBadNormal(motherExitNormal,
361 localPoint, localDirection,
362 motherStep, motherSolid,
363 "From motherSolid::DistanceToOut");
366 if ( motherStep<=ourStep )
368 ourStep = motherStep;
371 if ( validExitNormal )
382 validExitNormal =
false;
386 newSafety = ourSafety;
390 noStep = LocateNextVoxel(localPoint, localDirection, ourStep,
axis);
409 G4VSolid *motherSolid, *sampleSolid;
411 G4int sampleNo, curVoxelNodeNo;
414 G4long curNoVolumes, contentNo;
426 motherSolid = motherLogical->
GetSolid();
433 ourSafety = motherSafety;
444 width,
offset, consuming);
455 curVoxelNodeNo =
G4int((localPoint(fVoxelAxis)
456 -fVoxelHeader->GetMinExtent()) / fVoxelSliceWidth );
457 curVoxelNode = fVoxelHeader->GetSlice(curVoxelNodeNo)->GetNode();
458 fVoxelNodeNo = curVoxelNodeNo;
463 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
469 sampleSolid= IdentifyAndPlaceSolid( sampleNo,samplePhysical,sampleParam );
476 if ( sampleSafety<ourSafety )
478 ourSafety = sampleSafety;
482 voxelSafety = ComputeVoxelSafety(localPoint,
axis);
483 if ( voxelSafety<ourSafety )
485 ourSafety=voxelSafety;
500 const EAxis pAxis)
const
510 G4double voxelSafety, plusVoxelSafety, minusVoxelSafety;
511 G4double curNodeOffset, minCurCommonDelta, maxCurCommonDelta;
512 G4long minCurNodeNoDelta, maxCurNodeNoDelta;
517 curNodeOffset = fVoxelNodeNo*fVoxelSliceWidth;
518 minCurCommonDelta = localPoint(fVoxelAxis)
519 - fVoxelHeader->GetMinExtent()-curNodeOffset;
520 maxCurNodeNoDelta =
fVoxelNode->GetMaxEquivalentSliceNo()-fVoxelNodeNo;
521 minCurNodeNoDelta = fVoxelNodeNo-
fVoxelNode->GetMinEquivalentSliceNo();
522 maxCurCommonDelta = fVoxelSliceWidth-minCurCommonDelta;
523 plusVoxelSafety = minCurNodeNoDelta*fVoxelSliceWidth+minCurCommonDelta;
524 minusVoxelSafety = maxCurNodeNoDelta*fVoxelSliceWidth+maxCurCommonDelta;
525 voxelSafety = std::min(plusVoxelSafety,minusVoxelSafety);
546G4bool G4ParameterisedNavigation::
564 G4double minVal, maxVal, curMinExtent, curCoord;
566 curMinExtent = fVoxelHeader->GetMinExtent();
567 curCoord = localPoint(fVoxelAxis)+currentStep*localDirection(fVoxelAxis);
568 minVal = curMinExtent+
fVoxelNode->GetMinEquivalentSliceNo()*fVoxelSliceWidth;
571 if ( minVal<=curCoord )
573 maxVal = curMinExtent
574 + (
fVoxelNode->GetMaxEquivalentSliceNo()+1)*fVoxelSliceWidth;
575 if ( maxVal<curCoord )
577 newNodeNo =
fVoxelNode->GetMaxEquivalentSliceNo()+1;
578 if ( newNodeNo<
G4int(fVoxelHeader->GetNoSlices()) )
580 fVoxelNodeNo = newNodeNo;
581 fVoxelNode = fVoxelHeader->GetSlice(newNodeNo)->GetNode();
588 newNodeNo =
fVoxelNode->GetMinEquivalentSliceNo()-1;
595 fVoxelNodeNo = newNodeNo;
596 fVoxelNode = fVoxelHeader->GetSlice(newNodeNo)->GetNode();
610 const G4int blockedNum,
613 const G4bool pLocatedOnEdge,
623 G4int voxelNoDaughters, replicaNo;
634 if ( voxelNoDaughters==0 ) {
return false; }
646 for (
auto sampleNo=voxelNoDaughters-1; sampleNo>=0; sampleNo-- )
648 replicaNo = motherVoxelNode->
GetVolume(sampleNo);
649 if ( (replicaNo!=blockedNum) || (pPhysical!=blockedVol) )
653 pSolid = IdentifyAndPlaceSolid( replicaNo, pPhysical, pParam );
668 localPoint = samplePoint;
679 pPhysical, &parentTouchable) );
697 if (
auto pVoxelHeader = motherLogical->GetVoxelHeader() )
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4ThreadLocal T * G4GeomSplitter< T >::offset
CLHEP::HepRotation G4RotationMatrix
CLHEP::Hep3Vector G4ThreeVector
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)
G4LogicalVolume represents a leaf node or unpositioned subtree in the geometry hierarchy....
G4VSolid * GetSolid() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
void SetSolid(G4VSolid *pSolid)
G4SmartVoxelHeader * GetVoxelHeader() const
void UpdateMaterial(G4Material *pMaterial)
G4NavigationHistory is a class responsible for the maintenance of the history of the path taken throu...
void NewLevel(G4VPhysicalVolume *pNewMother, EVolume vType=kNormal, G4int nReplica=-1)
const G4AffineTransform & GetTopTransform() const
G4VPhysicalVolume * GetTopVolume() const
G4SmartVoxelNode * ParamVoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
~G4ParameterisedNavigation() override
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX) override
G4double ComputeStep(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) 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
G4SmartVoxelNode defines a node in the smart voxel hierarchy, i.e. a 'slice' of space along a given a...
G4int GetVolume(G4int pVolumeNo) const
std::size_t GetNoContained() const
G4TouchableHistory is an object representing a touchable detector element, and its history in the geo...
G4VPVParameterisation ia an abstract base class for Parameterisation, able to compute the transformat...
virtual G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=nullptr)
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
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
G4VSolid is an abstract base class for solids, physical shapes that can be tracked through....
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
const axis_t axis_to_type< N >::axis