37 #include <CLHEP/Units/SystemOfUnits.h>
46 : fId(id), fVerbose(0), fMinTriggerDistance(
DBL_MAX ), fReportSoftWarnings( false )
69 G4cout <<
"*************** " << fType <<
" *****************" <<
G4endl
71 << std::setw(15) <<
"Safety/mm" <<
" "
72 << std::setw(15) <<
"Distance/mm" <<
" "
73 << std::setw(52) <<
"Position (local coordinates)"
76 << std::setw(15) << motherSafety /
millimeter <<
" "
77 << std::setw(15) <<
"N/C" <<
" " << localPoint <<
" - "
81 if ( motherSafety < 0.0 )
83 std::ostringstream message;
84 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
85 <<
" Current solid " << motherSolid->
GetName()
87 <<
" for the current (local) point " << localPoint;
88 message <<
" Solid info: " << *motherSolid <<
G4endl;
93 std::ostringstream message;
94 message <<
"Point is outside Current Volume - " <<
G4endl
96 <<
" is outside current volume '" << motherPhysical->
GetName()
99 message <<
" Estimated isotropic distance to solid (distToIn)= "
100 << estDistToSolid <<
G4endl;
101 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
103 message <<
" Solid info: " << *motherSolid <<
G4endl;
105 "Point is far outside Current Volume !" );
110 "Point is a little outside Current Volume.");
118 static const G4int precVerf= 16;
120 G4cout <<
" - Information on mother / key daughters ..." <<
G4endl;
121 G4cout <<
" Type " << std::setw(12) <<
"Solid-Name" <<
" "
122 << std::setw(3*(6+precVerf)) <<
" local point" <<
" "
123 << std::setw(4+precVerf) <<
"solid-Safety" <<
" "
124 << std::setw(4+precVerf) <<
"solid-Step" <<
" "
125 << std::setw(17) <<
"distance Method "
126 << std::setw(3*(6+precVerf)) <<
" local direction" <<
" "
128 G4cout <<
" Mother " << std::setw(12) << motherSolid->
GetName() <<
" "
129 << std::setw(4+precVerf) << localPoint <<
" "
130 << std::setw(4+precVerf) << motherSafety <<
" "
132 G4cout.precision(oldprec);
154 intersectionPoint= samplePoint + sampleStep * sampleDirection;
158 G4String solidResponse =
"-kInside-";
160 { solidResponse =
"-kOutside-"; }
162 { solidResponse =
"-kSurface-"; }
166 G4cout <<
" Invoked Inside() for solid: "
168 <<
". Solid replied: " << solidResponse <<
G4endl
169 <<
" For point p: " << intersectionPoint
170 <<
", considered as 'intersection' point." <<
G4endl;
173 G4double safetyIn= -1, safetyOut= -1;
174 G4double newDistIn= -1, newDistOut= -1;
189 std::ostringstream message;
190 message.precision(16);
191 message <<
"Conflicting response from Solid." <<
G4endl
192 <<
" Inaccurate solid DistanceToIn"
194 <<
" Solid gave DistanceToIn = "
195 << sampleStep <<
" yet returns " << solidResponse
196 <<
" for this point !" <<
G4endl
197 <<
" Point = " << intersectionPoint <<
G4endl
198 <<
" Safety values: " <<
G4endl;
201 message <<
" DistanceToIn(p) = " << safetyIn;
205 message <<
" DistanceToOut(p) = " << safetyOut;
208 message <<
" Solid Parameters: " << *sampleSolid;
216 if(
std::max( newDistIn, newDistOut ) <=
219 std::ostringstream message;
220 message <<
"Zero from both Solid DistanceIn and Out(p,v)." <<
G4endl
221 <<
" Identified point for which the solid "
223 <<
" has MAJOR problem: " <<
G4endl
224 <<
" --> Both DistanceToIn(p,v) and DistanceToOut(p,v) "
225 <<
"return Zero, an equivalent value or negative value."
227 <<
" Solid: " << sampleSolid <<
G4endl
228 <<
" Point p= " << intersectionPoint <<
G4endl
229 <<
" Direction v= " << sampleDirection <<
G4endl
230 <<
" DistanceToIn(p,v) = " << newDistIn <<
G4endl
231 <<
" DistanceToOut(p,v,..) = " << newDistOut <<
G4endl
232 <<
" Safety values: " <<
G4endl
233 <<
" DistanceToIn(p) = " << safetyIn <<
G4endl
234 <<
" DistanceToOut(p) = " << safetyOut;
243 static const G4int precVerf= 20;
246 << std::setw(12) << sampleSolid->
GetName() <<
" "
247 << std::setw(4+precVerf) << samplePoint <<
" "
248 << std::setw(4+precVerf) << sampleSafety <<
" "
249 << std::setw(4+precVerf) << sampleStep <<
" "
250 << std::setw(16) <<
"distanceToIn" <<
" "
251 << std::setw(4+precVerf) << localDirection <<
" "
253 G4cout.precision(oldprec);
276 G4bool SuspiciousDaughterDist = ( sampleStep >= motherStep )
283 msg <<
" WARNING - Called with 'infinite' step. " <<
G4endl;
284 msg <<
" Checks have no meaning if daughter step is infinite." <<
G4endl;
287 msg <<
" sampleStep < kInfinity " << (sampleStep<
kInfinity) << G4endl;
289 msg <<
" Returning immediately.";
290 G4Exception(
"G4NavigationLogger::CheckDaughterEntryPoint()",
304 G4ThreeVector localExitMotherPos= localPoint+motherStep*localDirection;
310 G4ThreeVector localEntryInDaughter = localPoint+sampleStep*localDirection;
311 EInside insideMother= motherSolid->
Inside( localEntryInDaughter );
313 G4String solidResponse =
"-kInside-";
314 if (insideMother ==
kOutside) { solidResponse =
"-kOutside-"; }
315 else if (insideMother ==
kSurface) { solidResponse =
"-kSurface-"; }
317 G4double distToReEntry = distExitToReEntry + motherStep;
318 G4ThreeVector localReEntryPoint = localPoint+distToReEntry*localDirection;
321 G4bool DaughterEntryIsOutside = SuspiciousDaughterDist
322 && ( (sampleStep < distToReEntry) || (insideMother ==
kOutside ) );
323 G4bool EntryIsMotherExit = std::fabs(sampleStep-motherStep) < kCarTolerance;
326 G4ThreeVector sampleEntryPoint= samplePoint+sampleStep*sampleDirection;
329 G4double sampleExitDist = sampleStep+sampleCrossingDist;
330 G4ThreeVector sampleExitPoint= samplePoint+sampleExitDist*sampleDirection;
332 G4bool TransitProblem = ( (sampleStep < motherStep)
333 && (sampleExitDist > motherStep + kCarTolerance) )
334 || ( EntryIsMotherExit && (sampleCrossingDist > kCarTolerance) );
336 if( DaughterEntryIsOutside
338 || (SuspiciousDaughterDist && (
fVerbose > 3) ) )
343 if( DaughterEntryIsOutside )
345 msg <<
"WARNING> Intersection distance to Daughter volume is further"
346 <<
" than the distance to boundary." <<
G4endl
347 <<
" It appears that part of the daughter volume is *outside*"
348 <<
" this mother. " <<
G4endl;
349 msg <<
" One of the following checks signaled a problem:" << G4endl
350 <<
" -sampleStep (dist to daugh) < mother-exit dist + distance "
351 <<
"to ReEntry point for mother " << G4endl
352 <<
" -position of daughter intersection is outside mother volume."
355 else if( TransitProblem )
357 G4double protrusion = sampleExitDist - motherStep;
359 msg <<
"WARNING> Daughter volume extends beyond mother boundary. "
361 if ( ( sampleStep < motherStep )
362 && (sampleExitDist > motherStep + kCarTolerance ) )
365 msg <<
" Crossing distance in the daughter causes is to extend"
366 <<
" beyond the mother exit. " <<
G4endl;
367 msg <<
" Length protruding = " << protrusion <<
G4endl;
369 if( EntryIsMotherExit )
372 msg <<
" Intersection distance to Daughter is within "
373 <<
" tolerance of the distance" <<
G4endl;
374 msg <<
" to the mother boundary * and * " <<
G4endl;
375 msg <<
" the crossing distance in the daughter is > tolerance."
381 msg <<
"NearMiss> Intersection to Daughter volume is in extension past the"
382 <<
" current exit point of the mother volume." <<
G4endl;
383 msg <<
" This is not an error - just an unusual occurence,"
384 <<
" possible in the case of concave volume. " <<
G4endl;
386 msg <<
"---- Information about intersection with daughter, mother: "
388 msg <<
" sampleStep (daughter) = " << sampleStep << G4endl
389 <<
" motherStep = " << motherStep << G4endl
390 <<
" distToRentry(mother) = " << distToReEntry << G4endl
391 <<
" Inside(entry pnt daug): " << solidResponse << G4endl
392 <<
" dist across daughter = " << sampleCrossingDist <<
G4endl;
393 msg <<
" Mother Name (Solid) : " << motherSolid->
GetName() << G4endl
394 <<
" In local (mother) coordinates: " << G4endl
395 <<
" Starting Point = " << localPoint << G4endl
396 <<
" Direction = " << localDirection << G4endl
397 <<
" Exit Point (mother)= " << localExitMotherPos << G4endl
398 <<
" Entry Point (daughter)= " << localPoint+sampleStep*localDirection
402 msg <<
" ReEntry Point (mother)= " << localReEntryPoint <<
G4endl;
406 msg <<
" No ReEntry - track does not encounter mother volume again! "
409 msg <<
" Daughter Name (Solid): " << sampleSolid->
GetName() << G4endl
410 <<
" In daughter coordinates: " << G4endl
411 <<
" Starting Point = " << samplePoint << G4endl
412 <<
" Direction = " << sampleDirection << G4endl
413 <<
" Entry Point (daughter)= " << sampleEntryPoint
415 msg <<
" Description of mother solid: " << G4endl
416 << *motherSolid << G4endl
417 <<
" Description of daughter solid: " << G4endl
418 << *sampleSolid <<
G4endl;
421 if( DaughterEntryIsOutside || TransitProblem )
428 <<
" -- Checked distance of Entry to daughter vs exit of mother"
450 << std::setw(15) << motherSafety <<
" "
451 << std::setw(15) << motherStep <<
" " << localPoint <<
" - "
455 if( ( motherStep < 0.0 ) || ( motherStep >=
kInfinity) )
460 std::ostringstream message;
461 message <<
"Current point is outside the current solid !" <<
G4endl
462 <<
" Problem in Navigation" <<
G4endl
463 <<
" Point (local coordinates): "
465 <<
" Local Direction: " << localDirection <<
G4endl
466 <<
" Solid: " << motherSolid->
GetName();
469 G4cout.precision(oldPrOut);
470 G4cerr.precision(oldPrErr);
474 static const G4int precVerf= 20;
476 G4cout <<
" Mother " << std::setw(12) << motherSolid->
GetName() <<
" "
477 << std::setw(4+precVerf) << localPoint <<
" "
478 << std::setw(4+precVerf) << motherSafety <<
" "
479 << std::setw(4+precVerf) << motherStep <<
" "
480 << std::setw(16) <<
"distanceToOut" <<
" "
481 << std::setw(4+precVerf) << localDirection <<
" "
483 G4cout.precision(oldprec);
500 banner = isMotherVolume;
504 G4String volumeType = isMotherVolume ?
" Mother " :
"Daughter";
507 G4cout <<
"************** " <<
fId <<
"::ComputeSafety() ****************"
510 << std::setw(15) <<
"Safety/mm" <<
" "
511 << std::setw(52) <<
"Position (local coordinates)"
515 << std::setw(15) << safety <<
" " << point <<
" - "
535 << std::setw(15) << sampleSafety <<
" ";
538 G4cout << std::setw(15) << sampleStep <<
" ";
542 G4cout << std::setw(15) <<
"Not-Available" <<
" ";
544 G4cout << samplePoint <<
" - "
548 G4cout <<
" dir= " << sampleDirection;
551 G4cout.precision(oldPrec);
566 const char* msg )
const
568 G4double normMag2 = unitNormal.mag2();
573 G4double normMag= std::sqrt(normMag2);
575 message.precision(10);
576 message <<
"============================================================"
578 message <<
" WARNING> Normal is not a unit vector. "
579 <<
" Expected normal-global-frame to be valid "
580 <<
" i.e. a unit vector!" << G4endl
581 <<
" - but |normal| = " << normMag
582 <<
" - and |normal|^2 = " << normMag2 << G4endl
583 <<
" which differ from 1.0 by: " << G4endl
584 <<
" |normal|-1 = " << normMag - 1.0
585 <<
" and |normal|^2 - 1 = " << normMag2 - 1.0 << G4endl
586 <<
" n = " << unitNormal <<
G4endl;
587 message <<
" Info string: " << * msg <<
G4endl;
588 message <<
"============================================================"
591 message.precision(16);
593 message <<
" Information on call to DistanceToOut: " <<
G4endl;
594 message <<
" Position = " << localPoint << G4endl
595 <<
" Direction = " << localDirection <<
G4endl;
596 message <<
" Obtained> distance = " << step <<
G4endl;
597 message <<
" > Exit position = " << localPoint+step*localDirection
599 message <<
" Parameters of solid: " <<
G4endl;
601 message <<
"============================================================";
632 "Erroneous call to ReportOutsideMother: no Solid is available");
653 if( safetyToOut > kCarTolerance
654 && ( distToOut < 0.0 || distToOut >=
kInfinity ) )
659 msg1 <<
" Dangerous inconsistency in response of solid." <<
G4endl
662 msg1 <<
" Mother volume gives safety > 0 despite being called for *Outside* point "
664 <<
" Location = " << localPoint <<
G4endl
665 <<
" Direction= " << localDirection <<
G4endl
666 <<
" - Safety (Isotropic d) = " << safetyToOut <<
G4endl
667 <<
" - Intersection Distance= " << distToOut <<
G4endl
675 if( std::fabs(distToOut) < kCarTolerance && std::fabs(distToInPos) < kCarTolerance )
685 if( std::fabs(distToOut) < kCarTolerance )
692 msg <<
" Warning> DistanceToOut(p,v): Distance from surface is not rounded to zero" <<
G4endl;
703 msg <<
"============================================================" <<
G4endl;
704 msg <<
" WARNING> Current Point appears to be Outside mother volume !! " <<
G4endl;
705 msg <<
" Response of DistanceToOut was negative or kInfinity when called in "
713 if( triggerDist <= 0.0 ) {
715 triggerDist =
std::max ( 1.0e+6 * kCarTolerance,
720 ? ( safetyToIn > triggerDist )
721 : ( safetyToOut > triggerDist );
729 G4Exception( fMethod,
"GeomNav0003", exceptionType, msg);
742 G4String fMethod =
fId +
"::ComputeStep() / output from G4NavigatorLogger::ReportVolumeAndIntersection";
749 os <<
" ERROR> Solid is not available. Logical Volume = " << logicalVol << std::endl;
768 const G4double epsilonDist = 1000.0 * kCarTolerance;
769 const G4ThreeVector PointPlusDir = localPoint + epsilonDist * localDirection;
770 const G4ThreeVector PointMinusDir = localPoint - epsilonDist * localDirection;
771 const G4ThreeVector PointPlusNorm = localPoint + epsilonDist * exitNormal;
772 const G4ThreeVector PointMinusNorm = localPoint - epsilonDist * exitNormal;
780 os <<
" Current physical volume = " << physical->
GetName() <<
G4endl;
781 os <<
" Position (loc) = " << localPoint <<
G4endl
782 <<
" Direction (dir) = " << localDirection <<
G4endl;
783 os <<
" For confirmation:" <<
G4endl;
784 os <<
" Response of DistanceToOut (loc, +dir)= " << distToOut <<
G4endl;
785 os <<
" Response of DistanceToOut (loc, -dir)= " << distToOutNeg <<
G4endl;
787 os <<
" Inside responds = " << inSolid <<
" , ie: ";
789 os <<
" Outside -- a problem, as observed in " << fMethod <<
G4endl;
791 os <<
" Surface -- unexpected / inconsistent response ! " <<
G4endl;
793 os <<
" Inside -- unexpected / inconsistent response ! " <<
G4endl;
795 os <<
" Obtain safety(ToIn) = " << safetyToIn <<
G4endl;
796 os <<
" Obtain safety(ToOut) = " << safetyToOut <<
G4endl;
797 os <<
" Response of DistanceToIn (loc, +dir)= " << distToInPos <<
G4endl;
798 os <<
" Response of DistanceToIn (loc, -dir)= " << distToInNeg <<
G4endl;
800 os <<
" Exit Normal at loc = " << exitNormal <<
G4endl;
801 os <<
" Dir . Normal = " << exitNormal.dot( localDirection );
804 os <<
" Checking points moved from position by distance/dir. Solid responses: " << G4endl
810 os <<
" Parameters of solid: " <<
G4endl;
812 os <<
"============================================================";
void AlongComputeStepLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, const G4ThreeVector &sampleDirection, const G4ThreeVector &localDirection, G4double sampleSafety, G4double sampleStep) const
void PrintDaughterLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, G4double sampleSafety, G4bool onlySafety, const G4ThreeVector &sampleDirection, G4double sampleStep) const
static const G4double kInfinity
std::ostringstream G4ExceptionDescription
CLHEP::Hep3Vector G4ThreeVector
G4double GetTolerance() const
virtual G4GeometryType GetEntityType() const =0
G4NavigationLogger(const G4String &id)
void ReportOutsideMother(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *motherPV, G4double tDist=30.0 *CLHEP::cm) const
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
virtual EInside Inside(const G4ThreeVector &p) const =0
void ReportVolumeAndIntersection(std::ostream &ostrm, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *physical) const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
G4bool CheckAndReportBadNormal(const G4ThreeVector &unitNormal, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double step, const G4VSolid *solid, const char *msg) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
const G4String EInsideNames[3]
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4bool fReportSoftWarnings
static const double perMillion
G4LogicalVolume * GetLogicalVolume() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
void ComputeSafetyLog(const G4VSolid *solid, const G4ThreeVector &point, G4double safety, G4bool isMotherVolume, G4int banner=-1) const
void PreComputeStepLog(const G4VPhysicalVolume *motherPhysical, G4double motherSafety, const G4ThreeVector &localPoint) const
static const double millimeter
void PostComputeStepLog(const G4VSolid *motherSolid, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double motherStep, G4double motherSafety) const
void CheckDaughterEntryPoint(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, const G4ThreeVector &sampleDirection, const G4VSolid *motherSolid, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double motherStep, G4double sampleStep) const
G4double fMinTriggerDistance
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
static G4GeometryTolerance * GetInstance()
G4VSolid * GetSolid() const
G4GLOB_DLL std::ostream G4cerr