GEMC  2.3
Geant4 Monte-Carlo Framework
cylindrical.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "asciiField.h"
3 #include "utils.h"
4 
5 // 2D phi-symmetric cylindrical field
6 // Dependent on 2 cartesian coordinates (transverse, longitudinal)
7 // Expressed in Cylindrical coordinate
8 // The values can be loaded from the map in any order
9 // as long as their speed is ordered.
10 // The values are indexed as B1_2D[transverse][longi]
11 // The field is two dimensional, ordered in the class as B1=BT, B2=BL
12 
13 // from fieldFactory: load field map
15 {
16  setlocale(LC_NUMERIC, "en_US");
17 
18  int np_1 = map->getCoordinateWithSpeed(0).np;
19  int np_2 = map->getCoordinateWithSpeed(1).np;
20  double min1 = map->getCoordinateWithSpeed(0).min;
21  double min2 = map->getCoordinateWithSpeed(1).min;
22  double cell1 = (map->getCoordinateWithSpeed(0).max - min1)/(np_1 - 1);
23  double cell2 = (map->getCoordinateWithSpeed(1).max - min2)/(np_2 - 1);
24 
25  // Allocate memory. [LONGI][TRANSVERSE]
26  // as initialized in the map
27  map->B1_2D = new double*[map->np[0]];
28  map->B2_2D = new double*[map->np[0]];
29  for (unsigned int i = 0; i < map->np[0]; ++i)
30  {
31  map->B1_2D[i] = new double[map->np[1]];
32  map->B2_2D[i] = new double[map->np[1]];
33  }
34 
35  double unit1 = get_number("1*" + map->getCoordinateWithSpeed(0).unit);
36  double unit2 = get_number("1*" + map->getCoordinateWithSpeed(1).unit);
37 
38  double scale = map->scaleFactor*get_number("1*" + map->unit);
39 
40  double d1, d2, b1, b2;
41 
42  // progress bar
43  int barWidth = 50;
44 
45  // using fscanf instead of c++ to read file, this is a lot faster
46  char ctmp[100];
47  string tmp;
48  FILE *fp = fopen (map->identifier.c_str(), "r");
49 
50  // ignoring header
51  while(tmp != "</mfield>")
52  {
53  fscanf(fp, "%s", ctmp);
54  tmp = string(ctmp);
55  }
56 
57  // now reading map values
58  for(int i1 = 0; i1<np_1 ; i1++)
59  {
60  for(int i2 = 0; i2<np_2 ; i2++)
61  {
62  fscanf(fp, "%lg %lg %lg %lg", &d1, &d2, &b1, &b2);
63 
64  d1 *= unit1;
65  d2 *= unit2;
66  b1 *= scale;
67  b2 *= scale;
68 
69  if(verbosity>4)
70  cout << " Loading Map: coordinates (" << d1 << ", " << d2 << ") values: (" << b1 << ", " << b2 << ")." << endl;
71 
72  // checking map consistency for first coordinate
73  if( (min1 + i1*cell1 - d1)/d1 > 0.001)
74  {
75  cout << " !! Error: first coordinate index wrong. Map point should be " << min1 + i1*cell1
76  << " but it's " << d1 << " instead." << endl;
77  cout << " min1: " << min1 << " cell1: " << cell1 << " unit1: " << unit1 << " i1: " << i1 << endl;
78  }
79  // checking map consistency for second coordinate
80  if( (min2 + i2*cell2 - d2)/d2 > 0.001)
81  {
82  cout << " !! Error: second coordinate index wrong. Map point should be " << min2 + i2*cell2
83  << " but it's " << d2 << " instead." << endl;
84  cout << " min2: " << min2 << " cell2: " << cell2 << " unit2: " << unit2 << " i2: " << i2 << endl;
85  }
86 
87  // calculating index
88  unsigned t1 = (unsigned) floor( ( d1 - min1 + cell1/2 ) / ( cell1 ) ) ;
89  unsigned t2 = (unsigned) floor( ( d2 - min2 + cell2/2 ) / ( cell2 ) ) ;
90 
91  // The values are indexed as B1_2D[transverse][longi]
92  if( map->getCoordinateWithSpeed(0).name == "transverse"
93  && map->getCoordinateWithSpeed(1).name == "longitudinal")
94  {
95  map->B1_2D[t1][t2] = b1;
96  map->B2_2D[t1][t2] = b2;
97  }
98  if( map->getCoordinateWithSpeed(0).name == "longitudinal"
99  && map->getCoordinateWithSpeed(1).name == "transverse")
100  {
101  map->B1_2D[t2][t1] = b1;
102  map->B2_2D[t2][t1] = b2;
103  }
104  }
105 
106  cout << " [";
107  double progress = (double)i1/(double)np_1;
108  int pos = progress*barWidth;
109  for (int i = 0; i < barWidth; ++i)
110  {
111  if (i < pos) cout << "=";
112  else if (i == pos) cout << ">";
113  else cout << " ";
114  }
115  cout << "] " << int(progress * 100.0) << " %\r";
116  cout.flush();
117  }
118  fclose(fp);
119 
120  cout << endl;
121 }
122 
123 // from mappedField: GetFieldValue
124 void gMappedField::GetFieldValue_Cylindrical( const double x[3], double *Bfield, int FIRST_ONLY) const
125 {
126  double LC = 0; // longitudinal
127  double TC = 0; // transverse
128  double phi = 0; // phi angle
129 
130  // map plane is in ZX, phi on X axis
131  if(symmetry == "cylindrical-z")
132  {
133  LC = x[2];
134  TC = sqrt(x[0]*x[0] + x[1]*x[1]);
135  phi = G4ThreeVector(x[0], x[1], x[2]).phi();
136  }
137  // map plane is in XY, phi on Y axis
138  else if(symmetry == "cylindrical-x")
139  {
140  LC = x[0];
141  TC = sqrt(x[1]*x[1] + x[2]*x[2]);
142  phi = G4ThreeVector(x[2], x[0], x[1]).phi();
143  }
144  // map plane is in XZ, phi on Z axis
145  else if(symmetry == "cylindrical-y")
146  {
147  LC = x[1];
148  TC = sqrt(x[0]*x[0] + x[2]*x[2]);
149  phi = G4ThreeVector(x[1], x[2], x[0]).phi();
150  }
151 
152  // map indexes, bottom of the cell
153  unsigned int IT = floor( ( TC - startMap[0] ) / cellSize[0] );
154  unsigned int IL = floor( ( LC - startMap[1] ) / cellSize[1] );
155 
156  if (TC < startMap[0] || LC < startMap[1]) return; // outside map, returning no field
157 
158  // no interpolation
159  if(interpolation == "none")
160  {
161  // checking if the point is closer to the top of the cell
162  if( fabs( startMap[0] + IT*cellSize[0] - TC) > fabs( startMap[0] + (IT+1)*cellSize[0] - TC) ) IT++;
163  if( fabs( startMap[1] + IL*cellSize[1] - LC) > fabs( startMap[1] + (IL+1)*cellSize[1] - LC) ) IL++;
164 
165  // outside map, returning no field
166  if(IT>=np[0] || IL>=np[1]) return;
167 
168  if(symmetry == "cylindrical-z")
169  {
170  Bfield[0] = B1_2D[IT][IL] * cos(phi);
171  Bfield[1] = B1_2D[IT][IL] * sin(phi);
172  Bfield[2] = B2_2D[IT][IL];
173  }
174  else if(symmetry == "cylindrical-x")
175  {
176  Bfield[0] = B2_2D[IT][IL];
177  Bfield[1] = B1_2D[IT][IL] * cos(phi);
178  Bfield[2] = B1_2D[IT][IL] * sin(phi);
179  }
180  else if(symmetry == "cylindrical-y")
181  {
182  Bfield[1] = B2_2D[IT][IL];
183  Bfield[0] = B1_2D[IT][IL] * sin(phi);
184  Bfield[2] = B1_2D[IT][IL] * cos(phi);
185  }
186  }
187  else if (interpolation == "linear")
188  {
189  // outside map, returning no field
190  if (IT+1 >= np[0] || IL+1 >= np[1]) return;
191 
192  // relative position within cell
193  double xtr = (TC - (startMap[0] + IT*cellSize[0])) / cellSize[0];
194  double xlr = (LC - (startMap[1] + IL*cellSize[1])) / cellSize[1];
195 
196  double b10 = B1_2D[IT][IL] * (1.0 - xtr) + B1_2D[IT+1][IL] * xtr;
197  double b11 = B1_2D[IT][IL+1] * (1.0 - xtr) + B1_2D[IT+1][IL+1] * xtr;
198  double b1 = b10 * (1.0 - xlr) + b11 * xlr;
199  double b20 = B2_2D[IT][IL] * (1.0 - xtr) + B2_2D[IT+1][IL] * xtr;
200  double b21 = B2_2D[IT][IL+1] * (1.0 - xtr) + B2_2D[IT+1][IL+1] * xtr;
201  double b2 = b20 * (1.0 - xlr) + b21 * xlr;
202 
203  if(symmetry == "cylindrical-z")
204  {
205  Bfield[0] = b1 * cos(phi);
206  Bfield[1] = b1 * sin(phi);
207  Bfield[2] = b2;
208  }
209  else if(symmetry == "cylindrical-x")
210  {
211  Bfield[0] = b2;
212  Bfield[1] = b1 * cos(phi);
213  Bfield[2] = b1 * sin(phi);
214  }
215  else if(symmetry == "cylindrical-y")
216  {
217  Bfield[1] = b2;
218  Bfield[0] = b1 * sin(phi);
219  Bfield[2] = b1 * cos(phi);
220  }
221  }
222  else cout << "unkown field interpolation method, field is not on!!!" << endl;
223 
224  // we don't worry about computer speed
225  // if verbosity is set this high
226  // so we can output units as well
227  if(verbosity>3 && FIRST_ONLY != 99)
228  {
229  cout << " > Track position in magnetic field: "
230  << "(" << (x[0] + mapOrigin[0])/cm << ", "
231  << (x[1] + mapOrigin[1])/cm << ", "
232  << (x[2] + mapOrigin[2])/cm << ") cm, " << endl;
233  cout << " Cylindrical: ";
234  cout << "loc. pos. = (" << x[0]/cm << ", " << x[1]/cm << ", " << x[2]/cm << ") cm, ";
235  cout << "tr=" << TC/cm << "cm, long=" << LC/cm << "cm, phi=" << phi/deg << ", ";
236  cout << "IT=" << IT << " ";
237  cout << "IL=" << IL << ", ";
238  cout << "B = (" << Bfield[0]/gauss << ", " << Bfield[1]/gauss << ", " << Bfield[2]/gauss << ") gauss " << endl;
239  }
240 }
241 
242 
243 
244 
245 
246 
unsigned int np
Definition: mappedField.h:40
string unit
field unit in the map
Definition: mappedField.h:97
double verbosity
string name
Definition: mappedField.h:39
unsigned int * np
Definition: mappedField.h:116
double scaleFactor
copy of the gfield scaleFactor
Definition: mappedField.h:96
double min
Definition: mappedField.h:41
double ** B1_2D
Definition: mappedField.h:107
double get_number(string v, int warn_no_unit)
Returns number with dimension from string, i.e. 100*cm.
double max
Definition: mappedField.h:42
double ** B2_2D
Definition: mappedField.h:108
gcoord getCoordinateWithSpeed(int speed)
return coordinate based on speed
Definition: mappedField.cc:38
string unit
Definition: mappedField.h:43
void GetFieldValue_Cylindrical(const double x[3], double *Bfield, int FIRST_ONLY) const
Definition: cylindrical.cc:124
void loadFieldMap_Cylindrical(gMappedField *, double)
Definition: cylindrical.cc:14
string identifier
Pointer to map in factory (for example, hostname / filename with path / date)
Definition: mappedField.h:92