BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSArray4DCoords.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSArray4DCoords.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSExtent.hh"
23#include "BDSFieldValue.hh"
24#include "BDSUtilities.hh"
25
26#include "CLHEP/Units/PhysicalConstants.h"
27
28#include <algorithm>
29#include <cmath>
30#include <limits>
31#include <ostream>
32#include <string>
33
34#include "globals.hh"
35
36BDSArray4DCoords::BDSArray4DCoords(G4int nXIn, G4int nYIn, G4int nZIn, G4int nTIn,
37 G4double xMinIn, G4double xMaxIn,
38 G4double yMinIn, G4double yMaxIn,
39 G4double zMinIn, G4double zMaxIn,
40 G4double tMinIn, G4double tMaxIn,
41 BDSDimensionType xDimensionIn,
42 BDSDimensionType yDimensionIn,
43 BDSDimensionType zDimensionIn,
44 BDSDimensionType tDimensionIn):
45 BDSArray4D(nXIn,nYIn,nZIn,nTIn),
46 xMin(xMinIn), xMax(xMaxIn),
47 yMin(yMinIn), yMax(yMaxIn),
48 zMin(zMinIn), zMax(zMaxIn),
49 tMin(tMinIn), tMax(tMaxIn),
50 smallestSpatialStep(std::numeric_limits<double>::max()),
51 xDimension(xDimensionIn),
52 yDimension(yDimensionIn),
53 zDimension(zDimensionIn),
54 tDimension(tDimensionIn),
55 dimensions{0,1,2,3}
56{
57 // There are 1 fewer differences than the points.
58 if (nX > 1)
59 {
60 xStep = (xMax - xMin) / ((G4double)nX - 1);
61 CheckStep(xStep, "x");
62 smallestSpatialStep = std::min(smallestSpatialStep, xStep);
63 }
64 else
65 {xStep = 1;}
66 if (nY > 1)
67 {
68 yStep = (yMax - yMin) / ((G4double)nY - 1);
69 CheckStep(yStep, "y");
70 smallestSpatialStep = std::min(smallestSpatialStep, yStep);
71 }
72 else
73 {yStep = 1;}
74 if (nZ > 1)
75 {
76 zStep = (zMax - zMin) / ((G4double)nZ - 1);
77 CheckStep(zStep, "z");
78 smallestSpatialStep = std::min(smallestSpatialStep, zStep);
79 }
80 else
81 {zStep = 1;}
82 if (nT > 1)
83 {
84 tStep = (tMax - tMin) / ((G4double)nT - 1);
85 CheckStep(tStep, "t");
86 G4double lengthScale = CLHEP::c_light * tStep;
87 smallestSpatialStep = std::min(smallestSpatialStep, lengthScale);
88 }
89 else
90 {tStep = 1;}
92}
93
94void BDSArray4DCoords::CheckStep(G4double step, const G4String& name)
95{
96 if (!BDS::IsFinite(step))
97 {
98 throw BDSException(__METHOD_NAME__, "Invalid " + name + "min and " + name +
99 "max in array leading to 0 step size between points.");
100 }
101}
102
104 G4double y,
105 G4double z,
106 G4double t) const
107{
108 G4bool rx = x < xMin || x > xMax;
109 G4bool ry = y < yMin || y > yMax;
110 G4bool rz = z < zMin || z > zMax;
111 G4bool rt = t < tMin || t > tMax;
112 return rx || ry || rz || rt;
113}
114
116 G4double y,
117 G4double z,
118 G4double t) const
119{
120 if (OutsideCoords(x,y,z,t))
121 {
122 throw BDSException(__METHOD_NAME__, "(" +
123 std::to_string(x) + ", " +
124 std::to_string(y) + ", " +
125 std::to_string(z) + ", " +
126 std::to_string(t) + ") is outside array");
127 }
128}
129
131 G4double y,
132 G4double z,
133 G4double t,
134 BDSFieldValue (&localData)[2][2][2][2],
135 G4double& xFrac,
136 G4double& yFrac,
137 G4double& zFrac,
138 G4double& tFrac) const
139{
140 G4double xArrayCoords, yArrayCoords, zArrayCoords, tArrayCoords;
141 ArrayCoordsFromXYZT(x, xArrayCoords, y, yArrayCoords, z, zArrayCoords, t, tArrayCoords);
142 auto x1 = (G4int)std::floor(xArrayCoords);
143 auto y1 = (G4int)std::floor(yArrayCoords);
144 auto z1 = (G4int)std::floor(zArrayCoords);
145 auto t1 = (G4int)std::floor(tArrayCoords);
146
147 xFrac = xArrayCoords - x1;
148 yFrac = yArrayCoords - y1;
149 zFrac = zArrayCoords - z1;
150 tFrac = tArrayCoords - t1;
151
152 for (G4int i = 0; i < 2; i++)
153 {
154 for (G4int j = 0; j < 2; j++)
155 {
156 for (G4int k = 0; k < 2; k++)
157 {
158 for (G4int l = 0; l < 2; l++)
159 {localData[i][j][k][l] = GetConst(x1+i, y1+j, z1+k, t1+l);}
160 }
161 }
162 }
163}
164
166 G4double y,
167 G4double z,
168 G4double t,
169 BDSFieldValue (&localData)[4][4][4][4],
170 G4double& xFrac,
171 G4double& yFrac,
172 G4double& zFrac,
173 G4double& tFrac) const
174{
175 G4double xArrayCoords, yArrayCoords, zArrayCoords, tArrayCoords;
176 ArrayCoordsFromXYZT(x, xArrayCoords, y, yArrayCoords, z, zArrayCoords, t, tArrayCoords);
177 auto x1 = (G4int)std::floor(xArrayCoords);
178 auto y1 = (G4int)std::floor(yArrayCoords);
179 auto z1 = (G4int)std::floor(zArrayCoords);
180 auto t1 = (G4int)std::floor(tArrayCoords);
181
182 xFrac = xArrayCoords - x1;
183 yFrac = yArrayCoords - y1;
184 zFrac = zArrayCoords - z1;
185 tFrac = tArrayCoords - t1;
186
187 for (G4int i = 0; i < 4; i++)
188 {
189 for (G4int j = 0; j < 4; j++)
190 {
191 for (G4int k = 0; k < 4; k++)
192 {
193 for (G4int l = 0; l < 4; l++)
194 {localData[i][j][k][l] = GetConst(x1-1+i, y1-1+j, z1-1+k, t1-1+l);}
195 }
196 }
197 }
198}
199
201 G4double y,
202 G4double z,
203 G4double t) const
204{
205 G4int xind = NearestX(x);
206 G4int yind = NearestY(y);
207 G4int zind = NearestZ(z);
208 G4int tind = NearestT(t);
209 BDSFieldValue result = GetConst(xind, yind, zind, tind); // here we're constructing a copy on purpose
210 return result;
211}
212
213std::ostream& BDSArray4DCoords::Print(std::ostream& out) const
214{
215 out << "X: (" << xMin << ", " << xMax << ")" << G4endl;
216 out << "Y: (" << yMin << ", " << yMax << ")" << G4endl;
217 out << "Z: (" << zMin << ", " << zMax << ")" << G4endl;
218 out << "T: (" << tMin << ", " << tMax << ")" << G4endl;
219 return BDSArray4D::Print(out);
220}
221
222std::ostream& operator<< (std::ostream& out, BDSArray4DCoords const &a)
223{
224 return a.Print(out);
225}
226
228{
229 return BDSExtent(xMin, xMax, yMin, yMax, zMin, zMax);
230}
231
233{
234 dimensions[0] = FirstDimension().underlying();
235 dimensions[1] = SecondDimension().underlying();
236 dimensions[2] = ThirdDimension().underlying();
237 dimensions[3] = FourthDimension().underlying();
238}
239
241{
242 G4int result = -1;
243 G4int match = spatialDimension.underlying();
244 for (G4int i = 0; i < 4; i++)
245 {
246 if (dimensions[i] == match)
247 {
248 result = i;
249 break;
250 }
251 }
252 return result;
253}
Overlay of 4D array that provides uniform only spatial coordinate mapping.
G4double xMin
Dimension parameter - protected for derived class access.
virtual G4bool OutsideCoords(G4double x, G4double y, G4double z, G4double t) const
Whether the spatial coordinates lie outside the range of the array or not.
G4double yMin
Dimension parameter - protected for derived class access.
G4double yStep
Dimension parameter - protected for derived class access.
BDSDimensionType ThirdDimension() const
Accessor for each dimension label. e.g. array 'x' = spatial z.
virtual std::ostream & Print(std::ostream &out) const
virtual G4int NearestY(G4double y) const
Not much point in being both virtual and inline (in our use case) but has to be virtual.
virtual G4int NearestX(G4double x) const
Not much point in being both virtual and inline (in our use case) but has to be virtual.
BDSDimensionType SecondDimension() const
Accessor for each dimension label. e.g. array 'x' = spatial z.
virtual BDSExtent Extent() const
Return the SPATIAL (only) extent of this field without any offset. Ignores time.
G4double zMax
Dimension parameter - protected for derived class access.
virtual G4int NearestT(G4double t) const
Not much point in being both virtual and inline (in our use case) but has to be virtual.
G4double tMin
Dimension parameter - protected for derived class access.
BDSDimensionType FourthDimension() const
Accessor for each dimension label. e.g. array 'x' = spatial z.
G4double zMin
Dimension parameter - protected for derived class access.
virtual G4int NearestZ(G4double z) const
Not much point in being both virtual and inline (in our use case) but has to be virtual.
G4double xStep
Dimension parameter - protected for derived class access.
virtual void OutsideCoordsWarn(G4double x, G4double y, G4double z, G4double t) const
virtual void ExtractSection2x2x2x2(G4double x, G4double y, G4double z, G4double t, BDSFieldValue(&localData)[2][2][2][2], G4double &xFrac, G4double &yFrac, G4double &zFrac, G4double &tFrac) const
Extract 2x2x2x2 points lying around coordinate x.
G4int DimensionIndex(BDSDimensionType spatialDimension) const
G4double yMax
Dimension parameter - protected for derived class access.
G4double xMax
Dimension parameter - protected for derived class access.
virtual void ExtractSection4x4x4x4(G4double x, G4double y, G4double z, G4double t, BDSFieldValue(&localData)[4][4][4][4], G4double &xFrac, G4double &yFrac, G4double &zFrac, G4double &tFrac) const
Extract 4x4x4x4 points lying around coordinate x.
G4double tMax
Dimension parameter - protected for derived class access.
G4double zStep
Dimension parameter - protected for derived class access.
void ArrayCoordsFromXYZT(G4double &x, G4double &xArr, G4double &y, G4double &yArr, G4double &z, G4double &zArr, G4double &t, G4double &tArr) const
Utility version to forward to individual function.
BDSArray4DCoords()=delete
virtual BDSFieldValue ExtractNearest(G4double x, G4double y=0, G4double z=0, G4double t=0) const
Extract nearest field value from array.
G4double tStep
Dimension parameter - protected for derived class access.
BDSDimensionType FirstDimension() const
Accessor for each dimension label. e.g. array 'x' = spatial z.
void BuildDimensionIndex()
Build up an array of ints based on the order of dimensions stored in the array.
4D array and base class for 3,2 & 1D arrays.
Definition: BDSArray4D.hh:51
const G4int nZ
Dimension.
Definition: BDSArray4D.hh:122
const G4int nY
Dimension.
Definition: BDSArray4D.hh:121
virtual const BDSFieldValue & GetConst(G4int x, G4int y=0, G4int z=0, G4int t=0) const
Definition: BDSArray4D.cc:46
const G4int nX
Dimension.
Definition: BDSArray4D.hh:120
virtual std::ostream & Print(std::ostream &out) const
Definition: BDSArray4D.cc:91
const G4int nT
Dimension.
Definition: BDSArray4D.hh:123
General exception with possible name of object and message.
Definition: BDSException.hh:35
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
type underlying() const
return underlying value (can be used in switch statement)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())