#include "lem4Axial2DElField.hh" #include "G4UnitsTable.hh" //#include "lem4Parameters.hh" lem4Axial2DElField::lem4Axial2DElField(const char* filename, G4double fieldValue, G4double lenUnit, G4double fieldNormalisation, G4LogicalVolume* logVolume, G4ThreeVector positionOfTheCenter) : F04ElementField(positionOfTheCenter, logVolume), ffieldValue(fieldValue) //lem4Axial2DElField::lem4Axial2DElField(const G4String filename, double fieldValue, double lenUnit, double fieldNormalisation, double offset) : ffieldValue(fieldValue/1000.0), zOffset(offset), invertR(false), invertZ(false) { // double lenUnit = decimeter; = 100 // Base unit mm // double fieldUnit = kV; = 0.001 // Base unit MV // double fieldNorm = 0.00001 = 1E-5 // = 0.001/100 G4cout << "\n-----------------------------------------------------------" << "\n Electric field" << "\n-----------------------------------------------------------" << G4endl; // G4cout << " kilovolt = "<< kilovolt << G4endl; // = 1e-3 MV - default G4 unit ///G4cout << "\n Potential set to "<< fieldValue/1000.0/kilovolt << " kV"<< G4endl; G4cout << "\n Potential set to "<< fieldValue/kilovolt << " kV"<< G4endl; G4cout << "\n ---> " "Reading 2D E-field map from " << filename << " ... " << G4endl; std::ifstream file(filename); // Open the file for reading // Start reading file content char buffer[256]; // Read table dimensions first file >> nr >> nz; // r - radial, z - longitudinal coordinate G4cout << " 2D field table dimensions (r-z): [" << nr << ", " << nz << "] " << G4endl; // Set up storage space for table rField.resize(nr); zField.resize(nr); int ir, iz; for (ir = 0; ir < nr; ir++) { rField[ir].resize(nz); zField[ir].resize(nz); } // Ignore header information. All lines whose first character // is '%' are considered to be part of the header. do { file.getline(buffer, 256); } while (buffer[0] != '%'); // Read in the data: [r, z, Er, Ez] double rval, zval, er, ez; for (ir = 0; ir < nr; ir++) { for (iz = 0; iz < nz; iz++) { file >> rval >> zval >> er >> ez; if (ir == 0 && iz == 0) { minr = rval * lenUnit; minz = zval * lenUnit; } rField[ir][iz] = er*fieldNormalisation; zField[ir][iz] = ez*fieldNormalisation; } } G4cout << " Normalisation coeff.: " << fieldNormalisation << G4endl; file.close(); maxr = rval * lenUnit; maxz = zval * lenUnit; G4cout << "\n ---> ... done reading (assumed order: r, z, Er, Ez)." << G4endl; G4cout << "\n ---> Min values r, z: " << minr/cm << " " << minz/cm << " cm " << "\n ---> Max values r, z: " << maxr/cm << " " << maxz/cm << " cm " << G4endl; // Should really check that the limits are not the wrong way around. if (maxr < minr) {Invert("x");} ///{std::swap(maxr, minr); invertR = true;} if (maxz < minz) {Invert("z");} ///{std::swap(maxz, minz); invertZ = true;} if (maxr < minr || maxz < minz){ ///(invertR == true || invertZ == true){ G4cout << "\n After reordering:" << "\n ---> Min values r, z: " << minr/cm << " " << minz/cm << " cm " << "\n ---> Max values r, z: " << maxr/cm << " " << maxz/cm << " cm " << G4endl; } dr = maxr - minr; dz = maxz - minz; G4cout << " ---> Range of values: " << dr/cm << " cm (in r) and " << dz/cm << " cm (in z)." << "\n-----------------------------------------------------------\n" << G4endl; } ///lem4Axial2DElField::~lem4Axial2DElField() /// Made virtual! ///{ /// delete [] &rField ; /// delete [] &zField ; ///} void lem4Axial2DElField::addFieldValue(const G4double point[4], G4double *field) const { G4double B[3]; // Field value obtained from the field table ///TS ///G4cout<<"TTfileTT Global coord. ("<GetName()<0) ? 1.:-1.; // Check that the point is within the defined region if ( r < maxr && z < maxz ) { // Relative point position within region, normalized to [0,1]. double rfraction = (r - minr) / dr; double zfraction = (z - minz) / dz; // Need addresses of these to pass to modf below. // modf uses its second argument as an OUTPUT argument. double rdindex, zdindex; // Position of the point within the cuboid defined by the // nearest surrounding tabulated points double rlocal = ( modf(rfraction*(nr-1), &rdindex)); double zlocal = ( modf(zfraction*(nz-1), &zdindex)); // The indices of the nearest tabulated point whose coordinates // are all less than those of the given point int rindex = static_cast(rdindex); 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 ((rindex<0)||(rindex>(nr-2))) { std::cout<<"SERIOUS PROBLEM: rindex out of range! rindex="<GetLatestEventNr(); // G4int evNrKriz=6795; //457; //14250 // if (evNr==evNrKriz) { // std::cout<<"evNr="<0) ? 1.:-1.; //if (evNr==evNrKriz) std::cout<<"r ="<evNrKriz) std::cout<<"bol som tu"<(rdindex); 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 ((rindex<0)||(rindex>(nr-2))) { std::cout<<"SERIOUS PROBLEM: rindex out of range! rindex="<0) ? Efield_R * (point[0]/r) : 0.; Efield[1] = (r>0) ? Efield_R * (point[1]/r) : 0.; Efield[2] = zField[rindex ][zindex ] * (1-rlocal) * (1-zlocal) + zField[rindex ][zindex+1] * (1-rlocal) * zlocal + zField[rindex+1][zindex ] * rlocal * (1-zlocal) + zField[rindex+1][zindex+1] * rlocal * zlocal ; // ATTENTION if dealing with MAGNETIC FIELDS reverse x, y and z signs!! Efield[0] = Efield[0] * ffieldValue; // * z_sign; Efield[1] = Efield[1] * ffieldValue; // * z_sign; Efield[2] = Efield[2] * ffieldValue * z_sign; } // Set some small field if field is almost zero (to avoid internal problems of Geant). if (sqrt(Efield[0]*Efield[0]+Efield[1]*Efield[1]+Efield[2]*Efield[2])<1.0E-12*volt) { // if (evNr>evNrKriz) std::cout<<"bol som tuna"<-1*cm)&&(point[2]<1*cm)) { // printf ("for point= %f %f %f B= %10.10f %10.10f %10.10f \n", // point[0],point[1],point[2],Bfield[0]/tesla,Bfield[1]/tesla,Bfield[2]/tesla); // } // if (evNr>evNrKriz) std::cout<<"this is the end"< > rFieldTemp(rField); std::vector< std::vector< double > > zFieldTemp(zField); G4bool invertR=false; G4bool invertZ=false; G4cout<<"Check that the lem4Axial2DElField::Invert() function works properly!"<