BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSInterpolatorRoutines.hh
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#ifndef BDSINTERPOLATORROUTINES_H
19#define BDSINTERPOLATORROUTINES_H
20
21#include "G4Types.hh"
22
23#include "BDSFieldValue.hh"
24
25#include <cmath>
26
27namespace BDS
28{
29 // These routines are templated for any type. They can be used with a type
30 // that provides both L and R operator+ operator- with their own type and
31 // operator+ operator- operator* with a double.
32
35 template<class T>
36 T mag(const T& v) {return std::abs(v);}
38 template<template<class> class BDSFieldValue, class V>
39 V mag(const BDSFieldValue<V>& v){return v.mag();}
40
43 template<class T>
44 T Linear1D(const T p[2],
45 G4double x)
46 {return p[0]*(1.-x) + p[1]*x;}
47
49 template<class T>
50 T Linear2D(const T p[2][2],
51 G4double x,
52 G4double y)
53 {
54 T arr[2];
55 arr[0] = BDS::Linear1D<T>(p[0], y);
56 arr[1] = BDS::Linear1D<T>(p[1], y);
57 return BDS::Linear1D<T>(arr, x);
58 }
59
61 template<class T>
62 T Linear3D(const T p[2][2][2],
63 G4double x,
64 G4double y,
65 G4double z)
66 {
67 T arr[2];
68 arr[0] = BDS::Linear2D<T>(p[0], y, z);
69 arr[1] = BDS::Linear2D<T>(p[1], y, z);
70 return BDS::Linear1D<T>(arr, x);
71 }
72
74 template<class T>
75 T Linear4D(const T p[2][2][2][2],
76 G4double x,
77 G4double y,
78 G4double z,
79 G4double t)
80 {
81 T arr[2];
82 arr[0] = BDS::Linear3D<T>(p[0], y, z, t);
83 arr[1] = BDS::Linear3D<T>(p[1], y, z, t);
84 return BDS::Linear1D<T>(arr, x);
85 }
86
89 template<class T>
90 T Cubic1D(const T p[4],
91 G4double x)
92 {
93 return p[1]+0.5 * x*(p[2]-p[0]+x*(2.*p[0]-5.*p[1]+4.*p[2]-p[3]+x*(3.*(p[1]-p[2])+p[3]-p[0])));
94 }
95
97 template<class T>
98 T Cubic2D(const T p[4][4],
99 G4double x,
100 G4double y)
101 {
102 T arr[4];
103 arr[0] = BDS::Cubic1D<T>(p[0], y);
104 arr[1] = BDS::Cubic1D<T>(p[1], y);
105 arr[2] = BDS::Cubic1D<T>(p[2], y);
106 arr[3] = BDS::Cubic1D<T>(p[3], y);
107 return BDS::Cubic1D<T>(arr, x);
108 }
109
111 template<class T>
112 T Cubic3D(const T p[4][4][4],
113 G4double x,
114 G4double y,
115 G4double z)
116 {
117 T arr[4];
118 arr[0] = BDS::Cubic2D<T>(p[0], y, z);
119 arr[1] = BDS::Cubic2D<T>(p[1], y, z);
120 arr[2] = BDS::Cubic2D<T>(p[2], y, z);
121 arr[3] = BDS::Cubic2D<T>(p[3], y, z);
122 return BDS::Cubic1D<T>(arr, x);
123 }
124
126 template<class T>
127 T Cubic4D(const T p[4][4][4][4],
128 G4double x,
129 G4double y,
130 G4double z,
131 G4double t)
132 {
133 T arr[4];
134 arr[0] = BDS::Cubic3D<T>(p[0], y, z, t);
135 arr[1] = BDS::Cubic3D<T>(p[1], y, z, t);
136 arr[2] = BDS::Cubic3D<T>(p[2], y, z, t);
137 arr[3] = BDS::Cubic3D<T>(p[3], y, z, t);
138 return BDS::Cubic1D<T>(arr, x);
139 }
140
142 template<class T>
143 double Linear1DMagOnly(const T p[2],
144 G4double x)
145 {
146 return (double)(mag(p[0])*(1.-x) + mag(p[1])*x);
147 }
148
150 template<class T>
151 double Linear2DMagOnly(const T p[2][2],
152 G4double x,
153 G4double y)
154 {
155 double arr[2];
156 arr[0] = BDS::Linear1DMagOnly(p[0], y);
157 arr[1] = BDS::Linear1DMagOnly(p[1], y);
158 return BDS::Linear1DMagOnly(arr, x);
159 }
160
162 template<class T>
163 double Linear3DMagOnly(const T p[2][2][2],
164 G4double x,
165 G4double y,
166 G4double z)
167 {
168 double arr[2];
169 arr[0] = BDS::Linear2DMagOnly(p[0], y, z);
170 arr[1] = BDS::Linear2DMagOnly(p[1], y, z);
171 return BDS::Linear1DMagOnly(arr, x);
172 }
173
175 template<class T>
176 double Linear4DMagOnly(const T p[2][2][2][2],
177 G4double x,
178 G4double y,
179 G4double z,
180 G4double t)
181 {
182 double arr[2];
183 arr[0] = BDS::Linear3DMagOnly(p[0], y, z, t);
184 arr[1] = BDS::Linear3DMagOnly(p[1], y, z, t);
185 return BDS::Linear1DMagOnly(arr, x);
186 }
187
189 template<class T>
190 T Linear1DMag(const T p[2],
191 G4double x)
192 {
193 T v = BDS::Linear1D(p,x);
194 double vMag = Linear1DMagOnly(p, x);
195 double factor = vMag / mag(v);
196 if (std::isnan(factor))
197 {factor = 1.0;}
198 v *= factor;
199 return v;
200 }
201
203 template<class T>
204 T Linear2DMag(const T p[2][2],
205 G4double x,
206 G4double y)
207 {
208 T v = BDS::Linear2D(p, x, y);
209 double vMag = BDS::Linear2DMagOnly(p, x, y);
210 double factor = vMag / mag(v);
211 if (std::isnan(factor))
212 {factor = 1.0;}
213 v *= factor;
214 return v;
215 }
216
218 template<class T>
219 T Linear3DMag(const T p[2][2][2],
220 G4double x,
221 G4double y,
222 G4double z)
223 {
224 T v = BDS::Linear3D(p, x, y, z);
225 double vMag = BDS::Linear3DMagOnly(p, x, y, z);
226 double factor = vMag / mag(v);
227 if (std::isnan(factor))
228 {factor = 1.0;}
229 v *= factor;
230 return v;
231 }
232
234 template<class T>
235 T Linear4DMag(const T p[2][2][2][2],
236 G4double x,
237 G4double y,
238 G4double z,
239 G4double t)
240 {
241 T v = BDS::Linear4D(p, x, y, z, t);
242 double vMag = BDS::Linear4DMagOnly(p, x, y, z, t);
243 double factor = vMag / mag(v);
244 if (std::isnan(factor))
245 {factor = 1.0;}
246 v *= factor;
247 return v;
248 }
249}
250
251#endif
T mag() const
Get the magnitude of it.
Return either G4Tubs or G4CutTubs depending on flat face.
T Cubic3D(const T p[4][4][4], G4double x, G4double y, G4double z)
Cubic interpolation in 3 dimensions.
T Linear3DMag(const T p[2][2][2], G4double x, G4double y, G4double z)
Linear interpolation in 3 dimensions including magnitude interpolation.
T Linear1D(const T p[2], G4double x)
T Cubic4D(const T p[4][4][4][4], G4double x, G4double y, G4double z, G4double t)
Cubic interpolation in 4 dimensions.
T Linear1DMag(const T p[2], G4double x)
Linear interpolation in 1 dimension including magnitude interpolation.
T Cubic1D(const T p[4], G4double x)
T Linear4D(const T p[2][2][2][2], G4double x, G4double y, G4double z, G4double t)
Linear interpolation in 4 dimensions.
double Linear4DMagOnly(const T p[2][2][2][2], G4double x, G4double y, G4double z, G4double t)
Linear interpolation of the magnitude in 4 dimensions.
T Linear3D(const T p[2][2][2], G4double x, G4double y, G4double z)
Linear interpolation in 3 dimensions.
double Linear1DMagOnly(const T p[2], G4double x)
Linear interpolation of the magnitude in 1 dimension.
T mag(const T &v)
T Linear2D(const T p[2][2], G4double x, G4double y)
Linear interpolation in 2 dimensions.
T Linear2DMag(const T p[2][2], G4double x, G4double y)
Linear interpolation in 2 dimensions including magnitude interpolation.
T Linear4DMag(const T p[2][2][2][2], G4double x, G4double y, G4double z, G4double t)
Linear interpolation in 4 dimensions including magnitude interpolation.
T Cubic2D(const T p[4][4], G4double x, G4double y)
Cubic interpolation in 2 dimensions.
double Linear3DMagOnly(const T p[2][2][2], G4double x, G4double y, G4double z)
Linear interpolation of the magnitude in 3 dimensions.
double Linear2DMagOnly(const T p[2][2], G4double x, G4double y)
Linear interpolation of the magnitude in 2 dimensions.