Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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
49 numberOfXNodes(0), numberOfYNodes(0),
50 verboseLevel(0), useBicubic(false)
51{
52 cache = new G4Physics2DVectorCache();
53}
54
55// --------------------------------------------------------------
56
59 numberOfXNodes(nx), numberOfYNodes(ny),
60 verboseLevel(0), useBicubic(false)
61{
62 cache = new G4Physics2DVectorCache();
64}
65
66// --------------------------------------------------------------
67
69{
70 delete cache;
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; }
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();
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;
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;
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
206void 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
273void
274G4Physics2DVector::PutVectors(const std::vector<G4double>& vecX,
275 const std::vector<G4double>& vecY)
276{
277 ClearVectors();
278 numberOfXNodes = vecX.size();
279 numberOfYNodes = vecY.size();
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
293void 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; }
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
358void
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
372size_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// --------------------------------------------------------------
std::vector< G4double > G4PV2DDataVector
G4PhysicsVectorType
@ T_G4PhysicsFreeVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4bool Retrieve(std::ifstream &fIn)
void FindBinLocationY(G4double y)
G4Physics2DVector & operator=(const G4Physics2DVector &)
void BicubicInterpolation(size_t idx, size_t idy)
void CopyData(const G4Physics2DVector &vec)
void PutVectors(const std::vector< G4double > &vecX, const std::vector< G4double > &vecY)
G4double GetValue(size_t idx, size_t idy) const
size_t FindBinLocation(G4double z, const G4PV2DDataVector &)
void FindBinLocationX(G4double x)
void Store(std::ofstream &fOut)
void ScaleVector(G4double factor)
void PutValue(size_t idx, size_t idy, G4double value)
void ComputeValue(G4double x, G4double y)