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

Last change on this file since 1351 was 1347, checked in by garnier, 15 years ago

geant4 tag 9.4

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