Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Physics2DVector.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id:$
28 //
29 //
30 // --------------------------------------------------------------
31 // GEANT 4 class implementation file
32 //
33 // G4Physics2DVector.cc
34 //
35 // Author: Vladimir Ivanchenko
36 //
37 // Creation date: 25.09.2011
38 //
39 // --------------------------------------------------------------
40 
41 #include <iomanip>
42 
43 #include "G4Physics2DVector.hh"
44 
45 // --------------------------------------------------------------
46 
48  : type(T_G4PhysicsFreeVector),
49  numberOfXNodes(0), numberOfYNodes(0),
50  verboseLevel(0), useBicubic(false)
51 {}
52 
53 // --------------------------------------------------------------
54 
56  : type(T_G4PhysicsFreeVector),
57  numberOfXNodes(nx), numberOfYNodes(ny),
58  verboseLevel(0), useBicubic(false)
59 {
61 }
62 
63 // --------------------------------------------------------------
64 
66 {
67  ClearVectors();
68 }
69 
70 // --------------------------------------------------------------
71 
73 {
74  type = right.type;
75 
76  numberOfXNodes = right.numberOfXNodes;
77  numberOfYNodes = right.numberOfYNodes;
78 
79  verboseLevel = right.verboseLevel;
80  useBicubic = right.useBicubic;
81 
82  xVector = right.xVector;
83  yVector = right.yVector;
84 
86  CopyData(right);
87 }
88 
89 // --------------------------------------------------------------
90 
92 {
93  if (&right==this) { return *this; }
94  ClearVectors();
95 
96  type = right.type;
97 
98  numberOfXNodes = right.numberOfXNodes;
99  numberOfYNodes = right.numberOfYNodes;
100 
101  verboseLevel = right.verboseLevel;
102  useBicubic = right.useBicubic;
103 
104  PrepareVectors();
105  CopyData(right);
106 
107  return *this;
108 }
109 
110 // --------------------------------------------------------------
111 
113 {
114  xVector.resize(numberOfXNodes,0.);
115  yVector.resize(numberOfYNodes,0.);
116  value.resize(numberOfYNodes,0);
117  for(size_t j=0; j<numberOfYNodes; ++j) {
119  v->resize(numberOfXNodes,0.);
120  value[j] = v;
121  }
122 }
123 
124 // --------------------------------------------------------------
125 
127 {
128  for(size_t j=0; j<numberOfYNodes; ++j) {
129  delete value[j];
130  }
131 }
132 
133 // --------------------------------------------------------------
134 
136 {
137  for(size_t i=0; i<numberOfXNodes; ++i) {
138  xVector[i] = right.xVector[i];
139  }
140  for(size_t j=0; j<numberOfYNodes; ++j) {
141  yVector[j] = right.yVector[j];
142  G4PV2DDataVector* v0 = right.value[j];
143  for(size_t i=0; i<numberOfXNodes; ++i) {
144  PutValue(i,j,(*v0)[i]);
145  }
146  }
147 }
148 
149 // --------------------------------------------------------------
150 
152  size_t& idx, size_t& idy) const
153 {
154  G4double x = xx;
155  G4double y = yy;
156 
157  // no interpolation outside the table
158  if(x < xVector[0]) {
159  x = xVector[0];
160  } else if(x > xVector[numberOfXNodes - 1]) {
161  x = xVector[numberOfXNodes - 1];
162  }
163  if(y < yVector[0]) {
164  y = yVector[0];
165  } else if(y > yVector[numberOfYNodes - 1]) {
166  y = yVector[numberOfYNodes - 1];
167  }
168 
169  // find bins
170  idx = FindBinLocationX(x, idx);
171  idy = FindBinLocationY(y, idy);
172 
173  // interpolate
174  if(useBicubic) {
175  return BicubicInterpolation(x, y, idx, idy);
176  } else {
177  G4double x1 = xVector[idx];
178  G4double x2 = xVector[idx+1];
179  G4double y1 = yVector[idy];
180  G4double y2 = yVector[idy+1];
181  G4double v11= GetValue(idx, idy);
182  G4double v12= GetValue(idx+1, idy);
183  G4double v21= GetValue(idx, idy+1);
184  G4double v22= GetValue(idx+1, idy+1);
185  return ((y2 - y)*(v11*(x2 - x) + v12*(x - x1)) +
186  ((y - y1)*(v21*(x2 - x) + v22*(x - x1))))/((x2 - x1)*(y2 - y1));
187  }
188 }
189 
190 // --------------------------------------------------------------
191 
192 G4double
194  size_t idx, size_t idy) const
195 {
196  // Bicubic interpolation according to
197  // 1. H.M. Antia, "Numerical Methods for Scientists and Engineers",
198  // MGH, 1991.
199  // 2. W.H. Press et al., "Numerical recipes. The Art of Scientific
200  // Computing", Cambridge University Press, 2007.
201  G4double x1 = xVector[idx];
202  G4double x2 = xVector[idx+1];
203  G4double y1 = yVector[idy];
204  G4double y2 = yVector[idy+1];
205  G4double f1 = GetValue(idx, idy);
206  G4double f2 = GetValue(idx+1, idy);
207  G4double f3 = GetValue(idx+1, idy+1);
208  G4double f4 = GetValue(idx, idy+1);
209 
210  G4double dx = x2 - x1;
211  G4double dy = y2 - y1;
212 
213  G4double h1 = (x - x1)/dx;
214  G4double h2 = (y - y1)/dy;
215 
216  G4double h12 = h1*h1;
217  G4double h13 = h12*h1;
218  G4double h22 = h2*h2;
219  G4double h23 = h22*h2;
220 
221  // Three derivatives at each of four points (1-4) defining the
222  // subregion are computed by numerical centered differencing from
223  // the functional values already tabulated on the grid.
224 
225  G4double f1x = DerivativeX(idx, idy, dx);
226  G4double f2x = DerivativeX(idx+1, idy, dx);
227  G4double f3x = DerivativeX(idx+1, idy+1, dx);
228  G4double f4x = DerivativeX(idx, idy+1, dx);
229 
230  G4double f1y = DerivativeY(idx, idy, dy);
231  G4double f2y = DerivativeY(idx+1, idy, dy);
232  G4double f3y = DerivativeY(idx+1, idy+1, dy);
233  G4double f4y = DerivativeY(idx, idy+1, dy);
234 
235  G4double dxy = dx*dy;
236  G4double f1xy = DerivativeXY(idx, idy, dxy);
237  G4double f2xy = DerivativeXY(idx+1, idy, dxy);
238  G4double f3xy = DerivativeXY(idx+1, idy+1, dxy);
239  G4double f4xy = DerivativeXY(idx, idy+1, dxy);
240 
241  return
242  f1 + f1y*h2 + (3*(f4-f1) - 2*f1y - f4y)*h22 + (2*(f1 - f4) + f1y + f4y)*h23
243  + f1x*h1 + f1xy*h1*h2 +(3*(f4x - f1x) - 2*f1xy - f4xy)*h1*h22
244  + (2*(f1x - f4x) + f1xy + f4xy)*h1*h23
245  + (3*(f2 - f1) - 2*f1x - f2x)*h12 + (3*f2y - 3*f1y - 2*f1xy - f2xy)*h12*h2
246  + (9*(f1 - f2 + f3 - f4) + 6*f1x + 3*f2x - 3*f3x - 6*f4x + 6*f1y - 6*f2y
247  - 3*f3y + 3*f4y + 4*f1xy + 2*f2xy + f3xy + 2*f4xy)*h12*h22
248  + (6*(-f1 + f2 - f3 + f4) - 4*f1x - 2*f2x + 2*f3x + 4*f4x - 3*f1y
249  + 3*f2y + 3*f3y - 3*f4y - 2*f1xy - f2xy - f3xy - 2*f4xy)*h12*h23
250  + (2*(f1 - f2) + f1x + f2x)*h13 + (2*(f1y - f2y) + f1xy + f2xy)*h13*h2
251  + (6*(-f1 + f2 -f3 + f4) + 3*(-f1x - f2x + f3x + f4x) - 4*f1y
252  + 4*f2y + 2*f3y - 2*f4y - 2*f1xy - 2*f2xy - f3xy - f4xy)*h13*h22
253  + (4*(f1 - f2 + f3 - f4) + 2*(f1x + f2x - f3x - f4x)
254  + 2*(f1y - f2y - f3y + f4y) + f1xy + f2xy + f3xy + f4xy)*h13*h23;
255 }
256 
257 // --------------------------------------------------------------
258 
259 void
260 G4Physics2DVector::PutVectors(const std::vector<G4double>& vecX,
261  const std::vector<G4double>& vecY)
262 {
263  ClearVectors();
264  numberOfXNodes = vecX.size();
265  numberOfYNodes = vecY.size();
266  PrepareVectors();
267  for(size_t i = 0; i<numberOfXNodes; ++i) {
268  xVector[i] = vecX[i];
269  }
270  for(size_t j = 0; j<numberOfYNodes; ++j) {
271  yVector[j] = vecY[j];
272  }
273 }
274 
275 // --------------------------------------------------------------
276 
277 void G4Physics2DVector::Store(std::ofstream& out)
278 {
279  // binning
280  G4int prec = out.precision();
281  out << G4int(type) << " " << numberOfXNodes << " " << numberOfYNodes
282  << G4endl;
283  out << std::setprecision(5);
284 
285  // contents
286  for(size_t i = 0; i<numberOfXNodes-1; ++i) {
287  out << xVector[i] << " ";
288  }
289  out << xVector[numberOfXNodes-1] << G4endl;
290  for(size_t j = 0; j<numberOfYNodes-1; ++j) {
291  out << yVector[j] << " ";
292  }
293  out << yVector[numberOfYNodes-1] << G4endl;
294  for(size_t j = 0; j<numberOfYNodes; ++j) {
295  for(size_t i = 0; i<numberOfXNodes-1; ++i) {
296  out << GetValue(i, j) << " ";
297  }
298  out << GetValue(numberOfXNodes-1,j) << G4endl;
299  }
300  out.precision(prec);
301  out.close();
302 }
303 
304 // --------------------------------------------------------------
305 
307 {
308  // initialisation
309  ClearVectors();
310 
311  // binning
312  G4int k;
313  in >> k >> numberOfXNodes >> numberOfYNodes;
314  if (in.fail() || 0 >= numberOfXNodes || 0 >= numberOfYNodes ||
315  numberOfXNodes >= INT_MAX || numberOfYNodes >= INT_MAX) {
316  return false;
317  }
318  PrepareVectors();
319  type = G4PhysicsVectorType(k);
320 
321  // contents
322  G4double val;
323  for(size_t i = 0; i<numberOfXNodes; ++i) {
324  in >> xVector[i];
325  if (in.fail()) { return false; }
326  }
327  for(size_t j = 0; j<numberOfYNodes; ++j) {
328  in >> yVector[j];
329  if (in.fail()) { return false; }
330  }
331  for(size_t j = 0; j<numberOfYNodes; ++j) {
332  for(size_t i = 0; i<numberOfXNodes; ++i) {
333  in >> val;
334  if (in.fail()) { return false; }
335  PutValue(i, j, val);
336  }
337  }
338  in.close();
339  return true;
340 }
341 
342 // --------------------------------------------------------------
343 
344 void
346 {
347  G4double val;
348  for(size_t j = 0; j<numberOfYNodes; ++j) {
349  for(size_t i = 0; i<numberOfXNodes; ++i) {
350  val = GetValue(i, j)*factor;
351  PutValue(i, j, val);
352  }
353  }
354 }
355 
356 // --------------------------------------------------------------
357 
358 size_t
360  const G4PV2DDataVector& v) const
361 {
362  size_t lowerBound = 0;
363  size_t upperBound = v.size() - 2;
364 
365  while (lowerBound <= upperBound)
366  {
367  size_t midBin = (lowerBound + upperBound)/2;
368  if( z < v[midBin] ) { upperBound = midBin-1; }
369  else { lowerBound = midBin+1; }
370  }
371 
372  return upperBound;
373 }
374 
375 // --------------------------------------------------------------
376 
378  size_t& idy) const
379 {
380  G4double y = yy;
381 
382  // no interpolation outside the table
383  if(y < yVector[0]) {
384  y = yVector[0];
385  } else if(y > yVector[numberOfYNodes - 1]) {
386  y = yVector[numberOfYNodes - 1];
387  }
388 
389  // find bins
390  idy = FindBinLocationY(y, idy);
391 
392  G4double x1 = InterpolateLinearX(*(value[idy]), rand);
393  G4double x2 = InterpolateLinearX(*(value[idy+1]), rand);
394  G4double res = x1;
395  G4double del = yVector[idy+1] - yVector[idy];
396  if(del != 0.0) {
397  res += (x2 - x1)*(y - yVector[idy])/del;
398  }
399  return res;
400 }
401 
402 // --------------------------------------------------------------
403 
404 G4double G4Physics2DVector::InterpolateLinearX(G4PV2DDataVector& v,
405  G4double rand) const
406 {
407  size_t nn = v.size();
408  if(1 >= nn) { return 0.0; }
409  size_t n1 = 0;
410  size_t n2 = nn/2;
411  size_t n3 = nn - 1;
412  G4double y = rand*v[n3];
413  while (n1 + 1 != n3)
414  {
415  if (y > v[n2])
416  { n1 = n2; }
417  else
418  { n3 = n2; }
419  n2 = (n3 + n1 + 1)/2;
420  }
421  G4double res = xVector[n1];
422  G4double del = v[n3] - v[n1];
423  if(del > 0.0) {
424  res += (y - v[n1])*(xVector[n3] - res)/del;
425  }
426  return res;
427 }
428 
429 // --------------------------------------------------------------
std::vector< G4double > G4PV2DDataVector
G4double GetValue(size_t idx, size_t idy) const
G4double z
Definition: TRTMaterials.hh:39
G4PhysicsVectorType
void Store(std::ofstream &fOut)
size_t FindBinLocation(G4double z, const G4PV2DDataVector &) const
size_t FindBinLocationX(G4double x, size_t lastidx) const
int G4int
Definition: G4Types.hh:78
void CopyData(const G4Physics2DVector &vec)
void PutValue(size_t idx, size_t idy, G4double value)
G4double Value(G4double x, G4double y, size_t &lastidx, size_t &lastidy) const
bool G4bool
Definition: G4Types.hh:79
G4Physics2DVector & operator=(const G4Physics2DVector &)
#define INT_MAX
Definition: templates.hh:111
G4bool Retrieve(std::ifstream &fIn)
G4double BicubicInterpolation(G4double x, G4double y, size_t idx, size_t idy) const
size_t FindBinLocationY(G4double y, size_t lastidy) const
const XML_Char int const XML_Char * value
#define G4endl
Definition: G4ios.hh:61
void PutVectors(const std::vector< G4double > &vecX, const std::vector< G4double > &vecY)
double G4double
Definition: G4Types.hh:76
void ScaleVector(G4double factor)
G4double FindLinearX(G4double rand, G4double y, size_t &lastidy) const