#include <BLCoil.hh>
A BLCoil consists only of the parameters describing the coil geometry and a field map for unit current density. It is not a BLElement, and cannot be placed geometrically -- see BLSolenoid for that.
Cylindrical symmetry around z is assumed. The field is approximated by computing the field from nSheets infinitesimally-thin current sheets interpolating from innerRadius to OuterRadius, each length long. The solution to Maxwell's Equations for each sheet is used.
The field has been verified to be correct within 0.2% for both a long solenoid and for a pair of Helmholtz coils.
Effect of nSheets on accuracy: consider the coil innerRadius=330.0*mm, outerRadius=505.0*mm, length=167.0*mm. Compute the maximum error for 1000 random points, excluding the region within 2 cm of the coils; use 99 sheets as the "correct" value. In the region 0<=r<2*outerRadius, 0<z<10*outerRadius, for 0.1% accuracy one needs 11 sheets, and for 1% one needs 4 sheets. In the region 0<=r<innerRadius/2, same z, for 0.1% accuracy one needs 5 sheets, and for 1% one needs 2 sheets. Note that inside the coils this approximation of using thin sheets is not very good; but interpolating on a grid and coordinating sheet positions with the grid is probably about as good as one can do -- at least the values will be smooth (which is not true for the bare computation -- there's a singularity at every sheet, and Bz jumps from +infinity to -infinity across the sheet).
Note that Bz does not decrease to 0.1% of its central value until z>10*(innerRadius+outerRadius)/2; it decreases to 1% at ~5 times that average radius.
BLCoil can also read a mapFile defining the field (rather than doing the above computation). For instance, it could be from opera-2d. The mapFile gives tables of Bz and Br on a grid in the z-r plane. mapFile format: lines beginning with # are comments, and are ignored. The first line contains the parameters in name=value form: z0 initial value of z (mm) dz grid interval along z (mm) nz number of grid points along z dr grid interval along r (mm) nr number of grid points along r reflectZ set nonzero to reflect in the z=0 plane (inverting Br) current the current for this field (A/mm^2) All parameters are required. If reflectZ is nonzero then z0 must be 0.0 (only z>=0 is contained in the file). The point with local coordinates (z=0,r=0) is what gets placed.
Then follow the two maps in any order. Each map begins with a line giving its name (Bz or Br) in column 1, followed by nz lines each containing nr floats (Tesla). The first value in each line is for r=0. Values are separated by one or more spaces (the first value on each line may but need not be preceeded by spaces). The main reason to use a mapFile is to accurately include the effects of iron. That implies that the map may not be accurate for values of current other than that for which the map was generated.
See BLCMDfieldmap for a more general EM field read from a map-file.
BLCoil was separated from BLSolenoid so multiple solenoids with the same geometry (coil) could share a single (large) field map for the coil -- the B field is scaled by current/currentOfMap, where currentOfMap is 1.0 for the computed field, and is the current parameter from a mapFile.
This class does not use BLFieldMap becuase it predates it, and because the map must include the parameters so construct() will know whether or not the map corresponds to the current values. You can, of course, build a solenoid out of a BLTubs and a BLFieldMap.
Public Member Functions | |
BLCoil () | |
Default constructor. | |
BLCoil (G4String _name, G4double _innerRadius, G4double _outerRadius, G4double _length, G4int _nSheets=0, G4double _tolerance=0.0, G4double _maxR=0.0, G4double _maxZ=0.0, G4double _dR=0.0, G4double _dZ=0.0, G4int _nR=0, G4int _nZ=0, G4String _filename="") | |
Complex Constructor. All arguments that default to 0 are related to generating the field map; those that are 0 will be determined by tolerance. To construct the map the minimum info is tolerance and maxR; if either of them is 0, no map will be generated or used. NOTE: without a map, field values inside the coils will fluctuate wildly, because points on the sheets are singular; map construction is designed to minimize this. Without a map, nSheets must be given. tolerance is a fraction of the best value at r=0,z=0; values smaller than about 0.001 are unrealistic (and expensive!). | |
virtual | ~BLCoil () |
Destructor. | |
BLCoil (const BLCoil &r) | |
Copy constructor. | |
void | printCoil () |
printCoil() will print a description | |
void | addField (const G4double point[4], G4double field[6], G4double currentAmpPerMm2) const |
addField() adds the field value for the given point[] into field[]. Note that point[] is relative to the center of the coil. Units for current are Amp/mm^2. | |
void | generateFieldMap () |
generateFieldMap() will generate the field map (for execution speedup). If just maxR and tolerance were given, all other map parameters will be automatically determined so that the estimated error is less than the specified tolerance. The field map is cached in a disk file which is automatically recreated if anything changes (may take several minutes). | |
void | readMapFile () |
readMapFile() will read the mapFile. | |
void | displayMapValues (G4double r, G4double z) |
displayMapValues() will display the 4 map values around a point. | |
Static Public Member Functions | |
static BLCoil * | find (G4String name) |
find() returns a pointer to the named BLCoil. | |
Private Member Functions | |
void | getUnitField (G4double r, G4double z, G4double &Br, G4double &Bz) |
getUnitField() will return Br and Bz for unit current. | |
void | determineMaxR () |
determineMaxR() will determine maxR based on tolerance. Uses nSheets=99 to determine center field, and walks out far enough so (Bz/Bz0)<0.5*tolerance. | |
void | determineMaxZ () |
determineMaxZ() will determine maxZ based on tolerance. Uses nSheets=99 to determine on-axis field, and walks out far enough so (Bz/Bz0)<0.5*tolerance. | |
void | determineNsheets () |
determineNsheets() will determine nSheets, given maxZ and tolerance. Increases nSheets until maxError < tolerance/4 (the other 3/4 of tolerance is for mapping errors). Checks just a handful of points selected to be representative. | |
G4double | estimateMapError () |
estimateMapError() will estimate the maximum error in mapping, given maxZ, nSheets, dR, dZ, nR, nZ, and an allocated but uninitialized fieldMap. It generates 1000 random points and returns the maximum error; quits early if tolerance is exceeded. Error is (currentMap - best)/best(r=0,z=0), where best is computed with no map and nSheets=99. For each point it generates the 4 surrounding values of fieldMap (this is faster than generating the entire map first). Returns the maximum error of either Bz or Br, normalized to Bz(r=0,z=0,nSheets=99). | |
G4double | computeError (G4double r, G4double z, BLCoil &best, G4bool makeMap) |
computeError() computes the error for a single point. Error is (currentMap - best)/best(r=0,z=0), where best should be an identical BLCoil with no map and nSheets=99. If makeMap is true, it generates the 4 surrounding values of the fieldMap. | |
void | getSheetField (G4double r, G4double z, G4double &Br, G4double &Bz, G4double sheetR, G4double sheetLen, G4double currentAmpPerMm) const |
getSheetField() returns the B field from an infinitesimally-thin sheet of current. Arguments: r and z are the cylindrical coordinates of the point in question relative to center of the coil (axis along z), mm. Br and Bz return the computed B field at that point (geant4 units) sheetR is the radius of the current sheet (mm) sheetLen is the length of the current sheet (mm) currentAmpPerMm is the current of the sheet (Amp per linear mm) | |
Private Attributes | |
G4String | name |
G4double | innerRadius |
G4double | outerRadius |
G4double | length |
G4int | nSheets |
G4String | material |
G4double | tolerance |
G4double | maxR |
G4double | minZ |
G4double | maxZ |
G4double | dR |
G4double | dZ |
G4int | nR |
G4int | nZ |
G4String | filename |
G4String | mapFile |
G4int | exactComputation |
float * | mapBr |
float * | mapBz |
G4double | sheetR0 |
G4double | sheetDR |
G4double | norm |
G4bool | goodMap |
G4bool | reflectZ |
G4double | currentOfMap |
Static Private Attributes | |
static std::map< G4String, BLCoil * > | mapCoil |
Friends | |
class | BLCMDcoil |
class | BLCMDsolenoid |
class | SolenoidField |
BLCoil::BLCoil | ( | ) |
Default constructor.
References currentOfMap, dR, dZ, exactComputation, filename, goodMap, innerRadius, length, mapBr, mapBz, mapFile, material, maxR, maxZ, minZ, name, norm, nR, nSheets, nZ, outerRadius, reflectZ, sheetDR, sheetR0, and tolerance.
00034 { 00035 // provide initial values for fields 00036 name = ""; 00037 innerRadius = 0.0; 00038 outerRadius = 0.0; 00039 length = 0.0; 00040 nSheets = 0; 00041 material = "Cu"; 00042 tolerance = 0.002; 00043 maxR = 0.0; 00044 minZ = 0.0; 00045 maxZ = 0.0; 00046 dR = 0.0; 00047 dZ = 0.0; 00048 nR = 0; 00049 nZ = 0; 00050 filename = ""; 00051 exactComputation = 0; 00052 mapFile = ""; 00053 mapBr = 0; 00054 mapBz = 0; 00055 sheetR0 = 0.0; 00056 sheetDR = 0.0; 00057 norm = 0.0; 00058 goodMap = false; 00059 reflectZ = true; 00060 currentOfMap = 1.0; 00061 }
BLCoil::BLCoil | ( | G4String | _name, | |
G4double | _innerRadius, | |||
G4double | _outerRadius, | |||
G4double | _length, | |||
G4int | _nSheets = 0 , |
|||
G4double | _tolerance = 0.0 , |
|||
G4double | _maxR = 0.0 , |
|||
G4double | _maxZ = 0.0 , |
|||
G4double | _dR = 0.0 , |
|||
G4double | _dZ = 0.0 , |
|||
G4int | _nR = 0 , |
|||
G4int | _nZ = 0 , |
|||
G4String | _filename = "" | |||
) | [inline] |
Complex Constructor. All arguments that default to 0 are related to generating the field map; those that are 0 will be determined by tolerance. To construct the map the minimum info is tolerance and maxR; if either of them is 0, no map will be generated or used. NOTE: without a map, field values inside the coils will fluctuate wildly, because points on the sheets are singular; map construction is designed to minimize this. Without a map, nSheets must be given. tolerance is a fraction of the best value at r=0,z=0; values smaller than about 0.001 are unrealistic (and expensive!).
References dR, dZ, exactComputation, filename, goodMap, innerRadius, length, mapBr, mapBz, maxR, maxZ, name, norm, nR, nSheets, nZ, outerRadius, sheetDR, sheetR0, and tolerance.
00153 { 00154 name=_name; innerRadius=_innerRadius; 00155 outerRadius=_outerRadius; length=_length; 00156 nSheets=_nSheets; tolerance=_tolerance; maxR=_maxR; 00157 maxZ=_maxZ; dR=_dR; dZ=_dZ; nR=_nR; nZ=_nZ; 00158 filename = _filename; 00159 exactComputation = 0; 00160 mapBr=0; mapBz=0; sheetR0=0.0; sheetDR=0.0; norm=0.0; 00161 goodMap=false; 00162 if(nSheets > 0) { 00163 sheetDR=(outerRadius-innerRadius)/nSheets; 00164 sheetR0=innerRadius + sheetDR/2.0; 00165 } 00166 if(filename == "") filename = name + ".dat"; 00167 }
BLCoil::~BLCoil | ( | ) | [virtual] |
BLCoil::BLCoil | ( | const BLCoil & | r | ) |
Copy constructor.
References currentOfMap, dR, dZ, exactComputation, filename, goodMap, innerRadius, length, mapBr, mapBz, mapFile, material, maxR, maxZ, minZ, name, norm, nR, nSheets, nZ, outerRadius, reflectZ, sheetDR, sheetR0, and tolerance.
00072 { 00073 name = ""; 00074 innerRadius = r.innerRadius; 00075 outerRadius = r.outerRadius; 00076 length = r.length; 00077 nSheets = r.nSheets; 00078 material = r.material; 00079 tolerance = r.tolerance; 00080 maxR = r.maxR; 00081 minZ = r.minZ; 00082 maxZ = r.maxZ; 00083 dR = r.dR; 00084 dZ = r.dZ; 00085 nR = r.nR; 00086 nZ = r.nZ; 00087 filename = r.filename; 00088 exactComputation = r.exactComputation; 00089 mapFile = r.mapFile; 00090 mapBr = 0; 00091 mapBz = 0; 00092 sheetR0 = r.sheetR0; 00093 sheetDR = r.sheetDR; 00094 norm = 0.0; 00095 goodMap = false; 00096 reflectZ = r.reflectZ; 00097 currentOfMap = r.currentOfMap; 00098 }
void BLCoil::printCoil | ( | ) |
printCoil() will print a description
References dR, dZ, filename, innerRadius, length, mapFile, material, maxR, maxZ, name, nSheets, outerRadius, and tolerance.
Referenced by BLCMDcoil::command().
00101 { 00102 printf("coil %-7s ",name.c_str()); 00103 printf("innerRadius=%.1f ",innerRadius); 00104 printf("outerRadius=%.1f ",outerRadius); 00105 printf("length=%.1f ",length); 00106 printf("material=%s ",material.c_str()); 00107 printf("\n\t\t"); 00108 if(mapFile == "") { 00109 printf("tolerance=%.3f ",tolerance); 00110 printf("nSheets=%d ",nSheets); 00111 printf("\n\t\t"); 00112 printf("maxR=%.1f ",maxR); 00113 printf("maxZ=%.1f ",maxZ); 00114 printf("dR=%.1f ",dR); 00115 printf("dZ=%.1f ",dZ); 00116 printf("filename=%s ",filename.c_str()); 00117 printf("\n"); 00118 } else { 00119 printf("mapFile=%s\n",mapFile.c_str()); 00120 } 00121 }
BLCoil * BLCoil::find | ( | G4String | name | ) | [static] |
void BLCoil::addField | ( | const G4double | point[4], | |
G4double | field[6], | |||
G4double | currentAmpPerMm2 | |||
) | const |
addField() adds the field value for the given point[] into field[]. Note that point[] is relative to the center of the coil. Units for current are Amp/mm^2.
References BLAssert, currentOfMap, dR, dZ, exactComputation, getSheetField(), goodMap, innerRadius, length, mapBr, mapBz, maxR, maxZ, minZ, name, nR, nSheets, nZ, outerRadius, reflectZ, sheetDR, and sheetR0.
Referenced by SolenoidField::addFieldValue(), and getUnitField().
00132 { 00133 G4double z = point[2]; 00134 G4double r = sqrt(point[0]*point[0] + point[1]*point[1]); 00135 00136 if(goodMap && exactComputation == 0) { 00137 BLAssert(mapBr != 0 && mapBz != 0 && dR > 0.0 && dZ > 0.0); 00138 BLAssert(nR > 0 && nZ > 0); 00139 if(z < minZ+0.002*mm || z > maxZ-0.002*mm || r > maxR-0.002*mm) 00140 return; 00141 G4double sign = 1.0; 00142 if(reflectZ) { 00143 // map covers only z >= 0 00144 if(z < 0.0) { 00145 sign = -sign; 00146 z = -z; 00147 } 00148 } else { 00149 z -= minZ; 00150 } 00151 // 2-d linear average of the 4 surrounding points 00152 int i = (int)(r/dR); 00153 int j = (int)(z/dZ); 00154 if(i >= 0 && i < nR-1 && j >= 0 && j < nZ-1) { 00155 ; 00156 } else { 00157 printf("\ni=%d j=%d nR=%d nZ=%d r=%.3f z=%.3f dR=%.3f dZ=%.3f\n",i,j,nR,nZ,r,z,dR,dZ); 00158 printf("z=%.6f maxZ=%.6f r=%.6f maxR=%.5f\n",z,maxZ,r,maxR); 00159 fflush(stdout); 00160 } 00161 BLAssert(i >= 0 && i < nR-1 && j >= 0 && j < nZ-1); 00162 float fr = 1.0 - (r - i*dR) / dR; 00163 BLAssert(fr >= 0.0 && fr <= 1.0); 00164 float fz = 1.0 - (z - j*dZ) / dZ; 00165 BLAssert(fz >= 0.0 && fz <= 1.0); 00166 00167 G4double Bz = mapBz[j*nR+i]*fr*fz + 00168 mapBz[j*nR+i+1]*(1.0-fr)*fz + 00169 mapBz[(j+1)*nR+i]*fr*(1.0-fz) + 00170 mapBz[(j+1)*nR+i+1]*(1.0-fr)*(1.0-fz); 00171 G4double Br = mapBr[j*nR+i]*fr*fz + 00172 mapBr[j*nR+i+1]*(1.0-fr)*fz + 00173 mapBr[(j+1)*nR+i]*fr*(1.0-fz) + 00174 mapBr[(j+1)*nR+i+1]*(1.0-fr)*(1.0-fz); 00175 G4double phi = atan2(point[1], point[0]); 00176 currentAmpPerMm2 /= currentOfMap; 00177 field[0] += sign * currentAmpPerMm2 * Br * cos(phi); 00178 field[1] += sign * currentAmpPerMm2 * Br * sin(phi); 00179 field[2] += currentAmpPerMm2 * Bz; 00180 return; 00181 } 00182 00183 // Computation for no map 00184 if(nSheets > 0 && sheetDR > 0.0 && sheetR0 > 0.0); else printf("%s: nSheets=%d sheetR0=%.3f sheetDR=%.3f innerRadius=%.3f outerRadius=%.3f length=%.3f\n",name.c_str(),nSheets,sheetR0,sheetDR,innerRadius,outerRadius,length); 00185 BLAssert(nSheets > 0 && sheetDR > 0.0 && sheetR0 > 0.0); 00186 G4double Br=0.0, Bz=0.0; 00187 G4double rSheet = sheetR0; 00188 G4double currentAmpPerMm = currentAmpPerMm2 * sheetDR; 00189 for(int i=0; i<nSheets; ++i) { 00190 G4double br, bz; 00191 // avoid singularity when r==rSheet 00192 if(fabs(r-rSheet) < sheetDR/8.0) { 00193 getSheetField(r+sheetDR/4.0,z,br,bz,rSheet,length, 00194 currentAmpPerMm); 00195 G4double br1, bz1; 00196 getSheetField(r-sheetDR/4.0,z,br1,bz1,rSheet,length, 00197 currentAmpPerMm); 00198 br = (br+br1)/2.0; 00199 bz = (bz+bz1)/2.0; 00200 } else { 00201 getSheetField(r,z,br,bz,rSheet,length,currentAmpPerMm); 00202 } 00203 Br += br; 00204 Bz += bz; 00205 rSheet += sheetDR; 00206 } 00207 G4double phi = atan2(point[1], point[0]); 00208 field[0] += Br * cos(phi); 00209 field[1] += Br * sin(phi); 00210 field[2] += Bz; 00211 }
void BLCoil::generateFieldMap | ( | ) |
generateFieldMap() will generate the field map (for execution speedup). If just maxR and tolerance were given, all other map parameters will be automatically determined so that the estimated error is less than the specified tolerance. The field map is cached in a disk file which is automatically recreated if anything changes (may take several minutes).
References BLAssert, currentOfMap, determineMaxR(), determineMaxZ(), determineNsheets(), dR, dZ, estimateMapError(), exactComputation, filename, getUnitField(), goodMap, innerRadius, length, mapBr, mapBz, mapFile, maxR, maxZ, minZ, name, norm, nR, nSheets, nZ, outerRadius, readMapFile(), reflectZ, sheetDR, sheetR0, BLTime::time(), and tolerance.
Referenced by BLCMDcoil::command().
00214 { 00215 if(exactComputation != 0) { 00216 minZ = -DBL_MAX; 00217 maxZ = DBL_MAX; 00218 maxR = DBL_MAX; 00219 if(nSheets <= 0) nSheets = 1; 00220 sheetDR = (outerRadius-innerRadius) / nSheets; 00221 sheetR0 = innerRadius + sheetDR/2.0; 00222 return; 00223 } 00224 00225 if(mapFile != "") { 00226 readMapFile(); 00227 return; 00228 } 00229 00230 struct FileHeader { 00231 long magic, nR, nZ, nSheets; 00232 double innerRadius, outerRadius, length, dR, dZ, error; 00233 // followed by nR*nZ float-s of mapBr 00234 // followed by nR*nZ float-s of mapBz 00235 }; 00236 // Had serious problems with files written on a different OS that 00237 // passed the check but generated gross tracking errors and/or 00238 // exceptions in malloc/free. Probably different compilers padding 00239 // FileHeader differently. 00240 #ifdef __linux 00241 const int MAGIC = 0x544A5232; // 'TJR2' 00242 #endif 00243 #ifdef WIN32 00244 const int MAGIC = 0x544A5235; // 'TJR5' 00245 #endif 00246 #ifdef __APPLE__ 00247 const int MAGIC = 0x544A5234; // 'TJR4' 00248 #endif 00249 #ifdef __CYGWIN__ 00250 const int MAGIC = 0x544A5235; // 'TJR5' 00251 #endif 00252 00253 printf("coilmap %-7s tolerance=%.5f [fraction of " 00254 "Bz(r=0,z=0)]\n",name.c_str(),tolerance); 00255 fflush(stdout); 00256 goodMap = false; 00257 00258 // read FileHeader from filename (if it exists), and check for 00259 // consistency with this coil 00260 #ifdef WIN32 00261 FILE *in = fopen(filename.c_str(),"rb"); 00262 #else 00263 FILE *in = fopen(filename.c_str(),"r"); 00264 #endif 00265 FileHeader fh; 00266 if(in) { 00267 if(fread(&fh,sizeof(fh),1,in) != 1) { 00268 printf("BLCoil::generateFieldMap Cannot read header\n"); 00269 if(in) fclose(in); 00270 in = 0; 00271 } 00272 if(fh.magic != MAGIC) { 00273 printf("BLCoil::generateFieldMap wrong magic\n"); 00274 if(in) fclose(in); 00275 in = 0; 00276 } 00277 if(fh.error > tolerance) { 00278 printf("BLCoil::generateFieldMap error > tolerance\n"); 00279 if(in) fclose(in); 00280 in = 0; 00281 } 00282 if(fabs(fh.innerRadius-innerRadius) > 0.001*mm) { 00283 printf("BLCoil::generateFieldMap wrong innerRadius\n"); 00284 if(in) fclose(in); 00285 in = 0; 00286 } 00287 if(fabs(fh.outerRadius-outerRadius) > 0.001*mm) { 00288 printf("BLCoil::generateFieldMap wrong outerRadius\n"); 00289 if(in) fclose(in); 00290 in = 0; 00291 } 00292 if(fabs(fh.length-length) > 0.001*mm) { 00293 printf("BLCoil::generateFieldMap wrong length\n"); 00294 if(in) fclose(in); 00295 in = 0; 00296 } 00297 if((dR > 0.001*mm && fabs(fh.dR-dR) > 0.001*mm)) { 00298 printf("BLCoil::generateFieldMap wrong dR\n"); 00299 if(in) fclose(in); 00300 in = 0; 00301 } 00302 if((dZ > 0.001*mm && fabs(fh.dZ-dZ) > 0.001*mm)) { 00303 printf("BLCoil::generateFieldMap wrong dZ\n"); 00304 if(in) fclose(in); 00305 in = 0; 00306 } 00307 if((fh.nR-1)*fh.dR < maxR || (fh.nZ-1)*fh.dZ < maxZ) { 00308 printf("BLCoil::generateFieldMap wrong maxR or maxZ\n"); 00309 if(in) fclose(in); 00310 in = 0; 00311 } 00312 } 00313 // setup data from file and read the maps from file 00314 if(in) { 00315 G4double orgMaxZ = maxZ; 00316 G4double orgMaxR = maxR; 00317 G4int orgNsheets = nSheets; 00318 nR = fh.nR; 00319 nZ = fh.nZ; 00320 dR = fh.dR; 00321 dZ = fh.dZ; 00322 nSheets = fh.nSheets; 00323 sheetDR=(outerRadius-innerRadius)/nSheets; 00324 sheetR0=innerRadius + sheetDR/2.0; 00325 norm = 0.0; 00326 maxR = (nR-1)*dR; 00327 maxZ = (nZ-1)*dZ; 00328 minZ = -maxZ; 00329 if(mapBr) delete[] mapBr; 00330 if(mapBz) delete[] mapBz; 00331 mapBr = new float[nZ*nR]; 00332 mapBz = new float[nZ*nR]; 00333 if(!mapBr || !mapBz) { 00334 G4Exception("coil","Out of memory",FatalException,""); 00335 } 00336 if(fread(mapBr,sizeof(float),nR*nZ,in) != (size_t)nR*nZ || 00337 fread(mapBz,sizeof(float),nR*nZ,in) != (size_t)nR*nZ) { 00338 fclose(in); 00339 in = 0; 00340 printf("BLCoil::generateFieldMap cannot read data\n"); 00341 // restore invalid data that came from file 00342 maxZ = orgMaxZ; 00343 minZ = -maxZ; 00344 reflectZ = true; 00345 maxR = orgMaxR; 00346 nSheets = orgNsheets; 00347 } 00348 } 00349 // if file is correct, use it. 00350 if(in) { 00351 fclose(in); 00352 in = 0; 00353 goodMap = true; 00354 printf("coilmap %-7s read file '%s' " 00355 "dR=%.1f dZ=%.1f\n",name.c_str(),filename.c_str(),dR,dZ); 00356 minZ = -maxZ; 00357 reflectZ = true; 00358 currentOfMap = 1.0; 00359 return; 00360 } 00361 00362 // file is not correct - generate map 00363 00364 if(maxR <= 0.0) 00365 determineMaxR(); 00366 if(maxZ <= 0.0) 00367 determineMaxZ(); 00368 if(nSheets <= 0) { 00369 determineNsheets(); 00370 } else { 00371 sheetDR = (outerRadius-innerRadius) / nSheets; 00372 sheetR0 = innerRadius + sheetDR/2.0; 00373 } 00374 00375 // initial estimate of dR,dZ,nR,nZ 00376 if(dR <= 0.0) 00377 dR = maxR/10; 00378 nR = (int)floor(maxR/dR) + 2; 00379 //@@ for now, assume dZ = dR.... 00380 if(dZ <= 0.0) 00381 dZ = dR; 00382 nZ = (int)floor(maxZ/dZ) + 2; 00383 00384 // loop until we achieve the required tolerance. Limit to 8 doublings. 00385 const int MAX_ITER=8; 00386 int iter; 00387 G4double err = 1.0; 00388 for(iter=0; iter<MAX_ITER; ++iter) { 00389 // for simplicity, discard all previous computations 00390 if(mapBr) delete[] mapBr; 00391 if(mapBz) delete[] mapBz; 00392 mapBr = new float[nZ*nR]; 00393 mapBz = new float[nZ*nR]; 00394 if(!mapBr || !mapBz) { 00395 G4Exception("coil","Out of memory",FatalException,""); 00396 } 00397 err = estimateMapError(); 00398 if(err < tolerance) 00399 break; 00400 dR /= 2.0; 00401 dZ /= 2.0; 00402 nR = (int)floor(maxR/dR) + 2; 00403 nZ = (int)floor(maxZ/dZ) + 2; 00404 } 00405 if(iter >= MAX_ITER) { 00406 G4Exception("coilmap","Failed to achieve required accuracy", 00407 FatalException, ""); 00408 } 00409 printf("coilmap %-7s nR=%d nZ=%d dR=%.1f dZ=%.1f " 00410 "error=%.6f\n",name.c_str(),nR,nZ,dR,dZ,err); 00411 00412 // fill the maps 00413 //@@ for simplicity, ignore all previous computations 00414 goodMap = false; 00415 time_t start = BLTime::time(); 00416 for(int i=0; i<nR; ++i) { 00417 G4double r = i * dR; 00418 for(int j=0; j<nZ; ++j) { 00419 G4double z = j * dZ; 00420 int k = j * nR + i; 00421 BLAssert( k >= 0 && k < nZ*nR); 00422 G4double Br,Bz; 00423 getUnitField(r,z,Br,Bz); 00424 mapBr[k] = Br; 00425 mapBz[k] = Bz; 00426 } 00427 // printf("coilmap %-7s %d%% %ld seconds\r", 00428 // name.c_str(),(100*(i+1))/nR,(long)(BLTime::time()-start)); 00429 // fflush(stdout); 00430 } 00431 printf("coilmap %-7s DONE %ld seconds\n", 00432 name.c_str(),(long)(BLTime::time()-start)); 00433 fflush(stdout); 00434 00435 // write the map 00436 if(filename != "") { 00437 #ifdef WIN32 00438 FILE *out = fopen(filename.c_str(),"wb"); 00439 #else 00440 FILE *out = fopen(filename.c_str(),"w"); 00441 #endif 00442 if(out) { 00443 FileHeader fh; 00444 fh.magic = MAGIC; 00445 fh.nR = nR; 00446 fh.nZ = nZ; 00447 fh.nSheets = nSheets; 00448 fh.innerRadius = innerRadius; 00449 fh.outerRadius = outerRadius; 00450 fh.length = length; 00451 fh.dR = dR; 00452 fh.dZ = dZ; 00453 fh.error = err; 00454 if(fwrite(&fh,sizeof(fh),1,out) != 1 || 00455 fwrite(mapBr,sizeof(float),nR*nZ,out) != (size_t)nR*nZ || 00456 fwrite(mapBz,sizeof(float),nR*nZ,out) != (size_t)nR*nZ) { 00457 printf("coilmap %-7s ERROR " 00458 "writing file '%s'\n", 00459 name.c_str(),filename.c_str()); 00460 } 00461 fclose(out); 00462 printf("coilmap %-7s wrote file '%s' %lu bytes\n", 00463 name.c_str(),filename.c_str(), 00464 (long)(sizeof(fh)+sizeof(float)*2*nR*nZ)); 00465 } 00466 } 00467 00468 goodMap = true; 00469 minZ = -maxZ; 00470 reflectZ = true; 00471 currentOfMap = 1.0; 00472 }
void BLCoil::readMapFile | ( | ) |
readMapFile() will read the mapFile.
References currentOfMap, dR, dZ, goodMap, mapBr, mapBz, mapFile, maxR, maxZ, minZ, nR, nZ, BLCommand::parseArgs(), BLCommand::printError(), and reflectZ.
Referenced by generateFieldMap().
00475 { 00476 FILE *in = fopen(mapFile.c_str(),"r"); 00477 if(!in) { 00478 BLCommand::printError("Cannot open mapFile '%s'\n",mapFile.c_str()); 00479 return; 00480 error: 00481 BLCommand::printError("Syntax error in mapFile '%s'\n",mapFile.c_str()); 00482 return; 00483 } 00484 00485 char line[512]; 00486 00487 // read first line (parameters of the map) 00488 // units are millimeters, Tesla, and Amperes/mm^2. 00489 do { 00490 if(!fgets(line,sizeof(line),in)) goto error; 00491 } while(line[0] == '#'); 00492 00493 BLArgumentVector argv; 00494 BLArgumentMap argm; 00495 if(BLCommand::parseArgs(line,argv,argm)) goto error; 00496 00497 // sample parameter line: 00498 // z0=0.0 dz=2.0 nz=1501 dr=5.0 nr=13 reflectZ=1 current=-101.1 00499 G4double z0 = atof(argm["z0"].c_str())*mm; 00500 dZ = atof(argm["dz"].c_str())*mm; 00501 nZ = atoi(argm["nz"].c_str()); 00502 dR = atof(argm["dr"].c_str())*mm; 00503 nR = atoi(argm["nr"].c_str()); 00504 reflectZ = (atoi(argm["reflectZ"].c_str()) != 0); 00505 currentOfMap = atof(argm["current"].c_str()); 00506 maxR = (nR-1)*dR; 00507 maxZ = z0 + (nZ-1)*dZ; 00508 if(reflectZ) { 00509 minZ = -maxZ; 00510 if(z0 != 0.0) goto error; 00511 } else { 00512 minZ = z0; 00513 } 00514 if(argv.size() > 0 || nZ <= 0 || nR <= 0 || maxR <= 0.0 || 00515 maxZ <= 0.0 || currentOfMap == 0.0) 00516 goto error; 00517 if(mapBr) delete[] mapBr; 00518 if(mapBz) delete[] mapBz; 00519 mapBr = new float[nZ*nR]; 00520 mapBz = new float[nZ*nR]; 00521 if(!mapBr || !mapBz) { 00522 G4Exception("coil","Out of memory",FatalException,""); 00523 } 00524 00525 // read the map -- there are two maps, Bz and Br, each introduced 00526 // by a line with its name in column 1. Each map consists of nZ 00527 // lines of nR floats. 00528 int i=-1; 00529 float *map=0; 00530 while(fgets(line,sizeof(line),in)) { 00531 if(line[0] == '#') continue; 00532 if(strncmp(line,"Bz",2) == 0) { 00533 if(i != -1 && i != nZ) goto error; 00534 i = 0; 00535 map = mapBz; 00536 continue; 00537 } else if(strncmp(line,"Br",2) == 0) { 00538 if(i != -1 && i != nZ) goto error; 00539 i = 0; 00540 map = mapBr; 00541 continue; 00542 } 00543 if(i < 0 || i >= nZ || !map) goto error; 00544 char *p = line; 00545 for(int j=0; j<nR; ++j) { 00546 char *q=0; 00547 if(*p == '\0') goto error; 00548 *map++ = strtod(p,&q)*tesla; 00549 if(q == 0 || p == q) goto error; 00550 p = q; 00551 } 00552 ++i; 00553 } 00554 if(i != nZ) goto error; 00555 fclose(in); 00556 goodMap = true; 00557 }
void BLCoil::displayMapValues | ( | G4double | r, | |
G4double | z | |||
) |
displayMapValues() will display the 4 map values around a point.
References computeError(), dR, dZ, getUnitField(), goodMap, innerRadius, length, mapBr, mapBz, maxR, name, norm, nR, nZ, and outerRadius.
00602 { 00603 if(!goodMap) { 00604 printf("BLCoil '%s' has no good map\n",name.c_str()); 00605 return; 00606 } 00607 if(z < 0.0) { 00608 printf("z must be >= 0\n"); 00609 return; 00610 } 00611 00612 BLCoil best("temp",innerRadius,outerRadius,length,99,0.0,maxR,maxZ); 00613 G4double Br,Bz; 00614 getUnitField(r,z,Br,Bz); 00615 00616 int ii = (int)(r/dR); 00617 int jj = (int)(z/dZ); 00618 if(ii+1 >= nR || jj+1 >= nZ) { 00619 printf("out of range\n"); 00620 return; 00621 } 00622 printf("r=%.3f z=%.3f Bz=%.6f T Br=%.6f T Berr=%.6f T\n", 00623 r,z,Bz/tesla,Bz/tesla, 00624 computeError(r,z,best,false)/norm/tesla); 00625 G4double bzmin=Bz, bzmax=Bz, bzavg=0.0; 00626 G4double brmin=Br, brmax=Br, bravg=0.0; 00627 for(int i=ii; i<=ii+1; ++i) { 00628 for(int j=jj; j<=jj+1; ++j) { 00629 if(bzmin > mapBz[j*nR+i]) bzmin = mapBz[j*nR+i]; 00630 if(bzmax < mapBz[j*nR+i]) bzmax = mapBz[j*nR+i]; 00631 if(brmin > mapBr[j*nR+i]) brmin = mapBr[j*nR+i]; 00632 if(brmax < mapBr[j*nR+i]) brmax = mapBr[j*nR+i]; 00633 bzavg += mapBz[j*nR+i]/4.0; 00634 bravg += mapBr[j*nR+i]/4.0; 00635 printf("Grid: r=%.3f z=%.3f Bz=%.6f T Br=%.6f T\n", 00636 dR*i,dZ*j,mapBz[j*nR+i]/tesla,mapBr[j*nR+i]/tesla); 00637 } 00638 } 00639 printf("BzVariation=%.4f BrVariation=%.4f (fractions of avg)\n", 00640 (bzmax-bzmin)/bzavg,(brmax-brmin)/bravg); 00641 }
void BLCoil::getUnitField | ( | G4double | r, | |
G4double | z, | |||
G4double & | Br, | |||
G4double & | Bz | |||
) | [private] |
getUnitField() will return Br and Bz for unit current.
References addField().
Referenced by computeError(), determineMaxR(), determineMaxZ(), displayMapValues(), and generateFieldMap().
00644 { 00645 G4double point[4]; 00646 point[0] = point[1] = point[2] = point[3] = 0.0; 00647 G4double f[6]; 00648 f[0]=f[1]=f[2]=f[3]=f[4]=f[5]=f[6]=0.0; 00649 point[0] = r; 00650 point[2] = z; 00651 addField(point,f,1.0); 00652 Br = f[0]; 00653 Bz = f[2]; 00654 }
void BLCoil::determineMaxR | ( | ) | [private] |
determineMaxR() will determine maxR based on tolerance. Uses nSheets=99 to determine center field, and walks out far enough so (Bz/Bz0)<0.5*tolerance.
References getUnitField(), innerRadius, length, maxR, name, norm, outerRadius, and tolerance.
Referenced by generateFieldMap().
00657 { 00658 G4double Br,Bz; 00659 BLCoil best("temp",innerRadius,outerRadius,length,99,0.0, 00660 10.0*outerRadius,100.0*outerRadius); 00661 if(norm == 0.0) { 00662 best.getUnitField(0.0,0.0,Br,Bz); 00663 norm = 1.0/Bz; 00664 } 00665 00666 // step out in maxR until 0.5*tolerance is achieved 00667 for(maxR=outerRadius+2.0*innerRadius; 00668 maxR<=outerRadius+32.0*innerRadius; 00669 maxR+=innerRadius) { 00670 best.getUnitField(maxR,0.0,Br,Bz); 00671 Bz = fabs(Bz); 00672 if(Bz*norm < 0.5*tolerance) break; 00673 } 00674 if(maxR <= outerRadius+32.0*innerRadius) { 00675 printf("BLCoil::determineMaxR '%s' maxR=%.1f err=%.6f\n", 00676 name.c_str(),maxR,Bz*norm); 00677 } else { 00678 G4Exception("coilmap determineMaxR", 00679 "Failed to achieve required accuracy", 00680 FatalException, ""); 00681 } 00682 }
void BLCoil::determineMaxZ | ( | ) | [private] |
determineMaxZ() will determine maxZ based on tolerance. Uses nSheets=99 to determine on-axis field, and walks out far enough so (Bz/Bz0)<0.5*tolerance.
References getUnitField(), innerRadius, length, maxR, name, norm, outerRadius, and tolerance.
Referenced by generateFieldMap().
00685 { 00686 G4double Br,Bz; 00687 BLCoil best("temp",innerRadius,outerRadius,length,99,0.0,maxR, 00688 100.0*outerRadius); 00689 if(norm == 0.0) { 00690 best.getUnitField(0.0,0.0,Br,Bz); 00691 norm = 1.0/Bz; 00692 } 00693 00694 // step out in maxZ until 0.5*tolerance is achieved 00695 for(maxZ=length/2.0+4.0*innerRadius; maxZ<=length/2.0+32.0*innerRadius; 00696 maxZ+=innerRadius) { 00697 best.getUnitField(0.0,maxZ,Br,Bz); 00698 if(Bz*norm < 0.5*tolerance) break; 00699 } 00700 if(maxZ <= length/2.0+32.0*innerRadius) { 00701 printf("BLCoil::determineMaxZ '%s' maxZ=%.1f err=%.6f\n", 00702 name.c_str(),maxZ,Bz*norm); 00703 } else { 00704 G4Exception("coilmap determineMaxZ", 00705 "Failed to achieve required accuracy", 00706 FatalException, ""); 00707 } 00708 }
void BLCoil::determineNsheets | ( | ) | [private] |
determineNsheets() will determine nSheets, given maxZ and tolerance. Increases nSheets until maxError < tolerance/4 (the other 3/4 of tolerance is for mapping errors). Checks just a handful of points selected to be representative.
References computeError(), exclude, innerRadius, length, maxR, name, nSheets, outerRadius, sheetDR, sheetR0, and tolerance.
Referenced by generateFieldMap().
00711 { 00712 BLCoil best("temp",innerRadius,outerRadius,length,99,0.0,maxR,maxZ); 00713 00714 G4double exclude = 0.1 * innerRadius; 00715 G4double err = 0.0; 00716 const int MAX_SHEETS=40; 00717 for(nSheets=2; nSheets<=MAX_SHEETS; nSheets+=2) { 00718 sheetDR = (outerRadius-innerRadius) / nSheets; 00719 sheetR0 = innerRadius + sheetDR/2.0; 00720 err = 0.0; 00721 for(int i=0; i<50; ++i) { 00722 G4double r = innerRadius - exclude; 00723 G4double z = G4UniformRand() * length/2.0; 00724 if(r >= maxR) r = maxR; 00725 G4double e = computeError(r,z,best,false); 00726 if(e > err) err = e; 00727 r = innerRadius + (outerRadius-innerRadius)*G4UniformRand(); 00728 if(r >= maxR) continue; 00729 z = length/2.0 + exclude; 00730 e = computeError(r,z,best,false); 00731 if(e > err) err = e; 00732 if(err > tolerance/4.0) break; 00733 } 00734 if(err <= tolerance/4.0) break; 00735 } 00736 00737 if(nSheets <= MAX_SHEETS) { 00738 printf("BLCoil::determineNsheets '%s' nSheets=%d err=%.6f\n", 00739 name.c_str(),nSheets,err); 00740 } else { 00741 G4Exception("coilmap determineNsheets", 00742 "Failed to achieve required accuracy", 00743 FatalException, ""); 00744 } 00745 }
G4double BLCoil::estimateMapError | ( | ) | [private] |
estimateMapError() will estimate the maximum error in mapping, given maxZ, nSheets, dR, dZ, nR, nZ, and an allocated but uninitialized fieldMap. It generates 1000 random points and returns the maximum error; quits early if tolerance is exceeded. Error is (currentMap - best)/best(r=0,z=0), where best is computed with no map and nSheets=99. For each point it generates the 4 surrounding values of fieldMap (this is faster than generating the entire map first). Returns the maximum error of either Bz or Br, normalized to Bz(r=0,z=0,nSheets=99).
References computeError(), exclude, innerRadius, length, maxR, outerRadius, and tolerance.
Referenced by generateFieldMap().
00748 { 00749 BLCoil best("temp",innerRadius,outerRadius,length,99,0.0,maxR,maxZ); 00750 00751 // generate 1000 random positions, "close" 00752 // to the coil in z, but exclude the coil (and nearby). 00753 G4double exclude = 0.1 * innerRadius; 00754 G4double err = 0.0; 00755 G4double genZ = length; 00756 if(length/2.0+exclude+10.0*mm > genZ) genZ = length/2.0+exclude+10.0*mm; 00757 for(int i=0; i<1000; ++i) { 00758 G4double r, z; 00759 do { 00760 r = G4UniformRand() * maxR; 00761 z = G4UniformRand() * genZ; 00762 } while(z < length/2+exclude && 00763 r > innerRadius-exclude && 00764 r < outerRadius+exclude); 00765 G4double e = computeError(r,z,best,true); 00766 if(e > err) err = e; 00767 if(err > tolerance) { 00768 break; 00769 } 00770 // if(i%10 == 0) 00771 // printf("BLCoil::estimateMapError nR=%d nZ=%d %d%%\r", 00772 // nR,nZ,(100*i)/1000), fflush(stdout); 00773 } 00774 00775 return err; 00776 }
G4double BLCoil::computeError | ( | G4double | r, | |
G4double | z, | |||
BLCoil & | best, | |||
G4bool | makeMap | |||
) | [private] |
computeError() computes the error for a single point. Error is (currentMap - best)/best(r=0,z=0), where best should be an identical BLCoil with no map and nSheets=99. If makeMap is true, it generates the 4 surrounding values of the fieldMap.
References BLAssert, dR, dZ, getUnitField(), goodMap, mapBr, mapBz, maxR, norm, nR, and nZ.
Referenced by determineNsheets(), displayMapValues(), and estimateMapError().
00780 { 00781 G4double Br,Bz; 00782 if(z < -maxZ || z > maxZ || r > maxR) return 0.0; 00783 G4bool originalGoodMap = goodMap; 00784 00785 if(norm == 0.0) { 00786 best.getUnitField(0.0,0.0,Br,Bz); 00787 norm = 1.0/Bz; 00788 } 00789 00790 if(makeMap) { 00791 // generate fieldMap for the 4 surrounding grid points 00792 BLAssert(mapBz != 0 && mapBr != 0 && nR > 0 && nZ > 0); 00793 BLAssert(z >= 0.0); 00794 goodMap = false; 00795 int i = (int)(r/dR); 00796 int j = (int)(z/dZ); 00797 BLAssert(i >= 0 && i < nR-1 && j >= 0 && j < nZ-1); 00798 00799 getUnitField(i*dR,j*dZ,Br,Bz); 00800 mapBz[j*nR+i] = Bz; 00801 mapBr[j*nR+i] = Br; 00802 00803 getUnitField((i+1)*dR,j*dZ,Br,Bz); 00804 mapBz[j*nR+(i+1)] = Bz; 00805 mapBr[j*nR+(i+1)] = Br; 00806 00807 getUnitField(i*dR,(j+1)*dZ,Br,Bz); 00808 mapBz[(j+1)*nR+i] = Bz; 00809 mapBr[(j+1)*nR+i] = Br; 00810 00811 getUnitField((i+1)*dR,(j+1)*dZ,Br,Bz); 00812 mapBz[(j+1)*nR+(i+1)] = Bz; 00813 mapBr[(j+1)*nR+(i+1)] = Br; 00814 00815 goodMap = true; 00816 } 00817 00818 G4double bestBr,bestBz; 00819 best.getUnitField(r,z,bestBr,bestBz); 00820 getUnitField(r,z,Br,Bz); 00821 G4double eBr = fabs(Br-bestBr)*norm; 00822 G4double eBz = fabs(Bz-bestBz)*norm; 00823 00824 goodMap = originalGoodMap; 00825 return (eBr>eBz ? eBr : eBz); 00826 }
void BLCoil::getSheetField | ( | G4double | r, | |
G4double | z, | |||
G4double & | Br, | |||
G4double & | Bz, | |||
G4double | sheetR, | |||
G4double | sheetLen, | |||
G4double | currentAmpPerMm | |||
) | const [private] |
getSheetField() returns the B field from an infinitesimally-thin sheet of current. Arguments: r and z are the cylindrical coordinates of the point in question relative to center of the coil (axis along z), mm. Br and Bz return the computed B field at that point (geant4 units) sheetR is the radius of the current sheet (mm) sheetLen is the length of the current sheet (mm) currentAmpPerMm is the current of the sheet (Amp per linear mm)
Referenced by addField().
00874 { 00875 // TJR: within this routine the sheet extends from z=0 to z=sheetLen, 00876 // externally it is centered at z=0. 00877 z += sheetLen/2.0; 00878 00879 //printf("BLCoil::getSheetField r=%.6g z=%.6g sheetR=%.6g sheetLen=%.6g\n",r,z,sheetR,sheetLen); fflush(stdout); 00880 G4double k; 00881 00882 G4double rposition = r/meter; 00883 G4double zposition = z/meter; 00884 00885 G4double rad = sheetR/meter; 00886 G4double len = sheetLen/meter; 00887 G4double cur = currentAmpPerMm; 00888 00889 // Left-end of sheet 00890 00891 G4double rho = rposition; 00892 z = -zposition; 00893 00894 G4double r1 = sqrt( pow(rad + rho,2) + z*z ); 00895 k = 2.0 / r1 * sqrt( rad * rho ); 00896 G4double c2 = -4.0 * rad*rho / pow(rad+rho,2); 00897 00898 G4double f1 = z * rad / ((rad + rho) * r1); 00899 G4double f2 = (rad - rho) / (2.0 * rad); 00900 00901 //printf("gsl_sf_ellint_E k=%.6g\n",k); fflush(stdout); 00902 G4double elle = gsl_sf_ellint_E(pi/2.0,k,GSL_PREC_DOUBLE); 00903 //printf("gsl_sf_ellint_F k=%.6g\n",k); fflush(stdout); 00904 G4double ellf = gsl_sf_ellint_F(pi/2.0,k,GSL_PREC_DOUBLE); 00905 //printf("gsl_sf_ellint_P k=%.6g c2=%.6g\n",k,c2); fflush(stdout); 00906 G4double ellpi = gsl_sf_ellint_P(pi/2.0,k,c2,GSL_PREC_DOUBLE); 00907 00908 G4double bz1 = f1 * ( ellf + f2 * ( ellpi - ellf ) ); 00909 00910 G4double br1; 00911 00912 if( rho != 0.0 ) { 00913 f1 = r1 / (4.*rho); 00914 br1 = f1 * ( 2. * ( ellf - elle ) - k * k * ellf ); 00915 } 00916 else { 00917 br1 = 0.0; 00918 } 00919 00920 G4double bz = -bz1; 00921 G4double br = -br1; 00922 00923 // Right-end of sheet 00924 00925 z = z + len; 00926 r1 = sqrt( pow(rad + rho,2) + z*z ); 00927 k = 2.0 / r1 * sqrt( rad * rho ); 00928 c2 = -4.0 * rad * rho / pow(rad + rho,2); 00929 00930 f1 = z * rad / ( (rad + rho) * r1); 00931 f2 = (rad - rho) / (2.0 * rad); 00932 00933 //printf("gsl_sf_ellint_E k=%.6g\n",k); fflush(stdout); 00934 elle = gsl_sf_ellint_E(pi/2.0,k,GSL_PREC_DOUBLE); 00935 //printf("gsl_sf_ellint_F k=%.6g\n",k); fflush(stdout); 00936 ellf = gsl_sf_ellint_F(pi/2.0,k,GSL_PREC_DOUBLE); 00937 //printf("gsl_sf_ellint_P k=%.6g c2=%.6g\n",k,c2); fflush(stdout); 00938 ellpi = gsl_sf_ellint_P(pi/2.0,k,c2,GSL_PREC_DOUBLE); 00939 00940 bz1 = f1 * ( ellf + f2 * ( ellpi - ellf ) ); 00941 00942 if ( rho != 0.0 ) { 00943 f1 = r1 / (4.0 * rho); 00944 br1 = f1 * ( 2.0 * ( ellf - elle ) - k * k * ellf ); 00945 } 00946 else { 00947 br1 = 0.0; 00948 } 00949 00950 bz = bz + bz1; // note change of sign 00951 br = br + br1; 00952 00953 G4double permfactor = 4.0e-7; 00954 00955 Br = permfactor * cur * br; 00956 Bz = permfactor * cur * bz; 00957 00958 }
friend class BLCMDcoil [friend] |
friend class BLCMDsolenoid [friend] |
friend class SolenoidField [friend] |
std::map< G4String, BLCoil * > BLCoil::mapCoil [static, private] |
Referenced by BLCMDcoil::command(), and find().
G4String BLCoil::name [private] |
Referenced by addField(), BLCoil(), determineMaxR(), determineMaxZ(), determineNsheets(), displayMapValues(), generateFieldMap(), and printCoil().
G4double BLCoil::innerRadius [private] |
G4double BLCoil::outerRadius [private] |
Referenced by addField(), BLCoil(), BLCMDsolenoid::construct(), BLCMDcoil::defineNamedArgs(), determineMaxR(), determineMaxZ(), determineNsheets(), displayMapValues(), estimateMapError(), generateFieldMap(), BLCMDsolenoid::generatePoints(), BLCMDsolenoid::getHeight(), BLCMDsolenoid::getWidth(), BLCMDsolenoid::isOutside(), and printCoil().
G4double BLCoil::length [private] |
Referenced by addField(), BLCoil(), BLCMDsolenoid::construct(), BLCMDcoil::defineNamedArgs(), determineMaxR(), determineMaxZ(), determineNsheets(), displayMapValues(), estimateMapError(), generateFieldMap(), BLCMDsolenoid::generatePoints(), BLCMDsolenoid::getLength(), BLCMDsolenoid::isOutside(), and printCoil().
G4int BLCoil::nSheets [private] |
Referenced by addField(), BLCoil(), BLCMDcoil::defineNamedArgs(), determineNsheets(), generateFieldMap(), and printCoil().
G4String BLCoil::material [private] |
Referenced by BLCoil(), BLCMDsolenoid::construct(), BLCMDcoil::defineNamedArgs(), and printCoil().
G4double BLCoil::tolerance [private] |
Referenced by BLCoil(), BLCMDcoil::defineNamedArgs(), determineMaxR(), determineMaxZ(), determineNsheets(), estimateMapError(), generateFieldMap(), and printCoil().
G4double BLCoil::maxR [private] |
G4double BLCoil::minZ [private] |
Referenced by addField(), BLCoil(), generateFieldMap(), readMapFile(), and SolenoidField::SolenoidField().
G4double BLCoil::maxZ [private] |
Referenced by addField(), BLCoil(), BLCMDcoil::defineNamedArgs(), generateFieldMap(), printCoil(), readMapFile(), and SolenoidField::SolenoidField().
G4double BLCoil::dR [private] |
Referenced by addField(), BLCoil(), computeError(), BLCMDcoil::defineNamedArgs(), displayMapValues(), generateFieldMap(), printCoil(), and readMapFile().
G4double BLCoil::dZ [private] |
Referenced by addField(), BLCoil(), computeError(), BLCMDcoil::defineNamedArgs(), displayMapValues(), generateFieldMap(), printCoil(), and readMapFile().
G4int BLCoil::nR [private] |
Referenced by addField(), BLCoil(), computeError(), displayMapValues(), generateFieldMap(), and readMapFile().
G4int BLCoil::nZ [private] |
Referenced by addField(), BLCoil(), computeError(), displayMapValues(), generateFieldMap(), and readMapFile().
G4String BLCoil::filename [private] |
Referenced by BLCoil(), BLCMDcoil::defineNamedArgs(), generateFieldMap(), and printCoil().
G4String BLCoil::mapFile [private] |
Referenced by BLCoil(), BLCMDcoil::defineNamedArgs(), generateFieldMap(), printCoil(), and readMapFile().
G4int BLCoil::exactComputation [private] |
Referenced by addField(), BLCoil(), BLCMDcoil::defineNamedArgs(), and generateFieldMap().
float* BLCoil::mapBr [private] |
Referenced by addField(), BLCoil(), computeError(), displayMapValues(), generateFieldMap(), readMapFile(), and ~BLCoil().
float* BLCoil::mapBz [private] |
Referenced by addField(), BLCoil(), computeError(), displayMapValues(), generateFieldMap(), readMapFile(), and ~BLCoil().
G4double BLCoil::sheetR0 [private] |
Referenced by addField(), BLCoil(), determineNsheets(), and generateFieldMap().
G4double BLCoil::sheetDR [private] |
Referenced by addField(), BLCoil(), determineNsheets(), and generateFieldMap().
G4double BLCoil::norm [private] |
Referenced by BLCoil(), computeError(), determineMaxR(), determineMaxZ(), displayMapValues(), and generateFieldMap().
G4bool BLCoil::goodMap [private] |
Referenced by addField(), BLCoil(), computeError(), displayMapValues(), generateFieldMap(), and readMapFile().
G4bool BLCoil::reflectZ [private] |
Referenced by addField(), BLCoil(), generateFieldMap(), and readMapFile().
G4double BLCoil::currentOfMap [private] |
Referenced by addField(), BLCoil(), generateFieldMap(), and readMapFile().