BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSFieldObjects.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSFieldManager.hh"
20#include "BDSGlobalConstants.hh"
21#include "BDSFieldInfo.hh"
22#include "BDSFieldObjects.hh"
23
24#include "G4ChordFinder.hh"
25#include "G4ElectroMagneticField.hh"
26#include "G4Field.hh"
27#include "G4FieldManager.hh"
28#include "G4LogicalVolume.hh"
29#include "G4MagIntegratorDriver.hh" // for G4MagInt_Driver
30#include "G4MagIntegratorStepper.hh"
31#include "G4MagneticField.hh"
32#include "G4Version.hh"
33
34#include <vector>
35
36BDSFieldObjects::BDSFieldObjects(const BDSFieldInfo* infoIn,
37 G4Field* fieldIn,
38 G4EquationOfMotion* equationOfMotionIn,
39 G4MagIntegratorStepper* magIntegratorStepperIn,
40 G4ChordFinder* chordFinderIn,
41 G4FieldManager* fieldManagerIn):
42 info(infoIn),
43 field(fieldIn),
44 equationOfMotion(equationOfMotionIn),
45 magIntegratorStepper(magIntegratorStepperIn),
46 chordFinder(chordFinderIn),
47 fieldManager(fieldManagerIn),
48 magIntDriver(nullptr)
49{;}
50
51BDSFieldObjects::BDSFieldObjects(const BDSFieldInfo* infoIn,
52 G4ElectroMagneticField* fieldIn,
53 G4EquationOfMotion* equationOfMotionIn,
54 G4MagIntegratorStepper* magIntegratorStepperIn):
55 info(infoIn),
56 field(fieldIn),
57 equationOfMotion(equationOfMotionIn),
58 magIntegratorStepper(magIntegratorStepperIn)
59{
60 G4double chordStepMinimum = info->ChordStepMinimum();
61 if (chordStepMinimum <= 0)
62 {chordStepMinimum = BDSGlobalConstants::Instance()->ChordStepMinimum();}
63
64 magIntDriver = new G4MagInt_Driver(chordStepMinimum,
66 magIntegratorStepper->GetNumberOfVariables());
67
68 chordFinder = new G4ChordFinder(magIntDriver);
69
70 // We use our custom field manager that is a thin wrapper for the Geant4 one
71 // that only identifies whether we have a primary track or not for BDSIntegratorMag
73
75 fieldManager->SetDeltaIntersection(globals->DeltaIntersection());
76 fieldManager->SetMinimumEpsilonStep(globals->MinimumEpsilonStep());
77 fieldManager->SetMaximumEpsilonStep(globals->MaximumEpsilonStep());
78 fieldManager->SetDeltaOneStep(globals->DeltaOneStep());
79}
80
81#if G4VERSION_NUMBER > 1049
82BDSFieldObjects::BDSFieldObjects(const BDSFieldInfo* infoIn,
83 G4MagneticField* fieldIn,
84 G4EquationOfMotion* equationOfMotionIn,
85 G4MagIntegratorStepper* magIntegratorStepperIn):
86 info(infoIn),
87 field(fieldIn),
88 equationOfMotion(equationOfMotionIn),
89 magIntegratorStepper(magIntegratorStepperIn)
90{
91 G4double chordStepMinimum = info->ChordStepMinimum();
92 if (chordStepMinimum <= 0)
93 {chordStepMinimum = BDSGlobalConstants::Instance()->ChordStepMinimum();}
94
95 magIntDriver = new G4MagInt_Driver(chordStepMinimum,
97 magIntegratorStepper->GetNumberOfVariables());
98
99 chordFinder = new G4ChordFinder(magIntDriver);
100 fieldManager = new G4FieldManager(field, chordFinder);
101
103 fieldManager->SetDeltaIntersection(globals->DeltaIntersection());
104 fieldManager->SetMinimumEpsilonStep(globals->MinimumEpsilonStep());
105 fieldManager->SetMaximumEpsilonStep(globals->MaximumEpsilonStep());
106 fieldManager->SetDeltaOneStep(globals->DeltaOneStep());
107}
108#endif
109
111{
112 delete field;
113 delete fieldManager;
114 delete chordFinder;
116 delete equationOfMotion;
117 //delete magIntDriver; // not needed since deleted by chordFinder
118}
119
120void BDSFieldObjects::AttachToVolume(G4LogicalVolume* volume,
121 G4bool penetrateToDaughterVolumes) const
122{
123 volume->SetFieldManager(fieldManager, penetrateToDaughterVolumes);
124 if (!info) // may not always exist
125 {return;}
126
127 // optionally attach user limits
128 auto ul = info->UserLimits();
129 if (ul)
130 {AttachUserLimitsToVolume(volume, ul, penetrateToDaughterVolumes);}
131}
132
133void BDSFieldObjects::AttachToVolume(const std::vector<G4LogicalVolume*>& volumes,
134 G4bool penetrateToDaughterVolumes) const
135{
136 for (auto volume : volumes)
137 {AttachToVolume(volume, penetrateToDaughterVolumes);}
138}
139
140void BDSFieldObjects::AttachUserLimitsToVolume(G4LogicalVolume* volume,
141 G4UserLimits* userLimits,
142 G4bool penetrateToDaughterVolumes) const
143{
144 volume->SetUserLimits(userLimits);
145 if (penetrateToDaughterVolumes)
146 {
147 for (G4int i = 0; i < (G4int)volume->GetNoDaughters(); i++)
148 {AttachUserLimitsToVolume(volume->GetDaughter(i)->GetLogicalVolume(), userLimits, penetrateToDaughterVolumes);}
149 }
150}
All info required to build complete field of any type.
Definition: BDSFieldInfo.hh:65
G4double ChordStepMinimum() const
Accessor.
G4UserLimits * UserLimits() const
Accessor.
Wrapper for Geant4's G4FieldManager to distinguish primaries.
void AttachToVolume(G4LogicalVolume *volume, G4bool penetrateToDaughterVolumes=true) const
Interface to easily attach to logical volume.
~BDSFieldObjects()
Destructor deletes all objects apart from the magnetic field.
G4FieldManager * fieldManager
Field manager.
G4Field * field
Reference to field this instance is based on.
const BDSFieldInfo * info
The complete information required to build this field.
G4MagIntegratorStepper * magIntegratorStepper
Stepper, selectable depending on smoothness of the field etc.
G4ChordFinder * chordFinder
Chord manager.
G4EquationOfMotion * equationOfMotion
Equation of motion, typically G4Mag_UsualEqRhs instance.
void AttachUserLimitsToVolume(G4LogicalVolume *volume, G4UserLimits *userLimits, G4bool penetrateToDaughterVolumes=true) const
G4MagInt_Driver * magIntDriver
EM field integrator driver (optional) - only for EM fields.
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.