Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4BrentLocator Class Reference

#include <G4BrentLocator.hh>

+ Inheritance diagram for G4BrentLocator:

Public Member Functions

 G4BrentLocator (G4Navigator *theNavigator)
 
 ~G4BrentLocator ()
 
G4bool EstimateIntersectionPoint (const G4FieldTrack &curveStartPointTangent, const G4FieldTrack &curveEndPointTangent, const G4ThreeVector &trialPoint, G4FieldTrack &intersectPointTangent, G4bool &recalculatedEndPoint, G4double &fPreviousSafety, G4ThreeVector &fPreviousSftOrigin)
 
- Public Member Functions inherited from G4VIntersectionLocator
 G4VIntersectionLocator (G4Navigator *theNavigator)
 
virtual ~G4VIntersectionLocator ()
 
virtual G4bool EstimateIntersectionPoint (const G4FieldTrack &curveStartPointTangent, const G4FieldTrack &curveEndPointTangent, const G4ThreeVector &trialPoint, G4FieldTrack &intersectPointTangent, G4bool &recalculatedEndPoint, G4double &fPreviousSafety, G4ThreeVector &fPreviousSftOrigin)=0
 
void printStatus (const G4FieldTrack &startFT, const G4FieldTrack &currentFT, G4double requestStep, G4double safety, G4int stepNum)
 
G4bool IntersectChord (const G4ThreeVector &StartPointA, const G4ThreeVector &EndPointB, G4double &NewSafety, G4double &PreviousSafety, G4ThreeVector &PreviousSftOrigin, G4double &LinearStepLength, G4ThreeVector &IntersectionPoint, G4bool *calledNavigator=nullptr)
 
void SetEpsilonStepFor (G4double EpsilonStep)
 
void SetDeltaIntersectionFor (G4double deltaIntersection)
 
void SetNavigatorFor (G4Navigator *fNavigator)
 
void SetChordFinderFor (G4ChordFinder *fCFinder)
 
void SetVerboseFor (G4int fVerbose)
 
G4int GetVerboseFor ()
 
G4double GetDeltaIntersectionFor ()
 
G4double GetEpsilonStepFor ()
 
G4NavigatorGetNavigatorFor ()
 
G4ChordFinderGetChordFinderFor ()
 
void SetSafetyParametersFor (G4bool UseSafety)
 
void AddAdjustementOfFoundIntersection (G4bool UseCorrection)
 
G4bool GetAdjustementOfFoundIntersection ()
 
void AdjustIntersections (G4bool UseCorrection)
 
G4bool AreIntersectionsAdjusted ()
 
void SetCheckMode (G4bool value)
 
G4bool GetCheckMode ()
 

Additional Inherited Members

- Static Public Member Functions inherited from G4VIntersectionLocator
static void printStatus (const G4FieldTrack &startFT, const G4FieldTrack &currentFT, G4double requestStep, G4double safety, G4int stepNum, std::ostream &oss, G4int verboseLevel)
 
- Protected Member Functions inherited from G4VIntersectionLocator
G4FieldTrack ReEstimateEndpoint (const G4FieldTrack &CurrentStateA, const G4FieldTrack &EstimtdEndStateB, G4double linearDistSq, G4double curveDist)
 
G4bool CheckAndReEstimateEndpoint (const G4FieldTrack &CurrentStartA, const G4FieldTrack &EstimatedEndB, G4FieldTrack &RevisedEndPoint, G4int &errorCode)
 
G4ThreeVector GetSurfaceNormal (const G4ThreeVector &CurrentInt_Point, G4bool &validNormal)
 
G4ThreeVector GetGlobalSurfaceNormal (const G4ThreeVector &CurrentE_Point, G4bool &validNormal)
 
G4bool AdjustmentOfFoundIntersection (const G4ThreeVector &A, const G4ThreeVector &CurrentE_Point, const G4ThreeVector &CurrentF_Point, const G4ThreeVector &MomentumDir, const G4bool IntersectAF, G4ThreeVector &IntersectionPoint, G4double &NewSafety, G4double &fPrevSafety, G4ThreeVector &fPrevSftOrigin)
 
void ReportTrialStep (G4int step_no, const G4ThreeVector &ChordAB_v, const G4ThreeVector &ChordEF_v, const G4ThreeVector &NewMomentumDir, const G4ThreeVector &NormalAtEntry, G4bool validNormal)
 
G4bool LocateGlobalPointWithinVolumeAndCheck (const G4ThreeVector &pos)
 
void LocateGlobalPointWithinVolumeCheckAndReport (const G4ThreeVector &pos, const G4String &CodeLocationInfo, G4int CheckMode)
 
void ReportReversedPoints (std::ostringstream &ossMsg, const G4FieldTrack &StartPointVel, const G4FieldTrack &EndPointVel, G4double NewSafety, G4double epsStep, const G4FieldTrack &CurrentA_PointVelocity, const G4FieldTrack &CurrentB_PointVelocity, const G4FieldTrack &SubStart_PointVelocity, const G4ThreeVector &CurrentE_Point, const G4FieldTrack &ApproxIntersecPointV, G4int sbstp_no, G4int sbstp_no_p, G4int depth)
 
void ReportProgress (std::ostream &oss, const G4FieldTrack &StartPointVel, const G4FieldTrack &EndPointVel, G4int substep_no, const G4FieldTrack &A_PtVel, const G4FieldTrack &B_PtVel, G4double safetyLast, G4int depth=-1)
 
void ReportImmediateHit (const char *MethodName, const G4ThreeVector &StartPosition, const G4ThreeVector &TrialPoint, G4double tolerance, unsigned long int numCalls)
 
- Protected Attributes inherited from G4VIntersectionLocator
G4double kCarTolerance
 
G4int fVerboseLevel = 0
 
G4bool fUseNormalCorrection = false
 
G4bool fCheckMode = false
 
G4bool fiUseSafety = false
 
G4NavigatorfiNavigator
 
G4ChordFinderfiChordFinder = nullptr
 
G4double fiEpsilonStep = -1.0
 
G4double fiDeltaIntersection = -1.0
 
G4NavigatorfHelpingNavigator
 
G4TouchableHistoryfpTouchable = nullptr
 

Detailed Description

Definition at line 47 of file G4BrentLocator.hh.

Constructor & Destructor Documentation

◆ G4BrentLocator()

G4BrentLocator::G4BrentLocator ( G4Navigator theNavigator)

Definition at line 37 of file G4BrentLocator.cc.

38 : G4VIntersectionLocator(theNavigator)
39{
40 // In case of too slow progress in finding Intersection Point
41 // intermediates Points on the Track must be stored.
42 // Initialise the array of Pointers [max_depth+1] to do this
43
44 G4ThreeVector zeroV(0.0,0.0,0.0);
45 for (auto idepth=0; idepth<max_depth+1; ++idepth )
46 {
47 ptrInterMedFT[ idepth ] = new G4FieldTrack( zeroV, zeroV, 0., 0., 0., 0.);
48 }
49}

◆ ~G4BrentLocator()

G4BrentLocator::~G4BrentLocator ( )

Definition at line 51 of file G4BrentLocator.cc.

52{
53 for ( auto idepth=0; idepth<max_depth+1; ++idepth )
54 {
55 delete ptrInterMedFT[idepth];
56 }
57}

Member Function Documentation

◆ EstimateIntersectionPoint()

G4bool G4BrentLocator::EstimateIntersectionPoint ( const G4FieldTrack curveStartPointTangent,
const G4FieldTrack curveEndPointTangent,
const G4ThreeVector trialPoint,
G4FieldTrack intersectPointTangent,
G4bool recalculatedEndPoint,
G4double fPreviousSafety,
G4ThreeVector fPreviousSftOrigin 
)
virtual

Implements G4VIntersectionLocator.

Definition at line 92 of file G4BrentLocator.cc.

101{
102 // Find Intersection Point ( A, B, E ) of true path AB - start at E.
103
104 G4bool found_approximate_intersection = false;
105 G4bool there_is_no_intersection = false;
106
107 G4FieldTrack CurrentA_PointVelocity = CurveStartPointVelocity;
108 G4FieldTrack CurrentB_PointVelocity = CurveEndPointVelocity;
109 G4ThreeVector CurrentE_Point = TrialPoint;
110 G4bool validNormalAtE = false;
111 G4ThreeVector NormalAtEntry;
112
113 G4FieldTrack ApproxIntersecPointV(CurveEndPointVelocity); // FT-Def-Construct
114 G4double NewSafety = 0.0;
115 G4bool last_AF_intersection = false;
116
117 // G4bool final_section= true; // Shows whether current section is last
118 // (i.e. B=full end)
119 G4bool first_section = true;
120 recalculatedEndPoint = false;
121
122 G4bool restoredFullEndpoint = false;
123
124 G4int oldprc; // cout, cerr precision
125 G4int substep_no = 0;
126
127 // Limits for substep number
128 //
129 const G4int max_substeps= 10000; // Test 120 (old value 100 )
130 const G4int warn_substeps= 1000; // 100
131
132 // Statistics for substeps
133 //
134 static G4ThreadLocal G4int max_no_seen= -1;
135
136 // Counter for restarting Bintermed
137 //
138 G4int restartB = 0;
139
140 //--------------------------------------------------------------------------
141 // Algorithm for the case if progress in founding intersection is too slow.
142 // Process is defined too slow if after N=param_substeps advances on the
143 // path, it will be only 'fraction_done' of the total length.
144 // In this case the remaining length is divided in two half and
145 // the loop is restarted for each half.
146 // If progress is still too slow, the division in two halfs continue
147 // until 'max_depth'.
148 //--------------------------------------------------------------------------
149
150 const G4int param_substeps = 50; // Test value for the maximum number
151 // of substeps
152 const G4double fraction_done = 0.3;
153
154 G4bool Second_half = false; // First half or second half of divided step
155
156 NormalAtEntry = GetSurfaceNormal(CurrentE_Point, validNormalAtE);
157
158 // We need to know this for the 'final_section':
159 // real 'final_section' or first half 'final_section'
160 // In algorithm it is considered that the 'Second_half' is true
161 // and it becomes false only if we are in the first-half of level
162 // depthness or if we are in the first section
163
164 G4int depth = 0; // Depth counts how many subdivisions of initial step made
165
166#ifdef G4DEBUG_FIELD
167 const G4double tolerance = 1.0e-8;
168 G4ThreeVector StartPosition = CurveStartPointVelocity.GetPosition();
169 if( (TrialPoint - StartPosition).mag() < tolerance * CLHEP::mm )
170 {
171 G4Exception("G4BrentLocator::EstimateIntersectionPoint()",
172 "GeomNav1002", JustWarning,
173 "Intersection point F is exactly at start point A." );
174 }
175#endif
176
177 // Intermediates Points on the Track = Subdivided Points must be stored.
178 // Give the initial values to 'InterMedFt'
179 // Important is 'ptrInterMedFT[0]', it saves the 'EndCurvePoint'
180 //
181 *ptrInterMedFT[0] = CurveEndPointVelocity;
182 for (auto idepth=1; idepth<max_depth+1; ++idepth )
183 {
184 *ptrInterMedFT[idepth] = CurveStartPointVelocity;
185 }
186
187 //Final_section boolean store
188 G4bool fin_section_depth[max_depth];
189 for (auto idepth=0; idepth<max_depth; ++idepth )
190 {
191 fin_section_depth[idepth] = true;
192 }
193
194 // 'SubStartPoint' is needed to calculate the length of the divided step
195 //
196 G4FieldTrack SubStart_PointVelocity = CurveStartPointVelocity;
197
198 do // Loop checking, 07.10.2016, J.Apostolakis
199 {
200 G4int substep_no_p = 0;
201 G4bool sub_final_section = false; // the same as final_section,
202 // but for 'sub_section'
203 SubStart_PointVelocity = CurrentA_PointVelocity;
204
205 do // Loop checking, 07.10.2016, J.Apostolakis
206 { // REPEAT param
207 G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition();
208 G4ThreeVector Point_B = CurrentB_PointVelocity.GetPosition();
209
210 // F = a point on true AB path close to point E
211 // (the closest if possible)
212 //
213 if(substep_no_p==0)
214 {
215 ApproxIntersecPointV = GetChordFinderFor()
216 ->ApproxCurvePointV( CurrentA_PointVelocity,
217 CurrentB_PointVelocity,
218 CurrentE_Point,
220 // The above method is the key & most intuitive part ...
221 }
222#ifdef G4DEBUG_FIELD
223 if( ApproxIntersecPointV.GetCurveLength() >
224 CurrentB_PointVelocity.GetCurveLength() * (1.0 + tolerance) )
225 {
226 G4Exception("G4BrentLocator::EstimateIntersectionPoint()",
227 "GeomNav0003", FatalException,
228 "Intermediate F point is past end B point" );
229 }
230#endif
231
232 G4ThreeVector CurrentF_Point = ApproxIntersecPointV.GetPosition();
233
234 // First check whether EF is small - then F is a good approx. point
235 // Calculate the length and direction of the chord AF
236 //
237 G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point;
238 G4ThreeVector NewMomentumDir = ApproxIntersecPointV.GetMomentumDir();
239 G4double MomDir_dot_Norm = NewMomentumDir.dot( NormalAtEntry ) ;
240
241#ifdef G4DEBUG_FIELD
242 G4ThreeVector ChordAB = Point_B - Point_A;
243
244 G4VIntersectionLocator::ReportTrialStep( substep_no, ChordAB,
245 ChordEF_Vector, NewMomentumDir, NormalAtEntry, validNormalAtE );
246#endif
247
248 G4bool adequate_angle;
249 adequate_angle = ( MomDir_dot_Norm >= 0.0 ) // Can use -epsilon instead.
250 || (! validNormalAtE ); // Makes criterion invalid
251 G4double EF_dist2 = ChordEF_Vector.mag2();
252 if ( ( EF_dist2 <= sqr(fiDeltaIntersection) && ( adequate_angle ) )
253 || ( EF_dist2 <= kCarTolerance*kCarTolerance ) )
254 {
255 found_approximate_intersection = true;
256
257 // Create the "point" return value
258 //
259 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
260 IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point );
261
263 {
264 // Try to Get Correction of IntersectionPoint using SurfaceNormal()
265 //
266 G4ThreeVector IP;
267 G4ThreeVector MomentumDir=ApproxIntersecPointV.GetMomentumDirection();
268 G4bool goodCorrection = AdjustmentOfFoundIntersection( Point_A,
269 CurrentE_Point, CurrentF_Point, MomentumDir,
270 last_AF_intersection, IP, NewSafety,
272 if ( goodCorrection )
273 {
274 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
275 IntersectedOrRecalculatedFT.SetPosition(IP);
276 }
277 }
278
279 // Note: in order to return a point on the boundary,
280 // we must return E. But it is F on the curve.
281 // So we must "cheat": we are using the position at point E
282 // and the velocity at point F !!!
283 //
284 // This must limit the length we can allow for displacement!
285 }
286 else // E is NOT close enough to the curve (ie point F)
287 {
288 // Check whether any volumes are encountered by the chord AF
289 // ---------------------------------------------------------
290 // First relocate to restore any Voxel etc information
291 // in the Navigator before calling ComputeStep()
292 //
294
295 G4ThreeVector PointG; // Candidate intersection point
296 G4double stepLengthAF;
297 G4bool usedNavigatorAF = false;
298 G4bool Intersects_AF = IntersectChord( Point_A, CurrentF_Point,
299 NewSafety,fPreviousSafety,
301 stepLengthAF,
302 PointG,
303 &usedNavigatorAF);
304 last_AF_intersection = Intersects_AF;
305 if( Intersects_AF )
306 {
307 // G is our new Candidate for the intersection point.
308 // It replaces "E" and we will repeat the test to see if
309 // it is a good enough approximate point for us.
310 // B <- F
311 // E <- G
312 //
313 G4FieldTrack EndPoint = ApproxIntersecPointV;
314 ApproxIntersecPointV = GetChordFinderFor()->ApproxCurvePointS(
315 CurrentA_PointVelocity, CurrentB_PointVelocity,
316 EndPoint,CurrentE_Point, CurrentF_Point,PointG,
317 true, GetEpsilonStepFor() );
318 CurrentB_PointVelocity = EndPoint;
319 CurrentE_Point = PointG;
320
321 // Need to recalculate the Exit Normal at the new PointG
322 // Know that a call was made to Navigator::ComputeStep in
323 // IntersectChord above.
324 //
325 G4bool validNormalLast;
326 NormalAtEntry = GetSurfaceNormal( PointG, validNormalLast );
327 validNormalAtE = validNormalLast;
328
329 // By moving point B, must take care if current
330 // AF has no intersection to try current FB!!
331 //
332 fin_section_depth[depth] = false;
333#ifdef G4VERBOSE
334 if( fVerboseLevel > 3 )
335 {
336 G4cout << "G4PiF::LI> Investigating intermediate point"
337 << " at s=" << ApproxIntersecPointV.GetCurveLength()
338 << " on way to full s="
339 << CurveEndPointVelocity.GetCurveLength() << G4endl;
340 }
341#endif
342 }
343 else // not Intersects_AF
344 {
345 // In this case:
346 // There is NO intersection of AF with a volume boundary.
347 // We must continue the search in the segment FB!
348 //
350
351 G4double stepLengthFB;
352 G4ThreeVector PointH;
353 G4bool usedNavigatorFB = false;
354
355 // Check whether any volumes are encountered by the chord FB
356 // ---------------------------------------------------------
357
358 G4bool Intersects_FB = IntersectChord( CurrentF_Point, Point_B,
359 NewSafety,fPreviousSafety,
361 stepLengthFB,
362 PointH,
363 &usedNavigatorFB);
364 if( Intersects_FB )
365 {
366 // There is an intersection of FB with a volume boundary
367 // H <- First Intersection of Chord FB
368
369 // H is our new Candidate for the intersection point.
370 // It replaces "E" and we will repeat the test to see if
371 // it is a good enough approximate point for us.
372
373 // Note that F must be in volume volA (the same as A)
374 // (otherwise AF would meet a volume boundary!)
375 // A <- F
376 // E <- H
377 //
378 G4FieldTrack InterMed = ApproxIntersecPointV;
379 ApproxIntersecPointV = GetChordFinderFor()->ApproxCurvePointS(
380 CurrentA_PointVelocity,CurrentB_PointVelocity,
381 InterMed,CurrentE_Point,CurrentF_Point,PointH,
382 false,GetEpsilonStepFor());
383 CurrentA_PointVelocity = InterMed;
384 CurrentE_Point = PointH;
385
386 // Need to recalculate the Exit Normal at the new PointG
387 //
388 G4bool validNormalLast;
389 NormalAtEntry = GetSurfaceNormal( PointH, validNormalLast );
390 validNormalAtE = validNormalLast;
391 }
392 else // not Intersects_FB
393 {
394 // There is NO intersection of FB with a volume boundary
395
396 if( fin_section_depth[depth] )
397 {
398 // If B is the original endpoint, this means that whatever
399 // volume(s) intersected the original chord, none touch the
400 // smaller chords we have used.
401 // The value of 'IntersectedOrRecalculatedFT' returned is
402 // likely not valid
403
404 // Check on real final_section or SubEndSection
405 //
406 if( ((Second_half)&&(depth==0)) || (first_section) )
407 {
408 there_is_no_intersection = true; // real final_section
409 }
410 else
411 {
412 // end of subsection, not real final section
413 // exit from the and go to the depth-1 level
414
415 substep_no_p = param_substeps+2; // exit from the loop
416
417 // but 'Second_half' is still true because we need to find
418 // the 'CurrentE_point' for the next loop
419 //
420 Second_half = true;
421 sub_final_section = true;
422 }
423 }
424 else
425 {
426 if( depth==0 )
427 {
428 // We must restore the original endpoint
429 //
430 CurrentA_PointVelocity = CurrentB_PointVelocity; // Got to B
431 CurrentB_PointVelocity = CurveEndPointVelocity;
432 SubStart_PointVelocity = CurrentA_PointVelocity;
433 ApproxIntersecPointV = GetChordFinderFor()
434 ->ApproxCurvePointV( CurrentA_PointVelocity,
435 CurrentB_PointVelocity,
436 CurrentE_Point,
438
439 restoredFullEndpoint = true;
440 ++restartB; // counter
441 }
442 else
443 {
444 // We must restore the depth endpoint
445 //
446 CurrentA_PointVelocity = CurrentB_PointVelocity; // Got to B
447 CurrentB_PointVelocity = *ptrInterMedFT[depth];
448 SubStart_PointVelocity = CurrentA_PointVelocity;
449 ApproxIntersecPointV = GetChordFinderFor()
450 ->ApproxCurvePointV( CurrentA_PointVelocity,
451 CurrentB_PointVelocity,
452 CurrentE_Point,
454 restoredFullEndpoint = true;
455 ++restartB; // counter
456 }
457 }
458 } // Endif (Intersects_FB)
459 } // Endif (Intersects_AF)
460
461 // Ensure that the new endpoints are not further apart in space
462 // than on the curve due to different errors in the integration
463 //
464 G4double linDistSq, curveDist;
465 linDistSq = ( CurrentB_PointVelocity.GetPosition()
466 - CurrentA_PointVelocity.GetPosition() ).mag2();
467 curveDist = CurrentB_PointVelocity.GetCurveLength()
468 - CurrentA_PointVelocity.GetCurveLength();
469
470 // Change this condition for very strict parameters of propagation
471 //
472 if( curveDist*curveDist*(1+2* GetEpsilonStepFor()) < linDistSq )
473 {
474 // Re-integrate to obtain a new B
475 //
476 G4FieldTrack newEndPointFT=
477 ReEstimateEndpoint( CurrentA_PointVelocity,
478 CurrentB_PointVelocity,
479 linDistSq, // to avoid recalculation
480 curveDist );
481 G4FieldTrack oldPointVelB = CurrentB_PointVelocity;
482 CurrentB_PointVelocity = newEndPointFT;
483
484 if ( (fin_section_depth[depth]) // real final section
485 &&( first_section || ((Second_half)&&(depth==0)) ) )
486 {
487 recalculatedEndPoint = true;
488 IntersectedOrRecalculatedFT = newEndPointFT;
489 // So that we can return it, if it is the endpoint!
490 }
491 }
492 if( curveDist < 0.0 )
493 {
494 fVerboseLevel = 5; // Print out a maximum of information
495 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
496 -1.0, NewSafety, substep_no );
497 std::ostringstream message;
498 message << "Error in advancing propagation." << G4endl
499 << " Error in advancing propagation." << G4endl
500 << " Point A (start) is " << CurrentA_PointVelocity
501 << G4endl
502 << " Point B (end) is " << CurrentB_PointVelocity
503 << G4endl
504 << " Curve distance is " << curveDist << G4endl
505 << G4endl
506 << "The final curve point is not further along"
507 << " than the original!" << G4endl;
508
509 if( recalculatedEndPoint )
510 {
511 message << "Recalculation of EndPoint was called with fEpsStep= "
513 }
514 oldprc = G4cerr.precision(20);
515 message << " Point A (Curve start) is " << CurveStartPointVelocity
516 << G4endl
517 << " Point B (Curve end) is " << CurveEndPointVelocity
518 << G4endl
519 << " Point A (Current start) is " << CurrentA_PointVelocity
520 << G4endl
521 << " Point B (Current end) is " << CurrentB_PointVelocity
522 << G4endl
523 << " Point S (Sub start) is " << SubStart_PointVelocity
524 << G4endl
525 << " Point E (Trial Point) is " << CurrentE_Point
526 << G4endl
527 << " Old Point F(Intersection) is " << CurrentF_Point
528 << G4endl
529 << " New Point F(Intersection) is " << ApproxIntersecPointV
530 << G4endl
531 << " LocateIntersection parameters are : Substep no= "
532 << substep_no << G4endl
533 << " Substep depth no= "<< substep_no_p << " Depth= "
534 << depth << G4endl
535 << " Restarted no= "<< restartB << " Epsilon= "
536 << GetEpsilonStepFor() <<" DeltaInters= "
538 G4cerr.precision( oldprc );
539
540 G4Exception("G4BrentLocator::EstimateIntersectionPoint()",
541 "GeomNav0003", FatalException, message);
542 }
543
544 if( restoredFullEndpoint )
545 {
546 fin_section_depth[depth] = restoredFullEndpoint;
547 restoredFullEndpoint = false;
548 }
549 } // EndIf ( E is close enough to the curve, ie point F. )
550 // tests ChordAF_Vector.mag() <= maximum_lateral_displacement
551
552#ifdef G4DEBUG_LOCATE_INTERSECTION
553 G4int trigger_substepno_print= warn_substeps - 20 ;
554
555 if( substep_no >= trigger_substepno_print )
556 {
557 G4cout << "Difficulty in converging in "
558 << "G4BrentLocator::EstimateIntersectionPoint()"
559 << G4endl
560 << " Substep no = " << substep_no << G4endl;
561 if( substep_no == trigger_substepno_print )
562 {
563 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
564 -1.0, NewSafety, 0);
565 }
566 G4cout << " State of point A: ";
567 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
568 -1.0, NewSafety, substep_no-1, 0);
569 G4cout << " State of point B: ";
570 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
571 -1.0, NewSafety, substep_no);
572 }
573#endif
574 ++substep_no;
575 ++substep_no_p;
576
577 } while ( ( ! found_approximate_intersection )
578 && ( ! there_is_no_intersection )
579 && ( substep_no_p <= param_substeps) ); // UNTIL found or
580 // failed param substep
581 first_section = false;
582
583 if( (!found_approximate_intersection) && (!there_is_no_intersection) )
584 {
585 G4double did_len = std::abs( CurrentA_PointVelocity.GetCurveLength()
586 - SubStart_PointVelocity.GetCurveLength());
587 G4double all_len = std::abs( CurrentB_PointVelocity.GetCurveLength()
588 - SubStart_PointVelocity.GetCurveLength());
589
590 G4double stepLengthAB;
591 G4ThreeVector PointGe;
592
593 // Check if progress is too slow and if it possible to go deeper,
594 // then halve the step if so
595 //
596 if ( ( did_len < fraction_done*all_len )
597 && (depth < max_depth) && (!sub_final_section) )
598 {
599 Second_half=false;
600 ++depth;
601
602 G4double Sub_len = (all_len-did_len)/(2.);
603 G4FieldTrack start = CurrentA_PointVelocity;
604 auto integrDriver =
606 integrDriver->AccurateAdvance(start, Sub_len, GetEpsilonStepFor());
607 *ptrInterMedFT[depth] = start;
608 CurrentB_PointVelocity = *ptrInterMedFT[depth];
609
610 // Adjust 'SubStartPoint' to calculate the 'did_length' in next loop
611 //
612 SubStart_PointVelocity = CurrentA_PointVelocity;
613
614 // Find new trial intersection point needed at start of the loop
615 //
616 G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition();
617 G4ThreeVector SubE_point = CurrentB_PointVelocity.GetPosition();
618
620 G4bool Intersects_AB = IntersectChord(Point_A, SubE_point,
621 NewSafety, fPreviousSafety,
622 fPreviousSftOrigin,stepLengthAB,
623 PointGe);
624 if( Intersects_AB )
625 {
626 last_AF_intersection = Intersects_AB;
627 CurrentE_Point = PointGe;
628 fin_section_depth[depth] = true;
629
630 // Need to recalculate the Exit Normal at the new PointG
631 //
632 G4bool validNormalAB;
633 NormalAtEntry = GetSurfaceNormal( PointGe, validNormalAB );
634 validNormalAtE = validNormalAB;
635 }
636 else
637 {
638 // No intersection found for first part of curve
639 // (CurrentA,InterMedPoint[depth]). Go to the second part
640 //
641 Second_half = true;
642 }
643 } // if did_len
644
645 if( (Second_half)&&(depth!=0) )
646 {
647 // Second part of curve (InterMed[depth],Intermed[depth-1]) )
648 // On the depth-1 level normally we are on the 'second_half'
649
650 Second_half = true;
651
652 // Find new trial intersection point needed at start of the loop
653 //
654 SubStart_PointVelocity = *ptrInterMedFT[depth];
655 CurrentA_PointVelocity = *ptrInterMedFT[depth];
656 CurrentB_PointVelocity = *ptrInterMedFT[depth-1];
657 // Ensure that the new endpoints are not further apart in space
658 // than on the curve due to different errors in the integration
659 //
660 G4double linDistSq, curveDist;
661 linDistSq = ( CurrentB_PointVelocity.GetPosition()
662 - CurrentA_PointVelocity.GetPosition() ).mag2();
663 curveDist = CurrentB_PointVelocity.GetCurveLength()
664 - CurrentA_PointVelocity.GetCurveLength();
665 if( curveDist*curveDist*(1+2*GetEpsilonStepFor() ) < linDistSq )
666 {
667 // Re-integrate to obtain a new B
668 //
669 G4FieldTrack newEndPointFT =
670 ReEstimateEndpoint( CurrentA_PointVelocity,
671 CurrentB_PointVelocity,
672 linDistSq, // to avoid recalculation
673 curveDist );
674 G4FieldTrack oldPointVelB = CurrentB_PointVelocity;
675 CurrentB_PointVelocity = newEndPointFT;
676 if ( depth==1 )
677 {
678 recalculatedEndPoint = true;
679 IntersectedOrRecalculatedFT = newEndPointFT;
680 // So that we can return it, if it is the endpoint!
681 }
682 }
683
684
685 G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition();
686 G4ThreeVector SubE_point = CurrentB_PointVelocity.GetPosition();
688 G4bool Intersects_AB = IntersectChord(Point_A, SubE_point, NewSafety,
690 fPreviousSftOrigin,stepLengthAB, PointGe);
691 if( Intersects_AB )
692 {
693 last_AF_intersection = Intersects_AB;
694 CurrentE_Point = PointGe;
695
696 G4bool validNormalAB;
697 NormalAtEntry = GetSurfaceNormal( PointGe, validNormalAB );
698 validNormalAtE = validNormalAB;
699 }
700
701 depth--;
702 fin_section_depth[depth]=true;
703 }
704 } // if(!found_aproximate_intersection)
705
706 } while ( ( ! found_approximate_intersection )
707 && ( ! there_is_no_intersection )
708 && ( substep_no <= max_substeps) ); // UNTIL found or failed
709
710 if( substep_no > max_no_seen )
711 {
712 max_no_seen = substep_no;
713#ifdef G4DEBUG_LOCATE_INTERSECTION
714 if( max_no_seen > warn_substeps )
715 {
716 trigger_substepno_print = max_no_seen-20; // Want to see last 20 steps
717 }
718#endif
719 }
720
721 if( ( substep_no >= max_substeps)
722 && !there_is_no_intersection
723 && !found_approximate_intersection )
724 {
725 G4cout << "ERROR - G4BrentLocator::EstimateIntersectionPoint()" << G4endl
726 << " Start and end-point of requested Step:" << G4endl;
727 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
728 -1.0, NewSafety, 0);
729 G4cout << " Start and end-point of current Sub-Step:" << G4endl;
730 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
731 -1.0, NewSafety, substep_no-1);
732 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
733 -1.0, NewSafety, substep_no);
734 std::ostringstream message;
735 message << "Too many substeps!" << G4endl
736 << " Convergence is requiring too many substeps: "
737 << substep_no << G4endl
738 << " Abandoning effort to intersect. " << G4endl
739 << " Found intersection = "
740 << found_approximate_intersection << G4endl
741 << " Intersection exists = "
742 << !there_is_no_intersection << G4endl;
743 oldprc = G4cout.precision( 10 );
744 G4double done_len = CurrentA_PointVelocity.GetCurveLength();
745 G4double full_len = CurveEndPointVelocity.GetCurveLength();
746 message << " Undertaken only length: " << done_len
747 << " out of " << full_len << " required." << G4endl
748 << " Remaining length = " << full_len - done_len;
749 G4cout.precision( oldprc );
750
751 G4Exception("G4BrentLocator::EstimateIntersectionPoint()",
752 "GeomNav0003", FatalException, message);
753 }
754 else if( substep_no >= warn_substeps )
755 {
756 oldprc= G4cout.precision( 10 );
757 std::ostringstream message;
758 message << "Many substeps while trying to locate intersection."
759 << G4endl
760 << " Undertaken length: "
761 << CurrentB_PointVelocity.GetCurveLength()
762 << " - Needed: " << substep_no << " substeps." << G4endl
763 << " Warning level = " << warn_substeps
764 << " and maximum substeps = " << max_substeps;
765 G4Exception("G4BrentLocator::EstimateIntersectionPoint()",
766 "GeomNav1002", JustWarning, message);
767 G4cout.precision( oldprc );
768 }
769 return !there_is_no_intersection; // Success or failure
770}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
#define fPreviousSftOrigin
#define fPreviousSafety
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double mag2() const
double dot(const Hep3Vector &) const
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector &currentEPoint, G4double epsStep)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector &currentEPoint, const G4ThreeVector &currentFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
G4VIntegrationDriver * GetIntegrationDriver()
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
Definition: G4Navigator.cc:608
virtual G4bool AccurateAdvance(G4FieldTrack &track, G4double hstep, G4double eps, G4double hinitial=0)=0
G4Navigator * GetNavigatorFor()
G4ChordFinder * GetChordFinderFor()
G4ThreeVector GetSurfaceNormal(const G4ThreeVector &CurrentInt_Point, G4bool &validNormal)
void ReportTrialStep(G4int step_no, const G4ThreeVector &ChordAB_v, const G4ThreeVector &ChordEF_v, const G4ThreeVector &NewMomentumDir, const G4ThreeVector &NormalAtEntry, G4bool validNormal)
G4bool IntersectChord(const G4ThreeVector &StartPointA, const G4ThreeVector &EndPointB, G4double &NewSafety, G4double &PreviousSafety, G4ThreeVector &PreviousSftOrigin, G4double &LinearStepLength, G4ThreeVector &IntersectionPoint, G4bool *calledNavigator=nullptr)
G4double GetEpsilonStepFor()
G4FieldTrack ReEstimateEndpoint(const G4FieldTrack &CurrentStateA, const G4FieldTrack &EstimtdEndStateB, G4double linearDistSq, G4double curveDist)
G4bool GetAdjustementOfFoundIntersection()
G4double GetDeltaIntersectionFor()
void printStatus(const G4FieldTrack &startFT, const G4FieldTrack &currentFT, G4double requestStep, G4double safety, G4int stepNum)
G4bool AdjustmentOfFoundIntersection(const G4ThreeVector &A, const G4ThreeVector &CurrentE_Point, const G4ThreeVector &CurrentF_Point, const G4ThreeVector &MomentumDir, const G4bool IntersectAF, G4ThreeVector &IntersectionPoint, G4double &NewSafety, G4double &fPrevSafety, G4ThreeVector &fPrevSftOrigin)
T sqr(const T &x)
Definition: templates.hh:128
#define G4ThreadLocal
Definition: tls.hh:77

The documentation for this class was generated from the following files: