File indexing completed on 2025-12-16 09:21:57
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
0036 #include "G4TBFieldMessenger.hh"
0037 #include "PHG4MagneticField.h"
0038
0039 #include <Geant4/G4CashKarpRKF45.hh>
0040 #include <Geant4/G4ChordFinder.hh>
0041 #include <Geant4/G4ClassicalRK4.hh>
0042 #include <Geant4/G4ExplicitEuler.hh>
0043 #include <Geant4/G4FieldManager.hh>
0044 #include <Geant4/G4ImplicitEuler.hh>
0045 #include <Geant4/G4MagIntegratorDriver.hh>
0046 #include <Geant4/G4MagIntegratorStepper.hh>
0047 #include <Geant4/G4Mag_UsualEqRhs.hh>
0048 #include <Geant4/G4MagneticField.hh>
0049 #include <Geant4/G4SimpleHeum.hh>
0050 #include <Geant4/G4SimpleRunge.hh>
0051 #include <Geant4/G4SystemOfUnits.hh>
0052 #include <Geant4/G4ThreeVector.hh>
0053 #include <Geant4/G4TransportationManager.hh>
0054 #include <Geant4/G4Types.hh> // for G4double, G4int
0055 #include <Geant4/G4UniformMagField.hh>
0056
0057 #include <cassert>
0058 #include <cstdlib> // for exit, size_t
0059 #include <iostream>
0060 #include <string>
0061
0062
0063
0064
0065
0066 G4TBMagneticFieldSetup::G4TBMagneticFieldSetup(PHField* phfield)
0067 {
0068 assert(phfield);
0069
0070 fEMfield = new PHG4MagneticField(phfield);
0071 fFieldMessenger = new G4TBFieldMessenger(this);
0072 fEquation = new G4Mag_UsualEqRhs(fEMfield);
0073 fMinStep = 0.005 * mm;
0074 fStepperType = 4;
0075
0076 fFieldManager = GetGlobalFieldManager();
0077 UpdateField();
0078 double point[4] = {0, 0, 0, 0};
0079 fEMfield->GetFieldValue(&point[0], &magfield_at_000[0]);
0080 for (double& i : magfield_at_000)
0081 {
0082 i = i / tesla;
0083 }
0084 if (verbosity > 0)
0085 {
0086 std::cout << "field: x" << magfield_at_000[0]
0087 << ", y: " << magfield_at_000[1]
0088 << ", z: " << magfield_at_000[2]
0089 << std::endl;
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
0162 G4TBMagneticFieldSetup::~G4TBMagneticFieldSetup()
0163 {
0164 delete fChordFinder;
0165 delete fStepper;
0166 delete fFieldMessenger;
0167 delete fEquation;
0168 delete fEMfield;
0169 }
0170
0171
0172
0173
0174
0175
0176
0177 void G4TBMagneticFieldSetup::UpdateField()
0178 {
0179 SetStepper();
0180
0181 fFieldManager->SetDetectorField(fEMfield);
0182
0183 delete fChordFinder;
0184
0185 fIntgrDriver = new G4MagInt_Driver(fMinStep,
0186 fStepper,
0187 fStepper->GetNumberOfVariables());
0188
0189 fChordFinder = new G4ChordFinder(fIntgrDriver);
0190
0191 fFieldManager->SetChordFinder(fChordFinder);
0192 }
0193
0194
0195
0196
0197
0198
0199 void G4TBMagneticFieldSetup::SetStepper()
0200 {
0201 G4int nvar = 8;
0202
0203 delete fStepper;
0204
0205 std::stringstream message;
0206
0207 switch (fStepperType)
0208 {
0209 case 0:
0210 fStepper = new G4ExplicitEuler(fEquation, nvar);
0211 message << "Stepper in use: G4ExplicitEuler";
0212 break;
0213 case 1:
0214 fStepper = new G4ImplicitEuler(fEquation, nvar);
0215 message << "Stepper in use: G4ImplicitEuler";
0216 break;
0217 case 2:
0218 fStepper = new G4SimpleRunge(fEquation, nvar);
0219 message << "Stepper in use: G4SimpleRunge";
0220 break;
0221 case 3:
0222 fStepper = new G4SimpleHeum(fEquation, nvar);
0223 message << "Stepper in use: G4SimpleHeum";
0224 break;
0225 case 4:
0226 fStepper = new G4ClassicalRK4(fEquation, nvar);
0227 message << "Stepper in use: G4ClassicalRK4 (default)";
0228 break;
0229 case 5:
0230 fStepper = new G4CashKarpRKF45(fEquation, nvar);
0231 message << "Stepper in use: G4CashKarpRKF45";
0232 break;
0233 case 6:
0234 fStepper = nullptr;
0235 message << "G4RKG3_Stepper is not currently working for Magnetic Field";
0236 break;
0237 case 7:
0238 fStepper = nullptr;
0239 message << "G4HelixExplicitEuler is not valid for Magnetic Field";
0240 break;
0241 case 8:
0242 fStepper = nullptr;
0243 message << "G4HelixImplicitEuler is not valid for Magnetic Field";
0244 break;
0245 case 9:
0246 fStepper = nullptr;
0247 message << "G4HelixSimpleRunge is not valid for Magnetic Field";
0248 break;
0249 default:
0250 fStepper = nullptr;
0251 }
0252
0253 if (verbosity > 0)
0254 {
0255 std::cout << " ---------- G4TBMagneticFieldSetup::SetStepper() -----------" << std::endl;
0256 std::cout << " " << message.str() << std::endl;
0257 std::cout << " Minimum step size: " << fMinStep / mm << " mm" << std::endl;
0258 std::cout << " -----------------------------------------------------------" << std::endl;
0259 }
0260
0261 if (!fStepper)
0262 {
0263 std::cout << "no stepper set, edxiting now" << std::endl;
0264 exit(1);
0265 }
0266
0267 return;
0268 }
0269
0270
0271
0272
0273
0274
0275 void G4TBMagneticFieldSetup::SetFieldValue(const G4double fieldValue)
0276 {
0277 G4ThreeVector fieldVector(0.0, 0.0, fieldValue);
0278
0279 SetFieldValue(fieldVector);
0280 }
0281
0282
0283
0284
0285
0286
0287 void G4TBMagneticFieldSetup::SetFieldValue(const G4ThreeVector& fieldVector)
0288 {
0289
0290 G4FieldManager* fieldMgr = GetGlobalFieldManager();
0291
0292 if (fieldVector != G4ThreeVector(0., 0., 0.))
0293 {
0294 delete fEMfield;
0295
0296 fEMfield = new G4UniformMagField(fieldVector);
0297
0298 fEquation->SetFieldObj(fEMfield);
0299
0300
0301
0302 fieldMgr->SetDetectorField(fEMfield);
0303 }
0304 else
0305 {
0306
0307
0308 delete fEMfield;
0309 fEMfield = nullptr;
0310 fEquation->SetFieldObj(fEMfield);
0311 fieldMgr->SetDetectorField(fEMfield);
0312 }
0313 }
0314
0315
0316
0317
0318
0319 G4FieldManager* G4TBMagneticFieldSetup::GetGlobalFieldManager()
0320 {
0321 return G4TransportationManager::GetTransportationManager()->GetFieldManager();
0322 }