BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
BesMagneticField.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * DISCLAIMER *
4// * *
5// * The following disclaimer summarizes all the specific disclaimers *
6// * of contributors to this software. The specific disclaimers,which *
7// * govern, are listed with their locations in: *
8// * http://cern.ch/geant4/license *
9// * *
10// * Neither the authors of this software system, nor their employing *
11// * institutes,nor the agencies providing financial support for this *
12// * work make any representation or warranty, express or implied, *
13// * regarding this software system or assume any liability for its *
14// * use. *
15// * *
16// * This code implementation is the intellectual property of the *
17// * GEANT4 collaboration. *
18// * By copying, distributing or modifying the Program (or any work *
19// * based on the Program) you indicate your acceptance of this *
20// * statement, and all its terms. *
21// ********************************************************************
22//
23//
24// $Id: BesMagneticField.cc,v 1.10 2022/01/24 23:40:34 dengzy Exp $
25// GEANT4 tag $Name: BesSim-00-01-30 $
26//
27// User Field setup class implementation.
28//
29
30#include "BesMagneticField.hh"
32
33#include "G4MagneticField.hh"
34
35#include "G4ChordFinder.hh"
36#include "G4FieldManager.hh"
37#include "G4MagIntegratorStepper.hh"
38#include "G4Mag_UsualEqRhs.hh"
39#include "G4PropagatorInField.hh"
40#include "G4TransportationManager.hh"
41
42#include "CLHEP/Random/RandGauss.h"
43#include "CLHEP/Random/RanecuEngine.h"
44#include "G4CashKarpRKF45.hh"
45#include "G4ClassicalRK4.hh"
46#include "G4ExplicitEuler.hh"
47#include "G4HelixExplicitEuler.hh"
48#include "G4HelixImplicitEuler.hh"
49#include "G4HelixSimpleRunge.hh"
50#include "G4ImplicitEuler.hh"
51#include "G4RKG3_Stepper.hh"
52#include "G4SimpleHeum.hh"
53#include "G4SimpleRunge.hh"
54#include "Randomize.hh"
55
56#include "GaudiKernel/MsgStream.h"
57#include "GaudiKernel/SmartDataPtr.h"
58// #include "GaudiKernel/IMagneticFieldSvc.h"
59#include "CLHEP/Geometry/Point3D.h"
60#include "CLHEP/Geometry/Vector3D.h"
61#include "CLHEP/Units/PhysicalConstants.h"
62#include "GaudiKernel/Bootstrap.h"
63#include "GaudiKernel/ISvcLocator.h"
64// #include "MagneticField/MagneticFieldSvc.h"
65
66#include "SimUtil/ReadBoostRoot.hh"
67#include <fstream>
68
69#include "G4SystemOfUnits.hh"
70
71#ifndef ENABLE_BACKWARDS_COMPATIBILITY
72typedef HepGeom::Point3D<double> HepPoint3D;
73#endif
74#ifndef ENABLE_BACKWARDS_COMPATIBILITY
75typedef HepGeom::Vector3D<double> HepVector3D;
76#endif
77
78//////////////////////////////////////////////////////////////////////////
79//
80// Magnetic field
81
83 ISvcLocator* svcLocator = Gaudi::svcLocator();
84 StatusCode sc = svcLocator->service( "MagneticFieldSvc", m_pIMF );
85 if ( sc != StatusCode::SUCCESS )
86 { G4cout << "Unable to open Magnetic field service" << G4endl; }
88}
89
91 if ( fFieldMessenger ) delete fFieldMessenger;
92 if ( fChordFinder ) delete fChordFinder;
93 if ( fEquation ) delete fEquation;
94 if ( fStepper ) delete fStepper;
95}
96///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97
98void BesMagneticField::GetFieldValue( const double Point[3], double* Bfield ) const {
99 double x = Point[0];
100 double y = Point[1];
101 double z = Point[2];
102
103 HepPoint3D r( x, y, z );
104 HepVector3D b;
105
106 if ( ReadBoostRoot::GetField() == 2 ) m_pIMF->fieldVector( r, b );
107 else m_pIMF->uniFieldVector( r, b );
108
109 Bfield[0] = b.x();
110 Bfield[1] = b.y();
111 Bfield[2] = b.z();
112
113 // caogf debug
114 // ofstream haha("field_out.dat",ios_base::app);
115 // haha<<x/mm<<" "<<y/mm<<" "<<z/mm<<" "<<Bfield[0]/tesla<<" "<<Bfield[1]/tesla<<"
116 //"<<Bfield[2]/tesla<<G4endl; haha.close();
117}
118
119//////////////////////////////////////////////////////////////
120// Initialise
121
123
125 fEquation = new G4Mag_UsualEqRhs( this );
126
127 fMinStep = 0.01 * mm; // minimal step of 1 mm is default
128
129 fStepperType = 4; // ClassicalRK4 is default stepper
130 fFieldManager = G4TransportationManager::GetTransportationManager()->GetFieldManager();
131 G4cout << "before CreateStepperAndChordFinder" << G4endl;
133}
134
135////////////////////////////////////////////////////////////////////////////////
136// Update field
137//
138
140 SetStepper();
141 G4cout << "The minimal step is equal to " << fMinStep / mm << " mm" << G4endl;
142
143 fFieldManager->SetDetectorField( this );
144
145 if ( fChordFinder ) delete fChordFinder;
146
147 fChordFinder = new G4ChordFinder( this, fMinStep, fStepper );
148
149 fChordFinder->SetDeltaChord( 0.25 * mm );
150 fFieldManager->SetChordFinder( fChordFinder );
151 fFieldManager->SetDeltaOneStep( 1.0e-2 * mm );
152 fFieldManager->SetDeltaIntersection( 1.0e-3 * mm );
153 fFieldManager->SetMinimumEpsilonStep( 5.0e-5 );
154 fFieldManager->SetMaximumEpsilonStep( 1.0e-3 );
155
156 G4PropagatorInField* fieldPropagator =
157 G4TransportationManager::GetTransportationManager()->GetPropagatorInField();
158 G4cout << "LargestAcceptableStep is " << fieldPropagator->GetLargestAcceptableStep() / m
159 << G4endl;
160 // read some values
161 G4cout << "field has created" << G4endl;
162 G4cout << "fDelta_One_Step_Value is " << fFieldManager->GetDeltaOneStep() << G4endl;
163 G4cout << "fDelta_Intersection_Val is " << fFieldManager->GetDeltaIntersection() << G4endl;
164 G4cout << "fEpsilonMin is " << fFieldManager->GetMinimumEpsilonStep() << G4endl;
165 G4cout << "fEpsilonMax is " << fFieldManager->GetMaximumEpsilonStep() << G4endl;
166 return;
167}
168
169/////////////////////////////////////////////////////////////////////////////
170//
171// Set stepper according to the stepper type
172//
173
175 if ( fStepper ) delete fStepper;
176
177 switch ( fStepperType )
178 {
179 case 0:
180 fStepper = new G4ExplicitEuler( fEquation );
181 G4cout << "G4ExplicitEuler is called" << G4endl;
182 break;
183 case 1:
184 fStepper = new G4ImplicitEuler( fEquation );
185 G4cout << "G4ImplicitEuler is called" << G4endl;
186 break;
187 case 2:
188 fStepper = new G4SimpleRunge( fEquation );
189 G4cout << "G4SimpleRunge is called" << G4endl;
190 break;
191 case 3:
192 fStepper = new G4SimpleHeum( fEquation );
193 G4cout << "G4SimpleHeum is called" << G4endl;
194 break;
195 case 4:
196 fStepper = new G4ClassicalRK4( fEquation );
197 G4cout << "G4ClassicalRK4 (default) is called" << G4endl;
198 break;
199 case 5:
200 fStepper = new G4HelixExplicitEuler( fEquation );
201 G4cout << "G4HelixExplicitEuler is called" << G4endl;
202 break;
203 case 6:
204 fStepper = new G4HelixImplicitEuler( fEquation );
205 G4cout << "G4HelixImplicitEuler is called" << G4endl;
206 break;
207 case 7:
208 fStepper = new G4HelixSimpleRunge( fEquation );
209 G4cout << "G4HelixSimpleRunge is called" << G4endl;
210 break;
211 case 8:
212 fStepper = new G4CashKarpRKF45( fEquation );
213 G4cout << "G4CashKarpRKF45 is called" << G4endl;
214 break;
215 case 9:
216 fStepper = new G4RKG3_Stepper( fEquation );
217 G4cout << "G4RKG3_Stepper is called" << G4endl;
218 break;
219 default: fStepper = 0;
220 }
221 return;
222}
223
224/////////////////////////////////////////////////////////////////////////////
225void BesMagneticField::SetDeltaOneStep( double newvalue ) {
226 fFieldManager = G4TransportationManager::GetTransportationManager()->GetFieldManager();
227 fFieldManager->SetDeltaOneStep( newvalue );
228}
230 fFieldManager = G4TransportationManager::GetTransportationManager()->GetFieldManager();
231 fFieldManager->SetDeltaIntersection( newvalue );
232}
234 fFieldManager = G4TransportationManager::GetTransportationManager()->GetFieldManager();
235 fFieldManager->SetMinimumEpsilonStep( newvalue );
236}
238 fFieldManager = G4TransportationManager::GetTransportationManager()->GetFieldManager();
239 fFieldManager->SetMaximumEpsilonStep( newvalue );
240}
HepGeom::Vector3D< double > HepVector3D
HepGeom::Point3D< double > HepPoint3D
G4Mag_UsualEqRhs * fEquation
void SetMaximumEpsilonStep(double newvalue)
G4MagIntegratorStepper * fStepper
G4FieldManager * fFieldManager
void SetDeltaIntersection(double newvalue)
G4ChordFinder * fChordFinder
IBesMagFieldSvc * m_pIMF
BesMagneticFieldMessenger * fFieldMessenger
void GetFieldValue(const double Point[3], double *Bfield) const
void SetMinimumEpsilonStep(double newvalue)
void SetDeltaOneStep(double newvalue)