00001
00002
00003
00004
00005 #ifdef SITE_HAS_GEANT4
00006 #include "G4I/G4IStepper.h"
00007 #include "G4I/G4IBField.h"
00008 #include "G4MagIntegratorDriver.hh"
00009 #include "G4Mag_UsualEqRhs.hh"
00010 #include "G4ClassicalRK4.hh"
00011 #include "G4Mag_EqRhs.hh"
00012 #include "SystemOfUnits.h"
00013
00014
00015
00016 G4IStepper::G4IStepper(BField* magField) :
00017 fStepMin(1.0e-2*m),
00018 fErrStep(1.0e-6),
00019 fMagField(magField),
00020 fRhs( new G4Mag_UsualEqRhs(&fMagField)),
00021 fStepper( new G4ClassicalRK4(fRhs)),
00022 fDriver( new G4MagInt_Driver(fStepMin,fStepper)),
00023 fCurveLength(0.0*m)
00024 { }
00025
00026
00027
00028 G4IStepper::G4IStepper(BField* magField,
00029 double stepMin, double errStep) :
00030 fStepMin(stepMin*m),
00031 fErrStep(errStep),
00032 fMagField(magField),
00033 fRhs( new G4Mag_UsualEqRhs(&fMagField)),
00034 fStepper( new G4ClassicalRK4(fRhs)),
00035 fDriver( new G4MagInt_Driver(fStepMin,fStepper)),
00036 fCurveLength(0.0*m)
00037 { }
00038
00039
00040
00041 G4IStepper::~G4IStepper()
00042 {
00043 if (fDriver) { delete fDriver; fDriver = 0; }
00044 if (fStepper) { delete fStepper; fStepper = 0; }
00045 if (fRhs) { delete fRhs; fRhs = 0; }
00046 }
00047
00048
00049
00050 bool G4IStepper::StepOnce(const double* xStart,
00051 const double* vDir,
00052 double momentum,
00053 double mass,
00054 double charge,
00055 double stepSize,
00056 double* xNext,
00057 double* vDirNext,
00058 double* pNext)
00059 {
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static const double c = c_light;
00074
00075
00076 static const double GeVc = GeV/c;
00077
00078
00079
00080 double energy = sqrt(momentum*momentum+mass*mass)*GeV;
00081 double v = c*momentum*GeV/energy;
00082
00083 G4FieldTrack fieldTrack(G4ThreeVector(m*xStart[0],m*xStart[1],m*xStart[2]),
00084 G4ThreeVector(v*vDir[0],v*vDir[1],v*vDir[2]),
00085 fCurveLength,
00086 energy);
00087
00088
00089 fDriver->SetChargeMomentumMass(charge,momentum*GeVc,mass*GeV);
00090
00091 bool stepOk = fDriver->AccurateAdvance(fieldTrack,stepSize*m,fErrStep);
00092
00093 xNext[0] = fieldTrack.GetPosition().x()/m;
00094 xNext[1] = fieldTrack.GetPosition().y()/m;
00095 xNext[2] = fieldTrack.GetPosition().z()/m;
00096
00097 double vxOut = fieldTrack.GetVelocity().x();
00098 double vyOut = fieldTrack.GetVelocity().y();
00099 double vzOut = fieldTrack.GetVelocity().z();
00100
00101 v = sqrt(vxOut*vxOut + vyOut*vyOut + vzOut*vzOut);
00102 vDirNext[0] = vxOut/v;
00103 vDirNext[1] = vyOut/v;
00104 vDirNext[2] = vzOut/v;
00105
00106 double beta = v/c;
00107 if (beta>1.0) beta=1.0;
00108 *pNext = mass*beta/sqrt(1.0-beta*beta);
00109
00110 return stepOk;
00111 }
00112
00113 #endif // SITE_HAS_GEANT4
00114