source: trunk/source/geometry/navigation/src/G4PropagatorInField.cc@ 1261

Last change on this file since 1261 was 1228, checked in by garnier, 16 years ago

update geant4.9.3 tag

File size: 25.6 KB
Line 
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//
27//
28//
29// This class implements an algorithm to track a particle in a
30// non-uniform magnetic field. It utilises an ODE solver (with
31// the Runge - Kutta method) to evolve the particle, and drives it
32// until the particle has traveled a set distance or it enters a new
33// volume.
34//
35// 14.10.96 John Apostolakis, design and implementation
36// 17.03.97 John Apostolakis, renaming new set functions being added
37//
38// $Id: G4PropagatorInField.cc,v 1.50 2009/12/10 08:41:54 japost Exp $
39// GEANT4 tag $ Name: $
40// ---------------------------------------------------------------------------
41
42#include "G4PropagatorInField.hh"
43#include "G4ios.hh"
44#include <iomanip>
45
46#include "G4ThreeVector.hh"
47#include "G4VPhysicalVolume.hh"
48#include "G4Navigator.hh"
49#include "G4GeometryTolerance.hh"
50#include "G4VCurvedTrajectoryFilter.hh"
51#include "G4ChordFinder.hh"
52#include "G4MultiLevelLocator.hh"
53
54///////////////////////////////////////////////////////////////////////////
55//
56// Constructors and destructor
57
58G4PropagatorInField::G4PropagatorInField( G4Navigator *theNavigator,
59 G4FieldManager *detectorFieldMgr,
60 G4VIntersectionLocator *vLocator )
61 : fDetectorFieldMgr(detectorFieldMgr),
62 fCurrentFieldMgr(detectorFieldMgr),
63 fNavigator(theNavigator),
64 End_PointAndTangent(G4ThreeVector(0.,0.,0.),
65 G4ThreeVector(0.,0.,0.),0.0,0.0,0.0,0.0,0.0),
66 fParticleIsLooping(false),
67 fVerboseLevel(0),
68 fMax_loop_count(1000),
69 fNoZeroStep(0),
70 fCharge(0.0), fInitialMomentumModulus(0.0), fMass(0.0),
71 fUseSafetyForOptimisation(true), // (false) is less sensitive to incorrect safety
72 fSetFieldMgr(false),
73 fZeroStepThreshold( 0.0 ),
74 fpTrajectoryFilter( 0 )
75{
76 if(fDetectorFieldMgr) { fEpsilonStep = fDetectorFieldMgr->GetMaximumEpsilonStep();}
77 else { fEpsilonStep= 1.0e-5; }
78 fActionThreshold_NoZeroSteps = 2;
79 fSevereActionThreshold_NoZeroSteps = 10;
80 fAbandonThreshold_NoZeroSteps = 50;
81 fFull_CurveLen_of_LastAttempt = -1;
82 fLast_ProposedStepLength = -1;
83 fLargestAcceptableStep = 1000.0 * meter;
84
85 fPreviousSftOrigin= G4ThreeVector(0.,0.,0.);
86 fPreviousSafety= 0.0;
87 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
88 fZeroStepThreshold= std::max( 1.0e5 * kCarTolerance, 1.0e-1 * micrometer ) ;
89#ifdef G4DEBUG_FIELD
90 G4cout << " PiF: Zero Step Threshold set to " << fZeroStepThreshold / millimeter
91 << " mm." << G4endl;
92 G4cout << " PiF: Value of kCarTolerance = " << kCarTolerance / millimeter
93 << " mm. " << G4endl;
94#endif
95
96 // Definding Intersection Locator and his parameters
97 if(vLocator==0){
98 fIntersectionLocator= new G4MultiLevelLocator(theNavigator);
99 fAllocatedLocator=true;
100 }else{
101 fIntersectionLocator=vLocator;
102 fAllocatedLocator=false;
103 }
104 RefreshIntersectionLocator(); // Copy all relevant parameters
105}
106
107G4PropagatorInField::~G4PropagatorInField()
108{
109 if(fAllocatedLocator)delete fIntersectionLocator;
110}
111
112// Update the IntersectionLocator with current parameters
113void
114G4PropagatorInField::RefreshIntersectionLocator()
115{
116 fIntersectionLocator->SetEpsilonStepFor(fEpsilonStep);
117 fIntersectionLocator->SetDeltaIntersectionFor(fCurrentFieldMgr->GetDeltaIntersection());
118 fIntersectionLocator->SetChordFinderFor(GetChordFinder());
119 fIntersectionLocator->SetSafetyParametersFor( fUseSafetyForOptimisation);
120}
121///////////////////////////////////////////////////////////////////////////
122//
123// Compute the next geometric Step
124
125G4double
126G4PropagatorInField::ComputeStep(
127 G4FieldTrack& pFieldTrack,
128 G4double CurrentProposedStepLength,
129 G4double& currentSafety, // IN/OUT
130 G4VPhysicalVolume* pPhysVol)
131{
132 const G4String MethodName("G4PropagatorInField::ComputeStep");
133
134 // If CurrentProposedStepLength is too small for finding Chords
135 // then return with no action (for now - TODO: some action)
136 //
137 if(CurrentProposedStepLength<kCarTolerance)
138 {
139 return kInfinity;
140 }
141
142 // Introducing smooth trajectory display (jacek 01/11/2002)
143 //
144 if (fpTrajectoryFilter)
145 {
146 fpTrajectoryFilter->CreateNewTrajectorySegment();
147 }
148
149 // Parameters for adaptive Runge-Kutta integration
150
151 G4double h_TrialStepSize; // 1st Step Size
152 G4double TruePathLength = CurrentProposedStepLength;
153 G4double StepTaken = 0.0;
154 G4double s_length_taken, epsilon ;
155 G4bool intersects;
156 G4bool first_substep = true;
157
158 G4double NewSafety;
159 fParticleIsLooping = false;
160
161 // If not yet done,
162 // Set the field manager to the local one if the volume has one,
163 // or to the global one if not
164 //
165 if( !fSetFieldMgr ) fCurrentFieldMgr= FindAndSetFieldManager( pPhysVol );
166 // For the next call, the field manager must again be set
167 fSetFieldMgr= false;
168
169 GetChordFinder()->SetChargeMomentumMass(fCharge, fInitialMomentumModulus, fMass);
170
171 // Values for Intersection Locator has to be updated on each call for the
172 // case that CurrentFieldManager has changed from the one of previous step
173 RefreshIntersectionLocator();
174
175 G4FieldTrack CurrentState(pFieldTrack);
176 G4FieldTrack OriginalState = CurrentState;
177
178 // If the Step length is "infinite", then an approximate-maximum Step
179 // length (used to calculate the relative accuracy) must be guessed.
180 //
181 if( CurrentProposedStepLength >= fLargestAcceptableStep )
182 {
183 G4ThreeVector StartPointA, VelocityUnit;
184 StartPointA = pFieldTrack.GetPosition();
185 VelocityUnit = pFieldTrack.GetMomentumDir();
186
187 G4double trialProposedStep = 1.e2 * ( 10.0 * cm +
188 fNavigator->GetWorldVolume()->GetLogicalVolume()->
189 GetSolid()->DistanceToOut(StartPointA, VelocityUnit) );
190 CurrentProposedStepLength= std::min( trialProposedStep,
191 fLargestAcceptableStep );
192 }
193 epsilon = fCurrentFieldMgr->GetDeltaOneStep() / CurrentProposedStepLength;
194 // G4double raw_epsilon= epsilon;
195 G4double epsilonMin= fCurrentFieldMgr->GetMinimumEpsilonStep();
196 G4double epsilonMax= fCurrentFieldMgr->GetMaximumEpsilonStep();;
197 if( epsilon < epsilonMin ) epsilon = epsilonMin;
198 if( epsilon > epsilonMax ) epsilon = epsilonMax;
199 SetEpsilonStep( epsilon );
200
201 // G4cout << "G4PiF: Epsilon of current step - raw= " << raw_epsilon
202 // << " final= " << epsilon << G4endl;
203
204 // Shorten the proposed step in case of earlier problems (zero steps)
205 //
206 if( fNoZeroStep > fActionThreshold_NoZeroSteps )
207 {
208 G4double stepTrial;
209
210 stepTrial= fFull_CurveLen_of_LastAttempt;
211 if( (stepTrial <= 0.0) && (fLast_ProposedStepLength > 0.0) )
212 stepTrial= fLast_ProposedStepLength;
213
214 G4double decreaseFactor = 0.9; // Unused default
215 if( (fNoZeroStep < fSevereActionThreshold_NoZeroSteps)
216 && (stepTrial > 100.0*fZeroStepThreshold) )
217 {
218 // Attempt quick convergence
219 //
220 decreaseFactor= 0.25;
221 }
222 else
223 {
224 // We are in significant difficulties, probably at a boundary that
225 // is either geometrically sharp or between very different materials.
226 // Careful decreases to cope with tolerance are required.
227 //
228 if( stepTrial > 100.0*fZeroStepThreshold )
229 decreaseFactor = 0.35; // Try decreasing slower
230 else if( stepTrial > 100.0*fZeroStepThreshold )
231 decreaseFactor= 0.5; // Try yet slower decreases
232 else if( stepTrial > 10.0*fZeroStepThreshold )
233 decreaseFactor= 0.75; // Try even slower decreases
234 else
235 decreaseFactor= 0.9; // Try very slow decreases
236 }
237 stepTrial *= decreaseFactor;
238
239#ifdef G4DEBUG_FIELD
240 G4cout << MethodName << ": "
241 << " Decreasing step - "
242 << " decreaseFactor= " << std::setw(8) << decreaseFactor
243 << " stepTrial = " << std::setw(18) << stepTrial << " "
244 << " fZeroStepThreshold = " << fZeroStepThreshold << G4endl;
245 PrintStepLengthDiagnostic(CurrentProposedStepLength, decreaseFactor,
246 stepTrial, pFieldTrack);
247#endif
248 if( stepTrial == 0.0 ) // Change to make it < 0.1 * kCarTolerance ??
249 {
250 G4cout << " G4PropagatorInField::ComputeStep "
251 << " Particle abandoned due to lack of progress in field."
252 << G4endl
253 << " Properties : " << pFieldTrack << " "
254 << G4endl;
255 G4cerr << " G4PropagatorInField::ComputeStep "
256 << " ERROR : attempting a zero step= " << stepTrial << G4endl
257 << " while attempting to progress after " << fNoZeroStep
258 << " trial steps. Will abandon step." << G4endl;
259 fParticleIsLooping= true;
260 return 0; // = stepTrial;
261 }
262 if( stepTrial < CurrentProposedStepLength )
263 CurrentProposedStepLength = stepTrial;
264 }
265 fLast_ProposedStepLength = CurrentProposedStepLength;
266
267 G4int do_loop_count = 0;
268 do
269 {
270 G4FieldTrack SubStepStartState = CurrentState;
271 G4ThreeVector SubStartPoint = CurrentState.GetPosition();
272
273 if( !first_substep) {
274 fNavigator->LocateGlobalPointWithinVolume( SubStartPoint );
275 }
276
277 // How far to attempt to move the particle !
278 //
279 h_TrialStepSize = CurrentProposedStepLength - StepTaken;
280
281 // Integrate as far as "chord miss" rule allows.
282 //
283 s_length_taken = GetChordFinder()->AdvanceChordLimited(
284 CurrentState, // Position & velocity
285 h_TrialStepSize,
286 fEpsilonStep,
287 fPreviousSftOrigin,
288 fPreviousSafety
289 );
290 // CurrentState is now updated with the final position and velocity.
291
292 fFull_CurveLen_of_LastAttempt = s_length_taken;
293
294 G4ThreeVector EndPointB = CurrentState.GetPosition();
295 G4ThreeVector InterSectionPointE;
296 G4double LinearStepLength;
297
298 // Intersect chord AB with geometry
299 intersects= IntersectChord( SubStartPoint, EndPointB,
300 NewSafety, LinearStepLength,
301 InterSectionPointE );
302 // E <- Intersection Point of chord AB and either volume A's surface
303 // or a daughter volume's surface ..
304
305 if( first_substep ) {
306 currentSafety = NewSafety;
307 } // Updating safety in other steps is potential future extention
308
309 if( intersects )
310 {
311 G4FieldTrack IntersectPointVelct_G(CurrentState); // FT-Def-Construct
312
313 // Find the intersection point of AB true path with the surface
314 // of vol(A), if it exists. Start with point E as first "estimate".
315 G4bool recalculatedEndPt= false;
316
317 G4bool found_intersection = fIntersectionLocator->
318 EstimateIntersectionPoint( SubStepStartState, CurrentState,
319 InterSectionPointE, IntersectPointVelct_G,
320 recalculatedEndPt,fPreviousSafety,fPreviousSftOrigin);
321 intersects = intersects && found_intersection;
322 if( found_intersection ) {
323 End_PointAndTangent= IntersectPointVelct_G; // G is our EndPoint ...
324 StepTaken = TruePathLength = IntersectPointVelct_G.GetCurveLength()
325 - OriginalState.GetCurveLength();
326 } else {
327 // intersects= false; // "Minor" chords do not intersect
328 if( recalculatedEndPt ){
329 CurrentState= IntersectPointVelct_G;
330 }
331 }
332 }
333 if( !intersects )
334 {
335 StepTaken += s_length_taken;
336 // For smooth trajectory display (jacek 01/11/2002)
337 if (fpTrajectoryFilter) {
338 fpTrajectoryFilter->TakeIntermediatePoint(CurrentState.GetPosition());
339 }
340 }
341 first_substep = false;
342
343#ifdef G4DEBUG_FIELD
344 if( fNoZeroStep > fActionThreshold_NoZeroSteps ) {
345 printStatus( SubStepStartState, // or OriginalState,
346 CurrentState, CurrentProposedStepLength,
347 NewSafety, do_loop_count, pPhysVol );
348 }
349#endif
350#ifdef G4VERBOSE
351 if( (fVerboseLevel > 1) && (do_loop_count > fMax_loop_count-10 )) {
352 if( do_loop_count == fMax_loop_count-9 ){
353 G4cout << "G4PropagatorInField::ComputeStep "
354 << " Difficult track - taking many sub steps." << G4endl;
355 }
356 printStatus( SubStepStartState, CurrentState, CurrentProposedStepLength,
357 NewSafety, do_loop_count, pPhysVol );
358 }
359#endif
360
361 do_loop_count++;
362
363 } while( (!intersects )
364 && (StepTaken + kCarTolerance < CurrentProposedStepLength)
365 && ( do_loop_count < fMax_loop_count ) );
366
367 if( do_loop_count >= fMax_loop_count )
368 {
369 fParticleIsLooping = true;
370
371 if ( fVerboseLevel > 0 ){
372 G4cout << "G4PropagateInField: Killing looping particle "
373 // << " of " << energy << " energy "
374 << " after " << do_loop_count << " field substeps "
375 << " totaling " << StepTaken / mm << " mm " ;
376 if( pPhysVol )
377 G4cout << " in the volume " << pPhysVol->GetName() ;
378 else
379 G4cout << " in unknown or null volume. " ;
380 G4cout << G4endl;
381 }
382 }
383
384 if( !intersects )
385 {
386 // Chord AB or "minor chords" do not intersect
387 // B is the endpoint Step of the current Step.
388 //
389 End_PointAndTangent = CurrentState;
390 TruePathLength = StepTaken;
391 }
392
393 // Set pFieldTrack to the return value
394 //
395 pFieldTrack = End_PointAndTangent;
396
397#ifdef G4VERBOSE
398 // Check that "s" is correct
399 //
400 if( std::fabs(OriginalState.GetCurveLength() + TruePathLength
401 - End_PointAndTangent.GetCurveLength()) > 3.e-4 * TruePathLength )
402 {
403 G4cerr << " ERROR - G4PropagatorInField::ComputeStep():" << G4endl
404 << " Curve length mis-match, is advancement wrong ? " << G4endl;
405 G4cerr << " The curve length of the endpoint should be: "
406 << OriginalState.GetCurveLength() + TruePathLength << G4endl
407 << " and it is instead: "
408 << End_PointAndTangent.GetCurveLength() << "." << G4endl
409 << " A difference of: "
410 << OriginalState.GetCurveLength() + TruePathLength
411 - End_PointAndTangent.GetCurveLength() << G4endl;
412 G4cerr << " Original state= " << OriginalState << G4endl
413 << " Proposed state= " << End_PointAndTangent << G4endl;
414 G4Exception("G4PropagatorInField::ComputeStep()", "IncorrectProposedEndPoint",
415 FatalException,
416 "Curve length mis-match between original state and proposed endpoint of propagation.");
417 }
418#endif
419
420 // In particular anomalous cases, we can get repeated zero steps
421 // In order to correct this efficiently, we identify these cases
422 // and only take corrective action when they occur.
423 //
424 if( ( (TruePathLength < fZeroStepThreshold)
425 && ( TruePathLength+kCarTolerance < CurrentProposedStepLength )
426 )
427 || ( TruePathLength < 0.5*kCarTolerance )
428 )
429 {
430 fNoZeroStep++;
431 }
432 else{
433 fNoZeroStep = 0;
434 }
435
436 if( fNoZeroStep > fAbandonThreshold_NoZeroSteps ) {
437 fParticleIsLooping = true;
438 G4cout << " WARNING - G4PropagatorInField::ComputeStep():" << G4endl
439 << " Zero progress for " << fNoZeroStep << " attempted steps."
440 << G4endl;
441 G4cout << "Proposed Step is "<<CurrentProposedStepLength <<" but Step Taken is "<< fFull_CurveLen_of_LastAttempt <<G4endl;
442 G4cout << "For Particle with Charge ="<<fCharge
443 << " Momentum="<< fInitialMomentumModulus<<" Mass="<< fMass<<G4endl;
444 if( pPhysVol )
445 G4cout << " in the volume " << pPhysVol->GetName() ;
446 else
447 G4cout << " in unknown or null volume. " ;
448 G4cout << G4endl;
449 if ( fVerboseLevel > 2 )
450 G4cout << " Particle that is stuck will be killed." << G4endl;
451 fNoZeroStep = 0;
452 }
453
454 return TruePathLength;
455}
456
457///////////////////////////////////////////////////////////////////////////
458//
459// Dumps status of propagator.
460
461void
462G4PropagatorInField::printStatus( const G4FieldTrack& StartFT,
463 const G4FieldTrack& CurrentFT,
464 G4double requestStep,
465 G4double safety,
466 G4int stepNo,
467 G4VPhysicalVolume* startVolume)
468{
469 const G4int verboseLevel= fVerboseLevel;
470 const G4ThreeVector StartPosition = StartFT.GetPosition();
471 const G4ThreeVector StartUnitVelocity = StartFT.GetMomentumDir();
472 const G4ThreeVector CurrentPosition = CurrentFT.GetPosition();
473 const G4ThreeVector CurrentUnitVelocity = CurrentFT.GetMomentumDir();
474
475 G4double step_len = CurrentFT.GetCurveLength() - StartFT.GetCurveLength();
476
477 if( ((stepNo == 0) && (verboseLevel <3))
478 || (verboseLevel >= 3) )
479 {
480 static G4int noPrecision= 4;
481 G4cout.precision(noPrecision);
482 // G4cout.setf(ios_base::fixed,ios_base::floatfield);
483 G4cout << std::setw( 6) << " "
484 << std::setw( 25) << " Current Position and Direction" << " "
485 << G4endl;
486 G4cout << std::setw( 5) << "Step#"
487 << std::setw(10) << " s " << " "
488 << std::setw(10) << "X(mm)" << " "
489 << std::setw(10) << "Y(mm)" << " "
490 << std::setw(10) << "Z(mm)" << " "
491 << std::setw( 7) << " N_x " << " "
492 << std::setw( 7) << " N_y " << " "
493 << std::setw( 7) << " N_z " << " " ;
494 // << G4endl;
495 G4cout // << " >>> "
496 << std::setw( 7) << " Delta|N|" << " "
497 // << std::setw( 7) << " Delta(N_z) " << " "
498 << std::setw( 9) << "StepLen" << " "
499 << std::setw(12) << "StartSafety" << " "
500 << std::setw( 9) << "PhsStep" << " ";
501 if( startVolume ) {
502 G4cout << std::setw(18) << "NextVolume" << " ";
503 }
504 G4cout << G4endl;
505 }
506 if((stepNo == 0) && (verboseLevel <=3)){
507 // Recurse to print the start values
508 //
509 printStatus( StartFT, StartFT, -1.0, safety, -1, startVolume);
510 }
511 if( verboseLevel <= 3 )
512 {
513 if( stepNo >= 0)
514 G4cout << std::setw( 4) << stepNo << " ";
515 else
516 G4cout << std::setw( 5) << "Start" ;
517 G4cout.precision(8);
518 G4cout << std::setw(10) << CurrentFT.GetCurveLength() << " ";
519 G4cout.precision(8);
520 G4cout << std::setw(10) << CurrentPosition.x() << " "
521 << std::setw(10) << CurrentPosition.y() << " "
522 << std::setw(10) << CurrentPosition.z() << " ";
523 G4cout.precision(4);
524 G4cout << std::setw( 7) << CurrentUnitVelocity.x() << " "
525 << std::setw( 7) << CurrentUnitVelocity.y() << " "
526 << std::setw( 7) << CurrentUnitVelocity.z() << " ";
527 // G4cout << G4endl;
528 // G4cout << " >>> " ;
529 G4cout.precision(3);
530 G4cout << std::setw( 7) << CurrentFT.GetMomentum().mag()- StartFT.GetMomentum().mag() << " ";
531 // << std::setw( 7) << CurrentUnitVelocity.z() - InitialUnitVelocity.z() << " ";
532 G4cout << std::setw( 9) << step_len << " ";
533 G4cout << std::setw(12) << safety << " ";
534 if( requestStep != -1.0 )
535 G4cout << std::setw( 9) << requestStep << " ";
536 else
537 G4cout << std::setw( 9) << "Init/NotKnown" << " ";
538
539 if( startVolume != 0)
540 {
541 G4cout << std::setw(12) << startVolume->GetName() << " ";
542 }
543#if 0
544 else
545 {
546 if( step_len != -1 )
547 G4cout << std::setw(12) << "OutOfWorld" << " ";
548 else
549 G4cout << std::setw(12) << "NotGiven" << " ";
550 }
551#endif
552
553 G4cout << G4endl;
554 }
555 else // if( verboseLevel > 3 )
556 {
557 // Multi-line output
558
559 G4cout << "Step taken was " << step_len
560 << " out of PhysicalStep= " << requestStep << G4endl;
561 G4cout << "Final safety is: " << safety << G4endl;
562
563 G4cout << "Chord length = " << (CurrentPosition-StartPosition).mag()
564 << G4endl;
565 G4cout << G4endl;
566 }
567}
568
569///////////////////////////////////////////////////////////////////////////
570//
571// Prints Step diagnostics
572
573void
574G4PropagatorInField::PrintStepLengthDiagnostic(
575 G4double CurrentProposedStepLength,
576 G4double decreaseFactor,
577 G4double stepTrial,
578 const G4FieldTrack& )
579{
580#if 0
581 G4cout << " PiF: NoZeroStep= " << fNoZeroStep
582 << " CurrentProposedStepLength= " << CurrentProposedStepLength
583 << " Full_curvelen_last=" << fFull_CurveLen_of_LastAttempt
584 << " last proposed step-length= " << fLast_ProposedStepLength
585 << " decrease factor = " << decreaseFactor
586 << " step trial = " << stepTrial
587 << G4endl;
588#endif
589 int iprec= G4cout.precision(8);
590 G4cout << " " << std::setw(12) << " PiF: NoZeroStep "
591 << " " << std::setw(20) << " CurrentProposed len "
592 << " " << std::setw(18) << " Full_curvelen_last"
593 << " " << std::setw(18) << " last proposed len "
594 << " " << std::setw(18) << " decrease factor "
595 << " " << std::setw(15) << " step trial "
596 << G4endl;
597
598 G4cout << " " << std::setw(10) << fNoZeroStep << " "
599 << " " << std::setw(20) << CurrentProposedStepLength
600 << " " << std::setw(18) << fFull_CurveLen_of_LastAttempt
601 << " " << std::setw(18) << fLast_ProposedStepLength
602 << " " << std::setw(18) << decreaseFactor
603 << " " << std::setw(15) << stepTrial
604 << G4endl;
605 G4cout.precision( iprec );
606
607}
608
609// Access the points which have passed through the filter. The
610// points are stored as ThreeVectors for the initial impelmentation
611// only (jacek 30/10/2002)
612// Responsibility for deleting the points lies with
613// SmoothTrajectoryPoint, which is the points' final
614// destination. The points pointer is set to NULL, to ensure that
615// the points are not re-used in subsequent steps, therefore THIS
616// METHOD MUST BE CALLED EXACTLY ONCE PER STEP. (jacek 08/11/2002)
617
618std::vector<G4ThreeVector>*
619G4PropagatorInField::GimmeTrajectoryVectorAndForgetIt() const
620{
621 // NB, GimmeThePointsAndForgetThem really forgets them, so it can
622 // only be called (exactly) once for each step.
623
624 if (fpTrajectoryFilter)
625 {
626 return fpTrajectoryFilter->GimmeThePointsAndForgetThem();
627 }
628 else
629 {
630 return 0;
631 }
632}
633
634void
635G4PropagatorInField::SetTrajectoryFilter(G4VCurvedTrajectoryFilter* filter)
636{
637 fpTrajectoryFilter = filter;
638}
639
640void G4PropagatorInField::ClearPropagatorState()
641{
642 // Goal: Clear all memory of previous steps, cached information
643
644 fParticleIsLooping= false;
645 fNoZeroStep= 0;
646
647 End_PointAndTangent= G4FieldTrack( G4ThreeVector(0.,0.,0.),
648 G4ThreeVector(0.,0.,0.),
649 0.0,0.0,0.0,0.0,0.0);
650 fFull_CurveLen_of_LastAttempt = -1;
651 fLast_ProposedStepLength = -1;
652
653 fPreviousSftOrigin= G4ThreeVector(0.,0.,0.);
654 fPreviousSafety= 0.0;
655}
656
657G4FieldManager* G4PropagatorInField::
658FindAndSetFieldManager( G4VPhysicalVolume* pCurrentPhysicalVolume)
659{
660 G4FieldManager* currentFieldMgr;
661
662 currentFieldMgr = fDetectorFieldMgr;
663 if( pCurrentPhysicalVolume)
664 {
665 G4FieldManager *pRegionFieldMgr= 0, *localFieldMgr = 0;
666 G4LogicalVolume* pLogicalVol= pCurrentPhysicalVolume->GetLogicalVolume();
667
668 if( pLogicalVol ) {
669 // Value for Region, if any, Overrides
670 G4Region* pRegion= pLogicalVol->GetRegion();
671 if( pRegion ) {
672 pRegionFieldMgr= pRegion->GetFieldManager();
673 if( pRegionFieldMgr )
674 currentFieldMgr= pRegionFieldMgr;
675 }
676
677 // 'Local' Value from logical volume, if any, Overrides
678 localFieldMgr= pLogicalVol->GetFieldManager();
679 if ( localFieldMgr )
680 currentFieldMgr = localFieldMgr;
681 }
682 }
683 fCurrentFieldMgr= currentFieldMgr;
684
685 // Flag that field manager has been set.
686 fSetFieldMgr= true;
687
688 return currentFieldMgr;
689}
690
691G4int G4PropagatorInField::SetVerboseLevel( G4int level )
692{
693 G4int oldval= fVerboseLevel;
694 fVerboseLevel= level;
695
696 // Forward the verbose level 'reduced' to ChordFinder,
697 // MagIntegratorDriver ... ?
698 //
699 G4MagInt_Driver* integrDriver= GetChordFinder()->GetIntegrationDriver();
700 integrDriver->SetVerboseLevel( fVerboseLevel - 2 );
701 G4cout << "Set Driver verbosity to " << fVerboseLevel - 2 << G4endl;
702
703 return oldval;
704}
Note: See TracBrowser for help on using the repository browser.