00001
00002 #include <iostream>
00003
00004 #include "BDSGlobalConstants.hh"
00005 #include "BDS3DMagField.hh"
00006
00007 BDS3DMagField::BDS3DMagField( const char* filename, double zOffset )
00008 :fZoffset(zOffset),invertX(false),invertY(false),invertZ(false)
00009 {
00010 fZoffset = -250*cm;
00011 zOffset = -250*cm;
00012 double lenUnit= m;
00013 double fieldUnit= tesla;
00014 G4cout << "\n-----------------------------------------------------------"
00015 << "\n Magnetic field"
00016 << "\n-----------------------------------------------------------";
00017
00018 G4cout << "\n ---> " "Reading the field grid from " << filename << " ... " << G4endl;
00019 std::ifstream file( filename );
00020
00021
00022 char buffer[256];
00023 file.getline(buffer,256);
00024
00025
00026 file >> nx >> ny >> nz;
00027
00028 G4cout << " [ Number of values x,y,z: "
00029 << nx << " " << ny << " " << nz << " ] "
00030 << G4endl;
00031
00032
00033 xField.resize( nx );
00034 yField.resize( nx );
00035 zField.resize( nx );
00036 int ix, iy, iz;
00037 for (ix=0; ix<nx; ix++) {
00038 xField[ix].resize(ny);
00039 yField[ix].resize(ny);
00040 zField[ix].resize(ny);
00041 for (iy=0; iy<ny; iy++) {
00042 xField[ix][iy].resize(nz);
00043 yField[ix][iy].resize(nz);
00044 zField[ix][iy].resize(nz);
00045 }
00046 }
00047
00048
00049
00050
00051 do {
00052 file.getline(buffer,256);
00053 } while ( buffer[1]!='0');
00054
00055
00056 double xval,yval,zval,bx,by,bz;
00057
00058 for (ix=0; ix<nx; ix++) {
00059 for (iy=0; iy<ny; iy++) {
00060 for (iz=0; iz<nz; iz++) {
00061 file >> xval >> yval >> zval >> bx >> by >> bz;
00062 if ( ix==0 && iy==0 && iz==0 ) {
00063 minx = xval * lenUnit;
00064 miny = yval * lenUnit;
00065 minz = zval * lenUnit;
00066 }
00067 xField[ix][iy][iz] = bx * fieldUnit;
00068 yField[ix][iy][iz] = by * fieldUnit;
00069 zField[ix][iy][iz] = bz * fieldUnit;
00070 }
00071 }
00072 }
00073 file.close();
00074
00075 maxx = xval * lenUnit;
00076 maxy = yval * lenUnit;
00077 maxz = zval * lenUnit;
00078
00079 G4cout << "\n ---> ... done reading " << G4endl;
00080
00081
00082 G4cout << " ---> assumed the order: x, y, z, Bx, By, Bz "
00083 << "\n ---> Min values x,y,z: "
00084 << minx/cm << " " << miny/cm << " " << minz/cm << " cm "
00085 << "\n ---> Max values x,y,z: "
00086 << maxx/cm << " " << maxy/cm << " " << maxz/cm << " cm "
00087 << "\n ---> The field will be offset by " << zOffset/cm << " cm " << G4endl;
00088
00089
00090 if (maxx < minx) {std::swap(maxx,minx); invertX = true;}
00091 if (maxy < miny) {std::swap(maxy,miny); invertY = true;}
00092 if (maxz < minz) {std::swap(maxz,minz); invertZ = true;}
00093 G4cout << "\nAfter reordering if neccesary"
00094 << "\n ---> Min values x,y,z: "
00095 << minx/cm << " " << miny/cm << " " << minz/cm << " cm "
00096 << " \n ---> Max values x,y,z: "
00097 << maxx/cm << " " << maxy/cm << " " << maxz/cm << " cm ";
00098
00099 dx = maxx - minx;
00100 dy = maxy - miny;
00101 dz = maxz - minz;
00102 G4cout << "\n ---> Dif values x,y,z (range): "
00103 << dx/cm << " " << dy/cm << " " << dz/cm << " cm in z "
00104 << "\n-----------------------------------------------------------" << G4endl;
00105 }
00106
00107 void BDS3DMagField::GetFieldValue(const double point[4],
00108 double *Bfield ) const
00109 {
00110
00111 double x = point[0];
00112 double y = point[1];
00113 double z = point[2] + fZoffset;
00114
00115 double signy=1;
00116 double signz=1;
00117
00118
00119 if( x < 0 ){
00120 #ifdef DEBUG
00121 G4cout << "x = " << x << ". Mirroring in x=0 plane." << G4endl;
00122 #endif
00123 x *= -1;
00124 signy = -1;
00125 signz = -1;
00126 }
00127
00128 if( z <0 ){
00129 #ifdef DEBUG
00130 G4cout << "z = " << z << ". Mirroring in z=0 plane." << G4endl;
00131 #endif
00132 z *= -1;
00133 signz = -1;
00134 }
00135
00136
00137 if ( x>=minx && x<=maxx &&
00138 y>=miny && y<=maxy &&
00139 z>=minz && z<=maxz ) {
00140
00141
00142
00143 double xfraction = (x - minx) / dx;
00144 double yfraction = (y - miny) / dy;
00145 double zfraction = (z - minz) / dz;
00146
00147 if (invertX) { xfraction = 1 - xfraction;}
00148 if (invertY) { yfraction = 1 - yfraction;}
00149 if (invertZ) { zfraction = 1 - zfraction;}
00150
00151
00152
00153 double xdindex, ydindex, zdindex;
00154
00155
00156
00157 double xlocal = ( std::modf(xfraction*(nx-1), &xdindex));
00158 double ylocal = ( std::modf(yfraction*(ny-1), &ydindex));
00159 double zlocal = ( std::modf(zfraction*(nz-1), &zdindex));
00160
00161
00162
00163 int xindex = static_cast<int>(xdindex);
00164 int yindex = static_cast<int>(ydindex);
00165 int zindex = static_cast<int>(zdindex);
00166
00167
00168 #ifdef DEBUG_INTERPOLATING_FIELD
00169 G4cout << "Local x,y,z: " << xlocal << " " << ylocal << " " << zlocal << G4endl;
00170 G4cout << "Index x,y,z: " << xindex << " " << yindex << " " << zindex << G4endl;
00171 double valx0z0, mulx0z0, valx1z0, mulx1z0;
00172 double valx0z1, mulx0z1, valx1z1, mulx1z1;
00173
00174
00175
00176
00177 #endif
00178
00179
00180 Bfield[0] =
00181 xField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
00182 xField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
00183 xField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
00184 xField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
00185 xField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
00186 xField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
00187 xField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
00188 xField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
00189 Bfield[1] = signy *(
00190 yField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
00191 yField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
00192 yField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
00193 yField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
00194 yField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
00195 yField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
00196 yField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
00197 yField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal );
00198 Bfield[2] = signz *(
00199 zField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
00200 zField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
00201 zField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
00202 zField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
00203 zField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
00204 zField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
00205 zField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
00206 zField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal );
00207
00208 } else {
00209 Bfield[0] = 0.0;
00210 Bfield[1] = 0.0;
00211 Bfield[2] = 0.0;
00212 }
00213 }
00214