ATLAS Offline Software
G4FieldManagerToolBase.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Primary include
7 
8 // CLHEP includes
9 #include "CLHEP/Units/SystemOfUnits.h"
10 
11 // Geant4 steppers
12 #include "G4AtlasRK4.hh"
13 #include "G4BogackiShampine23.hh"
14 #include "G4BogackiShampine45.hh"
15 #include "G4CashKarpRKF45.hh"
16 #include "G4ClassicalRK4.hh"
17 #include "G4DoLoMcPriRK34.hh"
18 #include "G4DormandPrince745.hh"
19 #include "G4DormandPrinceRK56.hh"
20 #include "G4DormandPrinceRK78.hh"
21 #include "G4FieldManager.hh"
22 #include "G4HelixExplicitEuler.hh"
23 #include "G4HelixImplicitEuler.hh"
24 #include "G4HelixSimpleRunge.hh"
25 #include "G4NystromRK4.hh"
26 #include "G4RK547FEq1.hh"
27 #include "G4RK547FEq2.hh"
28 #include "G4RK547FEq3.hh"
29 #include "G4RKG3_Stepper.hh"
30 #include "G4TsitourasRK45.hh"
31 
32 // Geant4 includes
33 #include "G4ChordFinder.hh"
34 #include "G4IntegrationDriver.hh"
35 #include "G4Mag_UsualEqRhs.hh"
36 #include "G4MagIntegratorStepper.hh"
37 #include "G4VIntegrationDriver.hh"
38 
39 //-----------------------------------------------------------------------------
40 // Implementation file for class : G4FieldManagerToolBase
41 //
42 // 2015-11-17: Andrea Dell'Acqua
43 //-----------------------------------------------------------------------------
44 
45 
46 //=============================================================================
47 // Standard constructor, initializes variables
48 //=============================================================================
50  const std::string& name,
51  const IInterface* parent)
52  : base_class(type, name, parent)
53 {
54 }
55 
56 //=============================================================================
57 // Initialize
58 //=============================================================================
60 {
61  ATH_MSG_DEBUG("G4FieldManagerToolBase::initialize()");
62 
63  // Skip field svc retrieval if field disabled.
64  if(m_fieldOn) {
65  ATH_CHECK( m_fieldSvc.retrieve() );
66  }
67  else {
68  ATH_MSG_DEBUG("Field disabled. Not retrieving G4 field svc.");
69  }
70  if (!m_equationOfMotion.empty())
71  {
72  ATH_CHECK(m_equationOfMotion.retrieve());
73  }
74  return StatusCode::SUCCESS;
75 }
76 
77 #if G4VERSION_NUMBER >= 1040
78 //=============================================================================
79 // Create the driver with a stepper (Geant4 >= 10.4)
80 //=============================================================================
81 G4VIntegrationDriver*
82 G4FieldManagerToolBase::createDriverAndStepper(const std::string& name, G4MagneticField* field) const
83 {
84  ATH_MSG_DEBUG("createDriverAndStepper");
85  G4Mag_EqRhs* eqRhs(nullptr);
86  if (!m_equationOfMotion.empty())
87  {
88  eqRhs = m_equationOfMotion->makeEquationOfMotion(field);
89  ATH_MSG_INFO("Configuring alternative equation of motion using " <<
90  m_equationOfMotion.name() );
91  }
92  else
93  {
94  ATH_MSG_VERBOSE("Using G4Mag_UsualEqRhs as the equation of motion.");
95  eqRhs = new G4Mag_UsualEqRhs(field);
96  }
97  // @TODO Add some way of confirming that the choices of Equation of
98  // motion and stepper are compatible.
99  G4VIntegrationDriver* driver = nullptr;
100  if (name=="HelixImplicitEuler") {
101  G4HelixImplicitEuler* stepper = new G4HelixImplicitEuler(eqRhs);
102  driver = new G4IntegrationDriver<G4HelixImplicitEuler>(
103  m_minStep, stepper, stepper->GetNumberOfVariables());
104  } else if (name=="HelixSimpleRunge") {
105  G4HelixSimpleRunge* stepper = new G4HelixSimpleRunge(eqRhs);
106  driver = new G4IntegrationDriver<G4HelixSimpleRunge>(
107  m_minStep, stepper, stepper->GetNumberOfVariables());
108  } else if (name=="HelixExplicitEuler") {
109  G4HelixExplicitEuler* stepper = new G4HelixExplicitEuler(eqRhs);
110  driver = new G4IntegrationDriver<G4HelixExplicitEuler>(
111  m_minStep, stepper, stepper->GetNumberOfVariables());
112  } else if (name=="NystromRK4") {
113  G4NystromRK4* stepper = new G4NystromRK4(eqRhs);
114  driver = new G4IntegrationDriver<G4NystromRK4>(
115  m_minStep, stepper, stepper->GetNumberOfVariables());
116  } else if (name=="ClassicalRK4") {
117  G4ClassicalRK4* stepper = new G4ClassicalRK4(eqRhs);
118  driver = new G4IntegrationDriver<G4ClassicalRK4>(
119  m_minStep, stepper, stepper->GetNumberOfVariables());
120  } else if (name=="AtlasRK4") {
121  G4AtlasRK4* stepper = new G4AtlasRK4(eqRhs);
122  driver = new G4IntegrationDriver<G4AtlasRK4>(
123  m_minStep, stepper, stepper->GetNumberOfVariables());
124  } else if (name=="BogackiShampine23") {
125  G4BogackiShampine23* stepper = new G4BogackiShampine23(eqRhs);
126  driver = new G4IntegrationDriver<G4BogackiShampine23>(
127  m_minStep, stepper, stepper->GetNumberOfVariables());
128  } else if (name=="BogackiShampine45") {
129  G4BogackiShampine45* stepper = new G4BogackiShampine45(eqRhs);
130  driver = new G4IntegrationDriver<G4BogackiShampine45>(
131  m_minStep, stepper, stepper->GetNumberOfVariables());
132  } else if (name=="CashKarpRKF45") {
133  G4CashKarpRKF45* stepper = new G4CashKarpRKF45(eqRhs);
134  driver = new G4IntegrationDriver<G4CashKarpRKF45>(
135  m_minStep, stepper, stepper->GetNumberOfVariables());
136  } else if (name=="DoLoMcPriRK34") {
137  G4DoLoMcPriRK34* stepper = new G4DoLoMcPriRK34(eqRhs);
138  driver = new G4IntegrationDriver<G4DoLoMcPriRK34>(
139  m_minStep, stepper, stepper->GetNumberOfVariables());
140  } else if (name=="DormandPrince745") {
141  G4DormandPrince745* stepper = new G4DormandPrince745(eqRhs);
142  driver = new G4IntegrationDriver<G4DormandPrince745>(
143  m_minStep, stepper, stepper->GetNumberOfVariables());
144  } else if (name=="DormandPrinceRK56") {
145  G4DormandPrinceRK56* stepper = new G4DormandPrinceRK56(eqRhs);
146  driver = new G4IntegrationDriver<G4DormandPrinceRK56>(
147  m_minStep, stepper, stepper->GetNumberOfVariables());
148  } else if (name=="DormandPrinceRK78") {
149  G4DormandPrinceRK78* stepper = new G4DormandPrinceRK78(eqRhs);
150  driver = new G4IntegrationDriver<G4DormandPrinceRK78>(
151  m_minStep, stepper, stepper->GetNumberOfVariables());
152  } else if (name=="RK547FEq1") {
153  G4RK547FEq1* stepper = new G4RK547FEq1(eqRhs);
154  driver = new G4IntegrationDriver<G4RK547FEq1>(
155  m_minStep, stepper, stepper->GetNumberOfVariables());
156  } else if (name=="RK547FEq2") {
157  G4RK547FEq2* stepper = new G4RK547FEq2(eqRhs);
158  driver = new G4IntegrationDriver<G4RK547FEq2>(
159  m_minStep, stepper, stepper->GetNumberOfVariables());
160  } else if (name=="RK547FEq3") {
161  G4RK547FEq3* stepper = new G4RK547FEq3(eqRhs);
162  driver = new G4IntegrationDriver<G4RK547FEq3>(
163  m_minStep, stepper, stepper->GetNumberOfVariables());
164  } else if (name=="RKG3_Stepper") {
165  G4RKG3_Stepper* stepper = new G4RKG3_Stepper(eqRhs);
166  driver = new G4IntegrationDriver<G4RKG3_Stepper>(
167  m_minStep, stepper, stepper->GetNumberOfVariables());
168  } else if (name=="TsitourasRK45") {
169  G4TsitourasRK45* stepper = new G4TsitourasRK45(eqRhs);
170  driver = new G4IntegrationDriver<G4TsitourasRK45>(
171  m_minStep, stepper, stepper->GetNumberOfVariables());
172  } else {
173  ATH_MSG_ERROR("Stepper " << name << " not available! returning NystromRK4!");
174  G4NystromRK4* stepper = new G4NystromRK4(eqRhs);
175  driver = new G4IntegrationDriver<G4NystromRK4>(
176  m_minStep, stepper, stepper->GetNumberOfVariables());
177  }
178  return driver;
179 }
180 #endif
181 
182 #if G4VERSION_NUMBER < 1040
183 //=============================================================================
184 // Create the stepper (Geant4 < 10.4)
185 //=============================================================================
186 G4MagIntegratorStepper*
187 G4FieldManagerToolBase::getStepper(const std::string& name, G4MagneticField* field) const
188 {
189  ATH_MSG_DEBUG("getStepper");
190  G4Mag_EqRhs* eqRhs(nullptr);
191  if (!m_equationOfMotion.empty())
192  {
193  eqRhs = m_equationOfMotion->makeEquationOfMotion(field);
194  ATH_MSG_INFO("Configuring alternative equation of motion using " <<
195  m_equationOfMotion.name() );
196  }
197  else
198  {
199  ATH_MSG_VERBOSE("Using G4Mag_UsualEqRhs as the equation of motion.");
200  eqRhs = new G4Mag_UsualEqRhs(field);
201  }
202  // @TODO Add some way of confirming that the choices of Equation of
203  // motion and stepper are compatible.
204  // @TODO consider moving the stepper choice into a tool as well?
205  // Only worthwhile if we envisage adding more stepper choices in the
206  // future.
207  if (name=="HelixImplicitEuler") return new G4HelixImplicitEuler(eqRhs);
208  else if (name=="HelixSimpleRunge") return new G4HelixSimpleRunge(eqRhs);
209  else if (name=="HelixExplicitEuler") return new G4HelixExplicitEuler(eqRhs);
210  else if (name=="NystromRK4") return new G4NystromRK4(eqRhs);
211  else if (name=="ClassicalRK4") return new G4ClassicalRK4(eqRhs);
212  else if (name=="AtlasRK4") return new G4AtlasRK4(eqRhs);
213  else if (name=="BogackiShampine23") return new G4BogackiShampine23(eqRhs);
214  else if (name=="BogackiShampine45") return new G4BogackiShampine45(eqRhs);
215  else if (name=="CashKarpRKF45") return new G4CashKarpRKF45(eqRhs);
216  else if (name=="DoLoMcPriRK34") return new G4DoLoMcPriRK34(eqRhs);
217  else if (name=="DormandPrince745") return new G4DormandPrince745(eqRhs);
218  else if (name=="DormandPrinceRK56") return new G4DormandPrinceRK56(eqRhs);
219  else if (name=="DormandPrinceRK78") return new G4DormandPrinceRK78(eqRhs);
220  else if (name=="RK547FEq1") return new G4RK547FEq1(eqRhs);
221  else if (name=="RK547FEq2") return new G4RK547FEq2(eqRhs);
222  else if (name=="RK547FEq3") return new G4RK547FEq3(eqRhs);
223  else if (name=="RKG3_Stepper") return new G4RKG3_Stepper(eqRhs);
224  else if (name=="TsitourasRK45") return new G4TsitourasRK45(eqRhs);
225  else {
226  ATH_MSG_ERROR("Stepper " << name << " not available! returning NystromRK4!");
227  return new G4NystromRK4(eqRhs);
228  }
229 }
230 #endif
231 
232 //=============================================================================
233 // Create the stepper
234 //=============================================================================
236 setFieldParameters(G4FieldManager* fieldMgr) const
237 {
238  ATH_MSG_DEBUG("setFieldParameters");
239  if (fieldMgr) {
240  if (m_deltaChord>0) fieldMgr->GetChordFinder()->SetDeltaChord(m_deltaChord);
241  if (m_deltaOneStep>0) fieldMgr->SetDeltaOneStep(m_deltaOneStep);
242  if (m_deltaIntersection>0) fieldMgr->SetDeltaIntersection(m_deltaIntersection);
243  if (m_minEps>0) fieldMgr->SetMinimumEpsilonStep(m_minEps);
244  if (m_maxEps>0) fieldMgr->SetMaximumEpsilonStep(m_maxEps);
245  }
246  else {
247  ATH_MSG_ERROR("setFieldParameters received NULL field mgr!");
248  return StatusCode::FAILURE;
249  }
250  return StatusCode::SUCCESS;
251 }
G4FieldManagerToolBase::initialize
virtual StatusCode initialize() override
Initialize method.
Definition: G4FieldManagerToolBase.cxx:59
G4FieldManagerToolBase::setFieldParameters
StatusCode setFieldParameters(G4FieldManager *fieldMgr) const
Common method to apply configuredfield parameters.
Definition: G4FieldManagerToolBase.cxx:236
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
G4FieldManagerToolBase::m_equationOfMotion
ToolHandle< IEquationOfMotionTool > m_equationOfMotion
The type of equation of motion to use.
Definition: G4FieldManagerToolBase.h:74
G4FieldManagerToolBase.h
G4FieldManagerToolBase::G4FieldManagerToolBase
G4FieldManagerToolBase(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.
Definition: G4FieldManagerToolBase.cxx:49
G4FieldManagerToolBase::m_minEps
Gaudi::Property< double > m_minEps
Definition: G4FieldManagerToolBase.h:79
G4FieldManagerToolBase::m_fieldOn
Gaudi::Property< bool > m_fieldOn
Definition: G4FieldManagerToolBase.h:68
G4FieldManagerToolBase::m_fieldSvc
ServiceHandle< IG4FieldSvc > m_fieldSvc
Handle to the G4 field service.
Definition: G4FieldManagerToolBase.h:65
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
G4FieldManagerToolBase::m_deltaOneStep
Gaudi::Property< double > m_deltaOneStep
Definition: G4FieldManagerToolBase.h:82
FullCPAlgorithmsTest_eljob.driver
driver
Definition: FullCPAlgorithmsTest_eljob.py:157
G4FieldManagerToolBase::m_deltaChord
Gaudi::Property< double > m_deltaChord
Definition: G4FieldManagerToolBase.h:81
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
G4FieldManagerToolBase::m_deltaIntersection
Gaudi::Property< double > m_deltaIntersection
Definition: G4FieldManagerToolBase.h:83
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
G4FieldManagerToolBase::m_minStep
Gaudi::Property< double > m_minStep
Definition: G4FieldManagerToolBase.h:85
G4FieldManagerToolBase::m_maxEps
Gaudi::Property< double > m_maxEps
Definition: G4FieldManagerToolBase.h:80
G4FieldManagerToolBase::getStepper
G4MagIntegratorStepper * getStepper(const std::string &stepperType, G4MagneticField *field) const
Common method to construct a stepper of requested type.
Definition: G4FieldManagerToolBase.cxx:187