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) Royal Holloway,
3University of London 2001 - 2023.
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#ifndef BDSINTERPOLATORROUTINES_H
20#define BDSINTERPOLATORROUTINES_H
21
22#include "G4Types.hh"
23
24#include "BDSFieldValue.hh"
25
26#include <cmath>
27
28namespace BDS
29{
30 // These routines are templated for any type. They can be used with a type
31 // that provides both L and R operator+ operator- with their own type and
32 // operator+ operator- operator* with a double.
33
36 template<class T>
37 T mag(const T& v) {return std::abs(v);}
39 template<template<class> class BDSFieldValue, class V>
40 V mag(const BDSFieldValue<V>& v){return v.mag();}
41
44 template<class T>
45 T Linear1D(const T p[2],
46 G4double x)
47 {return p[0]*(1.-x) + p[1]*x;}
48
50 template<class T>
51 T Linear2D(const T p[2][2],
52 G4double x,
53 G4double y)
54 {
55 T arr[2];
56 arr[0] = BDS::Linear1D<T>(p[0], y);
57 arr[1] = BDS::Linear1D<T>(p[1], y);
58 return BDS::Linear1D<T>(arr, x);
59 }
60
62 template<class T>
63 T Linear3D(const T p[2][2][2],
64 G4double x,
65 G4double y,
66 G4double z)
67 {
68 T arr[2];
69 arr[0] = BDS::Linear2D<T>(p[0], y, z);
70 arr[1] = BDS::Linear2D<T>(p[1], y, z);
71 return BDS::Linear1D<T>(arr, x);
72 }
73
75 template<class T>
76 T Linear4D(const T p[2][2][2][2],
77 G4double x,
78 G4double y,
79 G4double z,
80 G4double t)
81 {
82 T arr[2];
83 arr[0] = BDS::Linear3D<T>(p[0], y, z, t);
84 arr[1] = BDS::Linear3D<T>(p[1], y, z, t);
85 return BDS::Linear1D<T>(arr, x);
86 }
87
90 template<class T>
91 T Cubic1D(const T p[4],
92 G4double x)
93 {
94 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])));
95 }
96
98 template<class T>
99 T Cubic2D(const T p[4][4],
100 G4double x,
101 G4double y)
102 {
103 T arr[4];
104 arr[0] = BDS::Cubic1D<T>(p[0], y);
105 arr[1] = BDS::Cubic1D<T>(p[1], y);
106 arr[2] = BDS::Cubic1D<T>(p[2], y);
107 arr[3] = BDS::Cubic1D<T>(p[3], y);
108 return BDS::Cubic1D<T>(arr, x);
109 }
110
112 template<class T>
113 T Cubic3D(const T p[4][4][4],
114 G4double x,
115 G4double y,
116 G4double z)
117 {
118 T arr[4];
119 arr[0] = BDS::Cubic2D<T>(p[0], y, z);
120 arr[1] = BDS::Cubic2D<T>(p[1], y, z);
121 arr[2] = BDS::Cubic2D<T>(p[2], y, z);
122 arr[3] = BDS::Cubic2D<T>(p[3], y, z);
123 return BDS::Cubic1D<T>(arr, x);
124 }
125
127 template<class T>
128 T Cubic4D(const T p[4][4][4][4],
129 G4double x,
130 G4double y,
131 G4double z,
132 G4double t)
133 {
134 T arr[4];
135 arr[0] = BDS::Cubic3D<T>(p[0], y, z, t);
136 arr[1] = BDS::Cubic3D<T>(p[1], y, z, t);
137 arr[2] = BDS::Cubic3D<T>(p[2], y, z, t);
138 arr[3] = BDS::Cubic3D<T>(p[3], y, z, t);
139 return BDS::Cubic1D<T>(arr, x);
140 }
141
143 template<class T>
144 double Linear1DMagOnly(const T p[2],
145 G4double x)
146 {
147 return (double)(mag(p[0])*(1.-x) + mag(p[1])*x);
148 }
149
151 template<class T>
152 double Linear2DMagOnly(const T p[2][2],
153 G4double x,
154 G4double y)
155 {
156 double arr[2];
157 arr[0] = BDS::Linear1DMagOnly(p[0], y);
158 arr[1] = BDS::Linear1DMagOnly(p[1], y);
159 return BDS::Linear1DMagOnly(arr, x);
160 }
161
163 template<class T>
164 double Linear3DMagOnly(const T p[2][2][2],
165 G4double x,
166 G4double y,
167 G4double z)
168 {
169 double arr[2];
170 arr[0] = BDS::Linear2DMagOnly(p[0], y, z);
171 arr[1] = BDS::Linear2DMagOnly(p[1], y, z);
172 return BDS::Linear1DMagOnly(arr, x);
173 }
174
176 template<class T>
177 double Linear4DMagOnly(const T p[2][2][2][2],
178 G4double x,
179 G4double y,
180 G4double z,
181 G4double t)
182 {
183 double arr[2];
184 arr[0] = BDS::Linear3DMagOnly(p[0], y, z, t);
185 arr[1] = BDS::Linear3DMagOnly(p[1], y, z, t);
186 return BDS::Linear1DMagOnly(arr, x);
187 }
188
190 template<class T>
191 T Linear1DMag(const T p[2],
192 G4double x)
193 {
194 T v = BDS::Linear1D(p,x);
195 double vMag = Linear1DMagOnly(p, x);
196 double factor = vMag / mag(v);
197 if (std::isnan(factor))
198 {factor = 1.0;}
199 v *= factor;
200 return v;
201 }
202
204 template<class T>
205 T Linear2DMag(const T p[2][2],
206 G4double x,
207 G4double y)
208 {
209 T v = BDS::Linear2D(p, x, y);
210 double vMag = BDS::Linear2DMagOnly(p, x, y);
211 double factor = vMag / mag(v);
212 if (std::isnan(factor))
213 {factor = 1.0;}
214 v *= factor;
215 return v;
216 }
217
219 template<class T>
220 T Linear3DMag(const T p[2][2][2],
221 G4double x,
222 G4double y,
223 G4double z)
224 {
225 T v = BDS::Linear3D(p, x, y, z);
226 double vMag = BDS::Linear3DMagOnly(p, x, y, z);
227 double factor = vMag / mag(v);
228 if (std::isnan(factor))
229 {factor = 1.0;}
230 v *= factor;
231 return v;
232 }
233
235 template<class T>
236 T Linear4DMag(const T p[2][2][2][2],
237 G4double x,
238 G4double y,
239 G4double z,
240 G4double t)
241 {
242 T v = BDS::Linear4D(p, x, y, z, t);
243 double vMag = BDS::Linear4DMagOnly(p, x, y, z, t);
244 double factor = vMag / mag(v);
245 if (std::isnan(factor))
246 {factor = 1.0;}
247 v *= factor;
248 return v;
249 }
250}
251
252#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.