OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
MultipoleTStraight.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_STRAIGHT_H
19#define ABSBEAMLINE_MULTIPOLET_STRAIGHT_H
20
69
70class MultipoleTStraight final : public MultipoleTBase {
71public:
73 explicit MultipoleTStraight(MultipoleT* element);
75 void initialise() override;
79 // Container-agnostic: R/E/B views come from the caller's particle container.
81 Kokkos::View<Vector_t<double, 3>*> R, Kokkos::View<Vector_t<double, 3>*> E,
82 Kokkos::View<Vector_t<double, 3>*> B, double scaling, size_t count) override;
83 bool getField(
85 double scaling) override;
86
87private:
90
91 // Helpers
92 KOKKOS_INLINE_FUNCTION static Vector_t<double, 3> toMagnetCoords(
93 const Vector_t<double, 3>& R, const MultipoleTConfig& config);
94 template <class ViewType>
95 KOKKOS_INLINE_FUNCTION static bool computeBField(
96 const Vector_t<double, 3>& R, Vector_t<double, 3>& B, double scaling,
97 const MultipoleTConfig& config, const ViewType& tanhCoefficients);
98};
99
101 const Vector_t<double, 3>& R, const MultipoleTConfig& config) {
102 // Skew and entry angle
103 Vector_t<double, 3> result = rotateFrame(R, config);
104 // Magnet origin at the center rather than entry
105 result[2] -= config.length_m / 2.0;
106 return result;
107}
108
109template <class ViewType>
110KOKKOS_INLINE_FUNCTION bool MultipoleTStraight::computeBField(
111 const Vector_t<double, 3>& R, Vector_t<double, 3>& B, const double scaling,
112 const MultipoleTConfig& config, const ViewType& tanhCoefficients) {
113 const Vector_t<double, 3> RPrime = toMagnetCoords(R, config);
114 const bool insideAperture = Kokkos::abs(RPrime[1]) <= config.verticalAperture_m / 2.0
115 && Kokkos::abs(RPrime[0]) <= config.horizontalAperture_m / 2.0;
116 const bool insideBoundingBox = config.boundingBoxLength_m == 0.0
117 || Kokkos::abs(RPrime[2]) <= config.boundingBoxLength_m / 2.0;
118 if (insideAperture && insideBoundingBox) {
120 Kokkos::Array<double, MaxDerivatives> dt;
121 Kokkos::Array<double, MaxDerivatives> ds;
123 config.transverseProfile_m, config.maxFOrder_m * 2 + 2, RPrime[0], dt);
125 config.fringeS0_m, config.fringeLambdaLeft_m, config.fringeLambdaRight_m, RPrime[2],
126 tanhCoefficients, ds);
127 for (unsigned int n = 0; n <= config.maxFOrder_m; n++) {
128 double innerSumX{};
129 double innerSumZ{};
130 double innerSumS{};
131 for (unsigned int i = 0; i <= n; i++) {
132 const double k = factorial(n) / (factorial(i) * factorial(n - i));
133 innerSumX += k * dt[2 * i + 1] * ds[2 * n - 2 * i];
134 innerSumZ += k * dt[2 * i] * ds[2 * n - 2 * i];
135 innerSumS += k * dt[2 * i] * ds[2 * n - 2 * i + 1];
136 }
137 const double negOnePowN = powerInteger(-1.0, n);
138 const double xszk =
139 powerInteger(RPrime[1], 2 * n + 1) / factorial(2 * n + 1) * negOnePowN;
140 const double zzk = powerInteger(RPrime[1], 2 * n) / factorial(2 * n) * negOnePowN;
141 myB[0] += innerSumX * xszk;
142 myB[1] += innerSumZ * zzk;
143 myB[2] += innerSumS * xszk;
144 }
145 B += myB * scaling;
146 }
147 return !insideAperture;
148}
149
150#endif
ippl::Vector< T, Dim > Vector_t
Abstract base class for accelerator geometry classes.
Definition Geometry.h:42
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 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)
static KOKKOS_INLINE_FUNCTION bool computeBField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &B, double scaling, const MultipoleTConfig &config, const ViewType &tanhCoefficients)
StraightGeometry straightGeometry_m
void getField(Kokkos::View< Vector_t< double, 3 > * > R, Kokkos::View< Vector_t< double, 3 > * > E, Kokkos::View< Vector_t< double, 3 > * > B, double scaling, size_t count) override
static KOKKOS_INLINE_FUNCTION Vector_t< double, 3 > toMagnetCoords(const Vector_t< double, 3 > &R, const MultipoleTConfig &config)
BGeometryBase * getGeometry() override
void initialise() override
A geometry representing a straight line.
unsigned int maxFOrder_m
Kokkos::Array< double, NumPoles > transverseProfile_m