Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
F04GlobalField.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 //
28 //
29 //
30 #include <time.h>
31 
32 #include "Randomize.hh"
34 
35 #include "G4ExplicitEuler.hh"
36 #include "G4ImplicitEuler.hh"
37 #include "G4SimpleRunge.hh"
38 #include "G4SimpleHeum.hh"
39 #include "G4ClassicalRK4.hh"
40 #include "G4CashKarpRKF45.hh"
41 #include "G4SystemOfUnits.hh"
42 
43 #include "F04GlobalField.hh"
44 
45 F04GlobalField* F04GlobalField::fObject = 0;
46 
47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48 
49 F04GlobalField::F04GlobalField() : G4ElectroMagneticField(),
50  fMinStep(0.01*mm), fDeltaChord(3.0*mm),
51  fDeltaOneStep(0.01*mm), fDeltaIntersection(0.1*mm),
52  fEpsMin(2.5e-7*mm), fEpsMax(0.05*mm),
53  fEquation(0), fFieldManager(0),
54  fFieldPropagator(0), fStepper(0), fChordFinder(0)
55 //F04GlobalField::F04GlobalField() : G4MagneticField(),
56 // fMinStep(0.01*mm), fDeltaChord(3.0*mm),
57 // fDeltaOneStep(0.01*mm), fDeltaIntersection(0.1*mm),
58 // fEpsMin(2.5e-7*mm), fEpsMax(0.05*mm),
59 // fEquation(0), fFieldManager(0),
60 // fFieldPropagator(0), fStepper(0), fChordFinder(0)
61 {
62  fFieldMessenger = new F04FieldMessenger(this);
63 
64  fFields = new FieldList();
65 
66  fStepperType = 4 ; // ClassicalRK4 is default stepper
67 
68  // set object
69 
70  fObject = this;
71 
72  UpdateField();
73 }
74 
75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
76 
77 F04GlobalField::~F04GlobalField()
78 {
79  Clear();
80 
81  delete fFieldMessenger;
82 
83  if (fEquation) delete fEquation;
84  if (fFieldManager) delete fFieldManager;
85  if (fFieldPropagator) delete fFieldPropagator;
86  if (fStepper) delete fStepper;
87  if (fChordFinder) delete fChordFinder;
88 }
89 
90 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
91 
93 {
94  fFirst = true;
95 
96  fNfp = 0;
97  fFp = 0;
98 
99  Clear();
100 
101  // Construct equ. of motion of particles through B fields
102 // fEquation = new G4Mag_EqRhs(this);
103  // Construct equ. of motion of particles through e.m. fields
104 // fEquation = new G4EqMagElectricField(this);
105  // Construct equ. of motion of particles including spin through B fields
106 // fEquation = new G4Mag_SpinEqRhs(this);
107  // Construct equ. of motion of particles including spin through e.m. fields
108  fEquation = new G4EqEMFieldWithSpin(this);
109 
110  // Get transportation, field, and propagator managers
111  G4TransportationManager* transportManager =
113 
114  fFieldManager = GetGlobalFieldManager();
115 
116  fFieldPropagator = transportManager->GetPropagatorInField();
117 
118  // Need to SetFieldChangesEnergy to account for a time varying electric
119  // field (r.f. fields)
120  fFieldManager->SetFieldChangesEnergy(true);
121 
122  // Set the field
123  fFieldManager->SetDetectorField(this);
124 
125  // Choose a stepper for integration of the equation of motion
126  SetStepper();
127 
128  // Create a cord finder providing the (global field, min step length,
129  // a pointer to the stepper)
130  fChordFinder = new G4ChordFinder((G4MagneticField*)this,fMinStep,fStepper);
131 
132  // Set accuracy parameters
133  fChordFinder->SetDeltaChord( fDeltaChord );
134 
135  fFieldManager->SetAccuraciesWithDeltaOneStep(fDeltaOneStep);
136 
137  fFieldManager->SetDeltaIntersection(fDeltaIntersection);
138 
139  fFieldPropagator->SetMinimumEpsilonStep(fEpsMin);
140  fFieldPropagator->SetMaximumEpsilonStep(fEpsMax);
141 
142  G4cout << "Accuracy Parameters:" <<
143  " MinStep=" << fMinStep <<
144  " DeltaChord=" << fDeltaChord <<
145  " DeltaOneStep=" << fDeltaOneStep << G4endl;
146  G4cout << " " <<
147  " DeltaIntersection=" << fDeltaIntersection <<
148  " EpsMin=" << fEpsMin <<
149  " EpsMax=" << fEpsMax << G4endl;
150 
151  fFieldManager->SetChordFinder(fChordFinder);
152 
153 }
154 
155 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
156 
158 {
159  if (!fObject) new F04GlobalField();
160  return fObject;
161 }
162 
163 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
164 
166 {
167  if(fStepper) delete fStepper;
168 
169  switch ( fStepperType )
170  {
171  case 0:
172 // fStepper = new G4ExplicitEuler( fEquation, 8 ); // no spin tracking
173  fStepper = new G4ExplicitEuler( fEquation, 12 ); // with spin tracking
174  G4cout << "G4ExplicitEuler is called" << G4endl;
175  break;
176  case 1:
177 // fStepper = new G4ImplicitEuler( fEquation, 8 ); // no spin tracking
178  fStepper = new G4ImplicitEuler( fEquation, 12 ); // with spin tracking
179  G4cout << "G4ImplicitEuler is called" << G4endl;
180  break;
181  case 2:
182 // fStepper = new G4SimpleRunge( fEquation, 8 ); // no spin tracking
183  fStepper = new G4SimpleRunge( fEquation, 12 ); // with spin tracking
184  G4cout << "G4SimpleRunge is called" << G4endl;
185  break;
186  case 3:
187 // fStepper = new G4SimpleHeum( fEquation, 8 ); // no spin tracking
188  fStepper = new G4SimpleHeum( fEquation, 12 ); // with spin tracking
189  G4cout << "G4SimpleHeum is called" << G4endl;
190  break;
191  case 4:
192 // fStepper = new G4ClassicalRK4( fEquation, 8 ); // no spin tracking
193  fStepper = new G4ClassicalRK4( fEquation, 12 ); // with spin tracking
194  G4cout << "G4ClassicalRK4 (default) is called" << G4endl;
195  break;
196  case 5:
197 // fStepper = new G4CashKarpRKF45( fEquation, 8 ); // no spin tracking
198  fStepper = new G4CashKarpRKF45( fEquation, 12 ); // with spin tracking
199  G4cout << "G4CashKarpRKF45 is called" << G4endl;
200  break;
201  default: fStepper = 0;
202  }
203 }
204 
205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
206 
208 {
210  ->GetFieldManager();
211 }
212 
213 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
214 
215 void F04GlobalField::GetFieldValue(const G4double* point, G4double* field) const
216 {
217  // NOTE: this routine dominates the CPU time for tracking.
218  // Using the simple array fFp[] instead of fields[]
219  // directly sped it up
220 
221  field[0] = field[1] = field[2] = field[3] = field[4] = field[5] = 0.0;
222 
223  // protect against Geant4 bug that calls us with point[] NaN.
224  if(point[0] != point[0]) return;
225 
226  // (can't use fNfp or fFp, as they may change)
227  if (fFirst) ((F04GlobalField*)this)->SetupArray(); // (cast away const)
228 
229  for (int i=0; i<fNfp; ++i) {
230  const F04ElementField* p = fFp[i];
231  if (p->IsInBoundingBox(point)) {
232  p->AddFieldValue(point,field);
233  }
234  }
235 
236 }
237 
238 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
239 
241 {
242  if (fFields) {
243  if (fFields->size()>0) {
244  FieldList::iterator i;
245  for (i=fFields->begin(); i!=fFields->end(); ++i) delete *i;
246  fFields->clear();
247  }
248  }
249 
250  if (fFp) delete[] fFp;
251 
252  fFirst = true;
253 
254  fNfp = 0;
255  fFp = NULL;
256 }
257 
258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
259 
260 void F04GlobalField::SetupArray()
261 {
262  fFirst = false;
263  fNfp = fFields->size();
264  fFp = new const F04ElementField* [fNfp+1]; // add 1 so it's never 0
265  for (int i=0; i<fNfp; ++i) fFp[i] = (*fFields)[i];
266 }