/home/cern/BDSIM_new/src/BDSSkewSextStepper.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 24.7.2002
00004    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */
00006 
00007 // This code implementation is the intellectual property of
00008 // the GEANT4 collaboration.
00009 //
00010 // By copying, distributing or modifying the Program (or any work
00011 // based on the Program) you indicate your acceptance of this statement,
00012 // and all its terms.
00013 //
00014 // $Id: BDSSkewSextStepper.cc,v 1.2 2007/05/10 16:23:22 malton Exp $
00015 // GEANT4 tag $Name:  $
00016 //
00017 #include "BDSSkewSextStepper.hh"
00018 #include "G4ThreeVector.hh"
00019 #include "G4LineSection.hh"
00020 #include "G4TransportationManager.hh"
00021 
00022 extern G4double BDSLocalRadiusOfCurvature;
00023 extern G4int event_number;
00024 
00025 BDSSkewSextStepper::BDSSkewSextStepper(G4Mag_EqRhs *EqRhs)
00026    : G4MagIntegratorStepper(EqRhs,6)  // integrate over 6 variables only !!
00027                                        // position & velocity
00028 {
00029   fPtrMagEqOfMot = EqRhs;
00030 }
00031 
00032 
00033 void BDSSkewSextStepper::AdvanceHelix( const G4double  yIn[],
00034                                    G4ThreeVector Bfld,
00035                                    G4double  h,
00036                                    G4double  ySkewSext[])
00037 {  
00038   const G4double *pIn = yIn+3;
00039   G4ThreeVector v0= G4ThreeVector( pIn[0], pIn[1], pIn[2]);  
00040   G4ThreeVector InitMomDir=v0.unit();
00041 
00042   G4ThreeVector GlobalPosition= G4ThreeVector( yIn[0], yIn[1], yIn[2]);  
00043 
00044   G4double InitMag=v0.mag();
00045 
00046   G4double kappa= - fPtrMagEqOfMot->FCof()*itsBDblPrime/InitMag;
00047 
00048   // This is kappa in (T/m)*m^-2, so convert to standard Geant4 units:
00049   // it turns out that (1./(m*m))/(tesla/m) =1, so do nothing...!
00050    
00051   // relevant momentum scale is p_z, not P_tot:
00052   // check that the approximations are valid, else do a linear step:
00053   if(fabs(kappa)<1.e-12)
00054      {
00055        G4ThreeVector positionMove  = (h/InitMag) * v0;
00056        
00057        ySkewSext[0]   = yIn[0] + positionMove.x(); 
00058        ySkewSext[1]   = yIn[1] + positionMove.y(); 
00059        ySkewSext[2]   = yIn[2] + positionMove.z(); 
00060                                 
00061        ySkewSext[3] = v0.x();
00062        ySkewSext[4] = v0.y();
00063        ySkewSext[5] = v0.z();
00064 
00065        itsDist=0;
00066      }
00067   else 
00068     { 
00069       G4Navigator* SkewSextNavigator=
00070         G4TransportationManager::GetTransportationManager()->
00071         GetNavigatorForTracking();
00072 
00073       G4AffineTransform LocalAffine=SkewSextNavigator->
00074         GetLocalToGlobalTransform();
00075 
00076        // gab_dec03>>
00077       // position 
00078       // G4ThreeVector LocalR = SkewSextNavigator->GetCurrentLocalCoordinate();
00079        // position derivative r' (normalised to unity)
00080       // G4ThreeVector LocalRp= (SkewSextNavigator->ComputeLocalAxis(v0)).unit();
00081       G4AffineTransform GlobalAffine=SkewSextNavigator->
00082         GetGlobalToLocalTransform();
00083       G4ThreeVector LocalR=GlobalAffine.TransformPoint(GlobalPosition); 
00084       G4ThreeVector LocalRp=GlobalAffine.TransformAxis(InitMomDir);
00085       // gab_dec03<<
00086      
00087 
00088        G4double x0= LocalR.x(); 
00089        G4double y0= LocalR.y(); 
00090 
00091        //       G4double z0=LocalR.z();
00092 
00093        // Evaluate field at the approximate midpoint of the step.
00094        x0=x0+LocalRp.x()*h/2;
00095        y0=y0+LocalRp.y()*h/2;
00096 
00097        G4double xp=LocalRp.x();
00098        G4double yp=LocalRp.y();
00099        G4double zp=LocalRp.z();
00100 
00101 
00102        G4double x02My02=(x0*x0-y0*y0);
00103 
00104        // local r'' (for curvature)
00105        G4ThreeVector LocalRpp;
00106        LocalRpp.setX(2*zp*x0*y0);
00107        LocalRpp.setY(zp*x02My02);
00108        LocalRpp.setZ(-2*xp*x0*y0-yp*x02My02);
00109 
00110        LocalRpp*=kappa/2; // 2 is actually a 2! factor.;
00111 
00112        // determine effective curvature
00113       G4double R_1 = LocalRpp.mag();
00114       if(R_1>0.)
00115         {
00116            G4double h2=h*h;
00117            // chord distance (simple quadratic approx)
00118            itsDist= h2*R_1/8;
00119 
00120            // Save for Synchrotron Radiation calculations:
00121            BDSLocalRadiusOfCurvature=1./R_1;
00122 
00123            // central kick approximation
00124            G4double dx=LocalRp.x()*h + LocalRpp.x()*h2/2; 
00125            G4double dy=LocalRp.y()*h + LocalRpp.y()*h2/2;
00126 
00127            G4double dz=sqrt(h2*(1.-h2*R_1*R_1/12)-dx*dx-dy*dy);
00128 
00129            // check for precision problems
00130            G4double ScaleFac=(dx*dx+dy*dy+dz*dz)/h2;
00131     
00132            if(ScaleFac>1.0000001)
00133              {
00134                ScaleFac=sqrt(ScaleFac);
00135                dx/=ScaleFac;
00136                dy/=ScaleFac;
00137                dz/=ScaleFac;
00138              }
00139 
00140           
00141            LocalR.setX(LocalR.x()+dx);
00142            LocalR.setY(LocalR.y()+dy);
00143            LocalR.setZ(LocalR.z()+dz);
00144          
00145            LocalRp  = LocalRp + h*LocalRpp;
00146         }
00147        else
00148          {LocalR += h*LocalRp;}
00149 
00150       GlobalPosition=LocalAffine.TransformPoint(LocalR); 
00151       G4ThreeVector GlobalTangent=
00152         LocalAffine.TransformAxis(LocalRp)* InitMag;
00153           
00154        ySkewSext[0]   = GlobalPosition.x(); 
00155        ySkewSext[1]   = GlobalPosition.y(); 
00156        ySkewSext[2]   = GlobalPosition.z(); 
00157        
00158        ySkewSext[3] = GlobalTangent.x();
00159        ySkewSext[4] = GlobalTangent.y();
00160        ySkewSext[5] = GlobalTangent.z();      
00161     }
00162 }
00163 
00164 void BDSSkewSextStepper::Stepper( const G4double yInput[],
00165                      const G4double dydx[],
00166                      const G4double hstep,
00167                      G4double yOut[],
00168                      G4double yErr[]      )
00169 {  
00170    const G4int nvar = 6 ;
00171 
00172    G4int i;
00173    for(i=0;i<nvar;i++) yErr[i]=0;
00174 
00175    AdvanceHelix(yInput,0,hstep,yOut);
00176 
00177 
00178    return ;
00179 }
00180 
00181 G4double BDSSkewSextStepper::DistChord()   const 
00182 {
00183 return itsDist;
00184   // This is a class method that gives distance of Mid 
00185   //  from the Chord between the Initial and Final points.
00186 }
00187 
00188 BDSSkewSextStepper::~BDSSkewSextStepper()
00189 {}

Generated on Wed Mar 5 17:25:22 2008 for BDSIM by  doxygen 1.5.3