10 #ifndef IMPACTX_RFCAVITY_H
11 #define IMPACTX_RFCAVITY_H
49 4.3443060026047219e-002,
50 8.5602654094946495e-002,
54 -5.2579522442877296e-003,
55 -5.5025369142193678e-002,
56 4.6845673335028933e-002,
57 -2.3279346335638568e-002,
58 4.0800777539657775e-003,
59 4.1378326533752169e-003,
60 -2.5040533340490805e-003,
61 -4.0654981400000964e-003,
62 9.6630592067498289e-003,
63 -8.5275895985990214e-003,
64 -5.8078747006425020e-002,
65 -2.4044337836660403e-002,
66 1.0968240064697212e-002,
67 -3.4461179858301418e-003,
68 -8.1201564869443749e-004,
69 2.1438992904959380e-003,
70 -1.4997753525697276e-003,
71 1.8685171825676386e-004
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 namespace RFCavityData
93 static inline std::map<int, std::vector<amrex::ParticleReal>>
h_cos_coef = {};
95 static inline std::map<int, std::vector<amrex::ParticleReal>>
h_sin_coef = {};
98 static inline std::map<int, amrex::Gpu::DeviceVector<amrex::ParticleReal>>
d_cos_coef = {};
100 static inline std::map<int, amrex::Gpu::DeviceVector<amrex::ParticleReal>>
d_sin_coef = {};
109 static constexpr
auto name =
"RFCavity";
128 amrex::ParticleReal
ds,
129 amrex::ParticleReal escale,
130 amrex::ParticleReal freq,
131 amrex::ParticleReal phase,
132 std::vector<amrex::ParticleReal> cos_coef,
133 std::vector<amrex::ParticleReal> sin_coef,
134 amrex::ParticleReal
dx = 0,
135 amrex::ParticleReal
dy = 0,
136 amrex::ParticleReal rotation_degree = 0,
149 if (
m_ncoef !=
int(sin_coef.size()))
150 throw std::runtime_error(
"RFCavity: cos and sin coefficients must have same length!");
162 cos_coef.begin(), cos_coef.end(),
165 sin_coef.begin(), sin_coef.end(),
175 using BeamOptic::operator();
191 amrex::ParticleReal & AMREX_RESTRICT x,
192 amrex::ParticleReal & AMREX_RESTRICT y,
193 amrex::ParticleReal & AMREX_RESTRICT t,
194 amrex::ParticleReal & AMREX_RESTRICT px,
195 amrex::ParticleReal & AMREX_RESTRICT py,
196 amrex::ParticleReal & AMREX_RESTRICT pt,
197 [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu,
198 [[maybe_unused]]
RefPart const & refpart
201 using namespace amrex::literals;
207 amrex::ParticleReal xout =
x;
208 amrex::ParticleReal yout = y;
209 amrex::ParticleReal tout =
t;
212 amrex::ParticleReal pxout = px;
213 amrex::ParticleReal pyout = py;
214 amrex::ParticleReal ptout = pt;
226 xout = R(1,1)*
x + R(1,2)*px + R(1,3)*y
227 + R(1,4)*py + R(1,5)*
t + R(1,6)*pt;
228 pxout = R(2,1)*
x + R(2,2)*px + R(2,3)*y
229 + R(2,4)*py + R(2,5)*
t + R(2,6)*pt;
230 yout = R(3,1)*
x + R(3,2)*px + R(3,3)*y
231 + R(3,4)*py + R(3,5)*
t + R(3,6)*pt;
232 pyout = R(4,1)*
x + R(4,2)*px + R(4,3)*y
233 + R(4,4)*py + R(4,5)*
t + R(4,6)*pt;
234 tout = R(5,1)*
x + R(5,2)*px + R(5,3)*y
235 + R(5,4)*py + R(5,5)*
t + R(5,6)*pt;
236 ptout = R(6,1)*
x + R(6,2)*px + R(6,3)*y
237 + R(6,4)*py + R(6,5)*
t + R(6,6)*pt;
258 using namespace amrex::literals;
261 amrex::ParticleReal
const x = refpart.x;
262 amrex::ParticleReal
const px = refpart.px;
263 amrex::ParticleReal
const y = refpart.y;
264 amrex::ParticleReal
const py = refpart.py;
265 amrex::ParticleReal
const z = refpart.z;
266 amrex::ParticleReal
const pz = refpart.pz;
267 amrex::ParticleReal
const pt = refpart.pt;
268 amrex::ParticleReal
const s = refpart.s;
269 amrex::ParticleReal
const sedge = refpart.sedge;
272 for (
int i=1;
i<7;
i++) {
273 for (
int j=1; j<7; j++) {
275 refpart.map(
i, j) = 1.0_prt;
277 refpart.map(
i, j) = 0.0_prt;
282 amrex::ParticleReal
const slice_ds =
m_ds /
nslice();
285 amrex::ParticleReal
const bgi =
sqrt(
pow(pt, 2) - 1.0_prt);
288 amrex::ParticleReal
const zin =
s - sedge;
289 amrex::ParticleReal
const zout = zin + slice_ds;
293 amrex::ParticleReal
const ptf = refpart.pt;
296 refpart.x =
x + slice_ds*px/bgi;
297 refpart.y = y + slice_ds*py/bgi;
298 refpart.z = z + slice_ds*pz/bgi;
301 amrex::ParticleReal
const bgf =
sqrt(
pow(ptf, 2) - 1.0_prt);
304 refpart.px = px*bgf/bgi;
305 refpart.py = py*bgf/bgi;
306 refpart.pz = pz*bgf/bgi;
309 amrex::ParticleReal scale_in = 1.0_prt;
310 amrex::ParticleReal scale_fin = 1.0_prt;
312 for (
int i=1;
i<7;
i++) {
313 for (
int j=1; j<7; j++) {
322 refpart.map(
i, j) = refpart.map(
i, j) * scale_in / scale_fin;
327 refpart.s =
s + slice_ds;
336 std::tuple<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>
340 using namespace amrex::literals;
344 #if AMREX_DEVICE_COMPILE
354 amrex::ParticleReal
const zlen =
m_ds;
355 amrex::ParticleReal
const zmid = zlen / 2.0_prt;
358 amrex::ParticleReal efield = 0.0;
359 amrex::ParticleReal efieldp = 0.0;
360 amrex::ParticleReal efieldpp = 0.0;
361 amrex::ParticleReal efieldint = 0.0;
362 amrex::ParticleReal
const z = zeval - zmid;
364 if (std::abs(z) <= zmid)
366 efield = 0.5_prt*cos_data[0];
367 efieldint = z*efield;
368 for (
int j=1; j <
m_ncoef; ++j)
370 efield = efield + cos_data[j]*cos(j*2*
pi*z/zlen) +
371 sin_data[j]*sin(j*2*
pi*z/zlen);
372 efieldp = efieldp-j*2*
pi*cos_data[j]*sin(j*2*
pi*z/zlen)/zlen +
373 j*2*
pi*sin_data[j]*cos(j*2*
pi*z/zlen)/zlen;
374 efieldpp = efieldpp-
pow(j*2*
pi*cos_data[j]/zlen,2) *cos(j*2*
pi*z/zlen) -
375 pow(j*2*
pi*sin_data[j]/zlen,2) *sin(j*2*
pi*z/zlen);
376 efieldint = efieldint + zlen*cos_data[j]*sin(j*2*
pi*z/zlen)/(j*2*
pi) -
377 zlen*sin_data[j]*cos(j*2*
pi*z/zlen)/(j*2*
pi);
380 return std::make_tuple(efield, efieldp, efieldint);
392 void map3 (amrex::ParticleReal
const tau,
394 [[maybe_unused]] amrex::ParticleReal & zeval)
const
396 using namespace amrex::literals;
399 amrex::ParticleReal
const t = refpart.
t;
400 amrex::ParticleReal
const pt = refpart.
pt;
403 refpart.
t =
t + tau/
sqrt(1.0_prt -
pow(pt, -2));
413 amrex::ParticleReal
const betgam = refpart.
beta_gamma();
415 refpart.
map(5,5) = R(5,5) + tau*R(6,5)/
pow(betgam,3);
416 refpart.
map(5,6) = R(5,6) + tau*R(6,6)/
pow(betgam,3);
428 void map2 (amrex::ParticleReal
const tau,
430 amrex::ParticleReal & zeval)
const
432 using namespace amrex::literals;
434 amrex::ParticleReal
const t = refpart.
t;
435 amrex::ParticleReal
const pt = refpart.
pt;
440 amrex::ParticleReal
const k = (2.0_prt*
pi/
c)*
m_freq;
441 amrex::ParticleReal
const phi =
m_phase*(
pi/180.0_prt);
442 amrex::ParticleReal
const E0 =
m_escale;
445 auto [ez, ezp, ezint] =
RF_Efield(zeval);
453 amrex::ParticleReal
const s = tau/refpart.
beta_gamma();
454 amrex::ParticleReal
const L = E0*ezp*sin(k*
t+phi)/(2.0_prt*k);
456 refpart.
map(1,1) = (1.0_prt-
s*L)*R(1,1) +
s*R(2,1);
457 refpart.
map(1,2) = (1.0_prt-
s*L)*R(1,2) +
s*R(2,2);
458 refpart.
map(2,1) = -
s*
pow(L,2)*R(1,1) + (1.0_prt+
s*L)*R(2,1);
459 refpart.
map(2,2) = -
s*
pow(L,2)*R(1,2) + (1.0_prt+
s*L)*R(2,2);
461 refpart.
map(3,3) = (1.0_prt-
s*L)*R(3,3) +
s*R(4,3);
462 refpart.
map(3,4) = (1.0_prt-
s*L)*R(3,4) +
s*R(4,4);
463 refpart.
map(4,3) = -
s*
pow(L,2)*R(3,3) + (1.0_prt+
s*L)*R(4,3);
464 refpart.
map(4,4) = -
s*
pow(L,2)*R(3,4) + (1.0_prt+
s*L)*R(4,4);
476 void map1 (amrex::ParticleReal
const tau,
478 amrex::ParticleReal & zeval)
const
480 using namespace amrex::literals;
482 amrex::ParticleReal
const t = refpart.
t;
483 amrex::ParticleReal
const pt = refpart.
pt;
484 amrex::ParticleReal
const z = zeval;
489 amrex::ParticleReal
const k = (2.0_prt*
pi/
c)*
m_freq;
490 amrex::ParticleReal
const phi =
m_phase*(
pi/180.0_prt);
491 amrex::ParticleReal
const E0 =
m_escale;
497 auto [ezf, ezpf, ezintf] =
RF_Efield(zeval);
501 refpart.
pt = pt - E0*(ezintf-ezint)*cos(k*
t+phi);
505 amrex::ParticleReal
const M = E0*(ezintf-ezint)*k*sin(k*
t+phi);
506 amrex::ParticleReal
const L = E0*(ezpf-ezp)*sin(k*
t+phi)/(2.0_prt*k)+M/2.0_prt;
508 refpart.
map(2,1) = L*R(1,1) + R(2,1);
509 refpart.
map(2,2) = L*R(1,2) + R(2,2);
511 refpart.
map(4,3) = L*R(3,3) + R(4,3);
512 refpart.
map(4,4) = L*R(3,4) + R(4,4);
514 refpart.
map(6,5) = M*R(5,5) + R(6,5);
515 refpart.
map(6,6) = M*R(5,6) + R(6,6);
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
T_ParticleType ParticleType
static constexpr amrex::Real pi
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
static constexpr HostToDevice hostToDevice
void streamSynchronize() noexcept
constexpr std::enable_if_t< std::is_floating_point< T >::value, T > pi()
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > pow(const GpuComplex< T > &a_z, const T &a_y) noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
static std::map< int, std::vector< amrex::ParticleReal > > h_cos_coef
host: cosine coefficients in Fourier expansion of on-axis electric field Ez
Definition: RFCavity.H:93
static std::map< int, std::vector< amrex::ParticleReal > > h_sin_coef
host: sine coefficients in Fourier expansion of on-axis electric field Ez
Definition: RFCavity.H:95
static std::map< int, amrex::Gpu::DeviceVector< amrex::ParticleReal > > d_sin_coef
device: sine coefficients in Fourier expansion of on-axis electric field Ez
Definition: RFCavity.H:100
static std::map< int, amrex::Gpu::DeviceVector< amrex::ParticleReal > > d_cos_coef
device: cosine coefficients in Fourier expansion of on-axis electric field Ez
Definition: RFCavity.H:98
static int next_id
last used id for a created RF cavity
Definition: RFCavity.H:90
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp2_integrate_split3(RefPart &refpart, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition: Integrators.H:51
Definition: ImpactX.cpp:33
@ t
fixed t as the independent variable
Definition: RFCavity.H:45
amrex::Vector< amrex::ParticleReal > default_sin_coef
Definition: RFCavity.H:74
amrex::Vector< amrex::ParticleReal > default_cos_coef
Definition: RFCavity.H:46
Definition: RFCavity.H:108
amrex::ParticleReal m_escale
Definition: RFCavity.H:535
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map2(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition: RFCavity.H:428
amrex::ParticleReal * m_cos_h_data
number of Fourier coefficients
Definition: RFCavity.H:542
amrex::ParticleReal m_phase
RF frequency in Hz.
Definition: RFCavity.H:537
void finalize()
Definition: RFCavity.H:521
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(amrex::ParticleReal &AMREX_RESTRICT x, amrex::ParticleReal &AMREX_RESTRICT y, amrex::ParticleReal &AMREX_RESTRICT t, amrex::ParticleReal &AMREX_RESTRICT px, amrex::ParticleReal &AMREX_RESTRICT py, amrex::ParticleReal &AMREX_RESTRICT pt, [[maybe_unused]] uint64_t &AMREX_RESTRICT idcpu, [[maybe_unused]] RefPart const &refpart) const
Definition: RFCavity.H:190
amrex::ParticleReal * m_cos_d_data
non-owning pointer to host sine coefficients
Definition: RFCavity.H:544
int m_mapsteps
RF driven phase in deg.
Definition: RFCavity.H:538
RFCavity(amrex::ParticleReal ds, amrex::ParticleReal escale, amrex::ParticleReal freq, amrex::ParticleReal phase, std::vector< amrex::ParticleReal > cos_coef, std::vector< amrex::ParticleReal > sin_coef, amrex::ParticleReal dx=0, amrex::ParticleReal dy=0, amrex::ParticleReal rotation_degree=0, int mapsteps=1, int nslice=1)
Definition: RFCavity.H:127
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map1(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition: RFCavity.H:476
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map3(amrex::ParticleReal const tau, RefPart &refpart, [[maybe_unused]] amrex::ParticleReal &zeval) const
Definition: RFCavity.H:392
std::tuple< amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal > AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE RF_Efield(amrex::ParticleReal const zeval) const
Definition: RFCavity.H:338
static constexpr auto name
Definition: RFCavity.H:109
amrex::ParticleReal * m_sin_d_data
non-owning pointer to device cosine coefficients
Definition: RFCavity.H:545
ImpactXParticleContainer::ParticleType PType
Definition: RFCavity.H:110
int m_id
number of map integration steps per slice
Definition: RFCavity.H:539
amrex::ParticleReal * m_sin_h_data
non-owning pointer to host cosine coefficients
Definition: RFCavity.H:543
amrex::ParticleReal m_freq
scaling factor for RF electric field
Definition: RFCavity.H:536
int m_ncoef
unique RF cavity id used for data lookup map
Definition: RFCavity.H:541
Definition: ReferenceParticle.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal beta_gamma() const
Definition: ReferenceParticle.H:79
amrex::ParticleReal pt
energy, normalized by rest energy
Definition: ReferenceParticle.H:39
amrex::Array2D< amrex::ParticleReal, 1, 6, 1, 6 > map
linearized map
Definition: ReferenceParticle.H:44
amrex::ParticleReal t
clock time * c in meters
Definition: ReferenceParticle.H:35
Definition: alignment.H:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shift_out(amrex::ParticleReal &AMREX_RESTRICT x, amrex::ParticleReal &AMREX_RESTRICT y, amrex::ParticleReal &AMREX_RESTRICT px, amrex::ParticleReal &AMREX_RESTRICT py) const
Definition: alignment.H:91
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dx() const
Definition: alignment.H:120
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shift_in(amrex::ParticleReal &AMREX_RESTRICT x, amrex::ParticleReal &AMREX_RESTRICT y, amrex::ParticleReal &AMREX_RESTRICT px, amrex::ParticleReal &AMREX_RESTRICT py) const
Definition: alignment.H:61
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dy() const
Definition: alignment.H:130
Definition: beamoptic.H:149
Thick(amrex::ParticleReal ds, int nslice)
Definition: thick.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal ds() const
Definition: thick.H:53
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int nslice() const
Definition: thick.H:43
amrex::ParticleReal m_ds
Definition: thick.H:58