src/BDSXYMagField2.cc

00001 //Based on the Geant4 example examples/advanced/purging_magnet/src/PurgMagTabulatedField3D.cc
00002 #include "BDSGlobalConstants.hh"
00003 #include "BDSXYMagField2.hh"
00004 
00005 BDSXYMagField2::BDSXYMagField2( const char* filename ) 
00006   :invertX(false),invertY(false)
00007 {    
00008  
00009   double lenUnit= m;
00010   double fieldUnit= tesla; 
00011   G4cout << "\n-----------------------------------------------------------"
00012          << "\n      Magnetic field"
00013          << "\n-----------------------------------------------------------";
00014     
00015   G4cout << "\n ---> " "Reading the field grid from " << filename << " ... " << G4endl; 
00016   std::ifstream file( filename ); // Open the file for reading.
00017   
00018   // Ignore first blank line
00019   char buffer[256];
00020   file.getline(buffer,256);
00021   
00022   // Read table dimensions 
00023   file >> nx >> ny; // Note dodgy order
00024 
00025   G4cout << "  [ Number of values x,y: " 
00026          << nx << " " << ny << " ] "
00027          << G4endl;
00028 
00029   // Set up storage space for table
00030   xField.resize( nx );
00031   yField.resize( nx );
00032   zField.resize( nx );
00033   int ix, iy;
00034   for (ix=0; ix<nx; ix++) {
00035     xField[ix].resize(ny);
00036     yField[ix].resize(ny);
00037     zField[ix].resize(ny);
00038   }
00039   
00040   // Ignore other header information    
00041   // The first line whose second character is '0' is considered to
00042   // be the last line of the header.
00043   do {
00044     file.getline(buffer,256);
00045   } while ( buffer[1]!='0');
00046   
00047   // Read in the data
00048   double xval,yval,bx,by,bz;
00049   int ii=0;
00050   for (ix=0; ix<nx; ix++) {
00051     for (iy=0; iy<ny; iy++) {
00052       file >> xval >> yval >> bx >> by >> bz;
00053       //      G4cout << ii << " " << xval << " " << yval << " " << bx << " " << by << " "  << bz << G4endl;
00054       ii++;
00055       if ( ix==0 && iy==0 ) {
00056         minx = xval * lenUnit;
00057         miny = yval * lenUnit;
00058       }
00059       xField[ix][iy] = bx * fieldUnit;
00060       yField[ix][iy] = by * fieldUnit;
00061       zField[ix][iy] = bz * fieldUnit;
00062     }
00063   }
00064   file.close();
00065 
00066   maxx = xval * lenUnit;
00067   maxy = yval * lenUnit;
00068 
00069   G4cout << "\n ---> ... done reading " << G4endl;
00070 
00071   // G4cout << " Read values of field from file " << filename << G4endl; 
00072   G4cout << " ---> assumed the order:  x, y, Bx, By, Bz "
00073          << "\n ---> Min values x,y: " 
00074          << minx/cm << " " << miny/cm << " cm "
00075          << "\n ---> Max values x,y: " 
00076          << maxx/cm << " " << maxy/cm << " " << G4endl;
00077 
00078 
00079   // Should really check that the limits are not the wrong way around.
00080   if (maxx < minx) {std::swap(maxx,minx); invertX = true;} 
00081   if (maxy < miny) {std::swap(maxy,miny); invertY = true;} 
00082 
00083   G4cout << "\nAfter reordering if neccesary"  
00084          << "\n ---> Min values x,y: " 
00085          << minx/cm << " " << miny/cm << " cm "
00086          << " \n ---> Max values x,y: " 
00087          << maxx/cm << " " << maxy/cm << " cm ";
00088 
00089   dx = maxx - minx;
00090   dy = maxy - miny;
00091   G4cout << "\n ---> Dif values x,y (range): " 
00092          << dx/cm << " " << dy/cm << " " << " cm"
00093          << "\n-----------------------------------------------------------" << G4endl;
00094 }
00095 
00096 void BDSXYMagField2::GetFieldValue(const double point[4],
00097                                       double *Bfield ) const
00098 {
00099 
00100   double x = point[0];
00101   double y = point[1];
00102 
00103   // Check that the point is within the defined region 
00104   if ( x>=minx && x<=maxx &&
00105        y>=miny && y<=maxy ) {
00106     
00107     // Position of given point within region, normalized to the range
00108     // [0,1]
00109     double xfraction = (x - minx) / dx;
00110     double yfraction = (y - miny) / dy; 
00111 
00112     if (invertX) { xfraction = 1 - xfraction;}
00113     if (invertY) { yfraction = 1 - yfraction;}
00114 
00115     // Need addresses of these to pass to modf below.
00116     // modf uses its second argument as an OUTPUT argument.
00117     double xdindex, ydindex;
00118     
00119     // Position of the point within the cuboid defined by the
00120     // nearest surrounding tabulated points
00121     double xlocal = ( std::modf(xfraction*(nx-1), &xdindex));
00122     double ylocal = ( std::modf(yfraction*(ny-1), &ydindex));
00123     
00124     // The indices of the nearest tabulated point whose coordinates
00125     // are all less than those of the given point
00126     int xindex = static_cast<int>(xdindex);
00127     int yindex = static_cast<int>(ydindex);
00128     
00129 
00130 #ifdef DEBUG_INTERPOLATING_FIELD
00131     G4cout << "Local x,y: " << xlocal << " " << ylocal << G4endl;
00132     G4cout << "Index x,y: " << xindex << " " << yindex << G4endl;
00133     double valx0z0, mulx0z0, valx1z0, mulx1z0;
00134     double valx0z1, mulx0z1, valx1z1, mulx1z1;
00135     //   valx0z0= table[xindex  ][0];  mulx0z0=  (1-xlocal);
00136     //    valx1z0= table[xindex+1][0];  mulx1z0=   xlocal;
00137     //    valx0z1= table[xindex  ][0];  mulx0z1= (1-xlocal);
00138     //    valx1z1= table[xindex+1][0];  mulx1z1=  xlocal;
00139 #endif
00140 
00141         // 2-dimensional version
00142     Bfield[0] =
00143       xField[xindex  ][yindex  ] * (1-xlocal) * (1-ylocal)  +
00144       xField[xindex  ][yindex  ] * (1-xlocal) * (1-ylocal)   +
00145       xField[xindex  ][yindex+1] * (1-xlocal) *    ylocal   +
00146       xField[xindex  ][yindex+1] * (1-xlocal) *    ylocal    +
00147       xField[xindex+1][yindex  ] *    xlocal  * (1-ylocal)  +
00148       xField[xindex+1][yindex  ] *    xlocal  * (1-ylocal)   +
00149       xField[xindex+1][yindex+1] *    xlocal  *    ylocal   +
00150       xField[xindex+1][yindex+1] *    xlocal  *    ylocal   ;
00151     Bfield[1] =
00152       yField[xindex  ][yindex  ] * (1-xlocal) * (1-ylocal)  +
00153       yField[xindex  ][yindex  ] * (1-xlocal) * (1-ylocal)   +
00154       yField[xindex  ][yindex+1] * (1-xlocal) *    ylocal   +
00155       yField[xindex  ][yindex+1] * (1-xlocal) *    ylocal    +
00156       yField[xindex+1][yindex  ] *    xlocal  * (1-ylocal)  +
00157       yField[xindex+1][yindex  ] *    xlocal  * (1-ylocal)   +
00158       yField[xindex+1][yindex+1] *    xlocal  *    ylocal   +
00159       yField[xindex+1][yindex+1] *    xlocal  *    ylocal   ;
00160     Bfield[2] =
00161       zField[xindex  ][yindex  ] * (1-xlocal) * (1-ylocal)  +
00162       zField[xindex  ][yindex  ] * (1-xlocal) * (1-ylocal)   +
00163       zField[xindex  ][yindex+1] * (1-xlocal) *    ylocal   +
00164       zField[xindex  ][yindex+1] * (1-xlocal) *    ylocal    +
00165       zField[xindex+1][yindex  ] *    xlocal  * (1-ylocal)  +
00166       zField[xindex+1][yindex  ] *    xlocal  * (1-ylocal)   +
00167       zField[xindex+1][yindex+1] *    xlocal  *    ylocal   +
00168       zField[xindex+1][yindex+1] *    xlocal  *    ylocal   ;
00169 
00170   } else {
00171     Bfield[0] = 0.0;
00172     Bfield[1] = 0.0;
00173     Bfield[2] = 0.0;
00174   }
00175 }
00176 

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7