00001
00002
00003
00004
00005 #include "globals.hh"
00006 #include "BDSXYMagField.hh"
00007 #include <fstream>
00008
00009 using namespace std;
00010
00011 G4double GetNearestValue(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 DEBUG
00050 G4cout<<"reading file "<<fname<<G4endl;
00051 #endif
00052 struct XYFieldRecord rec;
00053
00054 ifstream bmapif;
00055 bmapif.open(fname);
00056
00057 while(bmapif.good())
00058 {
00059 bmapif>>rec.x>>rec.y>>rec.Bx>>rec.By>>rec.Bz;
00060
00061 if(!bmapif.good()) break;
00062 #ifdef DEBUG
00063 G4cout<<"read: "<<rec.x<<" "<<rec.y<<" "<<rec.Bx<<" "<<rec.By<<" "<<rec.Bz<<" "<<G4endl;
00064 #endif
00065 itsFieldValues.push_back(rec);
00066 }
00067
00068 bmapif.close();
00069 #ifdef DEBUG
00070 G4cout<<"done"<<G4endl;
00071 #endif
00072 return 0;
00073
00074 }
00075
00076
00077 void BDSXYMagField::Prepare(G4VPhysicalVolume *referenceVolume)
00078 {
00079 #ifdef DEBUG
00080 G4cout<<"BDSElement:: create XY field mesh"<<G4endl;
00081 #endif
00082 ReadFile(itsFileName);
00083
00084 if( itsFieldValues.size() == 0 )
00085 {
00086 G4cerr<<"empty bmap file "<<itsFileName<<" exiting..."<<G4endl;
00087 exit(1);
00088 }
00089
00090 const G4RotationMatrix* Rot=referenceVolume->GetFrameRotation();
00091 const G4ThreeVector Trans=referenceVolume->GetFrameTranslation();
00092
00093 G4ThreeVector B;
00094
00095
00096
00097
00098 vector<struct XYFieldRecord>::iterator it, itt;
00099
00100
00101 double xmax=0, ymax=0;
00102
00103 for(it=itsFieldValues.begin();it!=itsFieldValues.end();it++)
00104 {
00105 if( fabs((*it).x ) > xmax ) xmax = fabs((*it).x);
00106 if( fabs((*it).y ) > ymax) ymax = fabs((*it).y);
00107 }
00108
00109
00110
00111
00112 double hx=xmax, hxold=xmax;
00113 double hy=ymax, hyold=ymax;
00114
00115 xHalf = xmax / 2;
00116 yHalf = ymax / 2;
00117
00118 for(it=++itsFieldValues.begin();it!=itsFieldValues.end();it++)
00119 {
00120
00121 for(itt=itsFieldValues.begin();itt!=itsFieldValues.end();itt++)
00122 {
00123 #ifdef DEBUG
00124 G4cout<<(*it).x<<" "<<(*it).y<<" "<<" "<<(*it).Bx<<G4endl;
00125 #endif
00126 hxold = fabs((*it).x - (*itt).x);
00127 if( (hxold > 1.0e-11*m)&&(hxold<hx) ) hx = hxold;
00128
00129 hyold = fabs((*it).y - (*itt).y);
00130 if( (hyold > 1.0e-11*m)&&(hyold<hy) ) hy = hyold;
00131
00132 }
00133 }
00134
00135
00136
00137 G4cout<<"h ="<<hx<<":"<<hy<<":"<<G4endl;
00138 G4cout<<"xmax ="<<xmax<<":"<<ymax<<":"<<G4endl;
00139
00140
00141
00142
00143 G4int nX = static_cast<int> ( 2*xHalf / hx ) + 1;
00144 G4int nY = static_cast<int> ( 2*yHalf / hy ) + 1;
00145
00146
00147 G4cout<<"N ="<<nX<<":"<<nY<<G4endl;
00148
00149 AllocateMesh(nX,nY);
00150
00151 SetOriginRotation(*Rot);
00152 SetOriginTranslation(Trans);
00153
00154 G4double bx, by, bz, x, y;
00155
00156 for(int i=0; i<nX;i++)
00157 for(int j=0;j<nY;j++)
00158 {
00159 x = i * hx - xHalf;
00160 y = j * hy - yHalf;
00161
00162
00163
00164
00165
00166 G4double dist = GetNearestValue(itsFieldValues,x,y,bx,by,bz);
00167
00168 G4double tol = 100 * hx;
00169
00170 G4cout << "dist, tol: " << dist << " " << tol << G4endl;
00171
00172
00173 if(dist < tol) {
00174 SetBx(i,j,bx * tesla);
00175 SetBy(i,j,by * tesla);
00176 SetBz(i,j,bz * tesla);
00177
00178 } else {
00179 SetBx(i,j,0.);
00180 SetBy(i,j,0.);
00181 SetBz(i,j,0.);
00182 }
00183 }
00184
00185
00186
00187
00188 G4cout<<"writing test file"<<G4endl;
00189
00190 ofstream testf("btest.dat");
00191
00192 for(int i=0; i<nX;i++)
00193 for(int j=0;j<nY;j++)
00194 {
00195 testf<<i<<" "<<j<<" "" "<<
00196 GetBx(i,j)<<" "<<
00197 GetBy(i,j)<<" "<<
00198 GetBz(i,j)<<endl;
00199 }
00200
00201 testf.close();
00202
00203 }
00204
00205
00206 void BDSXYMagField::GetFieldValue(const G4double Point[4], G4double *Bfield ) const
00207 {
00208 G4double bx=0., by=0.;
00209 #if DEBUG
00210 G4double bz=0.;
00211 #endif
00212 G4int i=0,j=0;
00213
00214 G4ThreeVector local;
00215
00216 if( (nX <= 0) || (nY<=0) )
00217 {
00218 G4cerr<<"BDSXYMagField::GetFieldValue> Error: no mesh"<<G4endl;
00219 }
00220 else
00221 {
00222 local[0] = Point[0] - translation[0];
00223 local[1] = Point[1] - translation[1];
00224 local[2] = Point[2] - translation[2];
00225
00226 local *= rotation;
00227
00228 i = (G4int)(nX/2.0 + nX * local[0] / (2.0 * xHalf));
00229 j = (G4int)(nY/2.0 + nY * local[1] / (2.0 * yHalf));
00230
00231 if( (i>=nX) || (j>=nY) || (i<0) || (j<0)){
00232
00233
00234 } else {
00235 bx = Bx[i][j];
00236 by = By[i][j];
00237 #if DEBUG
00238 bz = Bz[i][j];
00239 G4cout << "Bx[" << i << "][" << j << "]=" << Bx[i][j] << G4endl;
00240 G4cout << "By[" << i << "][" << j << "]=" << By[i][j] << G4endl;
00241 G4cout << "Bz[" << i << "][" << j << "]=" << Bz[i][j] << G4endl;
00242 G4cout << "nX = " << nX << ", nY = " << nY << G4endl;
00243 #endif
00244 }
00245 }
00246
00247
00248 Bfield[0] = bx;
00249 Bfield[1] = by;
00250
00251
00252 Bfield[3] = 0;
00253 Bfield[4] = 0;
00254 Bfield[5] = 0;
00255
00256 #ifdef DEBUG
00257 G4cout<<" field value requested : "<<Point[0]<<" , "<<Point[1]<<" , "<<Point[2]<<" , "<<Point[3]<<" : "<<
00258 i<<" , "<<j<<" , "<<" "<<local[0]<<" "<<local[1]<<" "<<local[2]<<" "<<bx<<" "<<by<<" "<<bz<<G4endl;
00259 #endif
00260 }
00261
00262 int BDSXYMagField::AllocateMesh(int nx, int ny)
00263 {
00264 nX = nx;
00265 nY = ny;
00266
00267 Bx = new double*[nX];
00268 for(int i=0;i<nX;i++)
00269 {
00270 Bx[i] = new double[nY];
00271 }
00272
00273 By = new double*[nX];
00274 for(int i=0;i<nX;i++)
00275 {
00276 By[i] = new double[nY];
00277 }
00278
00279 Bz = new double*[nX];
00280 for(int i=0;i<nX;i++)
00281 {
00282 Bz[i] = new double[nY];
00283 }
00284
00285 return 0;
00286 }
00287
00288 inline
00289 void BDSXYMagField::SetBx(int i,int j,double val)
00290 {
00291 Bx[i][j] = val;
00292 }
00293
00294 inline
00295 void BDSXYMagField::SetBy(int i,int j,double val)
00296 {
00297 By[i][j] = val;
00298 }
00299
00300
00301 inline
00302 void BDSXYMagField::SetBz(int i,int j,double val)
00303 {
00304 Bz[i][j] = val;
00305 }
00306
00307 inline
00308 G4double BDSXYMagField::GetBx(int i,int j)
00309 {
00310 return Bx[i][j];
00311 }
00312
00313 inline
00314 G4double BDSXYMagField::GetBy(int i,int j)
00315 {
00316 return By[i][j];
00317 }
00318
00319 inline
00320 G4double BDSXYMagField::GetBz(int i,int j)
00321 {
00322 return Bz[i][j];
00323 }
00324
00325
00326 G4double GetNearestValue(vector<struct XYFieldRecord> fieldValues, G4double x, G4double y,
00327 G4double &bx,G4double &by, G4double &bz)
00328 {
00329 vector<struct XYFieldRecord>::iterator it;
00330
00331 G4double dist = 10.e+10;
00332
00333 for(it = fieldValues.begin(); it!=fieldValues.end();it++)
00334 {
00335 dist = sqrt( (x-(*it).x)*(x-(*it).x) + (y-(*it).y)*(y-(*it).y));
00336 bx = (*it).Bx;
00337 by = (*it).By;
00338 bz = (*it).Bz;
00339 }
00340
00341 return dist;
00342
00343 }
00344
00345
00346
00347
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