00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "BDSGlobalConstants.hh"
00018 #include "BDSSolenoidStepper.hh"
00019 #include "G4ThreeVector.hh"
00020 #include "G4TransportationManager.hh"
00021
00022 using std::max;
00023 extern G4double BDSLocalRadiusOfCurvature;
00024 extern G4int event_number;
00025
00026 const int DEBUG = 0;
00027
00028 BDSSolenoidStepper::BDSSolenoidStepper(G4Mag_EqRhs *EqRhs)
00029 : G4MagIntegratorStepper(EqRhs,6)
00030
00031 {
00032 fPtrMagEqOfMot = EqRhs;
00033 }
00034
00035 void BDSSolenoidStepper::AdvanceHelix( const G4double yIn[],
00036 G4ThreeVector Bfld,
00037 G4double h,
00038 G4double yOut[])
00039 {
00040
00041
00042
00043 G4double charge = (fPtrMagEqOfMot->FCof())/c_light;
00044
00045
00046
00047
00048
00049 G4double Bz;
00050 if(BDSGlobals->GetSynchRescale())
00051 {
00052 G4double B[3];
00053 fPtrMagEqOfMot->GetFieldValue(yIn, B);
00054 Bz = B[2];
00055 }
00056 else
00057 Bz = itsBField;
00058
00059
00060 if (DEBUG) G4cout << "BDSSolenoidStepper: step= " << h/m << " m" << G4endl;
00061 if (DEBUG) G4cout << "BDSSolenoidStepper: initial point in global coordinates:" << G4endl
00062 << " x= " << yIn[0]/m << "m" << G4endl
00063 << " y= " << yIn[1]/m << "m" << G4endl
00064 << " z= " << yIn[2]/m << "m" << G4endl
00065 << " px= " << yIn[3]/GeV << "GeV/c" << G4endl
00066 << " py= " << yIn[4]/GeV << "GeV/c" << G4endl
00067 << " pz= " << yIn[5]/GeV << "GeV/c" << G4endl
00068 << " q= " << charge/eplus << "e" << G4endl
00069 << " B= " << Bz/tesla << "T" << G4endl
00070 << G4endl;
00071
00072
00073
00074
00075
00076 const G4double *pIn = yIn+3;
00077 G4ThreeVector GlobalR = G4ThreeVector( yIn[0], yIn[1], yIn[2]);
00078 G4ThreeVector GlobalP = G4ThreeVector( pIn[0], pIn[1], pIn[2]);
00079 G4ThreeVector GlobalRp = GlobalP.unit();
00080 G4double InitPMag = GlobalP.mag();
00081
00082
00083
00084
00085
00086 G4Navigator* HelixNavigator=
00087 G4TransportationManager::GetTransportationManager()->
00088 GetNavigatorForTracking();
00089
00090 G4AffineTransform GlobalAffine = HelixNavigator->GetGlobalToLocalTransform();
00091 G4ThreeVector LocalR = GlobalAffine.TransformPoint(GlobalR);
00092 G4ThreeVector LocalRp = GlobalAffine.TransformAxis(GlobalRp);
00093
00094 if (DEBUG) G4cout << "BDSSolenoidStepper: initial point in local coordinates:" << G4endl
00095 << " x= " << LocalR[0]/m << "m" << G4endl
00096 << " y= " << LocalR[1]/m << "m" << G4endl
00097 << " z= " << LocalR[2]/m << "m" << G4endl
00098 << " x'= " << LocalRp[0] << G4endl
00099 << " y'= " << LocalRp[1] << G4endl
00100 << " z'= " << LocalRp[2] << G4endl
00101 << G4endl;
00102
00103
00104
00105
00106
00107 G4double R;
00108 if (Bz!=0)
00109 R = -(InitPMag*LocalRp.perp()/GeV)/(0.299792458 * Bz/tesla) * m;
00110 else
00111 R=DBL_MAX;
00112
00113
00114
00115 if( charge<0 ) R*=-1.;
00116 else if ( charge==0 ) R=DBL_MAX;
00117
00118
00119 BDSLocalRadiusOfCurvature=R;
00120
00121
00122 G4ThreeVector itsFinalR, itsFinalRp;
00123 if(fabs(R)<DBL_MAX)
00124 {
00125
00126
00127
00128
00129 G4double pitch;
00130 pitch = fabs(2*pi*R*LocalRp[2]/LocalRp.perp());
00131
00132
00133
00134
00135 G4ThreeVector Bhat(0.,0.,Bz/fabs(Bz));
00136 G4ThreeVector vhat=LocalRp;
00137 G4ThreeVector Rhat=(charge*vhat.cross(Bhat)).unit();
00138 G4ThreeVector center=LocalR+fabs(R)*Rhat;
00139
00140
00141
00142 G4double dz = h / sqrt(1. + pow(2.*pi*R/pitch,2));
00143 G4double dtheta = 2*pi*dz/pitch*R/fabs(R);
00144
00145 if (DEBUG) G4cout << "Parameters of helix: " << G4endl
00146 << " R= " << R/m << " m" << G4endl
00147 << " pitch= " << pitch/m << " m" <<G4endl
00148 << " center= " << center/m << " m"<<G4endl
00149 << " step length= " << h/m << " m"<<G4endl
00150 << " step dz= " << dz/m << " m"<<G4endl
00151 << " step dtheta= " << dtheta/radian << " rad"<<G4endl;
00152
00153
00154
00155
00156
00157
00158 G4ThreeVector itsInitialR = LocalR;
00159 G4ThreeVector itsInitialRp = LocalRp;
00160
00161
00162
00163
00164
00165
00166 itsFinalRp = itsInitialRp.rotateZ(dtheta);
00167 itsFinalR =
00168 center + (itsInitialR-center).rotateZ(dtheta) + G4ThreeVector(0,0,dz);
00169
00170
00171
00172
00173
00174 G4double Ang = fabs(dtheta);
00175 if(Ang<=pi){
00176 itsDist = fabs(R)*(1 - cos(0.5*Ang));
00177 } else
00178 if(Ang<twopi){
00179 itsDist = fabs(R)*(1 + cos(pi-0.5*Ang));
00180 } else
00181 itsDist = 2*fabs(R);
00182 }
00183 else
00184 {
00185 itsFinalR = LocalR + h * LocalRp;
00186 itsFinalRp = LocalRp;
00187 itsDist=0.;
00188 }
00189
00190 if (DEBUG) G4cout << "BDSSolenoidStepper: final point in local coordinates:" << G4endl
00191 << " x= " << itsFinalR[0]/m << "m" << G4endl
00192 << " y= " << itsFinalR[1]/m << "m" << G4endl
00193 << " z= " << itsFinalR[2]/m << "m" << G4endl
00194 << " x'= " << itsFinalRp[0] << G4endl
00195 << " y'= " << itsFinalRp[1] << G4endl
00196 << " z'= " << itsFinalRp[2] << G4endl
00197 << G4endl;
00198
00199
00200
00201
00202
00203 G4AffineTransform LocalAffine = HelixNavigator->GetLocalToGlobalTransform();
00204 GlobalR = LocalAffine.TransformPoint(itsFinalR);
00205 GlobalRp = LocalAffine.TransformAxis(itsFinalRp);
00206 GlobalP = InitPMag*GlobalRp;
00207
00208 yOut[0] = GlobalR.x();
00209 yOut[1] = GlobalR.y();
00210 yOut[2] = GlobalR.z();
00211
00212 yOut[3] = GlobalP.x();
00213 yOut[4] = GlobalP.y();
00214 yOut[5] = GlobalP.z();
00215
00216 if (DEBUG) G4cout << "BDSSolenoidStepper: final point in global coordinates:" << G4endl
00217 << " x= " << yOut[0]/m << "m" << G4endl
00218 << " y= " << yOut[1]/m << "m" << G4endl
00219 << " z= " << yOut[2]/m << "m" << G4endl
00220 << " px= " << yOut[3]/GeV << "GeV/c" << G4endl
00221 << " py= " << yOut[4]/GeV << "GeV/c" << G4endl
00222 << " pz= " << yOut[5]/GeV << "GeV/c" << G4endl
00223 << G4endl;
00224 }
00225
00226
00227 void BDSSolenoidStepper::Stepper( const G4double yInput[],
00228 const G4double dydx[],
00229 const G4double hstep,
00230 G4double yOut[],
00231 G4double yErr[] )
00232 {
00233 const G4int nvar = 6 ;
00234
00235 for(G4int i=0;i<nvar;i++) yErr[i]=0;
00236 AdvanceHelix(yInput,0,hstep,yOut);
00237 return ;
00238 }
00239
00240 G4double BDSSolenoidStepper::DistChord() const
00241 {
00242
00243 return itsDist;
00244
00245
00246 }
00247
00248 BDSSolenoidStepper::~BDSSolenoidStepper()
00249 {}