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
00020
00021
00022
00023 G4double charge = BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGCharge();
00024
00025 G4double momentum = (BDSGlobalConstants::Instance()->GetBeamMomentum())/CLHEP::GeV;
00026
00027 G4double brho = ( momentum / (0.299792458 * fabs(charge)));
00028
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
00037
00038
00039
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
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
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
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
00119
00120
00121
00122
00123
00124
00125
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;
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
00147
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;
00153 br -= (*its) * pow(r,order-1) * cos(order*phi) / fact;
00154
00155 bphi += (*it ) * pow(r,order-1) * cos(order*phi) / fact;
00156 bphi += (*its) * pow(r,order-1) * sin(order*phi) / fact;
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
00177
00178 G4AffineTransform LocalAffine = MulNavigator->GetLocalToGlobalTransform();
00179 G4ThreeVector GlobalBField = LocalAffine.TransformAxis(LocalBField);
00180
00181
00182
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