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