Class Reference for E1039 Core & Analysis Software
TabulatedField3D.cc
Go to the documentation of this file.
1 // ********************************************************************
2 // * License and Disclaimer *
3 // * *
4 // * The Geant4 software is copyright of the Copyright Holders of *
5 // * the Geant4 Collaboration. It is provided under the terms and *
6 // * conditions of the Geant4 Software License, included in the file *
7 // * LICENSE and available at http://cern.ch/geant4/license . These *
8 // * include a list of copyright holders. *
9 // * *
10 // * Neither the authors of this software system, nor their employing *
11 // * institutes,nor the agencies providing financial support for this *
12 // * work make any representation or warranty, express or implied, *
13 // * regarding this software system or assume any liability for its *
14 // * use. Please see the license in the file LICENSE and URL above *
15 // * for the full disclaimer and the limitation of liability. *
16 // * *
17 // * This code implementation is the result of the scientific and *
18 // * technical work of the GEANT4 collaboration. *
19 // * By using, copying, modifying or distributing the software (or *
20 // * any work based on the software) you agree to acknowledge its *
21 // * use in resulting scientific publications, and indicate your *
22 // * acceptance of all terms of the Geant4 Software license. *
23 // ********************************************************************
24 //
25 // Code developed by:
26 // S.Larsson and J. Generowicz.
27 //
28 // *************************************
29 // * *
30 // * PurgMagTabulatedField3D.cc *
31 // * *
32 // *************************************
33 //
34 // $Id: PurgMagTabulatedField3D.cc,v 1.4 2006/06/29 16:06:25 gunter Exp $
35 // GEANT4 tag $Name: geant4-09-01-patch-02 $
36 
37 #include "TabulatedField3D.hh"
38 
39 #include "GlobalConsts.h"
40 
41 TabulatedField3D::TabulatedField3D(double zOffset, int nX, int nY, int nZ, bool fMagnet, Settings* settings)
42 {
43  mySettings = settings;
45  {
46 
47  fmag = fMagnet;
48  fZoffset = zOffset;
49  nx = nX;
50  ny = nY;
51  nz = nZ;
52 
53  G4String filename;
54 
55  if (fmag)
56  filename = settings->fMagName;
57  else
58  filename = settings->kMagName;
59 
60  double fieldUnit= tesla;
61  G4cout << "\n-----------------------------------------------------------"
62  << "\n Magnetic field"
63  << "\n-----------------------------------------------------------"
64  << "\n ---> " "Reading the field grid from " << filename << " ... " << endl;
65  ifstream file( filename );
66  if (!file.good())
67  cout << "Field map input file error." << endl;
68 
69  char buffer[256];
70  file.getline(buffer,256);
71 
72  G4cout << " [ Number of values x,y,z: "
73  << nx << " " << ny << " " << nz << " ] "
74  << endl;
75 
76  // Set up storage space for table
77  xField.resize( nx );
78  yField.resize( nx );
79  zField.resize( nx );
80  int ix, iy, iz;
81  for (ix=0; ix<nx; ix++)
82  {
83  xField[ix].resize(ny);
84  yField[ix].resize(ny);
85  zField[ix].resize(ny);
86  for (iy=0; iy<ny; iy++)
87  {
88  xField[ix][iy].resize(nz);
89  yField[ix][iy].resize(nz);
90  zField[ix][iy].resize(nz);
91  }
92  }
93 
94  // Read in the data
95  double xval,yval,zval,bx,by,bz;
96 
97  minx = miny = minz = maxx = maxy = maxz = 0;
98 
99  for (ix=0; ix<nx; ix++)
100  {
101  for (iy=0; iy<ny; iy++)
102  {
103  for (iz=0; iz<nz; iz++)
104  {
105  // The field map has 1 column we don't use
106  file >> xval >> yval >> zval >> bx >> by >> bz;
107  if (xval*cm < minx)
108  minx = xval * cm;
109  if (yval*cm < miny)
110  miny = yval * cm;
111  if (zval*cm < minz)
112  minz = zval * cm;
113  if (xval*cm > maxx)
114  maxx = xval * cm;
115  if (yval*cm > maxy)
116  maxy = yval * cm;
117  if (zval*cm > maxz)
118  maxz = zval * cm;
119  xField[ix][iy][iz] = bx * fieldUnit;
120  yField[ix][iy][iz] = by * fieldUnit;
121  zField[ix][iy][iz] = bz * fieldUnit;
122  }
123  }
124  }
125  file.close();
126 
127  G4cout << "\n ---> ... done reading " << endl;
128  }
129  else // if loading field map from MySQL
130  {
131  fZoffset = zOffset;
132  nx = nX;
133  ny = nY;
134  nz = nZ;
135 
136  MYSQL_RES* resLimits;
137  MYSQL_RES* resField;
138  MYSQL_ROW row;
139 
140  con = mysql_init(NULL);
142  mySettings->sqlPort, NULL, 0);
143 
144  cout << mysql_error(con) << endl;
145  cout << mySettings->magnetSchema << endl;
146 
147  fmag = fMagnet;
148 
149  double fieldUnit= tesla;
150 
151  G4cout << "\n-----------------------------------------------------------"
152  << "\n Magnetic field"
153  << "\n-----------------------------------------------------------\n";
154 
155  G4cout << " [ Number of values x,y,z: "
156  << nx << " " << ny << " " << nz << " ] "
157  << endl;
158 
159  // Set up storage space for table
160  xField.resize( nx );
161  yField.resize( nx );
162  zField.resize( nx );
163  int ix, iy;
164  for (ix=0; ix<nx; ix++)
165  {
166  xField[ix].resize(ny);
167  yField[ix].resize(ny);
168  zField[ix].resize(ny);
169  for (iy=0; iy<ny; iy++)
170  {
171  xField[ix][iy].resize(nz);
172  yField[ix][iy].resize(nz);
173  zField[ix][iy].resize(nz);
174  }
175  }
176 
177  float xval,yval,zval,bx,by,bz;
178 
179  if (fmag)
180  {
181  mysql_query(con, "SELECT minX, minY, minZ, maxX, maxY, maxZ FROM Fmag_limits");
182  cout << mysql_error(con) << endl;
183  resLimits = mysql_store_result(con);
184  }
185  else
186  {
187  mysql_query(con, "SELECT minX, minY, minZ, maxX, maxY, maxZ FROM Kmag_limits");
188  cout << mysql_error(con) << endl;
189  resLimits = mysql_store_result(con);
190  }
191 
192  row = mysql_fetch_row(resLimits);
193 
194  minx = atof(row[0]) * cm;
195  miny = atof(row[1]) * cm;
196  minz = atof(row[2]) * cm;
197  maxx = atof(row[3]) * cm;
198  maxy = atof(row[4]) * cm;
199  maxz = atof(row[5]) * cm;
200 
201  mysql_free_result(resLimits);
202 
203  if (fmag)
204  {
205  mysql_query(con, "SELECT x, y, z, B_x, B_y, B_z FROM Fmag");
206  cout << mysql_error(con) << endl;
207  resField = mysql_store_result(con);
208  }
209  else
210  {
211  mysql_query(con, "SELECT x, y, z, B_x, B_y, B_z FROM Kmag");
212  cout << mysql_error(con) << endl;
213  resField = mysql_store_result(con);
214  }
215 
216  int xc, yc, zc;
217 
218  while ((row = mysql_fetch_row(resField)))
219  {
220  xval = atof(row[0]);
221  yval = atof(row[1]);
222  zval = atof(row[2]);
223  bx = atof(row[3]);
224  by = atof(row[4]);
225  bz = atof(row[5]);
226 
227  xc = floor((xval*cm-minx)*(nx-1)/(maxx-minx)+0.5);
228  yc = floor((yval*cm-miny)*(ny-1)/(maxy-miny)+0.5);
229  zc = floor((zval*cm-minz)*(nz-1)/(maxz-minz)+0.5);
230 
231  xField[xc][yc][zc] = bx*fieldUnit;
232  yField[xc][yc][zc] = by*fieldUnit;
233  zField[xc][yc][zc] = bz*fieldUnit;
234  }
235 
236  mysql_free_result(resField);
237 
238  G4cout << "\n ---> ... done reading " << endl;
239  }
240 
241  // This code is run whether it is loaded from ascii or MySQL
242 
243  G4cout << "\n ---> Min values x,y,z: "
244  << minx/cm << " " << miny/cm << " " << minz/cm << " cm "
245  << "\n ---> Max values x,y,z: "
246  << maxx/cm << " " << maxy/cm << " " << maxz/cm << " cm "
247  << "\n ---> The field will be offset by " << zOffset/cm << " cm " << endl;
248 
249  dx = maxx - minx;
250  dy = maxy - miny;
251  dz = maxz - minz;
252 
253  G4cout << "\n ---> Dif values x,y,z (range): "
254  << dx/cm << " " << dy/cm << " " << dz/cm << " cm in z "
255  << "\n-----------------------------------------------------------" << endl;
256 }
257 
258 void TabulatedField3D::GetFieldValue(const double point[3], double *Bfield ) const
259 {
260  Bfield[0] = 0.0;
261  Bfield[1] = 0.0;
262  Bfield[2] = 0.0;
263 
264  double x, y, z;
265 
266  x = point[0];
267  y = point[1];
268  z = point[2] + fZoffset;
269 
270  // Check that the point is within the defined region
271  if ( x>=minx && x<=maxx &&
272  y>=miny && y<=maxy &&
273  z>=minz && z<=maxz )
274  {
275  // Position of given point within region, normalized to the range
276  // [0,1]
277  double xfraction = (x - minx) / dx;
278  double yfraction = (y - miny) / dy;
279  double zfraction = (z - minz) / dz;
280 
281  // Need addresses of these to pass to modf below.
282  // modf uses its second argument as an OUTPUT argument.
283  double xdIndex, ydIndex, zdIndex;
284 
285  // Position of the point within the cuboid defined by the
286  // nearest surrounding tabulated points
287  double xlocal = ( std::modf(xfraction*(nx-1), &xdIndex));
288  double ylocal = ( std::modf(yfraction*(ny-1), &ydIndex));
289  double zlocal = ( std::modf(zfraction*(nz-1), &zdIndex));
290 
291  // The indices of the nearest tabulated point whose coordinates
292  // are all less than those of the given point
293  int xindex = static_cast<int>(xdIndex);
294  int yindex = static_cast<int>(ydIndex);
295  int zindex = static_cast<int>(zdIndex);
296 
297  // Full 3-dimensional version
298  Bfield[0] =
299  xField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
300  xField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
301  xField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
302  xField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
303  xField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
304  xField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
305  xField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
306  xField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
307  Bfield[1] =
308  yField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
309  yField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
310  yField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
311  yField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
312  yField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
313  yField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
314  yField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
315  yField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
316  Bfield[2] =
317  zField[xindex ][yindex ][zindex ] * (1-xlocal) * (1-ylocal) * (1-zlocal) +
318  zField[xindex ][yindex ][zindex+1] * (1-xlocal) * (1-ylocal) * zlocal +
319  zField[xindex ][yindex+1][zindex ] * (1-xlocal) * ylocal * (1-zlocal) +
320  zField[xindex ][yindex+1][zindex+1] * (1-xlocal) * ylocal * zlocal +
321  zField[xindex+1][yindex ][zindex ] * xlocal * (1-ylocal) * (1-zlocal) +
322  zField[xindex+1][yindex ][zindex+1] * xlocal * (1-ylocal) * zlocal +
323  zField[xindex+1][yindex+1][zindex ] * xlocal * ylocal * (1-zlocal) +
324  zField[xindex+1][yindex+1][zindex+1] * xlocal * ylocal * zlocal ;
325  }
326 
327  if (fmag)
328  {
329  Bfield[0] = Bfield[0]*mySettings->fMagMultiplier;
330  Bfield[1] = Bfield[1]*mySettings->fMagMultiplier;
331  Bfield[2] = Bfield[2]*mySettings->fMagMultiplier;
332  }
333  else
334  {
335  Bfield[0] = Bfield[0]*mySettings->kMagMultiplier;
336  Bfield[1] = Bfield[1]*mySettings->kMagMultiplier;
337  Bfield[2] = Bfield[2]*mySettings->kMagMultiplier;
338  }
339 }
#define NULL
Definition: Pdb.h:9
G4String sqlServer
Definition: Settings.hh:40
G4String login
Definition: Settings.hh:35
bool asciiFieldMap
Definition: Settings.hh:28
G4String password
Definition: Settings.hh:37
G4String kMagName
Definition: Settings.hh:39
int sqlPort
Definition: Settings.hh:41
double kMagMultiplier
Definition: Settings.hh:47
G4String fMagName
Definition: Settings.hh:38
G4String magnetSchema
Definition: Settings.hh:49
double fMagMultiplier
Definition: Settings.hh:46
TabulatedField3D(double, int, int, int, bool, Settings *)
void GetFieldValue(const double Point[3], double *Bfield) const