Geant4  9.6.p02
 All Classes 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 // GEANT4 tag $Name: not supported by cvs2svn $
29 //
30 //
31 // --------------------------------------------------------------
32 // GEANT 4 class implementation file
33 //
34 // G4Physics2DVector.cc
35 //
36 // Author: Vladimir Ivanchenko
37 //
38 // Creation date: 25.09.2011
39 //
40 // --------------------------------------------------------------
41 
42 #include "G4Physics2DVector.hh"
43 #include <iomanip>
44 
45 // --------------------------------------------------------------
46 
48  : type(T_G4PhysicsFreeVector),
49  numberOfXNodes(0), numberOfYNodes(0),
50  verboseLevel(0), useBicubic(false)
51 {
52  cache = new G4Physics2DVectorCache();
53 }
54 
55 // --------------------------------------------------------------
56 
58  : type(T_G4PhysicsFreeVector),
59  numberOfXNodes(nx), numberOfYNodes(ny),
60  verboseLevel(0), useBicubic(false)
61 {
62  cache = new G4Physics2DVectorCache();
64 }
65 
66 // --------------------------------------------------------------
67 
69 {
70  delete cache;
71  ClearVectors();
72 }
73 
74 // --------------------------------------------------------------
75 
77 {
78  type = right.type;
79 
80  numberOfXNodes = right.numberOfXNodes;
81  numberOfYNodes = right.numberOfYNodes;
82 
83  verboseLevel = right.verboseLevel;
84  useBicubic = right.useBicubic;
85 
86  xVector = right.xVector;
87  yVector = right.yVector;
88 
89  cache = new G4Physics2DVectorCache();
91  CopyData(right);
92 }
93 
94 // --------------------------------------------------------------
95 
97 {
98  if (&right==this) { return *this; }
99  ClearVectors();
100 
101  type = right.type;
102 
103  numberOfXNodes = right.numberOfXNodes;
104  numberOfYNodes = right.numberOfYNodes;
105 
106  verboseLevel = right.verboseLevel;
107  useBicubic = right.useBicubic;
108 
109  cache->Clear();
110  PrepareVectors();
111  CopyData(right);
112 
113  return *this;
114 }
115 
116 // --------------------------------------------------------------
117 
119 {
120  xVector.resize(numberOfXNodes,0.);
121  yVector.resize(numberOfYNodes,0.);
122  value.resize(numberOfYNodes,0);
123  for(size_t j=0; j<numberOfYNodes; ++j) {
125  v->resize(numberOfXNodes,0.);
126  value[j] = v;
127  }
128 }
129 
130 // --------------------------------------------------------------
131 
133 {
134  for(size_t j=0; j<numberOfYNodes; ++j) {
135  delete value[j];
136  }
137 }
138 
139 // --------------------------------------------------------------
140 
142 {
143  for(size_t i=0; i<numberOfXNodes; ++i) {
144  xVector[i] = right.xVector[i];
145  }
146  for(size_t j=0; j<numberOfYNodes; ++j) {
147  yVector[j] = right.yVector[j];
148  G4PV2DDataVector* v0 = right.value[j];
149  for(size_t i=0; i<numberOfXNodes; ++i) {
150  PutValue(i,j,(*v0)[i]);
151  }
152  }
153 }
154 
155 // --------------------------------------------------------------
156 
158 {
159  if(xx != cache->lastBinX) {
160  if(xx <= xVector[0]) {
161  cache->lastX = xVector[0];
162  cache->lastBinX = 0;
163  } else if(xx >= xVector[numberOfXNodes-1]) {
164  cache->lastX = xVector[numberOfXNodes-1];
165  cache->lastBinX = numberOfXNodes-2;
166  } else {
167  cache->lastX = xx;
168  FindBinLocationX(xx);
169  }
170  }
171  if(yy != cache->lastBinY) {
172  if(yy <= yVector[0]) {
173  cache->lastY = yVector[0];
174  cache->lastBinY = 0;
175  } else if(yy >= yVector[numberOfYNodes-1]) {
176  cache->lastY = yVector[numberOfYNodes-1];
177  cache->lastBinY = numberOfYNodes-2;
178  } else {
179  cache->lastY = yy;
180  FindBinLocationY(yy);
181  }
182  }
183  size_t idx = cache->lastBinX;
184  size_t idy = cache->lastBinY;
185  if(useBicubic) {
186  BicubicInterpolation(idx, idy);
187  } else {
188  G4double x1 = xVector[idx];
189  G4double x2 = xVector[idx+1];
190  G4double y1 = yVector[idy];
191  G4double y2 = yVector[idy+1];
192  G4double x = cache->lastX;
193  G4double y = cache->lastY;
194  G4double v11= GetValue(idx, idy);
195  G4double v12= GetValue(idx+1, idy);
196  G4double v21= GetValue(idx, idy+1);
197  G4double v22= GetValue(idx+1, idy+1);
198  cache->lastValue =
199  ((y2 - y)*(v11*(x2 - x) + v12*(x - x1)) +
200  ((y - y1)*(v21*(x2 - x) + v22*(x - x1))))/((x2 - x1)*(y2 - y1));
201  }
202 }
203 
204 // --------------------------------------------------------------
205 
206 void G4Physics2DVector::BicubicInterpolation(size_t idx, size_t idy)
207 {
208  // Bicubic interpolation according to
209  // 1. H.M. Antia, "Numerical Methods for Scientists and Engineers",
210  // MGH, 1991.
211  // 2. W.H. Press et al., "Numerical recipes. The Art of Scientific
212  // Computing", Cambridge University Press, 2007.
213  G4double x1 = xVector[idx];
214  G4double x2 = xVector[idx+1];
215  G4double y1 = yVector[idy];
216  G4double y2 = yVector[idy+1];
217  G4double x = cache->lastX;
218  G4double y = cache->lastY;
219  G4double f1 = GetValue(idx, idy);
220  G4double f2 = GetValue(idx+1, idy);
221  G4double f3 = GetValue(idx+1, idy+1);
222  G4double f4 = GetValue(idx, idy+1);
223 
224  G4double dx = x2 - x1;
225  G4double dy = y2 - y1;
226 
227  G4double h1 = (x - x1)/dx;
228  G4double h2 = (y - y1)/dy;
229 
230  G4double h12 = h1*h1;
231  G4double h13 = h12*h1;
232  G4double h22 = h2*h2;
233  G4double h23 = h22*h2;
234 
235  // Three derivatives at each of four points (1-4) defining the
236  // subregion are computed by numerical centered differencing from
237  // the functional values already tabulated on the grid.
238 
239  G4double f1x = DerivativeX(idx, idy, dx);
240  G4double f2x = DerivativeX(idx+1, idy, dx);
241  G4double f3x = DerivativeX(idx+1, idy+1, dx);
242  G4double f4x = DerivativeX(idx, idy+1, dx);
243 
244  G4double f1y = DerivativeY(idx, idy, dy);
245  G4double f2y = DerivativeY(idx+1, idy, dy);
246  G4double f3y = DerivativeY(idx+1, idy+1, dy);
247  G4double f4y = DerivativeY(idx, idy+1, dy);
248 
249  G4double dxy = dx*dy;
250  G4double f1xy = DerivativeXY(idx, idy, dxy);
251  G4double f2xy = DerivativeXY(idx+1, idy, dxy);
252  G4double f3xy = DerivativeXY(idx+1, idy+1, dxy);
253  G4double f4xy = DerivativeXY(idx, idy+1, dxy);
254 
255  cache->lastValue =
256  f1 + f1y*h2 + (3*(f4-f1) - 2*f1y - f4y)*h22 + (2*(f1 - f4) + f1y + f4y)*h23
257  + f1x*h1 + f1xy*h1*h2 +(3*(f4x - f1x) - 2*f1xy - f4xy)*h1*h22
258  + (2*(f1x - f4x) + f1xy + f4xy)*h1*h23
259  + (3*(f2 - f1) - 2*f1x - f2x)*h12 + (3*f2y - 3*f1y - 2*f1xy - f2xy)*h12*h2
260  + (9*(f1 - f2 + f3 - f4) + 6*f1x + 3*f2x - 3*f3x - 6*f4x + 6*f1y - 6*f2y
261  - 3*f3y + 3*f4y + 4*f1xy + 2*f2xy + f3xy + 2*f4xy)*h12*h22
262  + (6*(-f1 + f2 - f3 + f4) - 4*f1x - 2*f2x + 2*f3x + 4*f4x - 3*f1y
263  + 3*f2y + 3*f3y - 3*f4y - 2*f1xy - f2xy - f3xy - 2*f4xy)*h12*h23
264  + (2*(f1 - f2) + f1x + f2x)*h13 + (2*(f1y - f2y) + f1xy + f2xy)*h13*h2
265  + (6*(-f1 + f2 -f3 + f4) + 3*(-f1x - f2x + f3x + f4x) - 4*f1y
266  + 4*f2y + 2*f3y - 2*f4y - 2*f1xy - 2*f2xy - f3xy - f4xy)*h13*h22
267  + (4*(f1 - f2 + f3 - f4) + 2*(f1x + f2x - f3x - f4x)
268  + 2*(f1y - f2y - f3y + f4y) + f1xy + f2xy + f3xy + f4xy)*h13*h23;
269 }
270 
271 // --------------------------------------------------------------
272 
273 void
274 G4Physics2DVector::PutVectors(const std::vector<G4double>& vecX,
275  const std::vector<G4double>& vecY)
276 {
277  ClearVectors();
278  numberOfXNodes = vecX.size();
279  numberOfYNodes = vecY.size();
280  PrepareVectors();
281  if(!cache) { cache = new G4Physics2DVectorCache(); }
282  cache->Clear();
283  for(size_t i = 0; i<numberOfXNodes; ++i) {
284  xVector[i] = vecX[i];
285  }
286  for(size_t j = 0; j<numberOfYNodes; ++j) {
287  yVector[j] = vecY[j];
288  }
289 }
290 
291 // --------------------------------------------------------------
292 
293 void G4Physics2DVector::Store(std::ofstream& out)
294 {
295  // binning
296  G4int prec = out.precision();
297  out << G4int(type) << " " << numberOfXNodes << " " << numberOfYNodes
298  << G4endl;
299  out << std::setprecision(5);
300 
301  // contents
302  for(size_t i = 0; i<numberOfXNodes-1; ++i) {
303  out << xVector[i] << " ";
304  }
305  out << xVector[numberOfXNodes-1] << G4endl;
306  for(size_t j = 0; j<numberOfYNodes-1; ++j) {
307  out << yVector[j] << " ";
308  }
309  out << yVector[numberOfYNodes-1] << G4endl;
310  for(size_t j = 0; j<numberOfYNodes; ++j) {
311  for(size_t i = 0; i<numberOfXNodes-1; ++i) {
312  out << GetValue(i, j) << " ";
313  }
314  out << GetValue(numberOfXNodes-1,j) << G4endl;
315  }
316  out.precision(prec);
317  out.close();
318 }
319 
320 // --------------------------------------------------------------
321 
323 {
324  // initialisation
325  cache->Clear();
326  ClearVectors();
327 
328  // binning
329  G4int k;
330  in >> k >> numberOfXNodes >> numberOfYNodes;
331  if (in.fail()) { return false; }
332  PrepareVectors();
333  type = G4PhysicsVectorType(k);
334 
335  // contents
336  G4double val;
337  for(size_t i = 0; i<numberOfXNodes; ++i) {
338  in >> xVector[i];
339  if (in.fail()) { return false; }
340  }
341  for(size_t j = 0; j<numberOfYNodes; ++j) {
342  in >> yVector[j];
343  if (in.fail()) { return false; }
344  }
345  for(size_t j = 0; j<numberOfYNodes; ++j) {
346  for(size_t i = 0; i<numberOfXNodes; ++i) {
347  in >> val;
348  if (in.fail()) { return false; }
349  PutValue(i, j, val);
350  }
351  }
352  in.close();
353  return true;
354 }
355 
356 // --------------------------------------------------------------
357 
358 void
360 {
361  G4double val;
362  for(size_t j = 0; j<numberOfYNodes; ++j) {
363  for(size_t i = 0; i<numberOfXNodes; ++i) {
364  val = GetValue(i, j)*factor;
365  PutValue(i, j, val);
366  }
367  }
368 }
369 
370 // --------------------------------------------------------------
371 
372 size_t
374  const G4PV2DDataVector& v)
375 {
376  size_t lowerBound = 0;
377  size_t upperBound = v.size() - 2;
378 
379  while (lowerBound <= upperBound)
380  {
381  size_t midBin = (lowerBound + upperBound)/2;
382  if( z < v[midBin] ) { upperBound = midBin-1; }
383  else { lowerBound = midBin+1; }
384  }
385 
386  return upperBound;
387 }
388 
389 // --------------------------------------------------------------