Geant4_10
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  return false;
316  }
317  PrepareVectors();
318  type = G4PhysicsVectorType(k);
319 
320  // contents
321  G4double val;
322  for(size_t i = 0; i<numberOfXNodes; ++i) {
323  in >> xVector[i];
324  if (in.fail()) { return false; }
325  }
326  for(size_t j = 0; j<numberOfYNodes; ++j) {
327  in >> yVector[j];
328  if (in.fail()) { return false; }
329  }
330  for(size_t j = 0; j<numberOfYNodes; ++j) {
331  for(size_t i = 0; i<numberOfXNodes; ++i) {
332  in >> val;
333  if (in.fail()) { return false; }
334  PutValue(i, j, val);
335  }
336  }
337  in.close();
338  return true;
339 }
340 
341 // --------------------------------------------------------------
342 
343 void
345 {
346  G4double val;
347  for(size_t j = 0; j<numberOfYNodes; ++j) {
348  for(size_t i = 0; i<numberOfXNodes; ++i) {
349  val = GetValue(i, j)*factor;
350  PutValue(i, j, val);
351  }
352  }
353 }
354 
355 // --------------------------------------------------------------
356 
357 size_t
359  const G4PV2DDataVector& v) const
360 {
361  size_t lowerBound = 0;
362  size_t upperBound = v.size() - 2;
363 
364  while (lowerBound <= upperBound)
365  {
366  size_t midBin = (lowerBound + upperBound)/2;
367  if( z < v[midBin] ) { upperBound = midBin-1; }
368  else { lowerBound = midBin+1; }
369  }
370 
371  return upperBound;
372 }
373 
374 // --------------------------------------------------------------
375 
377  size_t& idy) const
378 {
379  G4double y = yy;
380 
381  // no interpolation outside the table
382  if(y < yVector[0]) {
383  y = yVector[0];
384  } else if(y > yVector[numberOfYNodes - 1]) {
385  y = yVector[numberOfYNodes - 1];
386  }
387 
388  // find bins
389  idy = FindBinLocationY(y, idy);
390 
391  G4double x1 = InterpolateLinearX(*(value[idy]), rand);
392  G4double x2 = InterpolateLinearX(*(value[idy+1]), rand);
393  G4double res = x1;
394  G4double del = yVector[idy+1] - yVector[idy];
395  if(del != 0.0) {
396  res += (x2 - x1)*(y - yVector[idy])/del;
397  }
398  return res;
399 }
400 
401 // --------------------------------------------------------------
402 
403 G4double G4Physics2DVector::InterpolateLinearX(G4PV2DDataVector& v,
404  G4double rand) const
405 {
406  size_t nn = v.size();
407  if(1 >= nn) { return 0.0; }
408  size_t n1 = 0;
409  size_t n2 = nn/2;
410  size_t n3 = nn - 1;
411  G4double y = rand*v[n3];
412  while (n1 + 1 != n3)
413  {
414  if (y > v[n2])
415  { n1 = n2; }
416  else
417  { n3 = n2; }
418  n2 = (n3 + n1 + 1)/2;
419  }
420  G4double res = xVector[n1];
421  G4double del = v[n3] - v[n1];
422  if(del > 0.0) {
423  res += (y - v[n1])*(xVector[n3] - res)/del;
424  }
425  return res;
426 }
427 
428 // --------------------------------------------------------------
Double_t y2[nxs]
Definition: Style.C:21
Double_t yy
Definition: macro.C:11
std::vector< G4double > G4PV2DDataVector
Double_t y1[nxs]
Definition: Style.C:20
G4double GetValue(size_t idx, size_t idy) const
Double_t x2[nxs]
Definition: Style.C:19
TH1F * h1
Definition: plot.C:43
ifstream in
Definition: comparison.C:7
G4PhysicsVectorType
Double_t xx
Definition: macro.C:10
Float_t f4
void Store(std::ofstream &fOut)
size_t FindBinLocation(G4double z, const G4PV2DDataVector &) const
tuple x
Definition: test.py:50
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)
Double_t y
Definition: plot.C:279
Float_t f1
G4double Value(G4double x, G4double y, size_t &lastidx, size_t &lastidy) const
Float_t f2
bool G4bool
Definition: G4Types.hh:79
Double_t x1[nxs]
Definition: Style.C:18
G4Physics2DVector & operator=(const G4Physics2DVector &)
tuple v
Definition: test.py:18
TH1F * h2
Definition: plot.C:46
Float_t f3
G4bool Retrieve(std::ifstream &fIn)
tuple z
Definition: test.py:28
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
Definition: expat.h:331
#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