Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// G4Physics2DVector class implementation
27//
28// Author: Vladimir Ivanchenko, 25.09.2011
29// --------------------------------------------------------------------
30
31#include <iomanip>
32
33#include "G4Physics2DVector.hh"
34
35// --------------------------------------------------------------
36
38
39// --------------------------------------------------------------
40
41G4Physics2DVector::G4Physics2DVector(std::size_t nx, std::size_t ny)
42{
43 if(nx < 2 || ny < 2)
44 {
46 ed << "G4Physics2DVector is too short: nx= " << nx << " numy= " << ny;
47 G4Exception("G4Physics2DVector::G4Physics2DVector()", "glob03",
48 FatalException, ed, "Both lengths should be above 1");
49 }
50 numberOfXNodes = nx;
51 numberOfYNodes = ny;
53}
54
55// --------------------------------------------------------------
56
58
59// --------------------------------------------------------------
60
62{
63 type = right.type;
64
65 numberOfXNodes = right.numberOfXNodes;
66 numberOfYNodes = right.numberOfYNodes;
67
68 verboseLevel = right.verboseLevel;
69 useBicubic = right.useBicubic;
70
71 xVector = right.xVector;
72 yVector = right.yVector;
73
75 CopyData(right);
76}
77
78// --------------------------------------------------------------
79
81{
82 if(&right == this)
83 {
84 return *this;
85 }
87
88 type = right.type;
89
90 numberOfXNodes = right.numberOfXNodes;
91 numberOfYNodes = right.numberOfYNodes;
92
93 verboseLevel = right.verboseLevel;
94 useBicubic = right.useBicubic;
95
97 CopyData(right);
98
99 return *this;
100}
101
102// --------------------------------------------------------------
103
105{
106 xVector.resize(numberOfXNodes, 0.);
107 yVector.resize(numberOfYNodes, 0.);
108 value.resize(numberOfYNodes);
109 for(std::size_t j = 0; j < numberOfYNodes; ++j)
110 {
111 value[j] = new G4PV2DDataVector(numberOfXNodes, 0.);
112 }
113}
114
115// --------------------------------------------------------------
116
118{
119 for(std::size_t j = 0; j < numberOfYNodes; ++j)
120 {
121 delete value[j];
122 }
123}
124
125// --------------------------------------------------------------
126
128{
129 for(std::size_t i = 0; i < numberOfXNodes; ++i)
130 {
131 xVector[i] = right.xVector[i];
132 }
133 for(std::size_t j = 0; j < numberOfYNodes; ++j)
134 {
135 yVector[j] = right.yVector[j];
136 G4PV2DDataVector* v0 = right.value[j];
137 for(std::size_t i = 0; i < numberOfXNodes; ++i)
138 {
139 PutValue(i, j, (*v0)[i]);
140 }
141 }
142}
143
144// --------------------------------------------------------------
145
147 std::size_t& idy) const
148{
149 // no interpolation outside the table
150 const G4double x =
151 std::min(std::max(xx, xVector[0]), xVector[numberOfXNodes - 1]);
152 const G4double y =
153 std::min(std::max(yy, yVector[0]), yVector[numberOfYNodes - 1]);
154
155 // find bins
156 idx = FindBinLocationX(x, idx);
157 idy = FindBinLocationY(y, idy);
158
159 // interpolate
160 if(useBicubic)
161 {
162 return BicubicInterpolation(x, y, idx, idy);
163 }
164 else
165 {
166 const G4double x1 = xVector[idx];
167 const G4double x2 = xVector[idx + 1];
168 const G4double y1 = yVector[idy];
169 const G4double y2 = yVector[idy + 1];
170 const G4double v11 = GetValue(idx, idy);
171 const G4double v12 = GetValue(idx + 1, idy);
172 const G4double v21 = GetValue(idx, idy + 1);
173 const G4double v22 = GetValue(idx + 1, idy + 1);
174 return ((y2 - y) * (v11 * (x2 - x) + v12 * (x - x1)) +
175 ((y - y1) * (v21 * (x2 - x) + v22 * (x - x1)))) /
176 ((x2 - x1) * (y2 - y1));
177 }
178}
179
180// --------------------------------------------------------------
181
183 const G4double y,
184 const std::size_t idx,
185 const std::size_t idy) const
186{
187 // Bicubic interpolation according to
188 // 1. H.M. Antia, "Numerical Methods for Scientists and Engineers",
189 // MGH, 1991.
190 // 2. W.H. Press et al., "Numerical recipes. The Art of Scientific
191 // Computing", Cambridge University Press, 2007.
192 const G4double x1 = xVector[idx];
193 const G4double x2 = xVector[idx + 1];
194 const G4double y1 = yVector[idy];
195 const G4double y2 = yVector[idy + 1];
196 const G4double f1 = GetValue(idx, idy);
197 const G4double f2 = GetValue(idx + 1, idy);
198 const G4double f3 = GetValue(idx + 1, idy + 1);
199 const G4double f4 = GetValue(idx, idy + 1);
200
201 const G4double dx = x2 - x1;
202 const G4double dy = y2 - y1;
203
204 const G4double h1 = (x - x1) / dx;
205 const G4double h2 = (y - y1) / dy;
206
207 const G4double h12 = h1 * h1;
208 const G4double h13 = h12 * h1;
209 const G4double h22 = h2 * h2;
210 const G4double h23 = h22 * h2;
211
212 // Three derivatives at each of four points (1-4) defining the
213 // subregion are computed by numerical centered differencing from
214 // the functional values already tabulated on the grid.
215
216 const G4double f1x = DerivativeX(idx, idy, dx);
217 const G4double f2x = DerivativeX(idx + 1, idy, dx);
218 const G4double f3x = DerivativeX(idx + 1, idy + 1, dx);
219 const G4double f4x = DerivativeX(idx, idy + 1, dx);
220
221 const G4double f1y = DerivativeY(idx, idy, dy);
222 const G4double f2y = DerivativeY(idx + 1, idy, dy);
223 const G4double f3y = DerivativeY(idx + 1, idy + 1, dy);
224 const G4double f4y = DerivativeY(idx, idy + 1, dy);
225
226 const G4double dxy = dx * dy;
227 const G4double f1xy = DerivativeXY(idx, idy, dxy);
228 const G4double f2xy = DerivativeXY(idx + 1, idy, dxy);
229 const G4double f3xy = DerivativeXY(idx + 1, idy + 1, dxy);
230 const G4double f4xy = DerivativeXY(idx, idy + 1, dxy);
231
232 return f1 + f1y * h2 + (3 * (f4 - f1) - 2 * f1y - f4y) * h22 +
233 (2 * (f1 - f4) + f1y + f4y) * h23 + f1x * h1 + f1xy * h1 * h2 +
234 (3 * (f4x - f1x) - 2 * f1xy - f4xy) * h1 * h22 +
235 (2 * (f1x - f4x) + f1xy + f4xy) * h1 * h23 +
236 (3 * (f2 - f1) - 2 * f1x - f2x) * h12 +
237 (3 * f2y - 3 * f1y - 2 * f1xy - f2xy) * h12 * h2 +
238 (9 * (f1 - f2 + f3 - f4) + 6 * f1x + 3 * f2x - 3 * f3x - 6 * f4x +
239 6 * f1y - 6 * f2y - 3 * f3y + 3 * f4y + 4 * f1xy + 2 * f2xy + f3xy +
240 2 * f4xy) *
241 h12 * h22 +
242 (6 * (-f1 + f2 - f3 + f4) - 4 * f1x - 2 * f2x + 2 * f3x + 4 * f4x -
243 3 * f1y + 3 * f2y + 3 * f3y - 3 * f4y - 2 * f1xy - f2xy - f3xy -
244 2 * f4xy) *
245 h12 * h23 +
246 (2 * (f1 - f2) + f1x + f2x) * h13 +
247 (2 * (f1y - f2y) + f1xy + f2xy) * h13 * h2 +
248 (6 * (-f1 + f2 - f3 + f4) + 3 * (-f1x - f2x + f3x + f4x) - 4 * f1y +
249 4 * f2y + 2 * f3y - 2 * f4y - 2 * f1xy - 2 * f2xy - f3xy - f4xy) *
250 h13 * h22 +
251 (4 * (f1 - f2 + f3 - f4) + 2 * (f1x + f2x - f3x - f4x) +
252 2 * (f1y - f2y - f3y + f4y) + f1xy + f2xy + f3xy + f4xy) *
253 h13 * h23;
254}
255
256// --------------------------------------------------------------
257
258void G4Physics2DVector::PutVectors(const std::vector<G4double>& vecX,
259 const std::vector<G4double>& vecY)
260{
261 ClearVectors();
262 std::size_t nx = vecX.size();
263 std::size_t ny = vecY.size();
264 if(nx < 2 || ny < 2)
265 {
267 ed << "G4Physics2DVector is too short: nx= " << nx << " ny= " << ny;
268 G4Exception("G4Physics2DVector::PutVectors()", "glob03", FatalException, ed,
269 "Both lengths should be above 1");
270 }
271
272 numberOfXNodes = nx;
273 numberOfYNodes = ny;
275 for(std::size_t i = 0; i < nx; ++i)
276 {
277 xVector[i] = vecX[i];
278 }
279 for(std::size_t j = 0; j < ny; ++j)
280 {
281 yVector[j] = vecY[j];
282 }
283}
284
285// --------------------------------------------------------------
286
287void G4Physics2DVector::Store(std::ofstream& out) const
288{
289 // binning
290 G4int prec = out.precision();
291 out << G4int(type) << " " << numberOfXNodes << " " << numberOfYNodes
292 << G4endl;
293 out << std::setprecision(8);
294
295 // contents
296 for(std::size_t i = 0; i < numberOfXNodes - 1; ++i)
297 {
298 out << xVector[i] << " ";
299 }
300 out << xVector[numberOfXNodes - 1] << G4endl;
301 for(std::size_t j = 0; j < numberOfYNodes - 1; ++j)
302 {
303 out << yVector[j] << " ";
304 }
305 out << yVector[numberOfYNodes - 1] << G4endl;
306 for(std::size_t j = 0; j < numberOfYNodes; ++j)
307 {
308 for(std::size_t i = 0; i < numberOfXNodes - 1; ++i)
309 {
310 out << GetValue(i, j) << " ";
311 }
312 out << GetValue(numberOfXNodes - 1, j) << G4endl;
313 }
314 out.precision(prec);
315 out.close();
316}
317
318// --------------------------------------------------------------
319
321{
322 // initialisation
323 ClearVectors();
324
325 // binning
326 G4int k, nx, ny;
327 in >> k >> nx >> ny;
328 if(in.fail() || 2 > nx || 2 > ny || nx >= INT_MAX || ny >= INT_MAX)
329 {
330 return false;
331 }
332 numberOfXNodes = nx;
333 numberOfYNodes = ny;
335 type = G4PhysicsVectorType(k);
336
337 // contents
338 G4double val;
339 for(G4int i = 0; i < nx; ++i)
340 {
341 in >> xVector[i];
342 if(in.fail())
343 {
344 return false;
345 }
346 }
347 for(G4int j = 0; j < ny; ++j)
348 {
349 in >> yVector[j];
350 if(in.fail())
351 {
352 return false;
353 }
354 }
355 for(G4int j = 0; j < ny; ++j)
356 {
357 for(G4int i = 0; i < nx; ++i)
358 {
359 in >> val;
360 if(in.fail())
361 {
362 return false;
363 }
364 PutValue(i, j, val);
365 }
366 }
367 in.close();
368 return true;
369}
370
371// --------------------------------------------------------------
372
374{
375 G4double val;
376 for(std::size_t j = 0; j < numberOfYNodes; ++j)
377 {
378 for(std::size_t i = 0; i < numberOfXNodes; ++i)
379 {
380 val = GetValue(i, j) * factor;
381 PutValue(i, j, val);
382 }
383 }
384}
385
386// --------------------------------------------------------------
387
389 std::size_t& idy) const
390{
391 G4double y = std::min(std::max(yy, yVector[0]), yVector[numberOfYNodes - 1]);
392
393 // find bins
394 idy = FindBinLocationY(y, idy);
395
396 G4double x1 = InterpolateLinearX(*(value[idy]), rand);
397 G4double x2 = InterpolateLinearX(*(value[idy + 1]), rand);
398 G4double res = x1;
399 G4double del = yVector[idy + 1] - yVector[idy];
400 if(del != 0.0)
401 {
402 res += (x2 - x1) * (y - yVector[idy]) / del;
403 }
404 return res;
405}
406
407// --------------------------------------------------------------
408
409G4double G4Physics2DVector::InterpolateLinearX(G4PV2DDataVector& v,
410 G4double rand) const
411{
412 std::size_t nn = v.size();
413 if(1 >= nn)
414 {
415 return 0.0;
416 }
417 std::size_t n1 = 0;
418 std::size_t n2 = nn / 2;
419 std::size_t n3 = nn - 1;
420 G4double y = rand * v[n3];
421 while(n1 + 1 != n3)
422 {
423 if(y > v[n2])
424 {
425 n1 = n2;
426 }
427 else
428 {
429 n3 = n2;
430 }
431 n2 = (n3 + n1 + 1) / 2;
432 }
433 G4double res = xVector[n1];
434 G4double del = v[n3] - v[n1];
435 if(del > 0.0)
436 {
437 res += (y - v[n1]) * (xVector[n3] - res) / del;
438 }
439 return res;
440}
441
442// --------------------------------------------------------------
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
std::vector< G4double > G4PV2DDataVector
G4PhysicsVectorType
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4bool Retrieve(std::ifstream &fIn)
G4Physics2DVector & operator=(const G4Physics2DVector &)
std::size_t FindBinLocationX(const G4double x, const std::size_t lastidx) const
void Store(std::ofstream &fOut) const
std::size_t FindBinLocationY(const G4double y, const std::size_t lastidy) const
void CopyData(const G4Physics2DVector &vec)
void PutVectors(const std::vector< G4double > &vecX, const std::vector< G4double > &vecY)
G4double BicubicInterpolation(const G4double x, const G4double y, const std::size_t idx, const std::size_t idy) const
G4double Value(G4double x, G4double y, std::size_t &lastidx, std::size_t &lastidy) const
void ScaleVector(G4double factor)
void PutValue(std::size_t idx, std::size_t idy, G4double value)
G4double GetValue(std::size_t idx, std::size_t idy) const
G4double FindLinearX(G4double rand, G4double y, std::size_t &lastidy) const
#define INT_MAX
Definition: templates.hh:90