Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4NavigationLogger.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// class G4NavigationLogger Implementation
27//
28// Author: G.Cosmo, 2010
29// --------------------------------------------------------------------
30
31#include <iomanip>
33
34#include "G4NavigationLogger.hh"
36
37using CLHEP::millimeter;
38
40 : fId(id)
41{
42}
43
45
46// ********************************************************************
47// PreComputeStepLog
48// ********************************************************************
49//
50void
52 G4double motherSafety,
53 const G4ThreeVector& localPoint) const
54{
55 G4VSolid* motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
56 G4String fType = fId + "::ComputeStep()";
57
58 if ( fVerbose == 1 || fVerbose > 4 )
59 {
60 G4cout << "*************** " << fType << " *****************" << G4endl
61 << " VolType "
62 << std::setw(15) << "Safety/mm" << " "
63 << std::setw(15) << "Distance/mm" << " "
64 << std::setw(52) << "Position (local coordinates)"
65 << " - Solid" << G4endl;
66 G4cout << " Mother "
67 << std::setw(15) << motherSafety / millimeter << " "
68 << std::setw(15) << "N/C" << " " << localPoint << " - "
69 << motherSolid->GetEntityType() << ": " << motherSolid->GetName()
70 << G4endl;
71 }
72 if ( motherSafety < 0.0 )
73 {
74 std::ostringstream message;
75 message << "Negative Safety In Voxel Navigation !" << G4endl
76 << " Current solid " << motherSolid->GetName()
77 << " gave negative safety: " << motherSafety / millimeter << G4endl
78 << " for the current (local) point " << localPoint;
79 message << " Solid info: " << *motherSolid << G4endl;
80 G4Exception(fType, "GeomNav0003", FatalException, message);
81 }
82 if( motherSolid->Inside(localPoint)==kOutside )
83 {
84 std::ostringstream message;
85 message << "Point is outside Current Volume - " << G4endl
86 << " Point " << localPoint / millimeter
87 << " is outside current volume '" << motherPhysical->GetName()
88 << "'" << G4endl;
89 G4double estDistToSolid= motherSolid->DistanceToIn(localPoint);
90 message << " Estimated isotropic distance to solid (distToIn)= "
91 << estDistToSolid << G4endl;
92 if( estDistToSolid > 100.0 * motherSolid->GetTolerance() )
93 {
94 message << " Solid info: " << *motherSolid << G4endl;
95 G4Exception(fType, "GeomNav0003", JustWarning, message,
96 "Point is far outside Current Volume !" );
97 }
98 else
99 {
100 G4Exception(fType, "GeomNav1001", JustWarning, message,
101 "Point is a little outside Current Volume.");
102 }
103 }
104
105 // Verification / verbosity
106 //
107 if ( fVerbose > 1 )
108 {
109 static const G4int precVerf = 16; // Precision
110 G4long oldprec = G4cout.precision(precVerf);
111 G4cout << " - Information on mother / key daughters ..." << G4endl;
112 G4cout << " Type " << std::setw(12) << "Solid-Name" << " "
113 << std::setw(3*(6+precVerf)) << " local point" << " "
114 << std::setw(4+precVerf) << "solid-Safety" << " "
115 << std::setw(4+precVerf) << "solid-Step" << " "
116 << std::setw(17) << "distance Method "
117 << std::setw(3*(6+precVerf)) << " local direction" << " "
118 << G4endl;
119 G4cout << " Mother " << std::setw(12) << motherSolid->GetName() << " "
120 << std::setw(4+precVerf) << localPoint << " "
121 << std::setw(4+precVerf) << motherSafety << " "
122 << G4endl;
123 G4cout.precision(oldprec);
124 }
125}
126
127// ********************************************************************
128// AlongComputeStepLog
129// ********************************************************************
130//
131void
133 const G4ThreeVector& samplePoint,
134 const G4ThreeVector& sampleDirection,
135 const G4ThreeVector& localDirection,
136 G4double sampleSafety,
137 G4double sampleStep) const
138{
139 // Check to see that the resulting point is indeed in/on volume.
140 // This check could eventually be made only for successful candidate.
141
142 if ( sampleStep < kInfinity )
143 {
144 G4ThreeVector intersectionPoint;
145 intersectionPoint = samplePoint + sampleStep * sampleDirection;
146 EInside insideIntPt = sampleSolid->Inside(intersectionPoint);
147 G4String fType = fId + "::ComputeStep()";
148
149 G4String solidResponse = "-kInside-";
150 if (insideIntPt == kOutside)
151 { solidResponse = "-kOutside-"; }
152 else if (insideIntPt == kSurface)
153 { solidResponse = "-kSurface-"; }
154
155 if ( fVerbose == 1 || fVerbose > 4 )
156 {
157 G4cout << " Invoked Inside() for solid: "
158 << sampleSolid->GetName()
159 << ". Solid replied: " << solidResponse << G4endl
160 << " For point p: " << intersectionPoint
161 << ", considered as 'intersection' point." << G4endl;
162 }
163
164 G4double safetyIn = -1, safetyOut = -1; // Set to invalid values
165 G4double newDistIn = -1, newDistOut = -1;
166 if( insideIntPt != kInside )
167 {
168 safetyIn = sampleSolid->DistanceToIn(intersectionPoint);
169 newDistIn = sampleSolid->DistanceToIn(intersectionPoint,
170 sampleDirection);
171 }
172 if( insideIntPt != kOutside )
173 {
174 safetyOut = sampleSolid->DistanceToOut(intersectionPoint);
175 newDistOut = sampleSolid->DistanceToOut(intersectionPoint,
176 sampleDirection);
177 }
178 if( insideIntPt != kSurface )
179 {
180 std::ostringstream message;
181 message.precision(16);
182 message << "Conflicting response from Solid." << G4endl
183 << " Inaccurate solid DistanceToIn"
184 << " for solid " << sampleSolid->GetName() << G4endl
185 << " Solid gave DistanceToIn = "
186 << sampleStep << " yet returns " << solidResponse
187 << " for this point !" << G4endl
188 << " Original Point = " << samplePoint << G4endl
189 << " Original Direction = " << sampleDirection << G4endl
190 << " Intersection Point = " << intersectionPoint << G4endl
191 << " Safety values: " << G4endl;
192 if ( insideIntPt != kInside )
193 {
194 message << " DistanceToIn(p) = " << safetyIn;
195 }
196 if ( insideIntPt != kOutside )
197 {
198 message << " DistanceToOut(p) = " << safetyOut;
199 }
200 message << G4endl;
201 message << " Solid Parameters: " << *sampleSolid;
202 G4Exception(fType, "GeomNav1001", JustWarning, message);
203 }
204 else
205 {
206 // If it is on the surface, *ensure* that either DistanceToIn
207 // or DistanceToOut returns a finite value ( >= Tolerance).
208 //
209 if( std::max( newDistIn, newDistOut ) <=
210 G4GeometryTolerance::GetInstance()->GetSurfaceTolerance() )
211 {
212 std::ostringstream message;
213 message << "Zero from both Solid DistanceIn and Out(p,v)." << G4endl
214 << " Identified point for which the solid "
215 << sampleSolid->GetName() << G4endl
216 << " has MAJOR problem: " << G4endl
217 << " --> Both DistanceToIn(p,v) and DistanceToOut(p,v) "
218 << "return Zero, an equivalent value or negative value."
219 << G4endl
220 << " Solid: " << sampleSolid << G4endl
221 << " Point p= " << intersectionPoint << G4endl
222 << " Direction v= " << sampleDirection << G4endl
223 << " DistanceToIn(p,v) = " << newDistIn << G4endl
224 << " DistanceToOut(p,v,..) = " << newDistOut << G4endl
225 << " Safety values: " << G4endl
226 << " DistanceToIn(p) = " << safetyIn << G4endl
227 << " DistanceToOut(p) = " << safetyOut;
228 G4Exception(fType, "GeomNav0003", FatalException, message);
229 }
230 }
231
232 // Verification / verbosity
233 //
234 if ( fVerbose > 1 )
235 {
236 static const G4int precVerf= 20; // Precision
237 G4long oldprec = G4cout.precision(precVerf);
238 G4cout << "Daughter "
239 << std::setw(12) << sampleSolid->GetName() << " "
240 << std::setw(4+precVerf) << samplePoint << " "
241 << std::setw(4+precVerf) << sampleSafety << " "
242 << std::setw(4+precVerf) << sampleStep << " "
243 << std::setw(16) << "distanceToIn" << " "
244 << std::setw(4+precVerf) << localDirection << " "
245 << G4endl;
246 G4cout.precision(oldprec);
247 }
248 }
249}
250
251// ********************************************************************
252// CheckDaughterEntryPoint
253// ********************************************************************
254//
255void
257 const G4ThreeVector& samplePoint,
258 const G4ThreeVector& sampleDirection,
259 const G4VSolid* motherSolid,
260 const G4ThreeVector& localPoint,
261 const G4ThreeVector& localDirection,
262 G4double motherStep,
263 G4double sampleStep) const
264{
265 const G4double kCarTolerance = motherSolid->GetTolerance();
266
267 // Double check the expected condition of being called
268 //
269 G4bool SuspiciousDaughterDist = ( sampleStep >= motherStep )
270 && ( sampleStep < kInfinity );
271
272 if( sampleStep >= kInfinity )
273 {
275 msg.precision(12);
276 msg << " WARNING - Called with 'infinite' step. " << G4endl;
277 msg << " Checks have no meaning if daughter step is infinite." << G4endl;
278 msg << " kInfinity = " << kInfinity / millimeter << G4endl;
279 msg << " sampleStep = " << sampleStep / millimeter << G4endl;
280 msg << " sampleStep < kInfinity " << (sampleStep<kInfinity) << G4endl;
281 msg << " kInfinity - sampleStep " << (kInfinity-sampleStep) / millimeter << G4endl;
282 msg << " Returning immediately.";
283 G4Exception("G4NavigationLogger::CheckDaughterEntryPoint()",
284 "GeomNav0003", JustWarning, msg);
285 return;
286 }
287
288 // The intersection point with the daughter is after the exit point
289 // from the mother volume !!
290 // This is legal / allowed to occur only if the mother is concave
291 // ****************************************************************
292 // If mother is convex the daughter volume must be encountered
293 // before the exit from the current volume!
294
295 // Check #1) whether the track will re-enter the current mother
296 // in the extension past its current exit point
297 G4ThreeVector localExitMotherPos = localPoint+motherStep*localDirection;
298 G4double distExitToReEntry = motherSolid->DistanceToIn(localExitMotherPos,
299 localDirection);
300
301 // Check #2) whether the 'entry' point in the daughter is inside the mother
302 //
303 G4ThreeVector localEntryInDaughter = localPoint+sampleStep*localDirection;
304 EInside insideMother = motherSolid->Inside( localEntryInDaughter );
305
306 G4String solidResponse = "-kInside-";
307 if (insideMother == kOutside) { solidResponse = "-kOutside-"; }
308 else if (insideMother == kSurface) { solidResponse = "-kSurface-"; }
309
310 G4double distToReEntry = distExitToReEntry + motherStep;
311 G4ThreeVector localReEntryPoint = localPoint+distToReEntry*localDirection;
312
313 // Clear error -- Daughter entry point is bad
314 constexpr G4double eps= 1.0e-10;
315 G4bool DaughterEntryIsOutside = SuspiciousDaughterDist
316 && ( (sampleStep * (1.0+eps) < distToReEntry) || (insideMother == kOutside ) );
317 G4bool EntryIsMotherExit = std::fabs(sampleStep-motherStep) < kCarTolerance;
318
319 // Check for more subtle error - is exit point of daughter correct ?
320 G4ThreeVector sampleEntryPoint = samplePoint+sampleStep*sampleDirection;
321 G4double sampleCrossingDist = sampleSolid->DistanceToOut( sampleEntryPoint,
322 sampleDirection );
323 G4double sampleExitDist = sampleStep+sampleCrossingDist;
324 G4ThreeVector sampleExitPoint = samplePoint+sampleExitDist*sampleDirection;
325
326 G4bool TransitProblem = ( (sampleStep < motherStep)
327 && (sampleExitDist > motherStep + kCarTolerance) )
328 || ( EntryIsMotherExit && (sampleCrossingDist > kCarTolerance) );
329
330 if( DaughterEntryIsOutside
331 || TransitProblem
332 || (SuspiciousDaughterDist && (fVerbose > 3) ) )
333 {
335 msg.precision(16);
336
337 if( DaughterEntryIsOutside )
338 {
339 msg << "WARNING> Intersection distance to Daughter volume is further"
340 << " than the distance to boundary." << G4endl
341 << " It appears that part of the daughter volume is *outside*"
342 << " this mother. " << G4endl;
343 msg << " One of the following checks signaled a problem:" << G4endl
344 << " -sampleStep (dist to daugh) < mother-exit dist + distance "
345 << "to ReEntry point for mother " << G4endl
346 << " -position of daughter intersection is outside mother volume."
347 << G4endl;
348 }
349 else if( TransitProblem )
350 {
351 G4double protrusion = sampleExitDist - motherStep;
352
353 msg << "WARNING> Daughter volume extends beyond mother boundary. "
354 << G4endl;
355 if ( ( sampleStep < motherStep )
356 && (sampleExitDist > motherStep + kCarTolerance ) )
357 {
358 // 1st Issue with Daughter
359 msg << " Crossing distance in the daughter causes is to extend"
360 << " beyond the mother exit. " << G4endl;
361 msg << " Length protruding = " << protrusion << G4endl;
362 }
363 if( EntryIsMotherExit )
364 {
365 // 1st Issue with Daughter
366 msg << " Intersection distance to Daughter is within "
367 << " tolerance of the distance" << G4endl;
368 msg << " to the mother boundary * and * " << G4endl;
369 msg << " the crossing distance in the daughter is > tolerance."
370 << G4endl;
371 }
372 }
373 else
374 {
375 msg << "NearMiss> Intersection to Daughter volume is in extension past the"
376 << " current exit point of the mother volume." << G4endl;
377 msg << " This is not an error - just an unusual occurrence,"
378 << " possible in the case of concave volume. " << G4endl;
379 }
380 msg << "---- Information about intersection with daughter, mother: "
381 << G4endl;
382 msg << " sampleStep (daughter) = " << sampleStep << G4endl
383 << " motherStep = " << motherStep << G4endl
384 << " distToRentry(mother) = " << distToReEntry << G4endl
385 << " Inside(entry pnt daug): " << solidResponse << G4endl
386 << " dist across daughter = " << sampleCrossingDist << G4endl;
387 msg << " Mother Name (Solid) : " << motherSolid->GetName() << G4endl
388 << " In local (mother) coordinates: " << G4endl
389 << " Starting Point = " << localPoint << G4endl
390 << " Direction = " << localDirection << G4endl
391 << " Exit Point (mother)= " << localExitMotherPos << G4endl
392 << " Entry Point (daughter)= " << localPoint+sampleStep*localDirection
393 << G4endl;
394 if( distToReEntry < kInfinity )
395 {
396 msg << " ReEntry Point (mother)= " << localReEntryPoint << G4endl;
397 }
398 else
399 {
400 msg << " No ReEntry - track does not encounter mother volume again! "
401 << G4endl;
402 }
403 msg << " Daughter Name (Solid): " << sampleSolid->GetName() << G4endl
404 << " In daughter coordinates: " << G4endl
405 << " Starting Point = " << samplePoint << G4endl
406 << " Direction = " << sampleDirection << G4endl
407 << " Entry Point (daughter)= " << sampleEntryPoint
408 << G4endl;
409 msg << " Description of mother solid: " << G4endl
410 << *motherSolid << G4endl
411 << " Description of daughter solid: " << G4endl
412 << *sampleSolid << G4endl;
413 G4String fType = fId + "::ComputeStep()";
414
415 if( DaughterEntryIsOutside || TransitProblem )
416 {
417 G4Exception(fType, "GeomNav0003", JustWarning, msg);
418 }
419 else
420 {
421 G4cout << fType
422 << " -- Checked distance of Entry to daughter vs exit of mother"
423 << G4endl;
424 G4cout << msg.str();
425 G4cout << G4endl;
426 }
427 }
428}
429
430// ********************************************************************
431// PostComputeStepLog
432// ********************************************************************
433//
434void
436 const G4ThreeVector& localPoint,
437 const G4ThreeVector& localDirection,
438 G4double motherStep,
439 G4double motherSafety) const
440{
441 if ( fVerbose == 1 || fVerbose > 4 )
442 {
443 G4cout << " Mother "
444 << std::setw(15) << motherSafety << " "
445 << std::setw(15) << motherStep << " " << localPoint << " - "
446 << motherSolid->GetEntityType() << ": " << motherSolid->GetName()
447 << G4endl;
448 }
449 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
450 {
451 G4String fType = fId + "::ComputeStep()";
452 G4long oldPrOut = G4cout.precision(16);
453 G4long oldPrErr = G4cerr.precision(16);
454 std::ostringstream message;
455 message << "Current point is outside the current solid !" << G4endl
456 << " Problem in Navigation" << G4endl
457 << " Point (local coordinates): "
458 << localPoint << G4endl
459 << " Local Direction: " << localDirection << G4endl
460 << " Solid: " << motherSolid->GetName();
461 motherSolid->DumpInfo();
462 G4Exception(fType, "GeomNav0003", FatalException, message);
463 G4cout.precision(oldPrOut);
464 G4cerr.precision(oldPrErr);
465 }
466 if ( fVerbose > 1 )
467 {
468 static const G4int precVerf = 20; // Precision
469 G4long oldprec = G4cout.precision(precVerf);
470 G4cout << " Mother " << std::setw(12) << motherSolid->GetName() << " "
471 << std::setw(4+precVerf) << localPoint << " "
472 << std::setw(4+precVerf) << motherSafety << " "
473 << std::setw(4+precVerf) << motherStep << " "
474 << std::setw(16) << "distanceToOut" << " "
475 << std::setw(4+precVerf) << localDirection << " "
476 << G4endl;
477 G4cout.precision(oldprec);
478 }
479}
480
481// ********************************************************************
482// ComputeSafetyLog
483// ********************************************************************
484//
485void
487 const G4ThreeVector& point,
488 G4double safety,
489 G4bool isMotherVolume,
490 G4int banner) const
491{
492 if( banner < 0 )
493 {
494 banner = static_cast<G4int>(isMotherVolume);
495 }
496 if( fVerbose >= 1 )
497 {
498 G4String volumeType = isMotherVolume ? " Mother " : "Daughter";
499 if (banner != 0)
500 {
501 G4cout << "************** " << fId << "::ComputeSafety() ****************"
502 << G4endl;
503 G4cout << " VolType "
504 << std::setw(15) << "Safety/mm" << " "
505 << std::setw(52) << "Position (local coordinates)"
506 << " - Solid" << G4endl;
507 }
508 G4cout << volumeType
509 << std::setw(15) << safety << " " << point << " - "
510 << solid->GetEntityType() << ": " << solid->GetName() << G4endl;
511 }
512}
513
514// ********************************************************************
515// PrintDaughterLog
516// ********************************************************************
517//
518void
520 const G4ThreeVector& samplePoint,
521 G4double sampleSafety,
522 G4bool withStep,
523 const G4ThreeVector& sampleDirection, G4double sampleStep ) const
524{
525 if ( fVerbose >= 1 )
526 {
527 G4long oldPrec = G4cout.precision(8);
528 G4cout << "Daughter "
529 << std::setw(15) << sampleSafety << " ";
530 if (withStep) // (sampleStep != -1.0 )
531 {
532 G4cout << std::setw(15) << sampleStep << " ";
533 }
534 else
535 {
536 G4cout << std::setw(15) << "Not-Available" << " ";
537 }
538 G4cout << samplePoint << " - "
539 << sampleSolid->GetEntityType() << ": " << sampleSolid->GetName();
540 if( withStep )
541 {
542 G4cout << " dir= " << sampleDirection;
543 }
544 G4cout << G4endl;
545 G4cout.precision(oldPrec);
546 }
547}
548
549// ********************************************************************
550// CheckAndReportBadNormal
551// ********************************************************************
552//
553G4bool
555CheckAndReportBadNormal(const G4ThreeVector& unitNormal,
556 const G4ThreeVector& localPoint,
557 const G4ThreeVector& localDirection,
558 G4double step,
559 const G4VSolid* solid,
560 const char* msg ) const
561{
562 G4double normMag2 = unitNormal.mag2();
563 G4bool badLength = ( std::fabs ( normMag2 - 1.0 ) > CLHEP::perMillion );
564
565 if( badLength )
566 {
567 G4double normMag = std::sqrt(normMag2);
569 message.precision(10);
570 message << "============================================================"
571 << G4endl;
572 message << " WARNING> Normal is not a unit vector. "
573 << " - but |normal| = " << normMag
574 << " - and |normal|^2 = " << normMag2 << G4endl
575 << " which differ from 1.0 by: " << G4endl
576 << " |normal|-1 = " << normMag - 1.0
577 << " and |normal|^2 - 1 = " << normMag2 - 1.0 << G4endl
578 << " n = " << unitNormal << G4endl;
579 message << " Info string: " << msg << G4endl;
580 message << "============================================================"
581 << G4endl;
582
583 message.precision(16);
584
585 message << " Information on call to DistanceToOut: " << G4endl;
586 message << " Position = " << localPoint << G4endl
587 << " Direction = " << localDirection << G4endl;
588 message << " Obtained> distance = " << step << G4endl;
589 message << " > Exit position = " << localPoint+step*localDirection
590 << G4endl;
591 message << " Parameters of solid: " << G4endl;
592 message << *solid;
593 message << "============================================================";
594
595 G4String fMethod = fId + "::ComputeStep()";
596 G4Exception( fMethod, "GeomNav0003", JustWarning, message);
597 }
598 return badLength;
599}
600
601// ********************************************************************
602// CheckAndReportBadNormal - due to Rotation Matrix
603// ********************************************************************
604//
605G4bool
607CheckAndReportBadNormal(const G4ThreeVector& rotatedNormal,
608 const G4ThreeVector& originalNormal,
609 const G4RotationMatrix& rotationM,
610 const char* msg ) const
611{
612 G4double normMag2 = rotatedNormal.mag2();
613 G4bool badLength = ( std::fabs ( normMag2 - 1.0 ) > CLHEP::perMillion );
614
615 if( badLength )
616 {
617 G4double normMag = std::sqrt(normMag2);
619 message.precision(10);
620 message << "============================================================"
621 << G4endl;
622 message << " WARNING> Rotated n(ormal) is not a unit vector. " << G4endl
623 << " |normal| = " << normMag
624 << " and |normal|^2 = " << normMag2 << G4endl
625 << " Diff from 1.0: " << G4endl
626 << " |normal|-1 = " << normMag - 1.0
627 << " and |normal|^2 - 1 = " << normMag2 - 1.0 << G4endl;
628 message << " Rotated n = (" << rotatedNormal.x() << "," << rotatedNormal.y() << ","
629 << rotatedNormal.z() << ")" << G4endl;
630 message << " Original n = (" << originalNormal.x() << "," << originalNormal.y() << ","
631 << originalNormal.z() << ")" << G4endl;
632 message << " Info string: " << msg << G4endl;
633 message << "============================================================"
634 << G4endl;
635
636 message.precision(16);
637
638 message << " Information on RotationMatrix : " << G4endl;
639 message << " Original: " << G4endl;
640 message << rotationM << G4endl;
641 message << " Inverse (used in transformation): " << G4endl;
642 message << rotationM.inverse() << G4endl;
643 message << "============================================================";
644
645 G4String fMethod = fId + "::ComputeStep()";
646 G4Exception( fMethod, "GeomNav0003", JustWarning, message);
647 }
648 return badLength;
649}
650
651// ********************************************************************
652// ReportOutsideMother
653// ********************************************************************
654//
655// Report Exception if point is outside mother.
656// Fatal exception will be used if either 'checkMode error is > triggerDist
657//
658void
660 const G4ThreeVector& localDirection,
661 const G4VPhysicalVolume* physical,
662 G4double triggerDist) const
663{
664 const G4LogicalVolume* logicalVol = physical != nullptr
665 ? physical->GetLogicalVolume() : nullptr;
666 const G4VSolid* solid = logicalVol != nullptr
667 ? logicalVol->GetSolid() : nullptr;
668
669 G4String fMethod = fId + "::ComputeStep()";
670
671 if( solid == nullptr )
672 {
673 G4Exception(fMethod, "GeomNav0003", FatalException,
674 "Erroneous call to ReportOutsideMother: no Solid is available");
675 return;
676 }
677 const G4double kCarTolerance = solid->GetTolerance();
678
679 // Double check reply - it should be kInfinity
680 const G4double distToOut = solid->DistanceToOut(localPoint, localDirection);
681 const EInside inSolid = solid->Inside(localPoint);
682 const G4double safetyToIn = solid->DistanceToIn(localPoint);
683 const G4double safetyToOut = solid->DistanceToOut(localPoint);
684 // const G4double distToInPos =
685 // solid->DistanceToIn(localPoint, localDirection);
686
687 // 1. Check consistency between Safety obtained and report from distance
688 // We must ensure that (mother)Safety <= 0.0
689 // in the case that the point is outside!
690 // [ If this is not the case, this problem can easily go undetected,
691 // except in Check mode ! ]
692 if( safetyToOut > kCarTolerance
693 && ( distToOut < 0.0 || distToOut >= kInfinity ) )
694 {
696 // fNavClerk->ReportBadSafety(localPoint, localDirection,
697 // motherPhysical, motherSafety, motherStep);
698 msg1 << " Dangerous inconsistency in response of solid." << G4endl
699 << " Solid type: " << solid->GetEntityType()
700 << " Name= " << solid->GetName() << G4endl;
701 msg1 << " Mother volume gives safety > 0 despite being called for *Outside* point "
702 << G4endl
703 << " Location = " << localPoint << G4endl
704 << " Direction= " << localDirection << G4endl
705 << " - Safety (Isotropic d) = " << safetyToOut << G4endl
706 << " - Intersection Distance= " << distToOut << G4endl
707 << G4endl;
708 G4Exception( fMethod, "GeomNav0123", JustWarning, msg1);
709 }
710
711 // 2. Inconsistency - Too many distances are zero (or will be rounded to zero)
712
713// if( std::fabs(distToOut) < kCarTolerance
714// && std::fabs(distToInPos) < kCarTolerance )
715// {
716 // If both distanceToIn and distanceToOut (p,v) are zero for
717 // one direction, the particle could get stuck!
718// }
719
721 msg.precision(10);
722
723 if( std::fabs(distToOut) < kCarTolerance )
724 {
725 // 3. Soft error - safety is not rounded to zero
726 // Report nothing - except in 'loud' mode
727 if( fReportSoftWarnings )
728 {
729 msg << " Warning> DistanceToOut(p,v): "
730 << "Distance from surface is not rounded to zero" << G4endl;
731 }
732 else
733 {
734 return;
735 }
736 }
737 else
738 {
739 // 4. General message - complain that the point is outside!
740 // and provide all information about the current location,
741 // direction and the answers of the solid
742 msg << "============================================================"
743 << G4endl;
744 msg << " WARNING> Current Point appears to be Outside mother volume !! "
745 << G4endl;
746 msg << " Response of DistanceToOut was negative or kInfinity"
747 << " when called in " << fMethod << G4endl;
748 }
749
750 // Generate and 'print'/stream all the information needed
751 this->ReportVolumeAndIntersection(msg, localPoint, localDirection, physical);
752
753 // Default for distance of 'major' error
754 if( triggerDist <= 0.0 )
755 {
756 triggerDist = std::max ( 1.0e+6 * kCarTolerance, // Well beyond tolerance
757 fMinTriggerDistance );
758 }
759
760 G4bool majorError = inSolid == kOutside
761 ? ( safetyToIn > triggerDist )
762 : ( safetyToOut > triggerDist );
763
764 G4ExceptionSeverity exceptionType = JustWarning;
765 if ( majorError )
766 {
767 exceptionType = FatalException;
768 }
769
770 G4Exception( fMethod, "GeomNav0003", exceptionType, msg);
771}
772
774{
775 const G4String EInsideNames[3] = { "kOutside", "kSurface", "kInside" };
776}
777
779ReportVolumeAndIntersection( std::ostream& os,
780 const G4ThreeVector& localPoint,
781 const G4ThreeVector& localDirection,
782 const G4VPhysicalVolume* physical ) const
783{
784 G4String fMethod = fId + "::ComputeStep()";
785 const G4LogicalVolume* logicalVol = physical != nullptr
786 ? physical->GetLogicalVolume() : nullptr;
787 const G4VSolid* solid = logicalVol != nullptr
788 ? logicalVol->GetSolid() : nullptr;
789 if( solid == nullptr )
790 {
791 os << " ERROR> Solid is not available. Logical Volume = "
792 << logicalVol << std::endl;
793 return;
794 }
795 const G4double kCarTolerance = solid->GetTolerance();
796
797 // Double check reply - it should be kInfinity
798 const G4double distToOut = solid->DistanceToOut(localPoint, localDirection);
799 const G4double distToOutNeg = solid->DistanceToOut(localPoint,
800 -localDirection);
801 const EInside inSolid = solid->Inside(localPoint);
802 const G4double safetyToIn = solid->DistanceToIn(localPoint);
803 const G4double safetyToOut = solid->DistanceToOut(localPoint);
804
805 const G4double distToInPos = solid->DistanceToIn(localPoint, localDirection);
806 const G4double distToInNeg = solid->DistanceToIn(localPoint, -localDirection);
807
808 const G4ThreeVector exitNormal = solid->SurfaceNormal(localPoint);
809
810 // Double check whether points nearby are in/surface/out
811 const G4double epsilonDist = 1000.0 * kCarTolerance;
812 const G4ThreeVector PointPlusDir = localPoint + epsilonDist * localDirection;
813 const G4ThreeVector PointMinusDir = localPoint - epsilonDist * localDirection;
814 const G4ThreeVector PointPlusNorm = localPoint + epsilonDist * exitNormal;
815 const G4ThreeVector PointMinusNorm = localPoint - epsilonDist * exitNormal;
816
817 const EInside inPlusDir = solid->Inside(PointPlusDir);
818 const EInside inMinusDir = solid->Inside(PointMinusDir);
819 const EInside inPlusNorm = solid->Inside(PointPlusNorm);
820 const EInside inMinusNorm = solid->Inside(PointMinusNorm);
821
822 // Basic information
823 os << " Current physical volume = " << physical->GetName() << G4endl;
824 os << " Position (loc) = " << localPoint << G4endl
825 << " Direction (dir) = " << localDirection << G4endl;
826 os << " For confirmation:" << G4endl;
827 os << " Response of DistanceToOut (loc, +dir)= " << distToOut << G4endl;
828 os << " Response of DistanceToOut (loc, -dir)= " << distToOutNeg << G4endl;
829
830 os << " Inside responds = " << inSolid << " , ie: ";
831 if( inSolid == kOutside )
832 {
833 os << " Outside -- a problem, as observed in " << fMethod << G4endl;
834 }
835 else if( inSolid == kSurface )
836 {
837 os << " Surface -- unexpected / inconsistent response ! " << G4endl;
838 }
839 else
840 {
841 os << " Inside -- unexpected / inconsistent response ! " << G4endl;
842 }
843 os << " Obtain safety(ToIn) = " << safetyToIn << G4endl;
844 os << " Obtain safety(ToOut) = " << safetyToOut << G4endl;
845 os << " Response of DistanceToIn (loc, +dir)= " << distToInPos << G4endl;
846 os << " Response of DistanceToIn (loc, -dir)= " << distToInNeg << G4endl;
847
848 os << " Exit Normal at loc = " << exitNormal << G4endl;
849 os << " Dir . Normal = " << exitNormal.dot( localDirection );
850 os << G4endl;
851
852 os << " Checking points moved from position by distance/direction." << G4endl
853 << " Solid responses: " << G4endl
854 << " +eps in direction : "
856 << " +eps in Normal : "
858 << " -eps in direction : "
860 << " -eps in Normal : "
862
863 os << " Parameters of solid: " << G4endl;
864 os << *solid;
865 os << "============================================================";
866}
const G4double kCarTolerance
G4ExceptionSeverity
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
double G4double
Definition G4Types.hh:83
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double mag2() const
double y() const
double dot(const Hep3Vector &) const
HepRotation inverse() const
static G4GeometryTolerance * GetInstance()
G4VSolid * GetSolid() const
void PreComputeStepLog(const G4VPhysicalVolume *motherPhysical, G4double motherSafety, const G4ThreeVector &localPoint) const
G4NavigationLogger(const G4String &id)
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
void PrintDaughterLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, G4double sampleSafety, G4bool onlySafety, const G4ThreeVector &sampleDirection, G4double sampleStep) const
G4bool CheckAndReportBadNormal(const G4ThreeVector &unitNormal, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double step, const G4VSolid *solid, const char *msg) const
void ComputeSafetyLog(const G4VSolid *solid, const G4ThreeVector &point, G4double safety, G4bool isMotherVolume, G4int banner=-1) const
void ReportVolumeAndIntersection(std::ostream &ostrm, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *physical) const
void PostComputeStepLog(const G4VSolid *motherSolid, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double motherStep, G4double motherSafety) const
void ReportOutsideMother(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *motherPV, G4double tDist=30.0 *CLHEP::cm) const
void AlongComputeStepLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, const G4ThreeVector &sampleDirection, const G4ThreeVector &localDirection, G4double sampleSafety, G4double sampleStep) const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4String GetName() const
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
void DumpInfo() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
virtual G4GeometryType GetEntityType() const =0
EInside
Definition geomdefs.hh:67
@ kInside
Definition geomdefs.hh:70
@ kOutside
Definition geomdefs.hh:68
@ kSurface
Definition geomdefs.hh:69