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