00001
00002
00003
00004
00005 #include "globals.hh"
00006 #include "BDSXYMagField.hh"
00007 #include <fstream>
00008 #include <vector>
00009 #include "CLHEP/Vector/Rotation.h"
00010
00011 G4double GetNearestValue(std::vector<struct XYFieldRecord> fieldValues, G4double x, G4double y,
00012 G4double &bx,G4double &by, G4double &bz);
00013
00014 BDSXYMagField::BDSXYMagField(G4String fname) :
00015 Bx(NULL), By(NULL), Bz(NULL), xHalf(0.0), yHalf(0.0), nX(0), nY(0), itsFileName(fname)
00016 {
00017 }
00018
00019 BDSXYMagField::~BDSXYMagField()
00020 {
00021
00022 if (Bx) {
00023 for(int i=0;i<nX;i++) {
00024 delete[] Bx[i];
00025 }
00026 delete[] Bx;
00027 }
00028 if (By) {
00029 for(int i=0;i<nX;i++) {
00030 delete[] By[i];
00031 }
00032 delete[] By;
00033 }
00034 if (Bz) {
00035 for(int i=0;i<nX;i++) {
00036 delete[] Bz[i];
00037 }
00038 delete[] Bz;
00039 }
00040 }
00041
00042 G4bool BDSXYMagField::DoesFieldChangeEnergy() const
00043 {
00044 return false;
00045 }
00046
00047 G4int BDSXYMagField::ReadFile(G4String fname)
00048 {
00049 #ifdef BDSDEBUG
00050 G4cout<<"reading file "<<fname<<G4endl;
00051 #endif
00052 struct XYFieldRecord rec;
00053
00054
00055
00056 std::ifstream bmapif;
00057 bmapif.open(fname.c_str());
00058 G4String exceptionString = "Unable to load field map file: " + fname;
00059 if(!bmapif) G4Exception(exceptionString.c_str(), "-1", FatalException, "");
00060
00061 while(bmapif.good())
00062 {
00063 bmapif>>rec.x>>rec.y>>rec.Bx>>rec.By>>rec.Bz;
00064
00065 if(!bmapif.good()) break;
00066 #ifdef BDSDEBUG
00067 G4cout<<"read: "<<rec.x<<" "<<rec.y<<" "<<rec.Bx<<" "<<rec.By<<" "<<rec.Bz<<" "<<G4endl;
00068 #endif
00069 itsFieldValues.push_back(rec);
00070 }
00071
00072 bmapif.close();
00073 #ifdef BDSDEBUG
00074 G4cout<<"done"<<G4endl;
00075 #endif
00076 return 0;
00077
00078 }
00079
00080
00081 void BDSXYMagField::Prepare(G4VPhysicalVolume *referenceVolume)
00082 {
00083 #ifdef BDSDEBUG
00084 G4cout<<"BDSXYMagField:: create XY field mesh"<<G4endl;
00085 #endif
00086 ReadFile(itsFileName);
00087
00088 if( itsFieldValues.size() == 0 )
00089 {
00090 G4cerr<<"empty bmap file "<<itsFileName<<" exiting..."<<G4endl;
00091 exit(1);
00092 }
00093
00094 const G4RotationMatrix* Rot= referenceVolume->GetFrameRotation();
00095 const G4ThreeVector Trans=referenceVolume->GetFrameTranslation();
00096
00097 G4ThreeVector B;
00098
00099
00100
00101
00102 std::vector<struct XYFieldRecord>::iterator it, itt;
00103
00104
00105 double xmax=0, ymax=0;
00106
00107 for(it=itsFieldValues.begin();it!=itsFieldValues.end();it++)
00108 {
00109 if( fabs((*it).x ) > xmax ) xmax = fabs((*it).x);
00110 if( fabs((*it).y ) > ymax) ymax = fabs((*it).y);
00111 }
00112
00113
00114
00115
00116 double hx=xmax, hxold=xmax;
00117 double hy=ymax, hyold=ymax;
00118
00119 xHalf = xmax / 2;
00120 yHalf = ymax / 2;
00121
00122 for(it=++itsFieldValues.begin();it!=itsFieldValues.end();it++)
00123 {
00124
00125 for(itt=itsFieldValues.begin();itt!=itsFieldValues.end();itt++)
00126 {
00127 #ifdef BDSDEBUG
00128 G4cout<<(*it).x<<" "<<(*it).y<<" "<<" "<<(*it).Bx<<G4endl;
00129 #endif
00130 hxold = fabs((*it).x - (*itt).x);
00131 if( (hxold > 1.0e-11*CLHEP::m)&&(hxold<hx) ) hx = hxold;
00132
00133 hyold = fabs((*it).y - (*itt).y);
00134 if( (hyold > 1.0e-11*CLHEP::m)&&(hyold<hy) ) hy = hyold;
00135
00136 }
00137 }
00138
00139
00140
00141 G4cout<<"h ="<<hx<<":"<<hy<<":"<<G4endl;
00142 G4cout<<"xmax ="<<xmax<<":"<<ymax<<":"<<G4endl;
00143
00144
00145
00146
00147 G4int nX = static_cast<int> ( 2*xHalf / hx ) + 1;
00148 G4int nY = static_cast<int> ( 2*yHalf / hy ) + 1;
00149
00150
00151 G4cout<<"N ="<<nX<<":"<<nY<<G4endl;
00152
00153 AllocateMesh(nX,nY);
00154
00155 SetOriginRotation(*Rot);
00156 SetOriginTranslation(Trans);
00157
00158 for(int i=0; i<nX;i++)
00159 for(int j=0;j<nY;j++)
00160 {
00161 G4double bx=0., by=0., bz=0.;
00162 G4double x = i * hx - xHalf;
00163 G4double y = j * hy - yHalf;
00164
00165
00166
00167
00168
00169 G4double dist = GetNearestValue(itsFieldValues,x,y,bx,by,bz);
00170
00171 G4double tol = 100 * hx;
00172
00173 G4cout << "dist, tol: " << dist << " " << tol << G4endl;
00174
00175
00176 if(dist < tol) {
00177 SetBx(i,j,bx * CLHEP::tesla);
00178 SetBy(i,j,by * CLHEP::tesla);
00179 SetBz(i,j,bz * CLHEP::tesla);
00180
00181 } else {
00182 SetBx(i,j,0.);
00183 SetBy(i,j,0.);
00184 SetBz(i,j,0.);
00185 }
00186 }
00187
00188
00189
00190
00191 G4cout<<"writing test file"<<G4endl;
00192
00193 std::ofstream testf("btest.dat");
00194
00195 for(int i=0; i<nX;i++)
00196 for(int j=0;j<nY;j++)
00197 {
00198 testf<<i<<" "<<j<<" "" "<<
00199 GetBx(i,j)<<" "<<
00200 GetBy(i,j)<<" "<<
00201 GetBz(i,j)<<std::endl;
00202 }
00203
00204 testf.close();
00205
00206 }
00207
00208
00209 void BDSXYMagField::GetFieldValue(const G4double Point[4], G4double *Bfield ) const
00210 {
00211 G4double bx=0., by=0.;
00212 #if BDSDEBUG
00213 G4double bz=0.;
00214 #endif
00215 G4int i=0,j=0;
00216
00217 G4ThreeVector local;
00218
00219 if( (nX <= 0) || (nY<=0) )
00220 {
00221 G4cerr<<"BDSXYMagField::GetFieldValue> Error: no mesh"<<G4endl;
00222 }
00223 else
00224 {
00225 local[0] = Point[0] - translation[0];
00226 local[1] = Point[1] - translation[1];
00227 local[2] = Point[2] - translation[2];
00228
00229 local *= Rotation();
00230
00231 i = (G4int)(nX/2.0 + nX * local[0] / (2.0 * xHalf));
00232 j = (G4int)(nY/2.0 + nY * local[1] / (2.0 * yHalf));
00233
00234 if( (i>=nX) || (j>=nY) || (i<0) || (j<0)){
00235
00236
00237 } else {
00238 bx = Bx[i][j];
00239 by = By[i][j];
00240 #if BDSDEBUG
00241 bz = Bz[i][j];
00242 G4cout << "Bx[" << i << "][" << j << "]=" << Bx[i][j] << G4endl;
00243 G4cout << "By[" << i << "][" << j << "]=" << By[i][j] << G4endl;
00244 G4cout << "Bz[" << i << "][" << j << "]=" << Bz[i][j] << G4endl;
00245 G4cout << "nX = " << nX << ", nY = " << nY << G4endl;
00246 #endif
00247 }
00248 }
00249
00250
00251 Bfield[0] = bx;
00252 Bfield[1] = by;
00253
00254
00255 Bfield[3] = 0;
00256 Bfield[4] = 0;
00257 Bfield[5] = 0;
00258
00259 #ifdef BDSDEBUG
00260 G4cout<<" field value requested : "<<Point[0]<<" , "<<Point[1]<<" , "<<Point[2]<<" , "<<Point[3]<<" : "<<
00261 i<<" , "<<j<<" , "<<" "<<local[0]<<" "<<local[1]<<" "<<local[2]<<" "<<bx<<" "<<by<<" "<<bz<<G4endl;
00262 #endif
00263 }
00264
00265 int BDSXYMagField::AllocateMesh(int nx, int ny)
00266 {
00267 nX = nx;
00268 nY = ny;
00269
00270 Bx = new double*[nX];
00271 for(int i=0;i<nX;i++)
00272 {
00273 Bx[i] = new double[nY];
00274 }
00275
00276 By = new double*[nX];
00277 for(int i=0;i<nX;i++)
00278 {
00279 By[i] = new double[nY];
00280 }
00281
00282 Bz = new double*[nX];
00283 for(int i=0;i<nX;i++)
00284 {
00285 Bz[i] = new double[nY];
00286 }
00287
00288 return 0;
00289 }
00290
00291 inline
00292 void BDSXYMagField::SetBx(int i,int j,double val)
00293 {
00294 Bx[i][j] = val;
00295 }
00296
00297 inline
00298 void BDSXYMagField::SetBy(int i,int j,double val)
00299 {
00300 By[i][j] = val;
00301 }
00302
00303
00304 inline
00305 void BDSXYMagField::SetBz(int i,int j,double val)
00306 {
00307 Bz[i][j] = val;
00308 }
00309
00310 inline
00311 G4double BDSXYMagField::GetBx(int i,int j)
00312 {
00313 return Bx[i][j];
00314 }
00315
00316 inline
00317 G4double BDSXYMagField::GetBy(int i,int j)
00318 {
00319 return By[i][j];
00320 }
00321
00322 inline
00323 G4double BDSXYMagField::GetBz(int i,int j)
00324 {
00325 return Bz[i][j];
00326 }
00327
00328
00329 G4double GetNearestValue(std::vector<struct XYFieldRecord> fieldValues, G4double x, G4double y,
00330 G4double &bx,G4double &by, G4double &bz)
00331 {
00332 std::vector<struct XYFieldRecord>::iterator it;
00333
00334 G4double nearestDist = 10.e+10;
00335
00336 for(it = fieldValues.begin(); it!=fieldValues.end();it++)
00337 {
00338 G4double dist = sqrt( (x-(*it).x)*(x-(*it).x) + (y-(*it).y)*(y-(*it).y));
00339 if (dist<nearestDist) {
00340 nearestDist = dist;
00341 bx = (*it).Bx;
00342 by = (*it).By;
00343 bz = (*it).Bz;
00344 }
00345 }
00346
00347 return nearestDist;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550