54 #include "G4mplEquationSetup.hh"
56 #include "G4mplEqMagElectricField.hh"
58 #include "G4MagneticField.hh"
59 #include "G4UniformMagField.hh"
60 #include "G4FieldManager.hh"
61 #include "G4TransportationManager.hh"
62 #include "G4Mag_UsualEqRhs.hh"
63 #include "G4MagIntegratorStepper.hh"
64 #include "G4ChordFinder.hh"
65 #include "G4MagIntegratorDriver.hh"
66 #include "G4AtlasRK4.hh"
67 #include "G4ClassicalRK4.hh"
74 #include "G4SystemOfUnits.hh"
75 #include "G4UniformMagField.hh"
77 #ifdef G4MULTITHREADED
78 G4mplEquationSetup::ESThreadMap_t G4mplEquationSetup::m_ESThreadMap;
83 G4mplEquationSetup::G4mplEquationSetup():
88 G4cout <<
"!!! G4mplEquationSetup constructor" << G4endl;
93 G4mplEquationSetup* G4mplEquationSetup::GetInstance()
95 #ifdef G4MULTITHREADED
110 G4mplEquationSetup::~G4mplEquationSetup()
113 G4cout <<
"!!! G4mplEquationSetup destructor" << G4endl;
115 delete fMonopoleEquation;
116 delete fMonopoleStepper;
118 delete fMonopoleChordFinder;
125 #ifdef G4MULTITHREADED
126 G4mplEquationSetup* G4mplEquationSetup::getES()
129 const auto tid = std::this_thread::get_id();
130 auto esPair = m_ESThreadMap.find(tid);
131 if(esPair == m_ESThreadMap.end())
133 else return esPair->second;
138 G4mplEquationSetup* G4mplEquationSetup::setES()
140 G4mplEquationSetup*
instance =
new G4mplEquationSetup;
141 const auto tid = std::this_thread::get_id();
142 auto inserted = m_ESThreadMap.insert( std::make_pair(tid,
instance)).first;
143 return (G4mplEquationSetup*) inserted->second;
162 G4mplEquationSetup::InitialiseForField(G4FieldManager* fieldManager )
164 if (fieldManager ==
nullptr) {
172 fOriginalChordFinder = fieldManager->GetChordFinder();
173 fCurrentFieldManager = fieldManager;
177 const G4MagneticField* magField =
dynamic_cast<const G4MagneticField*
>(fieldManager->GetDetectorField());
178 G4MagneticField* magFieldNC
ATLAS_THREAD_SAFE =
const_cast<G4MagneticField*
>(magField);
180 CreateStepperToChordFinder(magFieldNC);
186 G4mplEquationSetup::CreateStepperToChordFinder(G4MagneticField* magFieldNC)
188 if(magFieldNC ==
nullptr)
190 static G4ThreadLocal G4UniformMagField nullField( G4ThreeVector(0.0, 0.0, 0.0));
191 magFieldNC= &nullField;
194 delete fMonopoleEquation;
195 fMonopoleEquation =
new G4mplEqMagElectricField(magFieldNC);
197 delete fMonopoleStepper;
198 fMonopoleStepper =
new G4ClassicalRK4( fMonopoleEquation, 8 );
200 if ( !fMonopoleStepper )
202 G4ExceptionDescription ermsg;
203 ermsg <<
"The creation of a stepper for Monopoles failed - trying to use G4ClassicalRK4";
204 G4Exception(
"G4mplEquationSetup::InitialiseForField",
205 "FailureToCreateObject", FatalException, ermsg);
208 delete fMonopoleChordFinder;
210 auto integrDriver =
new G4MagInt_Driver( fMinStep, fMonopoleStepper,
212 fMonopoleStepper->GetNumberOfVariables() );
213 fMonopoleChordFinder =
new G4ChordFinder( integrDriver );
220 void G4mplEquationSetup::SwitchStepperAndChordFinder(G4bool useMonopoleEq,
221 G4FieldManager* fieldManager)
226 const G4MagneticField* magField =
dynamic_cast<const G4MagneticField*
>(fieldManager->GetDetectorField());
227 G4MagneticField* magFieldNC
ATLAS_THREAD_SAFE =
const_cast<G4MagneticField*
>(magField);
236 CheckAndUpdateField( magFieldNC );
239 fieldManager->SetChordFinder( fMonopoleChordFinder );
241 fieldManager->SetChordFinder( fOriginalChordFinder );
248 void G4mplEquationSetup::ResetIntegration(G4FieldManager* fieldManager)
253 if( fieldManager != fCurrentFieldManager){
254 G4ExceptionDescription ermsg;
255 ermsg <<
"This method expects to be called with the chordfinder it knows"
256 <<
" yet its is called with " << fieldManager
257 <<
" and expected " << fCurrentFieldManager << G4endl;
258 G4Exception(
"G4mplEquationSetup::ResetIntegration",
259 "InvalidState", FatalException, ermsg);
262 if( fCurrentFieldManager ) {
263 fCurrentFieldManager->SetChordFinder(fOriginalChordFinder);
266 G4cout <<
" G4mplEquationSetup: Reset Chord-Finder to original one (for pure electric charge): "
267 << fOriginalChordFinder << G4endl;
269 fOriginalChordFinder =
nullptr;
270 fCurrentFieldManager =
nullptr;
273 delete fMonopoleEquation; fMonopoleEquation=
nullptr;
274 delete fMonopoleStepper; fMonopoleStepper=
nullptr;
275 delete fMonopoleChordFinder; fMonopoleChordFinder=
nullptr;
280 void G4mplEquationSetup::CheckAndUpdateField( G4MagneticField* magFieldNC )
283 if( magFieldNC != fMonopoleEquation->GetFieldObj() )
287 CreateStepperToChordFinder(magFieldNC);