src/myQuadStepper.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 <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),  // integrate over 6 variables only !!
00018                                       // position & velocity
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   //G4cout<<"myQuadStepper: advancing through "<<h/m<<"  m "<<
00031   //"x="<<yIn[0] /m<<" y="<<yIn[1]/m<<" z="<<yIn[2]/m<<G4endl; 
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   //G4double h2=h*h;
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   // advance the orbit
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  // include the sign of the charge of the particles
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; // was ist das? 
00126   if(fabs(kappa)<std::numeric_limits<double>::epsilon()) return; // no gradient 
00127 
00128   G4double x1,x1p,y1,y1p,z1p;
00129   //G4double z1;
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   // Save for Synchrotron Radiation calculations:
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 // if (kappa<0)
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   // else // should not happen as already returned in that case
00189   //   {
00190   //     X11 = 1;
00191   //     X12 = 0;
00192   //     X21 = 0;
00193   //     X22 = 1;
00194   //     Y11 = 1;
00195   //     Y12 = 0;
00196   //     Y21 = 0;
00197   //     Y22 = 1;
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   x1 -=(kappa/ (24*R) ) * h2*h2;
00209   x1p-=(kappa/ (6*R) ) * h*h2;
00210   */
00211   G4double dx=x1-x0;
00212   G4double dy=y1-y0;
00213   // Linear chord length
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   // 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 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   // This is a class method that gives distance of Mid 
00263   // from the Chord between the Initial and Final points.
00264 }
00265 
00266 myQuadStepper::~myQuadStepper()
00267 {}

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7