10#ifndef IMPACTX_SOFTSOL_H
11#define IMPACTX_SOFTSOL_H
59 4.409581845710694E-002,
60 -9.416427163897508E-006,
61 -2.459452716865687E-002,
62 -3.272762575737291E-002,
63 -2.936414401076162E-002,
64 -1.995780078926890E-002,
65 -9.102893342953847E-003,
66 -2.456410658713271E-006,
67 5.788233017324325E-003,
68 8.040408292420691E-003,
69 7.480064552867431E-003,
70 5.230254569468851E-003,
71 2.447614547094685E-003,
72 -1.095525090532255E-006,
73 -1.614586867387170E-003,
74 -2.281365457438345E-003,
75 -2.148709081338292E-003,
76 -1.522541739363011E-003,
77 -7.185505862719508E-004,
78 -6.171194824600157E-007,
79 4.842109305036943E-004,
80 6.874508102002901E-004,
81 6.535550288205728E-004,
82 4.648795813759210E-004,
83 2.216564722797528E-004,
84 -4.100982995210341E-007,
85 -1.499332112463395E-004,
86 -2.151538438342482E-004,
87 -2.044590946652016E-004,
88 -1.468242784844341E-004
92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 inline std::map<int, std::vector<amrex::ParticleReal>>
h_cos_coef = {};
113 inline std::map<int, std::vector<amrex::ParticleReal>>
h_sin_coef = {};
116 inline std::map<int, amrex::Gpu::DeviceVector<amrex::ParticleReal>>
d_cos_coef = {};
118 inline std::map<int, amrex::Gpu::DeviceVector<amrex::ParticleReal>>
d_sin_coef = {};
131 static constexpr auto type =
"SoftSolenoid";
156 amrex::ParticleReal
ds,
157 amrex::ParticleReal bscale,
158 std::vector<amrex::ParticleReal> cos_coef,
159 std::vector<amrex::ParticleReal> sin_coef,
161 amrex::ParticleReal
dx = 0,
162 amrex::ParticleReal
dy = 0,
163 amrex::ParticleReal rotation_degree = 0,
168 std::optional<std::string>
name = std::nullopt
180 m_ncoef = int(cos_coef.size());
181 if (
m_ncoef !=
int(sin_coef.size()))
182 throw std::runtime_error(
"SoftSolenoid: cos and sin coefficients must have same length!");
194 cos_coef.begin(), cos_coef.end(),
197 sin_coef.begin(), sin_coef.end(),
207 using BeamOptic::operator();
218 using namespace amrex::literals;
220 Alignment::compute_constants(refpart);
237 template<
typename T_Real=amrex::ParticleReal,
typename T_IdCpu=u
int64_t>
250 using namespace amrex::literals;
266 auto const out = R *
v;
290 using namespace amrex::literals;
294 amrex::ParticleReal
const x = refpart.x;
295 amrex::ParticleReal
const px = refpart.px;
296 amrex::ParticleReal
const y = refpart.y;
297 amrex::ParticleReal
const py = refpart.py;
298 amrex::ParticleReal
const z = refpart.z;
299 amrex::ParticleReal
const pz = refpart.pz;
300 amrex::ParticleReal
const pt = refpart.pt;
301 amrex::ParticleReal
const s = refpart.s;
302 amrex::ParticleReal
const sedge = refpart.sedge;
305 refpart.map =
decltype(refpart.map)::Identity();
308 amrex::ParticleReal
const slice_ds =
m_ds /
nslice();
311 amrex::ParticleReal
const bgi = std::sqrt(powi<2>(pt) - 1.0_prt);
314 amrex::ParticleReal
const zin =
s - sedge;
315 amrex::ParticleReal
const zout = zin + slice_ds;
319 amrex::ParticleReal
const ptf = refpart.pt;
331 refpart.x = x + slice_ds*px/bgi;
332 refpart.y = y + slice_ds*py/bgi;
333 refpart.z = z + slice_ds*pz/bgi;
336 amrex::ParticleReal
const bgf = std::sqrt(powi<2>(ptf) - 1.0_prt);
339 refpart.px = px*bgf/bgi;
340 refpart.py = py*bgf/bgi;
341 refpart.pz = pz*bgf/bgi;
344 refpart.s =
s + slice_ds;
348 using LinearTransport::operator();
372 std::tuple<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>
376 using namespace amrex::literals;
380#if AMREX_DEVICE_COMPILE
390 amrex::ParticleReal
const zlen =
m_ds;
391 amrex::ParticleReal
const zmid = zlen * 0.5_prt;
394 amrex::ParticleReal bfield = 0.0;
395 amrex::ParticleReal bfieldp = 0.0;
396 amrex::ParticleReal bfieldint = 0.0;
397 amrex::ParticleReal
const z = zeval - zmid;
399 if (std::abs(z) <= zmid)
401 bfield = 0.5_prt*cos_data[0];
402 bfieldint = z*bfield;
403 for (
int j=1; j <
m_ncoef; ++j)
405 bfield = bfield + cos_data[j] * std::cos(j*2*pi*z/zlen) +
406 sin_data[j] * std::sin(j*2*pi*z/zlen);
407 bfieldp = bfieldp-j*2*pi*cos_data[j] * std::sin(j*2*pi*z/zlen)/zlen +
408 j*2*pi*sin_data[j] * std::cos(j*2*pi*z/zlen)/zlen;
409 bfieldint = bfieldint + zlen*cos_data[j] * std::sin(j*2*pi*z/zlen)/(j*2*pi) -
410 zlen*sin_data[j] * std::cos(j*2*pi*z/zlen)/(j*2*pi);
413 return std::make_tuple(bfield, bfieldp, bfieldint);
425 void map1 (amrex::ParticleReal
const tau,
427 [[maybe_unused]] amrex::ParticleReal & zeval)
const
429 using namespace amrex::literals;
433 amrex::ParticleReal
const t = refpart.
t;
434 amrex::ParticleReal
const pt = refpart.
pt;
435 amrex::ParticleReal
const z = zeval;
438 refpart.
t =
t + tau/std::sqrt(1.0_prt - powi<-2>(pt));
450 amrex::ParticleReal
const betgam = refpart.
beta_gamma();
452 refpart.
map(1,1) = R(1,1) + tau*R(2,1);
453 refpart.
map(1,2) = R(1,2) + tau*R(2,2);
454 refpart.
map(1,3) = R(1,3) + tau*R(2,3);
455 refpart.
map(1,4) = R(1,4) + tau*R(2,4);
457 refpart.
map(3,1) = R(3,1) + tau*R(4,1);
458 refpart.
map(3,2) = R(3,2) + tau*R(4,2);
459 refpart.
map(3,3) = R(3,3) + tau*R(4,3);
460 refpart.
map(3,4) = R(3,4) + tau*R(4,4);
462 refpart.
map(5,5) = R(5,5) + tau*R(6,5)/powi<2>(betgam);
463 refpart.
map(5,6) = R(5,6) + tau*R(6,6)/powi<2>(betgam);
476 void map2 (amrex::ParticleReal
const tau,
478 amrex::ParticleReal & zeval)
const
480 using namespace amrex::literals;
483 amrex::ParticleReal
const t = refpart.
t;
484 amrex::ParticleReal
const pt = refpart.
pt;
487 amrex::ParticleReal
const B0 =
501 amrex::ParticleReal
const alpha = B0*bz*0.5_prt;
502 amrex::ParticleReal
const alpha2 = powi<2>(
alpha);
504 refpart.
map(2,1) = R(2,1) - tau*alpha2*R(1,1);
505 refpart.
map(2,2) = R(2,2) - tau*alpha2*R(1,2);
506 refpart.
map(2,3) = R(2,3) - tau*alpha2*R(1,3);
507 refpart.
map(2,4) = R(2,4) - tau*alpha2*R(1,4);
509 refpart.
map(4,1) = R(4,1) - tau*alpha2*R(3,1);
510 refpart.
map(4,2) = R(4,2) - tau*alpha2*R(3,2);
511 refpart.
map(4,3) = R(4,3) - tau*alpha2*R(3,3);
512 refpart.
map(4,4) = R(4,4) - tau*alpha2*R(3,4);
525 void map3 (amrex::ParticleReal
const tau,
527 amrex::ParticleReal & zeval)
const
529 using namespace amrex::literals;
531 amrex::ParticleReal
const t = refpart.
t;
532 amrex::ParticleReal
const pt = refpart.
pt;
533 amrex::ParticleReal
const z = zeval;
536 amrex::ParticleReal
const B0 =
550 amrex::ParticleReal
const theta = tau*B0*bz*0.5_prt;
551 amrex::ParticleReal
const cs = std::cos(theta);
552 amrex::ParticleReal
const sn = std::sin(theta);
554 refpart.
map(1,1) = R(1,1)*cs + R(3,1)*sn;
555 refpart.
map(1,2) = R(1,2)*cs + R(3,2)*sn;
556 refpart.
map(1,3) = R(1,3)*cs + R(3,3)*sn;
557 refpart.
map(1,4) = R(1,4)*cs + R(3,4)*sn;
559 refpart.
map(2,1) = R(2,1)*cs + R(4,1)*sn;
560 refpart.
map(2,2) = R(2,2)*cs + R(4,2)*sn;
561 refpart.
map(2,3) = R(2,3)*cs + R(4,3)*sn;
562 refpart.
map(2,4) = R(2,4)*cs + R(4,4)*sn;
564 refpart.
map(3,1) = R(3,1)*cs - R(1,1)*sn;
565 refpart.
map(3,2) = R(3,2)*cs - R(1,2)*sn;
566 refpart.
map(3,3) = R(3,3)*cs - R(1,3)*sn;
567 refpart.
map(3,4) = R(3,4)*cs - R(1,4)*sn;
569 refpart.
map(4,1) = R(4,1)*cs - R(2,1)*sn;
570 refpart.
map(4,2) = R(4,2)*cs - R(2,2)*sn;
571 refpart.
map(4,3) = R(4,3)*cs - R(2,3)*sn;
572 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
PODVector< T, ArenaAllocator< T > > DeviceVector
constexpr T powi(T x) noexcept
__host__ __device__ void ignore_unused(const Ts &...)
SmallMatrix< T, N, 1, Order::F, StartIndex > SmallVector
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:116
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:113
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:111
int next_id
last used id for a created soft solenoid
Definition SoftSol.H:108
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:118
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:79
@ s
fixed s as the independent variable
Definition ImpactXParticleContainer.H:37
@ t
fixed t as the independent variable
Definition ImpactXParticleContainer.H:38
amrex::SmallMatrix< amrex::ParticleReal, 6, 6, amrex::Order::F, 1 > Map6x6
Definition CovarianceMatrix.H:20
static constexpr __host__ __device__ SmallMatrix< T, NRows, NCols, ORDER, StartIndex > Identity() noexcept
Definition ReferenceParticle.H:31
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal beta_gamma() const
Definition ReferenceParticle.H:110
amrex::ParticleReal pt
energy, normalized by rest energy
Definition ReferenceParticle.H:40
amrex::SmallMatrix< amrex::ParticleReal, 6, 6, amrex::Order::F, 1 > map
linearized map
Definition ReferenceParticle.H:45
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal rigidity_Tm() const
Definition ReferenceParticle.H:203
amrex::ParticleReal t
clock time * c in meters
Definition ReferenceParticle.H:36
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:374
int m_id
number of map integration steps per slice
Definition SoftSol.H:596
int m_mapsteps
unit specification for quad strength
Definition SoftSol.H:595
void compute_constants(RefPart const &refpart)
Definition SoftSol.H:216
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_Real &AMREX_RESTRICT t, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py, T_Real &AMREX_RESTRICT pt, T_IdCpu &AMREX_RESTRICT idcpu, RefPart const &AMREX_RESTRICT refpart) const
Definition SoftSol.H:239
AMREX_GPU_HOST AMREX_FORCE_INLINE Map6x6 transport_map(RefPart const &AMREX_RESTRICT refpart) const
Definition SoftSol.H:357
static constexpr auto type
Definition SoftSol.H:131
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map3(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition SoftSol.H:525
amrex::ParticleReal * m_cos_h_data
number of Fourier coefficients
Definition SoftSol.H:599
void finalize()
Definition SoftSol.H:579
int m_ncoef
unique soft solenoid id used for data lookup map
Definition SoftSol.H:598
ImpactXParticleContainer::ParticleType PType
Definition SoftSol.H:132
SoftSolenoid(amrex::ParticleReal ds, amrex::ParticleReal bscale, std::vector< amrex::ParticleReal > cos_coef, std::vector< amrex::ParticleReal > sin_coef, int unit, amrex::ParticleReal dx=0, amrex::ParticleReal dy=0, amrex::ParticleReal rotation_degree=0, amrex::ParticleReal aperture_x=0, amrex::ParticleReal aperture_y=0, int mapsteps=1, int nslice=1, std::optional< std::string > name=std::nullopt)
Definition SoftSol.H:155
amrex::ParticleReal m_bscale
Definition SoftSol.H:593
amrex::ParticleReal * m_cos_d_data
non-owning pointer to host sine coefficients
Definition SoftSol.H:601
amrex::ParticleReal * m_sin_h_data
non-owning pointer to host cosine coefficients
Definition SoftSol.H:600
int m_unit
scaling factor for solenoid Bz field
Definition SoftSol.H:594
amrex::ParticleReal * m_sin_d_data
non-owning pointer to device cosine coefficients
Definition SoftSol.H:602
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map2(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition SoftSol.H:476
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void map1(amrex::ParticleReal const tau, RefPart &refpart, amrex::ParticleReal &zeval) const
Definition SoftSol.H:425
amrex::Vector< amrex::ParticleReal > default_sin_coef
Definition SoftSol.H:91
amrex::Vector< amrex::ParticleReal > default_cos_coef
Definition SoftSol.H:53
Definition alignment.H:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shift_out(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py) const
Definition alignment.H:109
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dy() const
Definition alignment.H:146
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal dx() const
Definition alignment.H:136
Alignment(amrex::ParticleReal dx, amrex::ParticleReal dy, amrex::ParticleReal rotation_degree)
Definition alignment.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shift_in(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_Real &AMREX_RESTRICT px, T_Real &AMREX_RESTRICT py) const
Definition alignment.H:78
Definition beamoptic.H:219
Definition lineartransport.H:29
AMREX_GPU_HOST Named(std::optional< std::string > name)
Definition named.H:57
AMREX_FORCE_INLINE std::string name() const
Definition named.H:122
Definition pipeaperture.H:26
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void apply_aperture(T_Real &AMREX_RESTRICT x, T_Real &AMREX_RESTRICT y, T_IdCpu &AMREX_RESTRICT idcpu) const
Definition pipeaperture.H:59
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal aperture_x() const
Definition pipeaperture.H:90
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::ParticleReal aperture_y() const
Definition pipeaperture.H:101
PipeAperture(amrex::ParticleReal aperture_x, amrex::ParticleReal aperture_y)
Definition pipeaperture.H:32
Thick(amrex::ParticleReal ds, int nslice)
Definition thick.H:30
amrex::ParticleReal m_ds
Definition thick.H:58
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