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

Last change on this file since 1202 was 1058, checked in by garnier, 15 years ago

file release beta

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