// Geant4 simulation for MuSR // AUTHOR: Toni SHIROKA, Paul Scherrer Institut, PSI // DATE : 2008-05 // #include "lem4TabulatedField3D.hh" lem4TabulatedField3D* lem4TabulatedField3D::pointerToTabulatedField3D=NULL; lem4TabulatedField3D* lem4TabulatedField3D::GetInstance() { return pointerToTabulatedField3D; } lem4TabulatedField3D::lem4TabulatedField3D( const char* filename, double fieldValue ) :ffieldValue(fieldValue),invertX(false),invertY(false),invertZ(false) { pointerToTabulatedField3D=this; double lenUnit= meter; // double fieldUnit= tesla; G4cout << "\n-----------------------------------------------------------" << "\n Magnetic field" << "\n-----------------------------------------------------------" << endl; G4cout << " tesla="< " "Reading the field grid from " << filename << " ... " << G4endl; ifstream file( filename ); // Open the file for reading. // Ignore first blank line char buffer[256]; file.getline(buffer,256); // Read table dimensions file >> nx >> ny >> nz; // Note dodgy order G4cout << " [ Number of values x,y,z: " << nx << " " << ny << " " << nz << " ] " << endl; // Set up storage space for table xField.resize( nx ); yField.resize( nx ); zField.resize( nx ); int ix, iy, iz; for (ix=0; ix> xval >> yval >> zval >> bx >> by >> bz >> permeability; if ( ix==0 && iy==0 && iz==0 ) { minx = xval * lenUnit; miny = yval * lenUnit; minz = zval * lenUnit; } //xField[ix][iy][iz] = bx * fieldUnit * fieldValue; //yField[ix][iy][iz] = by * fieldUnit * fieldValue; //zField[ix][iy][iz] = bz * fieldUnit * fieldValue; // xField[ix][iy][iz] = bx * fieldValue; // yField[ix][iy][iz] = by * fieldValue; // zField[ix][iy][iz] = bz * fieldValue; xField[ix][iy][iz] = bx; yField[ix][iy][iz] = by; zField[ix][iy][iz] = bz; } } } file.close(); maxx = xval * lenUnit; maxy = yval * lenUnit; maxz = zval * lenUnit; G4cout << "\n ---> ... done reading " << endl; // G4cout << " Read values of field from file " << filename << endl; G4cout << " ---> assumed the order: x, y, z, Bx, By, Bz " << "\n ---> Min values x,y,z: " << minx/cm << " " << miny/cm << " " << minz/cm << " cm " << "\n ---> Max values x,y,z: " << maxx/cm << " " << maxy/cm << " " << maxz/cm << " cm " << endl; // Should really check that the limits are not the wrong way around. if (maxx < minx) {swap(maxx,minx); invertX = true;} if (maxy < miny) {swap(maxy,miny); invertY = true;} if (maxz < minz) {swap(maxz,minz); invertZ = true;} G4cout << "\nAfter reordering if neccesary" << "\n ---> Min values x,y,z: " << minx/cm << " " << miny/cm << " " << minz/cm << " cm " << " \n ---> Max values x,y,z: " << maxx/cm << " " << maxy/cm << " " << maxz/cm << " cm "; dx = maxx - minx; dy = maxy - miny; dz = maxz - minz; G4cout << "\n ---> Dif values x,y,z (range): " << dx/cm << " " << dy/cm << " " << dz/cm << " cm in z " << "\n-----------------------------------------------------------" << endl; } void lem4TabulatedField3D::GetFieldValue(const double point[4], double *Bfield ) const { Bfield[0]=0.; Bfield[1]=0.; Bfield[2]=0.; double x = point[0]+positionOffset[0]; double y = point[1]+positionOffset[1]; double z = point[2]+positionOffset[2]; // Check that the point is within the defined region if ( x>minx && xminy && yminz && z(xdindex); int yindex = static_cast(ydindex); int zindex = static_cast(zdindex); //cks The following check is necessary - even though xindex and zindex should never be out of range, // it may happen (due to some rounding error ?). It is better to leave the check here. if ((xindex<0)||(xindex>(nx-2))) { std::cout<<"SERIOUS PROBLEM: xindex out of range! xindex="<-1*cm)&&(point[2]<1*cm)) { // G4cout<<"Field at point ("<