Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4FieldManager.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4FieldManager implementation
27//
28// Author: John Apostolakis, 10.03.97 - design and implementation
29// -------------------------------------------------------------------
30
31#include "G4FieldManager.hh"
32#include "G4Field.hh"
33#include "G4MagneticField.hh"
34#include "G4ChordFinder.hh"
36#include "G4SystemOfUnits.hh"
37
38G4double G4FieldManager::fDefault_Delta_One_Step_Value= 0.01 * millimeter;
39G4double G4FieldManager::fDefault_Delta_Intersection_Val= 0.001 * millimeter;
40
42 G4ChordFinder* pChordFinder,
43 G4bool fieldChangesEnergy )
44 : fDetectorField(detectorField),
45 fChordFinder(pChordFinder),
46 fDelta_One_Step_Value( fDefault_Delta_One_Step_Value ),
47 fDelta_Intersection_Val( fDefault_Delta_Intersection_Val ),
48 fEpsilonMin( fEpsilonMinDefault ),
49 fEpsilonMax( fEpsilonMaxDefault)
50{
51 if ( detectorField != nullptr )
52 {
53 fFieldChangesEnergy = detectorField->DoesFieldChangeEnergy();
54 }
55 else
56 {
57 fFieldChangesEnergy = fieldChangesEnergy;
58 }
59
60 // Add to store
61 //
63}
64
66 : fDetectorField(detectorField), fAllocatedChordFinder(true),
67 fDelta_One_Step_Value( fDefault_Delta_One_Step_Value ),
68 fDelta_Intersection_Val( fDefault_Delta_Intersection_Val ),
69 fEpsilonMin( fEpsilonMinDefault ),
70 fEpsilonMax( fEpsilonMaxDefault )
71{
72 fChordFinder = new G4ChordFinder( detectorField );
73
74 // Add to store
75 //
77}
78
80{
81 G4Field* aField = nullptr;
82 G4FieldManager* aFM = nullptr;
83 G4ChordFinder* aCF = nullptr;
84 try {
85 if ( fDetectorField != nullptr )
86 {
87 aField = fDetectorField->Clone();
88 }
89
90 // Create a new field manager, note that we do not set
91 // any chordfinder now
92 //
93 aFM = new G4FieldManager( aField , nullptr , fFieldChangesEnergy );
94
95 // Check if originally we have the fAllocatedChordFinder variable
96 // set, in case, call chord constructor
97 //
98 if ( fAllocatedChordFinder )
99 {
100 aFM->CreateChordFinder( dynamic_cast<G4MagneticField*>(aField) );
101 }
102 else
103 {
104 // Chord was specified by user, should we clone?
105 // TODO: For the moment copy pointer, to be understood
106 // if cloning of ChordFinder is needed
107 //
108 aCF = fChordFinder; /*->Clone*/
109 aFM->fChordFinder = aCF;
110 }
111
112 // Copy values of other variables
113
114 aFM->fEpsilonMax = fEpsilonMax;
115 aFM->fEpsilonMin = fEpsilonMin;
116 aFM->fDelta_Intersection_Val = fDelta_Intersection_Val;
117 aFM->fDelta_One_Step_Value = fDelta_One_Step_Value;
118 // TODO: Should we really add to the store the cloned FM?
119 // Who will use this?
120 }
121 catch ( ... )
122 {
123 // Failed creating clone: probably user did not implement Clone method
124 // in derived classes?
125 // Perform clean-up after ourselves...
126 delete aField;
127 delete aFM;
128 delete aCF;
129 throw;
130 }
131 return aFM;
132}
133
135{
136 // Default is to do nothing!
137}
138
140{
141 if( fAllocatedChordFinder )
142 {
143 delete fChordFinder;
144 }
146}
147
148void
150{
151 if ( fAllocatedChordFinder )
152 {
153 delete fChordFinder;
154 }
155 fAllocatedChordFinder = false;
156
157 if( detectorMagField != nullptr )
158 {
159 fChordFinder = new G4ChordFinder( detectorMagField );
160 fAllocatedChordFinder = true;
161 }
162 else
163 {
164 fChordFinder = nullptr;
165 }
166}
167
168void G4FieldManager::InitialiseFieldChangesEnergy()
169{
170 if ( fDetectorField != nullptr )
171 {
172 fFieldChangesEnergy = fDetectorField->DoesFieldChangeEnergy();
173 }
174 else
175 {
176 fFieldChangesEnergy = false; // No field, no change!
177 }
178}
179
181 G4int failMode )
182{
183 G4VIntegrationDriver* driver = nullptr;
184 G4EquationOfMotion* equation = nullptr;
185 // G4bool compatibleField = false;
186 G4bool ableToSet = false;
187
188 fDetectorField = pDetectorField;
189 InitialiseFieldChangesEnergy();
190
191 // Must 'propagate' the field to the dependent classes
192 //
193 if( fChordFinder != nullptr )
194 {
195 failMode= std::max( failMode, 1) ;
196 // If a chord finder exists, warn in case of error!
197
198 driver = fChordFinder->GetIntegrationDriver();
199 if( driver != nullptr )
200 {
201 equation = driver->GetEquationOfMotion();
202
203 // Should check the compatibility between the
204 // field and the equation HERE
205
206 if( equation != nullptr )
207 {
208 equation->SetFieldObj(pDetectorField);
209 ableToSet = true;
210 }
211 }
212 }
213
214 if( !ableToSet && (failMode > 0) )
215 {
216 // If this fails, report the issue !
217
219 msg << "Unable to set the field in the dependent objects of G4FieldManager"
220 << G4endl;
221 msg << "All the dependent classes must be fully initialised,"
222 << "before it is possible to call this method." << G4endl;
223 msg << "The problem encountered was the following: " << G4endl;
224 if( fChordFinder == nullptr ) { msg << " No ChordFinder. " ; }
225 else if( driver == nullptr ) { msg << " No Integration Driver set. ";}
226 else if( equation == nullptr ) { msg << " No Equation found. " ; }
227 // else if( !compatibleField ) { msg << " Field not compatible. ";}
228 else { msg << " Can NOT find reason for failure. ";}
229 msg << G4endl;
230 G4ExceptionSeverity severity = (failMode != 1)
232 G4Exception("G4FieldManager::SetDetectorField", "Geometry001",
233 severity, msg);
234 }
235 return ableToSet;
236}
G4ExceptionSeverity
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4VIntegrationDriver * GetIntegrationDriver()
void SetFieldObj(G4Field *pField)
static void DeRegister(G4FieldManager *pVolume)
static void Register(G4FieldManager *pVolume)
virtual G4FieldManager * Clone() const
virtual ~G4FieldManager()
G4bool SetDetectorField(G4Field *detectorField, G4int failMode=0)
void CreateChordFinder(G4MagneticField *detectorMagField)
virtual void ConfigureForTrack(const G4Track *)
G4FieldManager(G4Field *detectorField=nullptr, G4ChordFinder *pChordFinder=nullptr, G4bool b=true)
virtual G4bool DoesFieldChangeEnergy() const =0
virtual G4Field * Clone() const
Definition: G4Field.cc:54
virtual G4EquationOfMotion * GetEquationOfMotion()=0