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

00001 #include "BDSGlobalConstants.hh" 
00002 
00003 #include "BDSMultipoleMagField.hh"
00004 
00005 #include "G4Navigator.hh"
00006 #include "G4ParticleDefinition.hh"
00007 #include "G4TransportationManager.hh"
00008 #include "BDSDebug.hh"
00009 
00010 BDSMultipoleMagField::BDSMultipoleMagField(std::list<G4double> kn, std::list<G4double> ks)
00011 {
00012 
00013 #ifdef BDSDEBUG
00014   G4cout << __METHOD_NAME__ << G4endl;
00015   G4cout<<"Creating BDSMultipoleMagField"<<G4endl;
00016   G4cout<<"size="<<kn.size()<<G4endl;
00017 #endif
00018 
00019   // compute magnetic rigidity brho
00020   // formula: B(Tesla)*rho(m) = p(GeV)/(0.299792458 * |charge(e)|)
00021   //
00022   // charge (in |e| units)
00023   G4double charge = BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGCharge();
00024   // momentum (in GeV/c)
00025   G4double momentum = (BDSGlobalConstants::Instance()->GetBeamMomentum())/CLHEP::GeV;
00026   // rigidity (in T*m)
00027   G4double brho = ( momentum / (0.299792458 * fabs(charge)));
00028   // rigidity (in Geant4 units)
00029   brho *= (CLHEP::tesla*CLHEP::m);
00030 #ifdef BDSDEBUG 
00031     G4cout<<"beam charge="<<charge<<"e"<<G4endl;
00032     G4cout<<"beam momentum="<<momentum<<"GeV/c"<<G4endl;
00033     G4cout<<"rigidity="<<brho/(CLHEP::tesla*CLHEP::m)<<"T*m"<<G4endl;
00034 #endif
00035 
00036   // convert strengths Kn from BDSIM units (m^-n) to Geant4 internal units
00037   // and compute coefficients of field expansion
00038   // Bn = Brho * Kn 
00039   // in Geant4 units
00040   bn = kn;
00041   bs = ks;
00042   std::list<G4double>::iterator it;
00043   std::list<G4double>::iterator its;
00044   int n(0);
00045   for(it=bn.begin(), its=bs.begin();it!=bn.end();it++, its++)
00046     {
00047       n++;
00048 #ifdef BDSDEBUG 
00049       G4cout<<2*n<<"-pole strengths:"<<G4endl;
00050       G4cout<<"Kn : "<<(*it )<<"m^-"<<n<<G4endl;
00051       G4cout<<"Ks : "<<(*its)<<"m^-"<<n<<G4endl;
00052 #endif
00053       (*it) *= brho/pow(CLHEP::m,n);
00054       (*its) *= brho/pow(CLHEP::m,n);
00055 #ifdef BDSDEBUG 
00056       G4cout<<2*n<<"-pole field coefficients:"<<G4endl;
00057       G4cout<<"Bn : "<<(*it )<<"T/m^"<<n-1<<G4endl;
00058       G4cout<<"Bs : "<<(*its)<<"T/m^"<<n-1<<G4endl;
00059 #endif
00060     }
00061 
00062   // write field map to debug file
00063   /*
00064     #ifdef BDSDEBUG 
00065     G4cout<<"Writing field map to file field.txt"<<G4endl;
00066     
00067     testf.open("field.txt");
00068     
00069     G4double pt[4];
00070     G4double b[6];
00071     
00072     testf<<"x(cm) y(cm) Bx(T) By(T) Bz(T) "<<G4endl;
00073     
00074     for(G4double x=-1*CLHEP::cm;x<1*CLHEP::cm;x+=0.1*CLHEP::mm)
00075     for(G4double y=-1*CLHEP::cm;y<1*CLHEP::cm;y+=0.1*CLHEP::mm){
00076     pt[0]= x;
00077     pt[1]= y;
00078     pt[2]= pt[3]=0;
00079         GetFieldValue(pt,b);
00080         testf<<x/CLHEP::cm<<" "<<y/CLHEP::cm<<" "
00081         <<b[0]/CLHEP::tesla<<" "<<b[1]/CLHEP::tesla<<" "<<b[2]/CLHEP::tesla<<G4endl;
00082         }
00083         #endif
00084   */
00085 }
00086 
00087 BDSMultipoleMagField::~BDSMultipoleMagField(){}
00088 
00089 void BDSMultipoleMagField::GetFieldValue( const G4double *Point,
00090                        G4double *Bfield ) const
00091 {
00092 #ifdef BDSDEBUG
00093   G4cout << __METHOD_NAME__ << G4endl;
00094   G4cout<<"Called GetFieldValue at position (in global coordinates): ("
00095         <<Point[0]/CLHEP::cm<<" "<<Point[1]/CLHEP::cm<<" "<<Point[2]/CLHEP::cm
00096         <<")cm"<<G4endl;
00097 #endif
00098 
00099   // convert global to local coordinates
00100   G4Navigator* MulNavigator=
00101     G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
00102   
00103   G4ThreeVector LocalR, GlobalR, LocalBField;
00104   
00105   GlobalR.setX(Point[0]);
00106   GlobalR.setY(Point[1]);
00107   GlobalR.setZ(Point[2]);
00108   G4AffineTransform GlobalAffine=MulNavigator->GetGlobalToLocalTransform();
00109   LocalR=GlobalAffine.TransformPoint(GlobalR); 
00110 
00111 #ifdef BDSDEBUG
00112   G4cout<<"Current position in local coordinates: ("
00113         <<LocalR[0]/CLHEP::cm<<" "<<LocalR[1]/CLHEP::cm<<" "<<LocalR[2]/CLHEP::cm
00114         <<") cm"<<G4endl;
00115 #endif
00116  
00117   //
00118   // compute B field in local coordinates
00119   // Bx = Br * cos(phi) - Bphi * sin(phi)
00120   // By = Br * sin(phi) + Bphi * cos(phi)
00121   // where, if n=1 is for dipole:
00122   // Br  (n) (normal) = +Bn/(n-1)! * r^(n-1) * sin(n*phi)
00123   // Bphi(n) (normal) = +Bn/(n-1)! * r^(n-1) * cos(n*phi)
00124   // Br  (n) (skewed) = +Bn/(n-1)! * r^(n-1) * cos(n*phi)
00125   // Bphi(n) (skewed) = -Bn/(n-1)! * r^(n-1) * sin(n*phi)
00126 
00127   G4double br = 0;
00128   G4double bphi = 0;
00129 
00130   std::list<G4double>::const_iterator it;
00131   std::list<G4double>::const_iterator its;
00132 
00133   G4double r = sqrt(LocalR[0]*LocalR[0] + LocalR[1]*LocalR[1]);
00134   G4double phi;
00135   if(fabs(r)>1.e-11*CLHEP::m) phi = atan2(LocalR[1],LocalR[0]);
00136   else phi = 0; // don't care
00137 
00138 #ifdef BDSDEBUG 
00139   G4cout<<"In local coordinates, r= "<<r/CLHEP::m<<"m, phi="<<phi<<"rad"<<G4endl;
00140 #endif
00141 
00142   G4int order=0;
00143   G4double fact = -1;
00144 
00145 
00146   // I want to use the strange convention of dipole coeff. with opposite sign -
00147   // then it is the same sign as angle 
00148   for(it=bn.begin(), its=bs.begin();it!=bn.end();it++, its++)
00149     {
00150       order++;
00151 
00152       br   += (*it ) * pow(r,order-1) * sin(order*phi) / fact; //normal
00153       br   -= (*its) * pow(r,order-1) * cos(order*phi) / fact; //skewed
00154 
00155       bphi += (*it ) * pow(r,order-1) * cos(order*phi) / fact; //normal
00156       bphi += (*its) * pow(r,order-1) * sin(order*phi) / fact; //skewed
00157 
00158       if(order==1) {br *= -1; bphi *=-1; }
00159 
00160       fact *= order;
00161     }
00162   
00163   LocalBField[0]=( br*cos(phi)-bphi*sin(phi) );
00164   LocalBField[1]=( br*sin(phi)+bphi*cos(phi) );
00165   LocalBField[2]=0;
00166 
00167 #ifdef BDSDEBUG 
00168   G4cout<<"order="<<order<<G4endl;
00169   G4cout<<"In local coordinates:"<<G4endl
00170         <<"Br="<<br/CLHEP::tesla<<"T, Bphi="<<bphi/CLHEP::tesla<<"T, "
00171         <<"Bx="<<LocalBField[0]/CLHEP::tesla<<"T, By="<<LocalBField[1]/CLHEP::tesla<<"T"
00172         <<G4endl;
00173 #endif
00174 
00175   //
00176   // convert B field to global coordinate system
00177   //
00178   G4AffineTransform LocalAffine = MulNavigator->GetLocalToGlobalTransform();
00179   G4ThreeVector GlobalBField = LocalAffine.TransformAxis(LocalBField);
00180 
00181   // currently BDSRK4Stepper - unlike the other steppers like BDSSextStepper -
00182   // wants B field in global coordinates (and in Geant4 units)
00183   Bfield[0]=GlobalBField.x();
00184   Bfield[1]=GlobalBField.y();
00185   Bfield[2]=GlobalBField.z();
00186 
00187   Bfield[3]=0.;
00188   Bfield[4]=0.;
00189   Bfield[5]=0.;
00190 }
00191 
00192 
00193 

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7