/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/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 "BDSDebug.hh"
00019 #include "G4Navigator.hh"
00020 #include "G4ThreeVector.hh"
00021 #include "G4TransportationManager.hh"
00022 
00023 extern G4double BDSLocalRadiusOfCurvature;
00024 
00025 BDSSextStepper::BDSSextStepper(G4Mag_EqRhs *EqRhs)
00026   : G4MagIntegratorStepper(EqRhs,6),  // integrate over 6 variables only !!
00027                                       // position & velocity
00028     itsBDblPrime(0.0), itsDist(0.0)
00029 {
00030   fPtrMagEqOfMot = EqRhs;
00031 }
00032 
00033 
00034 void BDSSextStepper::AdvanceHelix( const G4double  yIn[],
00035                                    G4ThreeVector,
00036                                    G4double  h,
00037                                    G4double  ySext[])
00038 {
00039 
00040   const G4double *pIn = yIn+3;
00041   G4ThreeVector v0= G4ThreeVector( pIn[0], pIn[1], pIn[2]);  
00042   G4ThreeVector InitMomDir=v0.unit();
00043 
00044   G4ThreeVector GlobalPosition= G4ThreeVector( yIn[0], yIn[1], yIn[2]);  
00045   G4double InitMag=v0.mag();
00046   G4double kappa=  (-fPtrMagEqOfMot->FCof()*itsBDblPrime) /InitMag;
00047 
00048 #ifdef BDSDEBUG  
00049   G4cout << __METHOD_NAME__ << G4endl;
00050   G4cout << __METHOD_NAME__ << "kappa                 : " << kappa << G4endl;
00051   G4cout << __METHOD_NAME__ << "InitMag               : " << InitMag << G4endl;
00052   G4cout << __METHOD_NAME__ << "fPtrMagEqOfMot::FCof(): " << fPtrMagEqOfMot->FCof() << G4endl;
00053   G4cout << __METHOD_NAME__ << "g''                   : " << itsBDblPrime<< G4endl;
00054   G4cout << __METHOD_NAME__ << "fPtrMagEqOfMot->FCof(): " << fPtrMagEqOfMot->FCof() << G4endl;
00055   G4cout << __METHOD_NAME__ << "h                     : " << h << G4endl;
00056 
00057   G4double charge = (fPtrMagEqOfMot->FCof())/CLHEP::c_light;
00058 
00059   G4Navigator* SextNavigator=
00060     G4TransportationManager::GetTransportationManager()->
00061     GetNavigatorForTracking();
00062   G4String VolName = SextNavigator->LocateGlobalPointAndSetup(GlobalPosition)->GetName();
00063 
00064   G4cout << "BDSSextStepper: " << VolName << G4endl
00065          << " step= " << h/CLHEP::m << " m" << G4endl
00066          << " x= " << yIn[0]/CLHEP::m << "m" << G4endl
00067          << " y= " << yIn[1]/CLHEP::m << "m" << G4endl
00068          << " z= " << yIn[2]/CLHEP::m << "m" << G4endl
00069          << " px= " << yIn[3]/CLHEP::GeV << "GeV/c" << G4endl
00070          << " py= " << yIn[4]/CLHEP::GeV << "GeV/c" << G4endl
00071          << " pz= " << yIn[5]/CLHEP::GeV << "GeV/c" << G4endl
00072          << " q= " << charge/CLHEP::eplus << "e" << G4endl
00073          << " dBy/dx= " << itsBDblPrime/(CLHEP::tesla/CLHEP::m/CLHEP::m) << "T/m^2" << G4endl
00074          << " k= " << kappa/(1./CLHEP::m2) << "m^-2" << G4endl
00075          << G4endl 
00076          << G4endl;
00077 #endif 
00078 
00079    if(fabs(kappa)<1.e-12)
00080      {
00081        G4ThreeVector positionMove  = (h/InitMag) * v0;
00082        
00083        ySext[0]   = yIn[0] + positionMove.x(); 
00084        ySext[1]   = yIn[1] + positionMove.y(); 
00085        ySext[2]   = yIn[2] + positionMove.z(); 
00086                                 
00087        ySext[3] = v0.x();
00088        ySext[4] = v0.y();
00089        ySext[5] = v0.z();
00090 
00091        itsDist=0;
00092      }
00093    else 
00094      {      
00095        G4Navigator* SextNavigator=
00096          G4TransportationManager::GetTransportationManager()->
00097          GetNavigatorForTracking();
00098        
00099        G4AffineTransform LocalAffine=SextNavigator->
00100          GetLocalToGlobalTransform();
00101        
00102        G4AffineTransform GlobalAffine=SextNavigator->
00103          GetGlobalToLocalTransform();
00104        G4ThreeVector LocalR=GlobalAffine.TransformPoint(GlobalPosition); 
00105        G4ThreeVector LocalRp=GlobalAffine.TransformAxis(InitMomDir);
00106        
00107        
00108        G4double x0=LocalR.x(); 
00109        G4double y0=LocalR.y();
00110 
00111        // Evaluate field at the approximate midpoint of the step.
00112        x0=x0+LocalRp.x()*h/2;
00113        y0=y0+LocalRp.y()*h/2;
00114        
00115        G4double x02My02=(x0*x0-y0*y0);
00116 
00117        G4double xp=LocalRp.x();
00118        G4double yp=LocalRp.y();
00119        G4double zp=LocalRp.z();
00120 
00121        // local r'' (for curvature)
00122        G4ThreeVector LocalRpp;
00123        LocalRpp.setX(- zp*x02My02);
00124        LocalRpp.setY(2*zp*x0*y0);
00125        LocalRpp.setZ(xp*x02My02-2*yp*x0*y0);
00126 
00127        //G4cout << "LocalRpp: " <<LocalRpp<< G4endl;
00128 
00129        LocalRpp*=kappa/2; // 2 is actually a 2! factor.
00130        // determine effective curvature
00131        G4double R_1 = LocalRpp.mag();
00132 
00133 
00134        if(R_1>0.)
00135          {    
00136            G4double h2=h*h;
00137            // chord distance (simple quadratic approx)
00138            itsDist= h2*R_1/8;
00139 
00140            // Save for Synchrotron Radiation calculations:
00141            BDSLocalRadiusOfCurvature=1./R_1;
00142            
00143            G4double dx=LocalRp.x()*h + LocalRpp.x()*h2 /2.; 
00144            G4double dy=LocalRp.y()*h + LocalRpp.y()*h2 /2.;
00145 
00146            G4double dz=sqrt(h2*(1.-h2*R_1*R_1/12)-dx*dx-dy*dy);
00147            // check for precision problems
00148            G4double ScaleFac=(dx*dx+dy*dy+dz*dz)/h2;
00149            if(ScaleFac>1.0000001)
00150              {
00151                ScaleFac=sqrt(ScaleFac);
00152                dx/=ScaleFac;
00153                dy/=ScaleFac;
00154                dz/=ScaleFac;
00155              }
00156 
00157          
00158            LocalR.setX(LocalR.x()+dx);
00159            LocalR.setY(LocalR.y()+dy);
00160            LocalR.setZ(LocalR.z()+dz);
00161           
00162            LocalRp = LocalRp+ h*LocalRpp;
00163 
00164          }
00165        else
00166          {LocalR += h*LocalRp;}
00167        
00168        GlobalPosition=LocalAffine.TransformPoint(LocalR); 
00169        G4ThreeVector GlobalTangent=LocalAffine.TransformAxis(LocalRp)*InitMag;
00170        
00171        ySext[0]   = GlobalPosition.x(); 
00172        ySext[1]   = GlobalPosition.y(); 
00173        ySext[2]   = GlobalPosition.z(); 
00174                                 
00175        ySext[3] = GlobalTangent.x();
00176        ySext[4] = GlobalTangent.y();
00177        ySext[5] = GlobalTangent.z();
00178      }
00179 }
00180 
00181 void BDSSextStepper::Stepper( const G4double yInput[],
00182                              const G4double[],
00183                              const G4double hstep,
00184                              G4double yOut[],
00185                              G4double yErr[]      )
00186 {  
00187   const G4int nvar = 6 ;
00188   G4int i;
00189  
00190   G4double yTemp[7], yIn[7];
00191   
00192   //  Saving yInput because yInput and yOut can be aliases for same array
00193   
00194   for(i=0;i<nvar;i++) yIn[i]=yInput[i];
00195   
00196   G4double h = hstep * 0.5;
00197   
00198   // Do two half steps
00199   AdvanceHelix(yIn,   (G4ThreeVector)0,  h, yTemp);
00200   AdvanceHelix(yTemp, (G4ThreeVector)0, h, yOut); 
00201   
00202   // Do a full Step
00203   h = hstep ;
00204   AdvanceHelix(yIn, (G4ThreeVector)0, h, yTemp); 
00205   
00206   for(i=0;i<nvar;i++) {
00207     yErr[i] = yOut[i] - yTemp[i] ;
00208     // if error small, set error to 0
00209     // this is done to prevent Geant4 going to smaller and smaller steps
00210     // ideally use some of the global constants instead of hardcoding here
00211     // could look at step size as well instead.
00212     if (std::abs(yErr[i]) < 1e-7) yErr[i] = 0;
00213   }
00214 }
00215 
00216 G4double BDSSextStepper::DistChord()   const 
00217 {
00218   return itsDist;
00219 }
00220 
00221 BDSSextStepper::~BDSSextStepper()
00222 {}

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7