File indexing completed on 2025-08-05 08:18:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "G4TBMagneticFieldSetup.hh"
0035 #include "G4TBFieldMessenger.hh"
0036 #include "PHG4MagneticField.h"
0037
0038 #include <Geant4/G4CashKarpRKF45.hh>
0039 #include <Geant4/G4ChordFinder.hh>
0040 #include <Geant4/G4ClassicalRK4.hh>
0041 #include <Geant4/G4ExplicitEuler.hh>
0042 #include <Geant4/G4FieldManager.hh>
0043 #include <Geant4/G4ImplicitEuler.hh>
0044 #include <Geant4/G4MagIntegratorDriver.hh>
0045 #include <Geant4/G4MagIntegratorStepper.hh>
0046 #include <Geant4/G4Mag_UsualEqRhs.hh>
0047 #include <Geant4/G4MagneticField.hh>
0048 #include <Geant4/G4SimpleHeum.hh>
0049 #include <Geant4/G4SimpleRunge.hh>
0050 #include <Geant4/G4SystemOfUnits.hh>
0051 #include <Geant4/G4ThreeVector.hh>
0052 #include <Geant4/G4TransportationManager.hh>
0053 #include <Geant4/G4Types.hh> // for G4double, G4int
0054 #include <Geant4/G4UniformMagField.hh>
0055
0056 #include <cassert>
0057 #include <cstdlib> // for exit, size_t
0058 #include <iostream>
0059 #include <string>
0060
0061
0062
0063
0064
0065 G4TBMagneticFieldSetup::G4TBMagneticFieldSetup(PHField* phfield)
0066 {
0067 assert(phfield);
0068
0069 fEMfield = new PHG4MagneticField(phfield);
0070 fFieldMessenger = new G4TBFieldMessenger(this);
0071 fEquation = new G4Mag_UsualEqRhs(fEMfield);
0072 fMinStep = 0.005 * mm;
0073 fStepperType = 4;
0074
0075 fFieldManager = GetGlobalFieldManager();
0076 UpdateField();
0077 double point[4] = {0, 0, 0, 0};
0078 fEMfield->GetFieldValue(&point[0], &magfield_at_000[0]);
0079 for (double& i : magfield_at_000)
0080 {
0081 i = i / tesla;
0082 }
0083 if (verbosity > 0)
0084 {
0085 std::cout << "field: x" << magfield_at_000[0]
0086 << ", y: " << magfield_at_000[1]
0087 << ", z: " << magfield_at_000[2]
0088 << std::endl;
0089 }
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 G4TBMagneticFieldSetup::~G4TBMagneticFieldSetup()
0162 {
0163 delete fChordFinder;
0164 delete fStepper;
0165 delete fFieldMessenger;
0166 delete fEquation;
0167 delete fEMfield;
0168 }
0169
0170
0171
0172
0173
0174
0175
0176 void G4TBMagneticFieldSetup::UpdateField()
0177 {
0178 SetStepper();
0179
0180 fFieldManager->SetDetectorField(fEMfield);
0181
0182 delete fChordFinder;
0183
0184 fIntgrDriver = new G4MagInt_Driver(fMinStep,
0185 fStepper,
0186 fStepper->GetNumberOfVariables());
0187
0188 fChordFinder = new G4ChordFinder(fIntgrDriver);
0189
0190 fFieldManager->SetChordFinder(fChordFinder);
0191 }
0192
0193
0194
0195
0196
0197
0198 void G4TBMagneticFieldSetup::SetStepper()
0199 {
0200 G4int nvar = 8;
0201
0202 delete fStepper;
0203
0204 std::stringstream message;
0205
0206 switch (fStepperType)
0207 {
0208 case 0:
0209 fStepper = new G4ExplicitEuler(fEquation, nvar);
0210 message << "Stepper in use: G4ExplicitEuler";
0211 break;
0212 case 1:
0213 fStepper = new G4ImplicitEuler(fEquation, nvar);
0214 message << "Stepper in use: G4ImplicitEuler";
0215 break;
0216 case 2:
0217 fStepper = new G4SimpleRunge(fEquation, nvar);
0218 message << "Stepper in use: G4SimpleRunge";
0219 break;
0220 case 3:
0221 fStepper = new G4SimpleHeum(fEquation, nvar);
0222 message << "Stepper in use: G4SimpleHeum";
0223 break;
0224 case 4:
0225 fStepper = new G4ClassicalRK4(fEquation, nvar);
0226 message << "Stepper in use: G4ClassicalRK4 (default)";
0227 break;
0228 case 5:
0229 fStepper = new G4CashKarpRKF45(fEquation, nvar);
0230 message << "Stepper in use: G4CashKarpRKF45";
0231 break;
0232 case 6:
0233 fStepper = nullptr;
0234 message << "G4RKG3_Stepper is not currently working for Magnetic Field";
0235 break;
0236 case 7:
0237 fStepper = nullptr;
0238 message << "G4HelixExplicitEuler is not valid for Magnetic Field";
0239 break;
0240 case 8:
0241 fStepper = nullptr;
0242 message << "G4HelixImplicitEuler is not valid for Magnetic Field";
0243 break;
0244 case 9:
0245 fStepper = nullptr;
0246 message << "G4HelixSimpleRunge is not valid for Magnetic Field";
0247 break;
0248 default:
0249 fStepper = nullptr;
0250 }
0251
0252 if (verbosity > 0)
0253 {
0254 std::cout << " ---------- G4TBMagneticFieldSetup::SetStepper() -----------" << std::endl;
0255 std::cout << " " << message.str() << std::endl;
0256 std::cout << " Minimum step size: " << fMinStep / mm << " mm" << std::endl;
0257 std::cout << " -----------------------------------------------------------" << std::endl;
0258 }
0259
0260 if (!fStepper)
0261 {
0262 std::cout << "no stepper set, edxiting now" << std::endl;
0263 exit(1);
0264 }
0265
0266 return;
0267 }
0268
0269
0270
0271
0272
0273
0274 void G4TBMagneticFieldSetup::SetFieldValue(const G4double fieldValue)
0275 {
0276 G4ThreeVector fieldVector(0.0, 0.0, fieldValue);
0277
0278 SetFieldValue(fieldVector);
0279 }
0280
0281
0282
0283
0284
0285
0286 void G4TBMagneticFieldSetup::SetFieldValue(const G4ThreeVector& fieldVector)
0287 {
0288
0289 G4FieldManager* fieldMgr = GetGlobalFieldManager();
0290
0291 if (fieldVector != G4ThreeVector(0., 0., 0.))
0292 {
0293 if (fEMfield)
0294 {
0295 delete fEMfield;
0296 }
0297 fEMfield = new G4UniformMagField(fieldVector);
0298
0299 fEquation->SetFieldObj(fEMfield);
0300
0301
0302
0303 fieldMgr->SetDetectorField(fEMfield);
0304 }
0305 else
0306 {
0307
0308
0309 delete fEMfield;
0310 fEMfield = nullptr;
0311 fEquation->SetFieldObj(fEMfield);
0312 fieldMgr->SetDetectorField(fEMfield);
0313 }
0314 }
0315
0316
0317
0318
0319
0320 G4FieldManager* G4TBMagneticFieldSetup::GetGlobalFieldManager()
0321 {
0322 return G4TransportationManager::GetTransportationManager()->GetFieldManager();
0323 }