00001
00002
00003
00004
00005
00006 #include "BDSGlobalConstants.hh"
00007 #include "BDSDipoleStepper.hh"
00008 #include "G4ThreeVector.hh"
00009 #include "G4TransportationManager.hh"
00010
00011 extern G4double BDSLocalRadiusOfCurvature;
00012
00013 BDSDipoleStepper::BDSDipoleStepper(G4Mag_EqRhs *EqRhs)
00014 : G4MagIntegratorStepper(EqRhs,6),
00015
00016 itsLength(0.0),itsAngle(0.0),itsBGrad(0.0),itsBField(0.0),itsDist(0.0)
00017 {
00018 fPtrMagEqOfMot = EqRhs;
00019 }
00020
00021
00022 void BDSDipoleStepper::AdvanceHelix( const G4double yIn[],
00023 G4ThreeVector,
00024 G4double h,
00025 G4double yOut[])
00026 {
00027 G4double charge = (fPtrMagEqOfMot->FCof())/CLHEP::c_light;
00028 #ifdef BDSDEBUG
00029 G4cout << "BDSDipoleStepper: step= " << h/CLHEP::m << " m" << G4endl
00030 << " x = " << yIn[0]/CLHEP::m << " m" << G4endl
00031 << " y = " << yIn[1]/CLHEP::m << " m" << G4endl
00032 << " z = " << yIn[2]/CLHEP::m << " m" << G4endl
00033 << " px = " << yIn[3]/CLHEP::GeV << " GeV/c" << G4endl
00034 << " py = " << yIn[4]/CLHEP::GeV << " GeV/c" << G4endl
00035 << " pz = " << yIn[5]/CLHEP::GeV << " GeV/c" << G4endl
00036 << " q = " << charge/CLHEP::eplus << " e" << G4endl
00037 << " B = " << itsBField/(CLHEP::tesla) << " T" << G4endl
00038
00039 << G4endl;
00040 #endif
00041
00042 const G4double *pIn = yIn+3;
00043 G4ThreeVector v0 = G4ThreeVector( pIn[0], pIn[1], pIn[2]);
00044
00045 G4ThreeVector GlobalPosition = G4ThreeVector( yIn[0], yIn[1], yIn[2]);
00046 G4double InitMag = v0.mag();
00047 G4ThreeVector InitMomDir = v0.unit();
00048
00049
00050
00051 if(itsBField==0 || fPtrMagEqOfMot->FCof()==0) {
00052 G4ThreeVector positionMove = h * InitMomDir;
00053
00054 yOut[0] = yIn[0] + positionMove.x();
00055 yOut[1] = yIn[1] + positionMove.y();
00056 yOut[2] = yIn[2] + positionMove.z();
00057
00058 yOut[3] = v0.x();
00059 yOut[4] = v0.y();
00060 yOut[5] = v0.z();
00061
00062
00063
00064
00065 itsDist=0;
00066 return;
00067 }
00068
00069
00070
00071
00072 G4Navigator* HelixNavigator=
00073 G4TransportationManager::GetTransportationManager()->
00074 GetNavigatorForTracking();
00075
00076 G4AffineTransform LocalAffine=HelixNavigator->
00077 GetLocalToGlobalTransform();
00078
00079 G4AffineTransform GlobalAffine=HelixNavigator->
00080 GetGlobalToLocalTransform();
00081
00082 G4ThreeVector LocalR=GlobalAffine.TransformPoint(GlobalPosition);
00083 G4ThreeVector LocalRp=GlobalAffine.TransformAxis(InitMomDir);
00084
00085 G4ThreeVector itsInitialR=LocalR;
00086 G4ThreeVector itsInitialRp=LocalRp;
00087
00088
00089
00090 G4ThreeVector itsFinalPoint,itsFinalDir;
00091 G4ThreeVector yhat(0.,1.,0.);
00092 G4ThreeVector vhat = LocalRp;
00093 G4ThreeVector vnorm = vhat.cross(yhat);
00094
00095
00096 G4double R=-(InitMag/CLHEP::GeV)/(0.299792458 * itsBField/CLHEP::tesla) * CLHEP::m;
00097
00098
00099 R*=charge;
00100
00101 G4double Theta = h/R;
00102
00103 G4double CosT_ov_2, SinT_ov_2, CosT, SinT;
00104 CosT_ov_2=cos(Theta/2);
00105 SinT_ov_2=sin(Theta/2);
00106
00107 CosT=(CosT_ov_2*CosT_ov_2)- (SinT_ov_2*SinT_ov_2);
00108 SinT=2*CosT_ov_2*SinT_ov_2;
00109
00110
00111 BDSLocalRadiusOfCurvature=R;
00112
00113 itsDist=fabs(R)*(1.-CosT_ov_2);
00114
00115 G4ThreeVector dPos=R*(SinT*vhat + (1-CosT)*vnorm);
00116
00117 itsFinalPoint=LocalR+dPos;
00118 itsFinalDir=CosT*vhat +SinT*vnorm;
00119
00120
00121
00122 G4double kappa= - fPtrMagEqOfMot->FCof()* ( itsBGrad) /InitMag;
00123
00124 if(true || fabs(kappa)<1.e-12) {
00125
00126 GlobalPosition=LocalAffine.TransformPoint(itsFinalPoint);
00127 G4ThreeVector GlobalTangent=LocalAffine.TransformAxis(itsFinalDir);
00128
00129 GlobalTangent*=InitMag;
00130
00131 yOut[0] = GlobalPosition.x();
00132 yOut[1] = GlobalPosition.y();
00133 yOut[2] = GlobalPosition.z();
00134
00135 yOut[3] = GlobalTangent.x();
00136 yOut[4] = GlobalTangent.y();
00137 yOut[5] = GlobalTangent.z();
00138
00139 return;
00140 }
00141
00142 G4double x1,x1p,y1,y1p,z1p;
00143
00144
00145 G4double NomEnergy = BDSGlobalConstants::Instance()->GetBeamTotalEnergy();
00146 G4double NomR = -(NomEnergy/CLHEP::GeV)/(0.299792458 * itsBField/CLHEP::tesla) * CLHEP::m;
00147
00148 G4double NominalPath = sqrt(NomR*NomR - LocalR.z()*LocalR.z()) - fabs(NomR)*cos(itsAngle/2);
00149
00150 G4double EndNomPath = sqrt(NomR*NomR - itsFinalPoint.z()*itsFinalPoint.z()) - fabs(NomR)*cos(itsAngle/2);
00151
00152 if(R<0)
00153 {
00154 NominalPath*=-1;
00155 EndNomPath*=-1;
00156 }
00157
00158 G4double x0=LocalR.x() - NominalPath;
00159 G4double y0=LocalR.y();
00160 G4double z0=LocalR.z();
00161
00162 G4double theta_in = asin(z0/NomR);
00163
00164 LocalRp.rotateY(-theta_in);
00165
00166 G4double xp=LocalRp.x();
00167 G4double yp=LocalRp.y();
00168 G4double zp=LocalRp.z();
00169
00170 G4double rootK=sqrt(fabs(kappa*zp));
00171 G4double rootKh=rootK*h*zp;
00172 G4double X11,X12,X21,X22;
00173 G4double Y11,Y12,Y21,Y22;
00174
00175 if (kappa>0)
00176 {
00177 X11= cos(rootKh);
00178 X12= sin(rootKh)/rootK;
00179 X21=-fabs(kappa)*X12;
00180 X22= X11;
00181
00182 Y11= cosh(rootKh);
00183 Y12= sinh(rootKh)/rootK;
00184 Y21= fabs(kappa)*Y12;
00185 Y22= Y11;
00186 }
00187 else
00188 {
00189 X11= cosh(rootKh);
00190 X12= sinh(rootKh)/rootK;
00191 X21= fabs(kappa)*X12;
00192 X22= X11;
00193
00194 Y11= cos(rootKh);
00195 Y12= sin(rootKh)/rootK;
00196 Y21= -fabs(kappa)*Y12;
00197 Y22= Y11;
00198 }
00199
00200 x1 = X11*x0 + X12*xp;
00201 x1p = X21*x0 + X22*xp;
00202
00203 y1 = Y11*y0 + Y12*yp;
00204 y1p = Y21*y0 + Y22*yp;
00205
00206 z1p = sqrt(1 - x1p*x1p -y1p*y1p);
00207
00208
00209
00210
00211
00212 G4double dx=x1-x0;
00213 G4double dy=y1-y0;
00214
00215
00216 LocalR.setX(dx +itsInitialR.x() + EndNomPath - NominalPath);
00217 LocalR.setY(dy + itsInitialR.y());
00218 LocalR.setZ(itsFinalPoint.z());
00219
00220
00221 LocalRp.setX(x1p);
00222 LocalRp.setY(y1p);
00223 LocalRp.setZ(z1p);
00224 LocalRp.rotateY(theta_in);
00225
00226 GlobalPosition=LocalAffine.TransformPoint(LocalR);
00227
00228 LocalRp.rotateY(-h/R);
00229 G4ThreeVector GlobalTangent=LocalAffine.TransformAxis(LocalRp);
00230
00231 GlobalTangent*=InitMag;
00232
00233
00234 yOut[0] = GlobalPosition.x();
00235 yOut[1] = GlobalPosition.y();
00236 yOut[2] = GlobalPosition.z();
00237
00238 yOut[3] = GlobalTangent.x();
00239 yOut[4] = GlobalTangent.y();
00240 yOut[5] = GlobalTangent.z();
00241
00242 }
00243
00244
00245 void BDSDipoleStepper::Stepper( const G4double yInput[],
00246 const G4double[],
00247 const G4double hstep,
00248 G4double yOut[],
00249 G4double yErr[] )
00250 {
00251 const G4int nvar = 6 ;
00252
00253 for(G4int i=0;i<nvar;i++) yErr[i]=0;
00254
00255 AdvanceHelix(yInput,(G4ThreeVector)0,hstep,yOut);
00256
00257 }
00258
00259 G4double BDSDipoleStepper::DistChord() const
00260 {
00261 return itsDist;
00262
00263
00264 }
00265
00266 BDSDipoleStepper::~BDSDipoleStepper()
00267 {}