/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSDipoleStepper.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
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),  // integrate over 6 variables only !!
00015                                       // position & velocity
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     //         << " k= " << kappa/(1./CLHEP::m2) << "m^-2" << G4endl
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   // in case of zero field (though what if there is a quadrupole part..)
00050   // or neutral particles do a linear step:
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     // Set to infinite radius for Synchrotron Radiation calculation:
00063     //    BDSLocalRadiusOfCurvature=DBL_MAX;
00064 
00065     itsDist=0;
00066     return;
00067   }
00068 
00069   //G4double h2=h*h;
00070 
00071   // global to local
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   // advance the orbit
00089  
00090   G4ThreeVector itsFinalPoint,itsFinalDir;
00091   G4ThreeVector yhat(0.,1.,0.);
00092   G4ThreeVector vhat  = LocalRp;
00093   G4ThreeVector vnorm = vhat.cross(yhat);
00094   
00095   // radius of curvature
00096   G4double R=-(InitMag/CLHEP::GeV)/(0.299792458 * itsBField/CLHEP::tesla) * CLHEP::m;
00097 
00098   // include the charge of the particles
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   // Save for Synchrotron Radiation calculations:
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   // gradient for quadrupolar field
00122   G4double kappa= - fPtrMagEqOfMot->FCof()* ( itsBGrad) /InitMag; // was ist das? 
00123   // ignore quadrupolar component for now as this needs fixing
00124   if(true || fabs(kappa)<1.e-12) { // no gradient
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   //G4double z1;
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 // if (kappa<0)
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   x1 -=(kappa/ (24*R) ) * h2*h2;
00210   x1p-=(kappa/ (6*R) ) * h*h2;
00211   */
00212   G4double dx=x1-x0;
00213   G4double dy=y1-y0;
00214   // Linear chord length
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   // gab: replace += with =
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   // This is a class method that gives distance of Mid 
00263   // from the Chord between the Initial and Final points.
00264 }
00265 
00266 BDSDipoleStepper::~BDSDipoleStepper()
00267 {}

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7