10 #ifndef IMPACTX_SOFTSOL_H
11 #define IMPACTX_SOFTSOL_H
55 4.409581845710694E-002,
56 -9.416427163897508E-006,
57 -2.459452716865687E-002,
58 -3.272762575737291E-002,
59 -2.936414401076162E-002,
60 -1.995780078926890E-002,
61 -9.102893342953847E-003,
62 -2.456410658713271E-006,
63 5.788233017324325E-003,
64 8.040408292420691E-003,
65 7.480064552867431E-003,
66 5.230254569468851E-003,
67 2.447614547094685E-003,
68 -1.095525090532255E-006,
69 -1.614586867387170E-003,
70 -2.281365457438345E-003,
71 -2.148709081338292E-003,
72 -1.522541739363011E-003,
73 -7.185505862719508E-004,
74 -6.171194824600157E-007,
75 4.842109305036943E-004,
76 6.874508102002901E-004,
77 6.535550288205728E-004,
78 4.648795813759210E-004,
79 2.216564722797528E-004,
80 -4.100982995210341E-007,
81 -1.499332112463395E-004,
82 -2.151538438342482E-004,
83 -2.044590946652016E-004,
84 -1.468242784844341E-004
88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 namespace SoftSolenoidData
107 static inline std::map<int, std::vector<amrex::ParticleReal>>
h_cos_coef = {};
109 static inline std::map<int, std::vector<amrex::ParticleReal>>
h_sin_coef = {};
112 static inline std::map<int, amrex::Gpu::DeviceVector<amrex::ParticleReal>>
d_cos_coef = {};
114 static inline std::map<int, amrex::Gpu::DeviceVector<amrex::ParticleReal>>
d_sin_coef = {};
123 static constexpr
auto name =
"SoftSolenoid";
140 amrex::ParticleReal
ds,
141 amrex::ParticleReal bscale,
142 std::vector<amrex::ParticleReal> cos_coef,
143 std::vector<amrex::ParticleReal> sin_coef,
144 amrex::ParticleReal
dx = 0,
145 amrex::ParticleReal
dy = 0,
146 amrex::ParticleReal rotation_degree = 0,
159 if (
m_ncoef !=
int(sin_coef.size()))
160 throw std::runtime_error(
"SoftSolenoid: cos and sin coefficients must have same length!");
172 cos_coef.begin(), cos_coef.end(),
175 sin_coef.begin(), sin_coef.end(),
185 using BeamOptic::operator();
198 PType& AMREX_RESTRICT p,
199 amrex::ParticleReal & AMREX_RESTRICT px,
200 amrex::ParticleReal & AMREX_RESTRICT py,
201 amrex::ParticleReal & AMREX_RESTRICT pt,
202 [[maybe_unused]]
RefPart const & refpart
205 using namespace amrex::literals;
211 amrex::ParticleReal
const x = p.pos(
RealAoS::x);
212 amrex::ParticleReal
const y = p.pos(
RealAoS::y);
216 amrex::ParticleReal pxout = px;
217 amrex::ParticleReal pyout = py;
218 amrex::ParticleReal ptout = pt;
230 p.pos(
RealAoS::x) = R(1,1)*x + R(1,2)*px + R(1,3)*y
231 + R(1,4)*py + R(1,5)*
t + R(1,6)*pt;
232 pxout = R(2,1)*x + R(2,2)*px + R(2,3)*y
233 + R(2,4)*py + R(2,5)*
t + R(2,6)*pt;
234 p.pos(
RealAoS::y) = R(3,1)*x + R(3,2)*px + R(3,3)*y
235 + R(3,4)*py + R(3,5)*
t + R(3,6)*pt;
236 pyout = R(4,1)*x + R(4,2)*px + R(4,3)*y
237 + R(4,4)*py + R(4,5)*
t + R(4,6)*pt;
238 p.pos(
RealAoS::t) = R(5,1)*x + R(5,2)*px + R(5,3)*y
239 + R(5,4)*py + R(5,5)*
t + R(5,6)*pt;
240 ptout = R(6,1)*x + R(6,2)*px + R(6,3)*y
241 + R(6,4)*py + R(6,5)*
t + R(6,6)*pt;
259 using namespace amrex::literals;
262 amrex::ParticleReal
const x = refpart.x;
263 amrex::ParticleReal
const px = refpart.px;
264 amrex::ParticleReal
const y = refpart.y;
265 amrex::ParticleReal
const py = refpart.py;
266 amrex::ParticleReal
const z = refpart.z;
267 amrex::ParticleReal
const pz = refpart.pz;
268 amrex::ParticleReal
const pt = refpart.pt;
269 amrex::ParticleReal
const s = refpart.s;
270 amrex::ParticleReal
const sedge = refpart.sedge;
273 for (
int i=1;
i<7;
i++) {
274 for (
int j=1; j<7; j++) {
275 auto const default_value = (
i == j) ? 1.0_prt : 0.0_prt;
276 refpart.map(
i, j) = default_value;
281 amrex::ParticleReal
const slice_ds =
m_ds /
nslice();
284 amrex::ParticleReal
const bgi =
sqrt(
pow(pt, 2) - 1.0_prt);
287 amrex::ParticleReal
const zin =
s - sedge;
288 amrex::ParticleReal
const zout = zin + slice_ds;
292 amrex::ParticleReal
const ptf = refpart.pt;
304 refpart.x = x + slice_ds*px/bgi;
305 refpart.y = y + slice_ds*py/bgi;
306 refpart.z = z + slice_ds*pz/bgi;
309 amrex::ParticleReal
const bgf =
sqrt(
pow(ptf, 2) - 1.0_prt);
312 refpart.px = px*bgf/bgi;
313 refpart.py = py*bgf/bgi;
314 refpart.pz = pz*bgf/bgi;
317 refpart.s =
s + slice_ds;
326 std::tuple<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>
330 using namespace amrex::literals;
334 #if AMREX_DEVICE_COMPILE
344 amrex::ParticleReal
const zlen =
m_ds;
345 amrex::ParticleReal
const zmid = zlen / 2.0_prt;
348 amrex::ParticleReal bfield = 0.0;
349 amrex::ParticleReal bfieldp = 0.0;
350 amrex::ParticleReal bfieldint = 0.0;
351 amrex::ParticleReal
const z = zeval - zmid;
353 if (std::abs(z) <= zmid)
355 bfield = 0.5_prt*cos_data[0];
356 bfieldint = z*bfield;
357 for (
int j=1; j <
m_ncoef; ++j)
359 bfield = bfield + cos_data[j]*cos(j*2*
pi*z/zlen) +
360 sin_data[j]*sin(j*2*
pi*z/zlen);
361 bfieldp = bfieldp-j*2*
pi*cos_data[j]*sin(j*2*
pi*z/zlen)/zlen +
362 j*2*
pi*sin_data[j]*cos(j*2*
pi*z/zlen)/zlen;
363 bfieldint = bfieldint + zlen*cos_data[j]*sin(j*2*
pi*z/zlen)/(j*2*
pi) -
364 zlen*sin_data[j]*cos(j*2*
pi*z/zlen)/(j*2*
pi);
367 return std::make_tuple(bfield, bfieldp, bfieldint);
379 void map1 (amrex::ParticleReal
const tau,
381 [[maybe_unused]] amrex::ParticleReal & zeval)
const
383 using namespace amrex::literals;
386 amrex::ParticleReal
const t = refpart.
t;
387 amrex::ParticleReal
const pt = refpart.
pt;
388 amrex::ParticleReal
const z = zeval;
391 refpart.
t =
t + tau/
sqrt(1.0_prt -
pow(pt, -2));
403 amrex::ParticleReal
const betgam = refpart.
beta_gamma();
405 refpart.
map(1,1) = R(1,1) + tau*R(2,1);
406 refpart.
map(1,2) = R(1,2) + tau*R(2,2);
407 refpart.
map(1,3) = R(1,3) + tau*R(2,3);
408 refpart.
map(1,4) = R(1,4) + tau*R(2,4);
410 refpart.
map(3,1) = R(3,1) + tau*R(4,1);
411 refpart.
map(3,2) = R(3,2) + tau*R(4,2);
412 refpart.
map(3,3) = R(3,3) + tau*R(4,3);
413 refpart.
map(3,4) = R(3,4) + tau*R(4,4);
415 refpart.
map(5,5) = R(5,5) + tau*R(6,5)/
pow(betgam,2);
416 refpart.
map(5,6) = R(5,6) + tau*R(6,6)/
pow(betgam,2);
429 void map2 (amrex::ParticleReal
const tau,
431 amrex::ParticleReal & zeval)
const
433 using namespace amrex::literals;
435 amrex::ParticleReal
const t = refpart.
t;
436 amrex::ParticleReal
const pt = refpart.
pt;
439 amrex::ParticleReal
const B0 =
m_bscale;
450 amrex::ParticleReal
const alpha = B0*bz/2.0_prt;
451 amrex::ParticleReal
const alpha2 =
pow(
alpha,2);
453 refpart.
map(2,1) = R(2,1) - tau*alpha2*R(1,1);
454 refpart.
map(2,2) = R(2,2) - tau*alpha2*R(1,2);
455 refpart.
map(2,3) = R(2,3) - tau*alpha2*R(1,3);
456 refpart.
map(2,4) = R(2,4) - tau*alpha2*R(1,4);
458 refpart.
map(4,1) = R(4,1) - tau*alpha2*R(3,1);
459 refpart.
map(4,2) = R(4,2) - tau*alpha2*R(3,2);
460 refpart.
map(4,3) = R(4,3) - tau*alpha2*R(3,3);
461 refpart.
map(4,4) = R(4,4) - tau*alpha2*R(3,4);
474 void map3 (amrex::ParticleReal
const tau,
476 amrex::ParticleReal & zeval)
const
478 using namespace amrex::literals;
480 amrex::ParticleReal
const t = refpart.
t;
481 amrex::ParticleReal
const pt = refpart.
pt;
482 amrex::ParticleReal
const z = zeval;
485 amrex::ParticleReal
const B0 =
m_bscale;
496 amrex::ParticleReal
const theta = tau*B0*bz/2.0_prt;
497 amrex::ParticleReal
const cs = cos(theta);
498 amrex::ParticleReal
const sn = sin(theta);
500 refpart.
map(1,1) = R(1,1)*cs + R(3,1)*sn;
501 refpart.
map(1,2) = R(1,2)*cs + R(3,2)*sn;
502 refpart.
map(1,3) = R(1,3)*cs + R(3,3)*sn;
503 refpart.
map(1,4) = R(1,4)*cs + R(3,4)*sn;
505 refpart.
map(2,1) = R(2,1)*cs + R(4,1)*sn;
506 refpart.
map(2,2) = R(2,2)*cs + R(4,2)*sn;
507 refpart.
map(2,3) = R(2,3)*cs + R(4,3)*sn;
508 refpart.
map(2,4) = R(2,4)*cs + R(4,4)*sn;
510 refpart.
map(3,1) = R(3,1)*cs - R(1,1)*sn;
511 refpart.
map(3,2) = R(3,2)*cs - R(1,2)*sn;
512 refpart.
map(3,3) = R(3,3)*cs - R(1,3)*sn;
513 refpart.
map(3,4) = R(3,4)*cs - R(1,4)*sn;
515 refpart.
map(4,1) = R(4,1)*cs - R(2,1)*sn;
516 refpart.
map(4,2) = R(4,2)*cs - R(2,2)*sn;
517 refpart.
map(4,3) = R(4,3)*cs - R(2,3)*sn;
518 refpart.
map(4,4) = R(4,4)*cs - R(2,4)*sn;
#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 magnetic field Bz
Definition: SoftSol.H:107
static int next_id
last used id for a created soft solenoid
Definition: SoftSol.H:104
static std::map< int, amrex::Gpu::DeviceVector< amrex::ParticleReal > > d_sin_coef
device: sine coefficients in Fourier expansion of on-axis magnetic field Bz
Definition: SoftSol.H:114
static std::map< int, std::vector< amrex::ParticleReal > > h_sin_coef
host: sine coefficients in Fourier expansion of on-axis magnetic field Bz
Definition: SoftSol.H:109
static std::map< int, amrex::Gpu::DeviceVector< amrex::ParticleReal > > d_cos_coef
device: cosine coefficients in Fourier expansion of on-axis magnetic field Bz
Definition: SoftSol.H:112
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
Definition: ImpactX.cpp:35
@ t
fixed t as the independent variable
@ x
position in x [m] (at fixed s OR fixed t)
Definition: ImpactXParticleContainer.H:49
@ y
position in y [m] (at fixed s OR fixed t)
Definition: ImpactXParticleContainer.H:50
@ t
c * time-of-flight [m] (at fixed s)
Definition: ImpactXParticleContainer.H:51
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: SoftSol.H:122
void finalize()
Definition: SoftSol.H:525
static constexpr auto name
Definition: SoftSol.H:123
amrex::ParticleReal * m_cos_d_data
non-owning pointer to host sine coefficients
Definition: SoftSol.H:547
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map2(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition: SoftSol.H:429
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map1(amrex::ParticleReal const tau, RefPart &refpart, [[maybe_unused]] amrex::ParticleReal &zeval) const
Definition: SoftSol.H:379
std::tuple< amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal > AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Sol_Bfield(amrex::ParticleReal const zeval) const
Definition: SoftSol.H:328
int m_ncoef
unique soft solenoid id used for data lookup map
Definition: SoftSol.H:544
amrex::ParticleReal * m_cos_h_data
number of Fourier coefficients
Definition: SoftSol.H:545
int m_mapsteps
scaling factor for solenoid Bz field
Definition: SoftSol.H:541
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map3(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition: SoftSol.H:474
SoftSolenoid(amrex::ParticleReal ds, amrex::ParticleReal bscale, 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: SoftSol.H:139
int m_id
number of map integration steps per slice
Definition: SoftSol.H:542
amrex::ParticleReal * m_sin_h_data
non-owning pointer to host cosine coefficients
Definition: SoftSol.H:546
ImpactXParticleContainer::ParticleType PType
Definition: SoftSol.H:124
amrex::ParticleReal m_bscale
Definition: SoftSol.H:540
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(PType &AMREX_RESTRICT p, amrex::ParticleReal &AMREX_RESTRICT px, amrex::ParticleReal &AMREX_RESTRICT py, amrex::ParticleReal &AMREX_RESTRICT pt, [[maybe_unused]] RefPart const &refpart) const
Definition: SoftSol.H:197
amrex::ParticleReal * m_sin_d_data
non-owning pointer to device cosine coefficients
Definition: SoftSol.H:548
amrex::Vector< amrex::ParticleReal > default_cos_coef
Definition: SoftSol.H:49
amrex::Vector< amrex::ParticleReal > default_sin_coef
Definition: SoftSol.H:87
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:135
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