OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
MultipoleTBase.h
Go to the documentation of this file.
1//
2// Cubic Spline Interpolation to replace GSL spline
3//
4// Copyright (c) 2023, Paul Scherrer Institute, Villigen PSI, Switzerland
5// All rights reserved
6//
7// This file is part of OPAL.
8//
9// OPAL is free software: you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation, either version 3 of the License, or
12// (at your option) any later version.
13//
14// You should have received a copy of the GNU General License
15// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
16//
17
18#ifndef ABSBEAMLINE_MULTIPOLET_BASE_H
19#define ABSBEAMLINE_MULTIPOLET_BASE_H
20
21#include "PartBunch/PartBunch.h"
22
69class MultipoleT;
70class BeamlineVisitor;
71class BGeometryBase;
72
74public:
76 explicit MultipoleTBase(MultipoleT* element);
78 virtual ~MultipoleTBase() = default;
79
80protected:
82 Kokkos::View<double**> tanhCoefficientsGpu_m;
83 Kokkos::View<double**>::host_mirror_type tanhCoefficientsHost_m;
84
85public:
87 virtual void initialise() = 0;
89 virtual BGeometryBase* getGeometry() = 0;
91 virtual void getField(
92 Kokkos::View<Vector_t<double, 3>*> /*R*/, Kokkos::View<Vector_t<double, 3>*> /*E*/,
93 Kokkos::View<Vector_t<double, 3>*> /*B*/, double /*scaling*/, size_t /*count*/) = 0;
94
96 virtual bool getField(
97 const Vector_t<double, 3>& /*R*/, Vector_t<double, 3>& /*E*/,
98 Vector_t<double, 3>& /*B*/, double /*scaling*/) = 0;
99
100 // Constants
101 static constexpr size_t MaxFactorial = 20;
102 static constexpr size_t MaxPowerInteger = 20;
103 static constexpr unsigned int MaxDerivatives = 20;
104
106 KOKKOS_INLINE_FUNCTION static double factorial(unsigned int n);
108 KOKKOS_INLINE_FUNCTION static double powerInteger(double x, unsigned int n);
110 KOKKOS_INLINE_FUNCTION static void calcTransverseDerivatives(
111 const Kokkos::Array<double, MultipoleTConfig::NumPoles>& poles,
112 unsigned int numDerivatives, double x,
113 Kokkos::Array<double, MaxDerivatives>& derivatives);
114 template <class ViewType>
115 KOKKOS_INLINE_FUNCTION static void calcFringeDerivatives(
116 const double& s0, const double& lambdaLeft, const double& lambdaRight, double s,
117 const ViewType& tanhCoefficients, Kokkos::Array<double, MaxDerivatives>& derivatives);
118 void generateTanhCoefficients(unsigned int numDerivatives);
119 KOKKOS_INLINE_FUNCTION static Vector_t<double, 3> rotateFrame(
120 const Vector_t<double, 3>& R, const MultipoleTConfig& config);
121 KOKKOS_INLINE_FUNCTION static void calcPowers(
122 double value, unsigned int maxPower, Kokkos::Array<double, MaxPowerInteger>& powers);
123};
124
125KOKKOS_INLINE_FUNCTION
126double MultipoleTBase::factorial(const unsigned int n) {
127 static constexpr double factorialTable[MaxFactorial + 1] = {
128 1.0,
129 1.0,
130 2.0,
131 6.0,
132 24.0,
133 120.0,
134 720.0,
135 5040.0,
136 40320.0,
137 362880.0,
138 3628800.0,
139 39916800.0,
140 479001600.0,
141 6227020800.0,
142 87178291200.0,
143 1307674368000.0,
144 20922789888000.0,
145 355687428096000.0,
146 6402373705728000.0,
147 121645100408832000.0,
148 2432902008176640000.0};
149 return factorialTable[n];
150}
151
152KOKKOS_INLINE_FUNCTION
153double MultipoleTBase::powerInteger(double x, unsigned int n) {
154 double result = 1.0;
155 while (n > 0) {
156 if (n & 1) {
157 result *= x;
158 }
159 x *= x;
160 n >>= 1;
161 }
162 return result;
163}
164
165KOKKOS_INLINE_FUNCTION
167 const Kokkos::Array<double, MultipoleTConfig::NumPoles>& poles,
168 const unsigned int numDerivatives, const double x,
169 Kokkos::Array<double, MaxDerivatives>& derivatives) {
170 Kokkos::Array<double, MultipoleTConfig::NumPoles> coefficients = poles;
171 for (unsigned int i = 0; i < numDerivatives; ++i) {
172 // Calculate the value of this derivative
173 derivatives[i] = 0;
174 for (unsigned int j = 0; j < MultipoleTConfig::NumPoles; ++j) {
175 derivatives[i] += coefficients[j] * powerInteger(x, j);
176 }
177 // Differentiate for the next derivative
178 for (unsigned int j = 0; j < MultipoleTConfig::NumPoles - 1; ++j) {
179 coefficients[j] = coefficients[j + 1] * static_cast<double>(j + 1);
180 }
181 coefficients[MultipoleTConfig::NumPoles - 1] = 0.0;
182 }
183}
184
185template <class ViewType>
186KOKKOS_INLINE_FUNCTION void MultipoleTBase::calcFringeDerivatives(
187 const double& s0, const double& lambdaLeft, const double& lambdaRight, const double s,
188 const ViewType& tanhCoefficients, Kokkos::Array<double, MaxDerivatives>& derivatives) {
189 const double tLeft = Kokkos::tanh((s + s0) / lambdaLeft);
190 const double tRight = Kokkos::tanh((s - s0) / lambdaRight);
191 double lambdaLeftN = 1.0;
192 double lambdaRightN = 1.0;
193 const unsigned int numDerivatives = tanhCoefficients.extent(0);
194 const unsigned int numCoefficients = tanhCoefficients.extent(1);
195 for (unsigned int i = 0; i < numDerivatives; ++i) {
196 // Evaluate the polynomial for both left and right
197 double tLeftN = 1.0;
198 double tRightN = 1.0;
199 double leftTerm = 0.0;
200 double rightTerm = 0.0;
201 for (unsigned int j = 0; j < numCoefficients; ++j) {
202 const auto coeff = tanhCoefficients(i, j);
203 leftTerm += coeff * tLeftN;
204 rightTerm += coeff * tRightN;
205 tLeftN *= tLeft;
206 tRightN *= tRight;
207 }
208 // Combine the left and right terms
209 derivatives[i] = (leftTerm / lambdaLeftN - rightTerm / lambdaRightN) / 2;
210 // Lambda powers for next derivative
211 lambdaLeftN *= lambdaLeft;
212 lambdaRightN *= lambdaRight;
213 }
214}
215
216KOKKOS_INLINE_FUNCTION
218 const Vector_t<double, 3>& R, const MultipoleTConfig& config) {
219 Vector_t<double, 3> R1(3), R2(3);
224 // 1st rotation
225 R1[0] = R[0] * std::cos(config.rotation_m) + R[1] * std::sin(config.rotation_m);
226 R1[1] = -R[0] * std::sin(config.rotation_m) + R[1] * std::cos(config.rotation_m);
227 R1[2] = R[2];
228 // 2nd rotation
229 R2[0] = R1[2] * std::sin(config.entranceAngle_m) + R1[0] * std::cos(config.entranceAngle_m);
230 R2[1] = R1[1];
231 R2[2] = R1[2] * std::cos(config.entranceAngle_m) - R1[0] * std::sin(config.entranceAngle_m);
232 return R2;
233}
234
235KOKKOS_INLINE_FUNCTION void MultipoleTBase::calcPowers(
236 const double value, const unsigned int maxPower,
237 Kokkos::Array<double, MaxPowerInteger>& powers) {
238 powers[0] = 1;
239 for (unsigned int i = 1; i <= maxPower; i++) {
240 powers[i] = powers[i - 1] * value;
241 }
242}
243
244#endif
ippl::Vector< T, Dim > Vector_t
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
Abstract base class for accelerator geometry classes.
Definition Geometry.h:42
virtual ~MultipoleTBase()=default
MultipoleT * element_m
static constexpr size_t MaxPowerInteger
static KOKKOS_INLINE_FUNCTION Vector_t< double, 3 > rotateFrame(const Vector_t< double, 3 > &R, const MultipoleTConfig &config)
static KOKKOS_INLINE_FUNCTION double powerInteger(double x, unsigned int n)
static KOKKOS_INLINE_FUNCTION void calcTransverseDerivatives(const Kokkos::Array< double, MultipoleTConfig::NumPoles > &poles, unsigned int numDerivatives, double x, Kokkos::Array< double, MaxDerivatives > &derivatives)
static KOKKOS_INLINE_FUNCTION void calcPowers(double value, unsigned int maxPower, Kokkos::Array< double, MaxPowerInteger > &powers)
static constexpr unsigned int MaxDerivatives
virtual void getField(Kokkos::View< Vector_t< double, 3 > * >, Kokkos::View< Vector_t< double, 3 > * >, Kokkos::View< Vector_t< double, 3 > * >, double, size_t)=0
static constexpr size_t MaxFactorial
Kokkos::View< double ** > tanhCoefficientsGpu_m
virtual void initialise()=0
virtual BGeometryBase * getGeometry()=0
static KOKKOS_INLINE_FUNCTION void calcFringeDerivatives(const double &s0, const double &lambdaLeft, const double &lambdaRight, double s, const ViewType &tanhCoefficients, Kokkos::Array< double, MaxDerivatives > &derivatives)
static KOKKOS_INLINE_FUNCTION double factorial(unsigned int n)
Kokkos::View< double ** >::host_mirror_type tanhCoefficientsHost_m
virtual bool getField(const Vector_t< double, 3 > &, Vector_t< double, 3 > &, Vector_t< double, 3 > &, double)=0
void generateTanhCoefficients(unsigned int numDerivatives)
static constexpr unsigned int NumPoles