1#ifndef OPALX_AstraFIELDMAP1DDYNAMIC_HH
2#define OPALX_AstraFIELDMAP1DDYNAMIC_HH
7#include <Kokkos_Core.hpp>
8#include <Kokkos_DualView.hpp>
55 double& xIni,
double& xFinal,
double& yIni,
double& yFinal,
double& zIni,
56 double& zFinal)
const override;
59 virtual void swap()
override;
62 virtual void getInfo(Inform* msg)
override;
90 template <
class ViewType>
93 const ViewType& FourCoefs,
double zbegin,
double length,
double xlrep,
int accuracy) {
94 const double RR2 = R(0) * R(0) + R(1) * R(1);
99 const double kz = two_pi * (R(2) - zbegin) / length + pi;
101 double ez = FourCoefs(0);
107 for (
int l = 1; l < accuracy; ++l, n += 2) {
108 const double base = dk * l;
110 const double coskzl = Kokkos::cos(kz * l);
111 const double sinkzl = Kokkos::sin(kz * l);
113 ez += FourCoefs(n) * coskzl - FourCoefs(n + 1) * sinkzl;
114 ezp += base * (-FourCoefs(n) * sinkzl - FourCoefs(n + 1) * coskzl);
115 ezpp += base * base * (-FourCoefs(n) * coskzl + FourCoefs(n + 1) * sinkzl);
116 ezppp += base * base * base * (FourCoefs(n) * sinkzl + FourCoefs(n + 1) * coskzl);
119 const double f = -(ezpp + ez * xlrep * xlrep) / 16.0;
120 const double fp = -(ezppp + ezp * xlrep * xlrep) / 16.0;
122 const double EfieldR = -(ezp / 2.0 + fp * RR2);
123 const double BfieldT = (ez / 2.0 + f * RR2) * xlrep /
Physics::c;
125 E(0) += EfieldR * R(0);
126 E(1) += EfieldR * R(1);
127 E(2) += ez + 4.0 * f * RR2;
129 B(0) -= BfieldT * R(1);
130 B(1) += BfieldT * R(0);
133 template <
class ViewType>
136 const ViewType& FourCoefs,
double zbegin,
double zend,
double length,
double xlrep,
137 int accuracy,
double electricScale,
double magneticScale,
double startField,
139 if (R(2) < startField || R(2) >= endField) {
143 if (R(2) < zbegin || R(2) >= zend) {
149 computeField(R, tmpE, tmpB, FourCoefs, zbegin, length, xlrep, accuracy);
151 E += electricScale * tmpE;
152 B += magneticScale * tmpB;
155 template <
class ViewType>
158 const ViewType& FourCoefs,
double zbegin,
double zend,
double length,
double xlrep,
159 int accuracy,
double entryElectricScale,
double entryMagneticScale,
160 double core1ElectricScale,
double core1MagneticScale,
double core2ElectricScale,
161 double core2MagneticScale,
double exitElectricScale,
double exitMagneticScale,
162 double startCoreField,
double startExitField,
double mappedStartExitField,
163 double periodLength,
double cellLength,
double elementLength) {
164 if (R(2) < -0.5 * periodLength || R(2) + 0.5 * periodLength >= elementLength) {
171 if (tmpR(2) < startCoreField) {
172 if (!(tmpR(2) >= zbegin && tmpR(2) < zend)) {
176 computeField(tmpR, tmpE, tmpB, FourCoefs, zbegin, length, xlrep, accuracy);
177 E += entryElectricScale * tmpE;
178 B += entryMagneticScale * tmpB;
179 }
else if (tmpR(2) < startExitField) {
180 tmpR(2) -= startCoreField;
181 const double z = tmpR(2);
183 tmpR(2) = tmpR(2) - periodLength * Kokkos::floor(tmpR(2) / periodLength);
184 tmpR(2) += startCoreField;
186 if (!(tmpR(2) >= zbegin && tmpR(2) < zend)) {
190 computeField(tmpR, tmpE, tmpB, FourCoefs, zbegin, length, xlrep, accuracy);
191 E += core1ElectricScale * tmpE;
192 B += core1MagneticScale * tmpB;
197 tmpR(2) = z + cellLength;
198 tmpR(2) = tmpR(2) - periodLength * Kokkos::floor(tmpR(2) / periodLength);
199 tmpR(2) += startCoreField;
201 if (!(tmpR(2) >= zbegin && tmpR(2) < zend)) {
205 computeField(tmpR, tmpE, tmpB, FourCoefs, zbegin, length, xlrep, accuracy);
206 E += core2ElectricScale * tmpE;
207 B += core2MagneticScale * tmpB;
209 tmpR(2) -= mappedStartExitField;
211 if (!(tmpR(2) >= zbegin && tmpR(2) < zend)) {
215 computeField(tmpR, tmpE, tmpB, FourCoefs, zbegin, length, xlrep, accuracy);
216 E += exitElectricScale * tmpE;
217 B += exitMagneticScale * tmpB;
226 void applyField(std::shared_ptr<ParticleContainer_t> pc,
double)
override;
241 std::shared_ptr<ParticleContainer_t> pc,
double electricScale,
double magneticScale,
242 double startField,
double endField);
279 std::shared_ptr<ParticleContainer_t> pc,
double entryElectricScale,
280 double entryMagneticScale,
double core1ElectricScale,
double core1MagneticScale,
281 double core2ElectricScale,
double core2MagneticScale,
double exitElectricScale,
282 double exitMagneticScale,
double startField,
double startCoreField,
283 double startExitField,
double mappedStartExitField,
double periodLength,
284 double cellLength,
double elementLength);
286 virtual void getOnaxisEz(std::vector<std::pair<double, double>>& F)
override;
ippl::Vector< T, Dim > Vector_t
double xlrep_m
Wave number (omega / c)
static KOKKOS_INLINE_FUNCTION void computeTravelingWaveField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double zend, double length, double xlrep, int accuracy, double entryElectricScale, double entryMagneticScale, double core1ElectricScale, double core1MagneticScale, double core2ElectricScale, double core2MagneticScale, double exitElectricScale, double exitMagneticScale, double startCoreField, double startExitField, double mappedStartExitField, double periodLength, double cellLength, double elementLength)
void freeMap() override
Pure virtual method to free the map data.
virtual double getFrequency() const override
Get the frequency.
Kokkos::DualView< double * > FourCoefs_m
Fourier coefficients of Ez(z) (device-accessible) Stored as: [a0, a1, b1, a2, b2, ....
static KOKKOS_INLINE_FUNCTION void computeField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double length, double xlrep, int accuracy)
void applyRFField(std::shared_ptr< ParticleContainer_t > pc, double electricScale, double magneticScale, double startField, double endField)
Apply RF-scaled Astra1DDynamic field to all particles.
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F) override
static KOKKOS_INLINE_FUNCTION void computeRFField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &FourCoefs, double zbegin, double zend, double length, double xlrep, int accuracy, double electricScale, double magneticScale, double startField, double endField)
int accuracy_m
Number of Fourier modes used.
virtual void setFrequency(double freq) override
Set the frequency.
virtual void getInfo(Inform *msg) override
Print info about the field map.
virtual void swap() override
Swap coordinates.
bool isInside(const Vector_t< double, 3 > &r) const override
Checks if the given coordinate is inside the volume covered by the fieldmap.
void applyField(std::shared_ptr< ParticleContainer_t > pc, double) override
Apply the FM to all the particles.
void applyTravelingWave(std::shared_ptr< ParticleContainer_t > pc, double entryElectricScale, double entryMagneticScale, double core1ElectricScale, double core1MagneticScale, double core2ElectricScale, double core2MagneticScale, double exitElectricScale, double exitMagneticScale, double startField, double startCoreField, double startExitField, double mappedStartExitField, double periodLength, double cellLength, double elementLength)
Apply the traveling-wave RF field map to all particles.
int num_gridpz_m
Number of grid points in z-direction (input sampling)
double length_m
Effective periodic length of the field map [m].
void readMap() override
Pure virtual method to read the map data. Called by the public static readMap().
double zbegin_m
Z Bounds relative to element edge.
virtual void getFieldDimensions(double &zBegin, double &zEnd) const override
Get the longitudinal dimensions of the field.
virtual bool getFieldDerivative(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const DiffDirection &dir) const override
Get the field derivative with respect to a direction.
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const override
Get the field strength at a given point.
Abstract base class for all field maps. It acts as a factory for creating specific field map types ba...
constexpr double two_pi
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.