10 #ifndef IMPACTX_RFCAVITY_H 11 #define IMPACTX_RFCAVITY_H 48 4.3443060026047219e-002,
49 8.5602654094946495e-002,
53 -5.2579522442877296e-003,
54 -5.5025369142193678e-002,
55 4.6845673335028933e-002,
56 -2.3279346335638568e-002,
57 4.0800777539657775e-003,
58 4.1378326533752169e-003,
59 -2.5040533340490805e-003,
60 -4.0654981400000964e-003,
61 9.6630592067498289e-003,
62 -8.5275895985990214e-003,
63 -5.8078747006425020e-002,
64 -2.4044337836660403e-002,
65 1.0968240064697212e-002,
66 -3.4461179858301418e-003,
67 -8.1201564869443749e-004,
68 2.1438992904959380e-003,
69 -1.4997753525697276e-003,
70 1.8685171825676386e-004
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92 amrex::ParticleReal* m_cos_data =
nullptr;
93 amrex::ParticleReal* m_sin_data =
nullptr;
96 amrex::ParticleReal escale,
97 amrex::ParticleReal freq,
98 amrex::ParticleReal phase,
100 ) : m_escale(escale), m_freq(freq), m_phase(phase), m_mapsteps(mapsteps)
115 static constexpr
auto name =
"RFCavity";
132 amrex::ParticleReal ds,
133 amrex::ParticleReal escale,
134 amrex::ParticleReal freq,
135 amrex::ParticleReal phase,
136 std::vector<amrex::ParticleReal> cos_coef,
137 std::vector<amrex::ParticleReal> sin_coef,
142 RFCavity_device_copyable(escale, freq, phase, mapsteps)
144 m_ncoef = cos_coef.size();
145 if (m_ncoef !=
int(sin_coef.size()))
146 throw std::runtime_error(
"RFCavity: cos and sin coefficients must have same length!");
148 m_cos_coef.resize(m_ncoef);
149 m_sin_coef.resize(m_ncoef);
151 cos_coef.begin(), cos_coef.end(),
154 sin_coef.begin(), sin_coef.end(),
158 m_cos_data = m_cos_coef.data();
159 m_sin_data = m_sin_coef.data();
164 : Thick(other.m_ds, other.m_nslice),
165 RFCavity_device_copyable(other.m_escale, other.m_freq, other.m_phase, other.m_mapsteps)
167 #if !AMREX_DEVICE_COMPILE 173 m_ncoef = m_cos_coef.size();
174 m_cos_data = m_cos_coef.data();
175 m_sin_data = m_sin_coef.data();
182 Thick::operator=(other);
183 RFCavity_device_copyable::operator=(other);
184 #if !AMREX_DEVICE_COMPILE 190 m_ncoef = m_cos_coef.size();
191 m_cos_data = m_cos_coef.data();
192 m_sin_data = m_sin_coef.data();
202 using BeamOptic::operator();
215 PType& AMREX_RESTRICT p,
216 amrex::ParticleReal & AMREX_RESTRICT px,
217 amrex::ParticleReal & AMREX_RESTRICT py,
218 amrex::ParticleReal & AMREX_RESTRICT pt,
219 [[maybe_unused]]
RefPart const & refpart
222 using namespace amrex::literals;
225 amrex::ParticleReal
const x = p.pos(0);
226 amrex::ParticleReal
const y = p.pos(1);
227 amrex::ParticleReal
const t = p.pos(2);
230 amrex::ParticleReal pxout = px;
231 amrex::ParticleReal pyout = py;
232 amrex::ParticleReal ptout = pt;
244 p.pos(0) = R(1,1)*x + R(1,2)*px + R(1,3)*y
245 + R(1,4)*py + R(1,5)*t + R(1,6)*pt;
246 pxout = R(2,1)*x + R(2,2)*px + R(2,3)*y
247 + R(2,4)*py + R(2,5)*t + R(2,6)*pt;
248 p.pos(1) = R(3,1)*x + R(3,2)*px + R(3,3)*y
249 + R(3,4)*py + R(3,5)*t + R(3,6)*pt;
250 pyout = R(4,1)*x + R(4,2)*px + R(4,3)*y
251 + R(4,4)*py + R(4,5)*t + R(4,6)*pt;
252 p.pos(2) = R(5,1)*x + R(5,2)*px + R(5,3)*y
253 + R(5,4)*py + R(5,5)*t + R(5,6)*pt;
254 ptout = R(6,1)*x + R(6,2)*px + R(6,3)*y
255 + R(6,4)*py + R(6,5)*t + R(6,6)*pt;
268 void operator() (
RefPart & AMREX_RESTRICT refpart)
const 270 using namespace amrex::literals;
273 amrex::ParticleReal
const x = refpart.x;
274 amrex::ParticleReal
const px = refpart.px;
275 amrex::ParticleReal
const y = refpart.y;
276 amrex::ParticleReal
const py = refpart.py;
277 amrex::ParticleReal
const z = refpart.z;
278 amrex::ParticleReal
const pz = refpart.pz;
279 amrex::ParticleReal
const pt = refpart.pt;
280 amrex::ParticleReal
const s = refpart.s;
281 amrex::ParticleReal
const sedge = refpart.sedge;
284 for (
int i=1;
i<7;
i++) {
285 for (
int j=1; j<7; j++) {
287 refpart.map(
i, j) = 1.0_prt;
289 refpart.map(
i, j) = 0.0_prt;
294 amrex::ParticleReal
const slice_ds = m_ds /
nslice();
297 amrex::ParticleReal
const bgi =
sqrt(
pow(pt, 2) - 1.0_prt);
300 amrex::ParticleReal
const zin = s - sedge;
301 amrex::ParticleReal
const zout = zin + slice_ds;
302 int const nsteps = m_mapsteps;
305 amrex::ParticleReal
const ptf = refpart.pt;
308 refpart.x = x + slice_ds*px/bgi;
309 refpart.y = y + slice_ds*py/bgi;
310 refpart.z = z + slice_ds*pz/bgi;
313 amrex::ParticleReal
const bgf =
sqrt(
pow(ptf, 2) - 1.0_prt);
316 refpart.px = px*bgf/bgi;
317 refpart.py = py*bgf/bgi;
318 refpart.pz = pz*bgf/bgi;
321 amrex::ParticleReal scale_in = 1.0_prt;
322 amrex::ParticleReal scale_fin = 1.0_prt;
324 for (
int i=1;
i<7;
i++) {
325 for (
int j=1; j<7; j++) {
334 refpart.map(
i, j) = refpart.map(
i, j) * scale_in / scale_fin;
339 refpart.s = s + slice_ds;
348 std::tuple<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>
352 using namespace amrex::literals;
356 amrex::ParticleReal
const zlen = m_ds;
357 amrex::ParticleReal
const zmid = zlen / 2.0_prt;
360 amrex::ParticleReal efield = 0.0;
361 amrex::ParticleReal efieldp = 0.0;
362 amrex::ParticleReal efieldpp = 0.0;
363 amrex::ParticleReal efieldint = 0.0;
364 amrex::ParticleReal
const z = zeval - zmid;
368 efield = 0.5_prt*m_cos_data[0];
369 efieldint = z*efield;
370 for (
int j=1; j < m_ncoef; ++j)
372 efield = efield + m_cos_data[j]*cos(j*2*
pi*z/zlen) +
373 m_sin_data[j]*sin(j*2*
pi*z/zlen);
374 efieldp = efieldp-j*2*
pi*m_cos_data[j]*sin(j*2*
pi*z/zlen)/zlen +
375 j*2*
pi*m_sin_data[j]*cos(j*2*
pi*z/zlen)/zlen;
376 efieldpp = efieldpp-
pow(j*2*
pi*m_cos_data[j]/zlen,2) *cos(j*2*
pi*z/zlen) -
377 pow(j*2*
pi*m_sin_data[j]/zlen,2) *sin(j*2*
pi*z/zlen);
378 efieldint = efieldint + zlen*m_cos_data[j]*sin(j*2*
pi*z/zlen)/(j*2*
pi) -
379 zlen*m_sin_data[j]*cos(j*2*
pi*z/zlen)/(j*2*
pi);
382 return std::make_tuple(efield, efieldp, efieldint);
394 void map3 (amrex::ParticleReal
const tau,
396 [[maybe_unused]] amrex::ParticleReal & zeval)
const 398 using namespace amrex::literals;
401 amrex::ParticleReal
const t = refpart.
t;
402 amrex::ParticleReal
const pt = refpart.
pt;
405 refpart.
t = t + tau/
sqrt(1.0_prt -
pow(pt, -2));
415 amrex::ParticleReal
const betgam = refpart.
beta_gamma();
417 refpart.
map(5,5) = R(5,5) + tau*R(6,5)/
pow(betgam,3);
418 refpart.
map(5,6) = R(5,6) + tau*R(6,6)/
pow(betgam,3);
430 void map2 (amrex::ParticleReal
const tau,
432 amrex::ParticleReal & zeval)
const 434 using namespace amrex::literals;
436 amrex::ParticleReal
const t = refpart.
t;
437 amrex::ParticleReal
const pt = refpart.
pt;
442 amrex::ParticleReal
const k = (2.0_prt*
pi/
c)*m_freq;
443 amrex::ParticleReal
const phi = m_phase*(
pi/180.0_prt);
444 amrex::ParticleReal
const E0 = m_escale;
447 auto [
ez, ezp, ezint] = RF_Efield(zeval);
455 amrex::ParticleReal
const s = tau/refpart.
beta_gamma();
456 amrex::ParticleReal
const L = E0*ezp*sin(k*t+phi)/(2.0_prt*k);
458 refpart.
map(1,1) = (1.0_prt-s*L)*R(1,1) + s*R(2,1);
459 refpart.
map(1,2) = (1.0_prt-s*L)*R(1,2) + s*R(2,2);
460 refpart.
map(2,1) = -s*
pow(L,2)*R(1,1) + (1.0_prt+s*L)*R(2,1);
461 refpart.
map(2,2) = -s*
pow(L,2)*R(1,2) + (1.0_prt+s*L)*R(2,2);
463 refpart.
map(3,3) = (1.0_prt-s*L)*R(3,3) + s*R(4,3);
464 refpart.
map(3,4) = (1.0_prt-s*L)*R(3,4) + s*R(4,4);
465 refpart.
map(4,3) = -s*
pow(L,2)*R(3,3) + (1.0_prt+s*L)*R(4,3);
466 refpart.
map(4,4) = -s*
pow(L,2)*R(3,4) + (1.0_prt+s*L)*R(4,4);
478 void map1 (amrex::ParticleReal
const tau,
480 amrex::ParticleReal & zeval)
const 482 using namespace amrex::literals;
484 amrex::ParticleReal
const t = refpart.
t;
485 amrex::ParticleReal
const pt = refpart.
pt;
486 amrex::ParticleReal
const z = zeval;
491 amrex::ParticleReal
const k = (2.0_prt*
pi/
c)*m_freq;
492 amrex::ParticleReal
const phi = m_phase*(
pi/180.0_prt);
493 amrex::ParticleReal
const E0 = m_escale;
496 auto [
ez, ezp, ezint] = RF_Efield(z);
499 auto [ezf, ezpf, ezintf] = RF_Efield(zeval);
503 refpart.
pt = pt - E0*(ezintf-ezint)*cos(k*t+phi);
507 amrex::ParticleReal
const M = E0*(ezintf-ezint)*k*sin(k*t+phi);
508 amrex::ParticleReal
const L = E0*(ezpf-ezp)*sin(k*t+phi)/(2.0_prt*k)+M/2.0_prt;
510 refpart.
map(2,1) = L*R(1,1) + R(2,1);
511 refpart.
map(2,2) = L*R(1,2) + R(2,2);
513 refpart.
map(4,3) = L*R(3,3) + R(4,3);
514 refpart.
map(4,4) = L*R(3,4) + R(4,4);
516 refpart.
map(6,5) = M*R(5,5) + R(6,5);
517 refpart.
map(6,6) = M*R(5,6) + R(6,6);
528 #endif // IMPACTX_RFCAVITY_H
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:53
amrex::Gpu::DeviceVector< amrex::ParticleReal > m_cos_coef
Definition: RFCavity.H:522
constexpr std::enable_if_t< std::is_floating_point< T >::value, T > pi()
Definition: ImpactX.cpp:31
static constexpr HostToDevice hostToDevice
Definition: beamoptic.H:134
amrex::ParticleReal pt
energy deviation, normalized by rest energy
Definition: ReferenceParticle.H:39
RFCavity & operator=(RFCavity const &other)
Definition: RFCavity.H:177
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
AMREX_GPU_HOST 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, int mapsteps=1, int nslice=1)
Definition: RFCavity.H:131
#define AMREX_FORCE_INLINE
amrex::ParticleReal m_freq
scaling factor for RF electric field
Definition: RFCavity.H:87
nslice
Definition: __init__.py:32
amrex::Vector< amrex::ParticleReal > default_sin_coef
Definition: RFCavity.H:73
amrex::ParticleReal m_escale
Definition: RFCavity.H:86
#define AMREX_GPU_HOST_DEVICE
amrex::ParticleReal t
clock time * c in meters
Definition: ReferenceParticle.H:35
amrex::Array2D< amrex::ParticleReal, 1, 6, 1, 6 > map
linearized map
Definition: ReferenceParticle.H:44
Particle< NStructReal, NStructInt > ParticleType
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T abs(const GpuComplex< T > &a_z) noexcept
Definition: ReferenceParticle.H:29
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > pow(const GpuComplex< T > &a_z, const T &a_y) noexcept
RFCavity(RFCavity const &other)
Definition: RFCavity.H:163
amrex::Vector< amrex::ParticleReal > default_cos_coef
Definition: RFCavity.H:45
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal beta_gamma() const
Definition: ReferenceParticle.H:79
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:350
static constexpr amrex::Real pi
Definition: RFCavity.H:43
Definition: RFCavity.H:110
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map2(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition: RFCavity.H:430
amrex::ParticleReal m_phase
RF frequency in Hz.
Definition: RFCavity.H:88
RFCavity_device_copyable(amrex::ParticleReal escale, amrex::ParticleReal freq, amrex::ParticleReal phase, int mapsteps=1)
non-owning pointer to device sine coefficients
Definition: RFCavity.H:95
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
Definition: RFCavity.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map3(amrex::ParticleReal const tau, RefPart &refpart, [[maybe_unused]] amrex::ParticleReal &zeval) const
Definition: RFCavity.H:394
void synchronize() noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map1(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition: RFCavity.H:478
int m_mapsteps
RF driven phase in deg.
Definition: RFCavity.H:89
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
amrex::Gpu::DeviceVector< amrex::ParticleReal > m_sin_coef
cosine coefficients in Fourier expansion of on-axis electric field Ez
Definition: RFCavity.H:523