Geant4 VMC Version 6.6
Loading...
Searching...
No Matches
TG4Field.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2014 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4Field.h"
17#include "TG4MagneticField.h"
18// #include "TG4ElectroMagneticField.h"
19// #include "TG4GravityField.h"
20#include "TG4G3Units.h"
21#include "TG4Globals.h"
22
23#include <TVirtualMCApplication.h>
24#include <TVirtualMagField.h>
25
26#include <G4SystemOfUnits.hh>
27
28#include <G4BogackiShampine23.hh>
29#include <G4BogackiShampine45.hh>
30#include <G4CashKarpRKF45.hh>
31#include <G4ChordFinder.hh>
32#include <G4ClassicalRK4.hh>
33#include <G4ConstRK4.hh>
34#include <G4DormandPrince745.hh>
35#include <G4DormandPrinceRK56.hh>
36#include <G4DormandPrinceRK78.hh>
37#include <G4EqEMFieldWithEDM.hh>
38#include <G4EqEMFieldWithSpin.hh>
39#include <G4EqMagElectricField.hh>
40#include <G4ExactHelixStepper.hh>
41#include <G4ExplicitEuler.hh>
42#include <G4FSALIntegrationDriver.hh>
43#include <G4FieldManager.hh>
44#include <G4HelixExplicitEuler.hh>
45#include <G4HelixHeum.hh>
46#include <G4HelixImplicitEuler.hh>
47#include <G4HelixMixedStepper.hh>
48#include <G4HelixSimpleRunge.hh>
49#include <G4ImplicitEuler.hh>
50#include <G4MagErrorStepper.hh>
51#include <G4MagHelicalStepper.hh>
52#include <G4MagIntegratorDriver.hh>
53#include <G4Mag_EqRhs.hh>
54#include <G4Mag_SpinEqRhs.hh>
55#include <G4Mag_UsualEqRhs.hh>
56#include <G4NystromRK4.hh>
57#include <G4RK547FEq1.hh>
58#include <G4RK547FEq2.hh>
59#include <G4RK547FEq3.hh>
60#include <G4RKG3_Stepper.hh>
61#include <G4SimpleHeum.hh>
62#include <G4SimpleRunge.hh>
63#include <G4TransportationManager.hh>
64#include <G4TsitourasRK45.hh>
65#include <G4VIntegrationDriver.hh>
66
67//_____________________________________________________________________________
69 TVirtualMagField* magField, G4LogicalVolume* lv)
70 : fVirtualMagField(magField),
71 fLogicalVolume(lv),
72 fEquation(0),
73 fStepper(0),
74 fDriver(0),
75 fChordFinder(0)
76{
78
79 // Consistency check
80 if (!magField) {
82 "TG4Field", "TG4Field:", "No TVirtualMagField is defined.");
83 }
84
85 Update(parameters);
86}
87
88//_____________________________________________________________________________
90{
92 delete fChordFinder;
93 delete fStepper;
94}
95
96//
97// private methods
98//
99
100//_____________________________________________________________________________
102 const TG4FieldParameters& parameters, TVirtualMagField* magField)
103{
106
107 if (parameters.GetFieldType() == kMagnetic) {
108 if (parameters.GetConstDistance() > 0.) {
109 fG4Field =
110 new TG4CachedMagneticField(magField, parameters.GetConstDistance());
111 }
112 else {
113 fG4Field = new TG4MagneticField(magField);
114 }
115 }
116 // else if ( parameters.GetFieldType() == kElectroMagnetic ) {
117 // fG4Field = new TG4ElectroMagneticField(magField);
118 // }
119
120 // add em, gravity field
121
122 return fG4Field;
123}
124
125//_____________________________________________________________________________
127{
129
130 // magnetic fields
131 G4MagneticField* magField = 0;
132 if (equation == kMagUsualEqRhs || equation == kMagSpinEqRhs) {
133 magField = dynamic_cast<G4MagneticField*>(fG4Field);
134 if (!magField) {
135 // add warning
136 return 0;
137 }
138 }
139
140 // electromagnetic fields
141 G4ElectroMagneticField* elMagField = 0;
142 if (equation >= kEqMagElectric && equation <= kEqEMFieldWithEDM) {
143 elMagField = dynamic_cast<G4ElectroMagneticField*>(fG4Field);
144 if (!elMagField) {
145 // add warning
146 return 0;
147 }
148 }
149
150 // electromagnetic fields
151 switch (equation) {
152 case kMagUsualEqRhs:
153 return new G4Mag_UsualEqRhs(magField);
154 break;
155
156 case kMagSpinEqRhs:
157 return new G4Mag_SpinEqRhs(magField);
158 break;
159
160 case kEqMagElectric:
161 return new G4EqMagElectricField(elMagField);
162 break;
163
165 return new G4EqEMFieldWithSpin(elMagField);
166 break;
167
169 return new G4EqEMFieldWithEDM(elMagField);
170 break;
171 case kUserEquation:
172 // nothing to be done
173 return 0;
174 break;
175 }
176
178 "TG4Field", "CreateEquation:", "Unknown equation type.");
179 return 0;
180}
181
182//_____________________________________________________________________________
183G4MagIntegratorStepper* TG4Field::CreateStepper(
184 G4EquationOfMotion* equation, StepperType stepper)
185{
187
188 // Check steppers which require equation of motion of G4Mag_EqRhs type
189 G4Mag_EqRhs* eqRhs = dynamic_cast<G4Mag_EqRhs*>(equation);
190 if (!eqRhs && stepper > kTsitourasRK45) {
191 TG4Globals::Exception("TG4Field", "CreateStepper:",
192 "The stepper type requires equation of motion of G4Mag_EqRhs type.");
193 return 0;
194 }
195
196 switch (stepper) {
198 return new G4BogackiShampine23(equation);
199 break;
200
202 return new G4BogackiShampine45(equation);
203 break;
204
205 case kCashKarpRKF45:
206 return new G4CashKarpRKF45(equation);
207 break;
208
209 case kClassicalRK4:
210 return new G4ClassicalRK4(equation);
211 break;
212
214 return new G4DormandPrince745(equation);
215 break;
216
218 return new G4DormandPrinceRK56(equation);
219 break;
220
222 return new G4DormandPrinceRK78(equation);
223 break;
224
225 case kExplicitEuler:
226 return new G4ExplicitEuler(equation);
227 break;
228
229 case kImplicitEuler:
230 return new G4ImplicitEuler(equation);
231 break;
232
233 case kSimpleHeum:
234 return new G4SimpleHeum(equation);
235 break;
236
237 case kSimpleRunge:
238 return new G4SimpleRunge(equation);
239 break;
240
241 case kTsitourasRK45:
242 return new G4TsitourasRK45(equation);
243 break;
244
245 case kConstRK4:
246 return new G4ConstRK4(eqRhs);
247 break;
248
250 return new G4ExactHelixStepper(eqRhs);
251 break;
252
254 return new G4HelixExplicitEuler(eqRhs);
255 break;
256
257 case kHelixHeum:
258 return new G4HelixHeum(eqRhs);
259 break;
260
262 return new G4HelixImplicitEuler(eqRhs);
263 break;
264
266 return new G4HelixMixedStepper(eqRhs);
267 break;
268
270 return new G4HelixSimpleRunge(eqRhs);
271 break;
272
273 case kNystromRK4:
274 return new G4NystromRK4(eqRhs);
275 break;
276
277 case kRKG3Stepper:
278 return new G4RKG3_Stepper(eqRhs);
279 break;
280 case kUserStepper:
281 // nothing to be done
282 return 0;
283 break;
284 default:
286 "TG4Field", "CreateStepper:", "Incorrect stepper type.");
287 return 0;
288 }
289}
290
291//_____________________________________________________________________________
293 G4EquationOfMotion* equation, StepperType stepperType, G4double minStep)
294{
296
297 switch (stepperType) {
298 case kRK547FEq1:
299 return new G4FSALIntegrationDriver<G4RK547FEq1>(
300 minStep, new G4RK547FEq1(equation));
301
302 case kRK547FEq2:
303 return new G4FSALIntegrationDriver<G4RK547FEq2>(
304 minStep, new G4RK547FEq2(equation));
305
306 case kRK547FEq3:
307 return new G4FSALIntegrationDriver<G4RK547FEq3>(
308 minStep, new G4RK547FEq3(equation));
309
310 default:
312 "TG4Field", "CreateFSALStepperAndDriver", "Incorrect stepper type.");
313 return 0;
314 }
315}
316
317//
318// public methods
319//
320
321//_____________________________________________________________________________
323{
325
326 // Create field
327 CreateG4Field(parameters, fVirtualMagField);
328
329 G4FieldManager* fieldManager = 0;
330
331 if (!fLogicalVolume) {
332 // global field
333 fieldManager =
334 G4TransportationManager::GetTransportationManager()->GetFieldManager();
335 }
336 else {
337 // local field
338 fieldManager = new G4FieldManager();
339 G4bool forceToAllDaughters = true;
340 fLogicalVolume->SetFieldManager(fieldManager, forceToAllDaughters);
341 }
342 fieldManager->SetDetectorField(fG4Field);
343
344 // Create equation of motion (or get the user one if defined)
345 if (parameters.GetEquationType() == kUserEquation) {
346 fEquation = parameters.GetUserEquationOfMotion();
347 fEquation->SetFieldObj(fG4Field);
348 }
349 else {
350 delete fEquation;
351 fEquation = nullptr;
353 }
354
355 // Create stepper (or get the user one if defined)
356 if (parameters.GetStepperType() == kUserStepper) {
357 // User stepper
358 fStepper = parameters.GetUserStepper();
359 }
360 else if (parameters.GetStepperType() >= kRK547FEq1) {
361 // FSAL stepper
362 delete fDriver;
363 delete fStepper;
364 fDriver = nullptr;
365 fStepper = nullptr;
367 fEquation, parameters.GetStepperType(), parameters.GetStepMinimum());
368 if (fDriver) {
369 fStepper = fDriver->GetStepper();
370 }
371 }
372 else {
373 // Normal stepper
374 delete fStepper;
375 fStepper = nullptr;
377 }
378
379 // Chord finder
380 delete fChordFinder;
381 if (parameters.GetFieldType() == kMagnetic) {
382 if (fDriver) {
383 fChordFinder = new G4ChordFinder(fDriver);
384 }
385 else {
386 // Chord finder
387 fChordFinder = new G4ChordFinder(static_cast<G4MagneticField*>(fG4Field),
388 parameters.GetStepMinimum(), fStepper);
389 }
390 fChordFinder->SetDeltaChord(parameters.GetDeltaChord());
391 }
392 else if (parameters.GetFieldType() == kElectroMagnetic) {
393 G4MagInt_Driver* intDriver = new G4MagInt_Driver(
394 parameters.GetStepMinimum(), fStepper, fStepper->GetNumberOfVariables());
395 if (intDriver) {
396 // Chord finder
397 fChordFinder = new G4ChordFinder(intDriver);
398 }
399 }
400 fieldManager->SetChordFinder(fChordFinder);
401 fieldManager->SetDetectorField(static_cast<G4MagneticField*>(fG4Field));
402
403 fieldManager->SetMinimumEpsilonStep(parameters.GetMinimumEpsilonStep());
404 fieldManager->SetMaximumEpsilonStep(parameters.GetMaximumEpsilonStep());
405 fieldManager->SetDeltaOneStep(parameters.GetDeltaOneStep());
406 fieldManager->SetDeltaIntersection(parameters.GetDeltaIntersection());
407}
Definition of the TG4CachedMagneticField class.
@ kRKG3Stepper
G4RKG3_Stepper.
@ kRK547FEq2
G4RK547FEq2.
@ kHelixSimpleRunge
G4HelixSimpleRunge.
@ kNystromRK4
G4NystromRK4.
@ kDormandPrince745
G4DormandPrince745.
@ kCashKarpRKF45
G4CashKarpRKF45.
@ kDormandPrinceRK78
G4DormandPrinceRK78.
@ kSimpleRunge
G4SimpleRunge.
@ kHelixImplicitEuler
G4HelixImplicitEuler.
@ kConstRK4
G4ConstRK4.
@ kUserStepper
User defined stepper.
@ kSimpleHeum
G4SimpleHeum.
@ kHelixHeum
G4HelixHeum.
@ kHelixExplicitEuler
G4HelixExplicitEuler.
@ kDormandPrinceRK56
G4DormandPrinceRK56.
@ kTsitourasRK45
G4TsitourasRK45.
@ kImplicitEuler
G4ImplicitEuler.
@ kExactHelixStepper
G4ExactHelixStepper.
@ kHelixMixedStepper
G4HelixMixedStepper.
@ kBogackiShampine45
G4BogackiShampine45.
@ kExplicitEuler
G4ExplicitEuler.
@ kRK547FEq1
G4RK547FEq1.
@ kRK547FEq3
G4RK547FEq3.
@ kBogackiShampine23
G4BogackiShampine23.
@ kClassicalRK4
G4ClassicalRK4.
@ kMagUsualEqRhs
@ kUserEquation
User defined equation of motion.
@ kEqEMFieldWithSpin
@ kMagSpinEqRhs
@ kEqMagElectric
@ kEqEMFieldWithEDM
@ kElectroMagnetic
electromagnetic field
@ kMagnetic
magnetic field
Definition of the TG4Field class.
Definition of the TG4G3Units class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4MagneticField class.
The cached magnetic field defined by the TVirtualMCApplication field map.
The magnetic field parameters.
G4double GetMaximumEpsilonStep() const
Return maximum epsilon step in global field manager.
G4EquationOfMotion * GetUserEquationOfMotion() const
Return the user defined equation of motion.
G4double GetMinimumEpsilonStep() const
Return minimum epsilon step in global field manager.
G4double GetDeltaOneStep() const
Return delta one step in global field manager.
static EquationType GetEquationType(const G4String &name)
G4double GetDeltaIntersection() const
Return delta intersection in global field manager.
static FieldType GetFieldType(const G4String &name)
G4double GetStepMinimum() const
Return minimum step in G4ChordFinder.
G4double GetDeltaChord() const
Return delta chord in G4ChordFinder.
G4double GetConstDistance() const
Return the distance within which the field is considered constant.
static StepperType GetStepperType(const G4String &name)
G4MagIntegratorStepper * GetUserStepper() const
Return the user defined integrator of particle's equation of motion.
G4EquationOfMotion * fEquation
The equation of motion.
Definition TG4Field.h:80
G4ChordFinder * fChordFinder
Chord finder.
Definition TG4Field.h:86
G4VIntegrationDriver * CreateFSALStepperAndDriver(G4EquationOfMotion *equation, StepperType stepper, G4double minStep)
Definition TG4Field.cxx:292
G4Field * CreateG4Field(const TG4FieldParameters &parameters, TVirtualMagField *magField)
Definition TG4Field.cxx:101
G4LogicalVolume * fLogicalVolume
The associated volume (if local field)
Definition TG4Field.h:78
TVirtualMagField * fVirtualMagField
The associated TGeo magnetic field.
Definition TG4Field.h:76
TG4Field(const TG4FieldParameters &parameters, TVirtualMagField *magField, G4LogicalVolume *lv=0)
Definition TG4Field.cxx:68
G4MagIntegratorStepper * fStepper
The magnetic integrator stepper.
Definition TG4Field.h:82
G4EquationOfMotion * CreateEquation(EquationType equation)
Definition TG4Field.cxx:126
G4MagIntegratorStepper * CreateStepper(G4EquationOfMotion *equation, StepperType stepper)
Definition TG4Field.cxx:183
G4VIntegrationDriver * fDriver
The magnetic integrator driver.
Definition TG4Field.h:84
void Update(const TG4FieldParameters &parameters)
Definition TG4Field.cxx:322
G4Field * fG4Field
Geant4 field.
Definition TG4Field.h:74
static void Exception(const TString &className, const TString &methodName, const TString &text)
The magnetic field defined via TVirtualMagField.