/home/cern/BDSIM_new/src/BDSSextStepper.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 25.12.2003
00004    Copyright (c) 2003 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: BDSSextStepper.cc,v 1.5 2007/11/14 12:57:06 malton Exp $
00015 // GEANT4 tag $Name:  $
00016 //
00017 #include "BDSSextStepper.hh"
00018 #include "G4ThreeVector.hh"
00019 #include "G4LineSection.hh"
00020 #include "G4TransportationManager.hh"
00021 
00022 extern G4double BDSLocalRadiusOfCurvature;
00023 
00024 extern G4int event_number;
00025 
00026 
00027 const G4int DEBUG = 0;
00028 
00029 BDSSextStepper::BDSSextStepper(G4Mag_EqRhs *EqRhs)
00030   : G4MagIntegratorStepper(EqRhs,6)  // integrate over 6 variables only !!
00031                                        // position & velocity
00032 {
00033   fPtrMagEqOfMot = EqRhs;
00034 }
00035 
00036 
00037 void BDSSextStepper::AdvanceHelix( const G4double  yIn[],
00038                                    G4ThreeVector Bfld,
00039                                    G4double  h,
00040                                    G4double  ySext[])
00041 {
00042 
00043   const G4double *pIn = yIn+3;
00044   G4ThreeVector v0= G4ThreeVector( pIn[0], pIn[1], pIn[2]);  
00045   G4ThreeVector InitMomDir=v0.unit();
00046 
00047   G4ThreeVector GlobalPosition= G4ThreeVector( yIn[0], yIn[1], yIn[2]);  
00048 
00049   G4double InitMag=v0.mag();
00050 
00051 
00052   G4double kappa=  (-fPtrMagEqOfMot->FCof()*itsBDblPrime) /InitMag;
00053    
00054 
00055    if(DEBUG) G4cout<<"sextupole stepper:"<<G4endl; 
00056   //  G4cout << "kappa: " << kappa << G4endl;
00057 //    G4cout << "InitMag: " << InitMag << G4endl;
00058 //    G4cout << "g'': " <<itsBDblPrime<< G4endl;
00059 //    G4cout << "fPtrMagEqOfMot->FCof(): " << fPtrMagEqOfMot->FCof() << G4endl << G4endl;
00060 //    G4cout << "h=: " <<h<< G4endl;
00061 
00062    if(fabs(kappa)<1.e-12)
00063      {
00064        G4ThreeVector positionMove  = (h/InitMag) * v0;
00065        
00066        ySext[0]   = yIn[0] + positionMove.x(); 
00067        ySext[1]   = yIn[1] + positionMove.y(); 
00068        ySext[2]   = yIn[2] + positionMove.z(); 
00069                                 
00070        ySext[3] = v0.x();
00071        ySext[4] = v0.y();
00072        ySext[5] = v0.z();
00073 
00074        itsDist=0;
00075      }
00076    else 
00077      {      
00078        G4Navigator* SextNavigator=
00079          G4TransportationManager::GetTransportationManager()->
00080          GetNavigatorForTracking();
00081        
00082        G4AffineTransform LocalAffine=SextNavigator->
00083          GetLocalToGlobalTransform();
00084        
00085        G4AffineTransform GlobalAffine=SextNavigator->
00086          GetGlobalToLocalTransform();
00087        G4ThreeVector LocalR=GlobalAffine.TransformPoint(GlobalPosition); 
00088        G4ThreeVector LocalRp=GlobalAffine.TransformAxis(InitMomDir);
00089        
00090        
00091        G4double x0=LocalR.x(); 
00092        G4double y0=LocalR.y();
00093 
00094        // Evaluate field at the approximate midpoint of the step.
00095        x0=x0+LocalRp.x()*h/2;
00096        y0=y0+LocalRp.y()*h/2;
00097        
00098        G4double x02My02=(x0*x0-y0*y0);
00099 
00100        G4double xp=LocalRp.x();
00101        G4double yp=LocalRp.y();
00102        G4double zp=LocalRp.z();
00103 
00104        // local r'' (for curvature)
00105        G4ThreeVector LocalRpp;
00106        LocalRpp.setX(- zp*x02My02);
00107        LocalRpp.setY(2*zp*x0*y0);
00108        LocalRpp.setZ(xp*x02My02-2*yp*x0*y0);
00109 
00110        //G4cout << "LocalRpp: " <<LocalRpp<< G4endl;
00111 
00112        LocalRpp*=kappa/2; // 2 is actually a 2! factor.
00113        // determine effective curvature
00114        G4double R_1 = LocalRpp.mag();
00115 
00116 
00117        if(R_1>0.)
00118          {    
00119            G4double h2=h*h;
00120            // chord distance (simple quadratic approx)
00121            itsDist= h2*R_1/8;
00122 
00123            // Save for Synchrotron Radiation calculations:
00124            BDSLocalRadiusOfCurvature=1./R_1;
00125            
00126            G4double dx=LocalRp.x()*h + LocalRpp.x()*h2 /2.; 
00127            G4double dy=LocalRp.y()*h + LocalRpp.y()*h2 /2.;
00128 
00129            G4double dz=sqrt(h2*(1.-h2*R_1*R_1/12)-dx*dx-dy*dy);
00130            // check for precision problems
00131            G4double ScaleFac=(dx*dx+dy*dy+dz*dz)/h2;
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          }
00148        else
00149          {LocalR += h*LocalRp;}
00150        
00151        GlobalPosition=LocalAffine.TransformPoint(LocalR); 
00152        G4ThreeVector GlobalTangent=LocalAffine.TransformAxis(LocalRp)*InitMag;
00153        
00154        ySext[0]   = GlobalPosition.x(); 
00155        ySext[1]   = GlobalPosition.y(); 
00156        ySext[2]   = GlobalPosition.z(); 
00157                                 
00158        ySext[3] = GlobalTangent.x();
00159        ySext[4] = GlobalTangent.y();
00160        ySext[5] = GlobalTangent.z();
00161      }
00162 }
00163 
00164 void BDSSextStepper::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  
00174   G4double yTemp[7], yIn[7];
00175   
00176   //  Saving yInput because yInput and yOut can be aliases for same array
00177   
00178   for(i=0;i<nvar;i++) yIn[i]=yInput[i];
00179   
00180   G4double h = hstep * 0.5; 
00181   
00182   // Do two half steps
00183   AdvanceHelix(yIn,   0,  h, yTemp);
00184   AdvanceHelix(yTemp, 0, h, yOut); 
00185   
00186   // Do a full Step
00187   h = hstep ;
00188   AdvanceHelix(yIn, 0, h, yTemp); 
00189   
00190   for(i=0;i<nvar;i++) yErr[i] = yOut[i] - yTemp[i] ;
00191   
00192   return ;
00193 }
00194 
00195 G4double BDSSextStepper::DistChord()   const 
00196 {
00197   return itsDist;
00198 }
00199 
00200 BDSSextStepper::~BDSSextStepper()
00201 {}

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