52 G4bool fieldChangesEnergy )
53 : fDetectorField(detectorField),
54 fChordFinder(pChordFinder)
56 if ( detectorField !=
nullptr )
62 fFieldChangesEnergy = fieldChangesEnergy;
67 G4cout <<
"G4FieldManager/ctor#1 fEpsilon Min/Max: eps_min = " << fEpsilonMin <<
" eps_max=" << fEpsilonMax <<
G4endl;
76 : fDetectorField(detectorField), fAllocatedChordFinder(true)
82 G4cout <<
"G4FieldManager/ctor#2 fEpsilon Min/Max: eps_min = " << fEpsilonMin <<
" eps_max=" << fEpsilonMax <<
G4endl;
91 if( fAllocatedChordFinder )
105 if ( fDetectorField !=
nullptr )
107 aField = fDetectorField->
Clone();
113 aFM =
new G4FieldManager( aField ,
nullptr , fFieldChangesEnergy );
118 if ( fAllocatedChordFinder )
129 aFM->fChordFinder = aCF;
134 aFM->fEpsilonMax = fEpsilonMax;
135 aFM->fEpsilonMin = fEpsilonMin;
136 aFM->fDelta_Intersection_Val = fDelta_Intersection_Val;
137 aFM->fDelta_One_Step_Value = fDelta_One_Step_Value;
152 G4cout <<
"G4FieldManager/clone fEpsilon Min/Max: eps_min = " << fEpsilonMin <<
" eps_max=" << fEpsilonMax <<
G4endl;
164 if ( fAllocatedChordFinder )
168 fAllocatedChordFinder =
false;
170 if( detectorMagField !=
nullptr )
173 fAllocatedChordFinder =
true;
177 fChordFinder =
nullptr;
181void G4FieldManager::InitialiseFieldChangesEnergy()
183 if ( fDetectorField !=
nullptr )
189 fFieldChangesEnergy =
false;
201 fDetectorField = pDetectorField;
202 InitialiseFieldChangesEnergy();
206 if( fChordFinder !=
nullptr )
208 failMode= std::max( failMode, 1) ;
211 driver = fChordFinder->GetIntegrationDriver();
212 if( driver !=
nullptr )
219 if( equation !=
nullptr )
227 if( !ableToSet && (failMode > 0) )
232 msg <<
"Unable to set the field in the dependent objects of G4FieldManager"
234 msg <<
"All the dependent classes must be fully initialised,"
235 <<
"before it is possible to call this method." <<
G4endl;
236 msg <<
"The problem encountered was the following: " <<
G4endl;
237 if( fChordFinder ==
nullptr ) { msg <<
" No ChordFinder. " ; }
238 else if( driver ==
nullptr ) { msg <<
" No Integration Driver set. ";}
239 else if( equation ==
nullptr ) { msg <<
" No Equation found. " ; }
241 else { msg <<
" Can NOT find reason for failure. ";}
245 G4Exception(
"G4FieldManager::SetDetectorField",
"Geometry001",
257 if(newEpsMax >= fEpsilonMin)
259 fEpsilonMax = newEpsMax;
263 G4cout <<
"G4FieldManager/SetEpsMax : eps_max = " << std::setw(10) << fEpsilonMax
264 <<
" ( Note: unchanged eps_min=" << std::setw(10) << fEpsilonMin <<
" )" <<
G4endl;
270 erm <<
" Call to set eps_max = " << newEpsMax <<
" . The problem is that"
271 <<
" its value must be at larger or equal to eps_min= " << fEpsilonMin <<
G4endl;
272 erm <<
" Modifying both to the same value " << newEpsMax <<
" to ensure consistency."
274 <<
" To avoid this warning, please set eps_min first, and ensure that "
277 fEpsilonMax = newEpsMax;
278 fEpsilonMin = newEpsMax;
302 fEpsilonMin = newEpsMin;
308 G4cout <<
"G4FieldManager/SetEpsMin : eps_min = "
309 << std::setw(10) << fEpsilonMin <<
G4endl;
311 if( fEpsilonMax < fEpsilonMin )
315 erm <<
"Setting eps_min = " << newEpsMin
316 <<
" For consistency set eps_max= " << fEpsilonMin
317 <<
" ( Old value = " << fEpsilonMax <<
" )" <<
G4endl;
318 fEpsilonMax = fEpsilonMin;
359 G4cout <<
"G4FieldManager::" << __func__
368 erm <<
"Proposed value for maximum-accepted-epsilon = " << maxAcceptValue
371 <<
"This may impact the robustness of integration of tracks in field."
374 <<
" , but future releases are expected " <<
G4endl
375 <<
" to tighten the limit of acceptable values to "
377 <<
"Suggestion: If you need better performance investigate using "
378 <<
"alternative, low-order RK integration methods or " <<
G4endl
379 <<
" helix-based methods (for pure B-fields) for low(er) energy tracks, "
380 <<
" especially electrons if you need better performance." <<
G4endl;
386 erm <<
" Proposed value for maximum accepted epsilon " << maxAcceptValue
391 erm <<
" Using the latter value instead." <<
G4endl;
398 erm <<
" NOTE: you can accept the ceiling value and turn this into a "
399 <<
" warning by using a 2nd argument " <<
G4endl
400 <<
" in your call to SetMaxAcceptedEpsilon: softFailure = true ";
408 G4Exception(methodName.c_str(),
"Geometry003", severity, erm);
418 erm <<
"Incorrect proposed value of " << name <<
" = " << value <<
G4endl
419 <<
" Its value is outside the permitted range from "
421 <<
" Clarification: " <<
G4endl;
422 G4long oldPrec = erm.precision();
425 erm <<
" a) The value must be positive and enough larger than the accuracy limit"
426 <<
" of the (G4)double type - ("
428 <<
" i.e. std::numeric_limits<G4double>::epsilon()= "
429 << std::numeric_limits<G4double>::epsilon()
430 <<
" to ensure that integration " <<
G4endl
431 <<
" could potentially achieve this acccuracy." <<
G4endl
436 erm <<
" b) It must be smaller than (or equal) " << std::setw(8)
438 <<
" to ensure robustness of integration - ("
443 G4bool badRoundoff = (std::fabs(1.0+value) == 1.0);
444 erm <<
" Unknown ERROR case -- extra check: " <<
G4endl;
445 erm <<
" c) as a floating point number (of type G4double) the sum (1+" << name
446 <<
" ) must be > 1 , ("
447 << (badRoundoff ?
"FAILED" :
"OK" ) <<
")" <<
G4endl
448 <<
" Now 1+eps_min = " << std::setw(20)
449 << std::setprecision(17) << (1+value) <<
G4endl
450 <<
" and (1.0+" << name <<
") - 1.0 = " << std::setw(20)
451 << std::setprecision(9) << (1.0+value)-1.0;
453 erm.precision(oldPrec);
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
G4ChordFinder is a class that provides Runge-Kutta integration of motion ODE and also has a method th...
G4EquationOfMotion is the abstract base class for the right hand size of the equation of motion of a ...
void SetFieldObj(G4Field *pField)
static void DeRegister(G4FieldManager *pFieldMan)
static void Register(G4FieldManager *pFieldMan)
G4FieldManager is a manager (store) for a pointer to the Field subclass that describes the field of a...
virtual G4FieldManager * Clone() const
static G4double GetMaxAcceptedEpsilon()
virtual ~G4FieldManager()
G4bool SetDetectorField(G4Field *detectorField, G4int failMode=0)
static constexpr G4double fMinAcceptedEpsilon
static constexpr G4double fMaxWarningEpsilon
void CreateChordFinder(G4MagneticField *detectorMagField)
G4bool SetMaximumEpsilonStep(G4double newEpsMax)
void ReportBadEpsilonValue(G4ExceptionDescription &erm, G4double value, const G4String &name) const
static G4double fMaxAcceptedEpsilon
G4bool SetMinimumEpsilonStep(G4double newEpsMin)
G4FieldManager(G4Field *detectorField=nullptr, G4ChordFinder *pChordFinder=nullptr, G4bool b=true)
static G4bool fVerboseConstruction
static constexpr G4double fMaxFinalEpsilon
virtual void ConfigureForTrack(const G4Track *pTrack)
static G4bool SetMaxAcceptedEpsilon(G4double maxEps, G4bool softFail=false)
G4Field is the abstract class for any kind of field. It allows any kind of field (vector,...
virtual G4bool DoesFieldChangeEnergy() const =0
virtual G4Field * Clone() const
virtual G4EquationOfMotion * GetEquationOfMotion()=0