ImpactX
SoftSol.H
Go to the documentation of this file.
1 /* Copyright 2022-2023 The Regents of the University of California, through Lawrence
2  * Berkeley National Laboratory (subject to receipt of any required
3  * approvals from the U.S. Dept. of Energy). All rights reserved.
4  *
5  * This file is part of ImpactX.
6  *
7  * Authors: Chad Mitchell, Axel Huebl
8  * License: BSD-3-Clause-LBNL
9  */
10 #ifndef IMPACTX_SOFTSOL_H
11 #define IMPACTX_SOFTSOL_H
12 
15 #include "mixin/alignment.H"
16 #include "mixin/beamoptic.H"
17 #include "mixin/thick.H"
18 
19 #include <ablastr/constant.H>
20 
21 #include <AMReX.H>
22 #include <AMReX_Array.H>
23 #include <AMReX_Extension.H>
24 #include <AMReX_REAL.H>
25 
26 #include <array>
27 #include <cmath>
28 #include <stdexcept>
29 #include <tuple>
30 #include <vector>
31 
32 
33 namespace impactx
34 {
48  {
50  0.350807812299706,
51  0.323554693720069,
52  0.260320578919415,
53  0.182848575294969,
54  0.106921016050403,
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
85  };
86 
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,
91  0, 0, 0, 0, 0
92  };
93  };
94 
101 namespace SoftSolenoidData
102 {
104  static inline int next_id = 0;
105 
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 = {};
110 
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 = {};
115 
116 } // namespace SoftSolenoidData
117 
119  : public elements::BeamOptic<SoftSolenoid>,
120  public elements::Thick,
121  public elements::Alignment
122  {
123  static constexpr auto name = "SoftSolenoid";
125 
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,
147  int mapsteps = 1,
148  int nslice = 1
149  )
150  : Thick(ds, nslice),
151  Alignment(dx, dy, rotation_degree),
152  m_bscale(bscale), m_mapsteps(mapsteps), m_id(SoftSolenoidData::next_id)
153  {
154  // next created soft solenoid has another id for its data
156 
157  // validate sin and cos coefficients are the same length
158  m_ncoef = int(cos_coef.size());
159  if (m_ncoef != int(sin_coef.size()))
160  throw std::runtime_error("SoftSolenoid: cos and sin coefficients must have same length!");
161 
162  // host data
167 
168  // device data
172  cos_coef.begin(), cos_coef.end(),
175  sin_coef.begin(), sin_coef.end(),
178 
179  // low-level objects we can use on device
182  }
183 
185  using BeamOptic::operator();
186 
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
203  ) const
204  {
205  using namespace amrex::literals; // for _rt and _prt
206 
207  // shift due to alignment errors of the element
208  shift_in(p.pos(RealAoS::x), p.pos(RealAoS::y), px, py);
209 
210  // access AoS data such as positions and cpu/id
211  amrex::ParticleReal const x = p.pos(RealAoS::x);
212  amrex::ParticleReal const y = p.pos(RealAoS::y);
213  amrex::ParticleReal const t = p.pos(RealAoS::t);
214 
215  // initialize output values of momenta
216  amrex::ParticleReal pxout = px;
217  amrex::ParticleReal pyout = py;
218  amrex::ParticleReal ptout = pt;
219 
220  // get the linear map
222 
223  // symplectic linear map for a solenoid is computed using the
224  // Hamiltonian formalism as described in:
225  // https://uspas.fnal.gov/materials/09UNM/ComputationalMethods.pdf.
226  // R denotes the transfer matrix in the basis (x,px,y,py,t,pt),
227  // so that, e.g., R(3,4) = dyf/dpyi.
228 
229  // push particles using the linear map
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;
242 
243  // assign updated momenta
244  px = pxout;
245  py = pyout;
246  pt = ptout;
247 
248  // undo shift due to alignment errors of the element
249  shift_out(p.pos(RealAoS::x), p.pos(RealAoS::y), px, py);
250  }
251 
257  void operator() (RefPart & AMREX_RESTRICT refpart) const
258  {
259  using namespace amrex::literals; // for _rt and _prt
260 
261  // assign input reference particle values
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;
271 
272  // initialize linear map (deviation) values
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;
277  }
278  }
279 
280  // length of the current slice
281  amrex::ParticleReal const slice_ds = m_ds / nslice();
282 
283  // compute intial value of beta*gamma
284  amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt);
285 
286  // call integrator to advance (t,pt)
287  amrex::ParticleReal const zin = s - sedge;
288  amrex::ParticleReal const zout = zin + slice_ds;
289  int const nsteps = m_mapsteps;
290 
291  integrators::symp2_integrate_split3(refpart,zin,zout,nsteps,*this);
292  amrex::ParticleReal const ptf = refpart.pt;
293 
294  /* print computed linear map:
295  for(int i=1; i<7; ++i){
296  for(int j=1; j<7; ++j){
297  amrex::PrintToFile("SolMap.txt") << i << " " <<
298  j << " " << refpart.map(i,j) << "\n";
299  }
300  }
301  */
302 
303  // advance position (x,y,z)
304  refpart.x = x + slice_ds*px/bgi;
305  refpart.y = y + slice_ds*py/bgi;
306  refpart.z = z + slice_ds*pz/bgi;
307 
308  // compute final value of beta*gamma
309  amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt);
310 
311  // advance momentum (px,py,pz)
312  refpart.px = px*bgf/bgi;
313  refpart.py = py*bgf/bgi;
314  refpart.pz = pz*bgf/bgi;
315 
316  // advance integrated path length
317  refpart.s = s + slice_ds;
318  }
319 
326  std::tuple<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>
328  Sol_Bfield (amrex::ParticleReal const zeval) const
329  {
330  using namespace amrex::literals; // for _rt and _prt
331 
332  // pick the right data depending if we are on the host side
333  // (reference particle push) or device side (particles):
334 #if AMREX_DEVICE_COMPILE
335  amrex::ParticleReal* cos_data = m_cos_d_data;
336  amrex::ParticleReal* sin_data = m_sin_d_data;
337 #else
338  amrex::ParticleReal* cos_data = m_cos_h_data;
339  amrex::ParticleReal* sin_data = m_sin_h_data;
340 #endif
341 
342  // specify constants
344  amrex::ParticleReal const zlen = m_ds;
345  amrex::ParticleReal const zmid = zlen / 2.0_prt;
346 
347  // compute on-axis magnetic field (z is relative to solenoid midpoint)
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;
352 
353  if (std::abs(z) <= zmid)
354  {
355  bfield = 0.5_prt*cos_data[0];
356  bfieldint = z*bfield;
357  for (int j=1; j < m_ncoef; ++j)
358  {
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);
365  }
366  }
367  return std::make_tuple(bfield, bfieldp, bfieldint);
368  }
369 
379  void map1 (amrex::ParticleReal const tau,
380  RefPart & refpart,
381  [[maybe_unused]] amrex::ParticleReal & zeval) const
382  {
383  using namespace amrex::literals; // for _rt and _prt
384 
385  // push the reference particle
386  amrex::ParticleReal const t = refpart.t;
387  amrex::ParticleReal const pt = refpart.pt;
388  amrex::ParticleReal const z = zeval;
389 
390  if (pt < -1.0_prt) {
391  refpart.t = t + tau/sqrt(1.0_prt - pow(pt, -2));
392  refpart.pt = pt;
393  }
394  else {
395  refpart.t = t;
396  refpart.pt = pt;
397  }
398 
399  zeval = z + tau;
400 
401  // push the linear map equations
403  amrex::ParticleReal const betgam = refpart.beta_gamma();
404 
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);
409 
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);
414 
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);
417 
418  }
419 
429  void map2 (amrex::ParticleReal const tau,
430  RefPart & refpart,
431  amrex::ParticleReal & zeval) const
432  {
433  using namespace amrex::literals; // for _rt and _prt
434 
435  amrex::ParticleReal const t = refpart.t;
436  amrex::ParticleReal const pt = refpart.pt;
437 
438  // Define parameters and intermediate constants
439  amrex::ParticleReal const B0 = m_bscale;
440 
441  // push the reference particle
442  auto [bz, bzp, bzint] = Sol_Bfield(zeval);
443  amrex::ignore_unused(bzp, bzint);
444 
445  refpart.t = t;
446  refpart.pt = pt;
447 
448  // push the linear map equations
450  amrex::ParticleReal const alpha = B0*bz/2.0_prt;
451  amrex::ParticleReal const alpha2 = pow(alpha,2);
452 
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);
457 
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);
462 
463  }
464 
474  void map3 (amrex::ParticleReal const tau,
475  RefPart & refpart,
476  amrex::ParticleReal & zeval) const
477  {
478  using namespace amrex::literals; // for _rt and _prt
479 
480  amrex::ParticleReal const t = refpart.t;
481  amrex::ParticleReal const pt = refpart.pt;
482  amrex::ParticleReal const z = zeval;
483 
484  // Define parameters and intermediate constants
485  amrex::ParticleReal const B0 = m_bscale;
486 
487  // push the reference particle
488  auto [bz, bzp, bzint] = Sol_Bfield(z);
489  amrex::ignore_unused(bzp, bzint);
490 
491  refpart.t = t;
492  refpart.pt = pt;
493 
494  // push the linear map equations
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);
499 
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;
504 
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;
509 
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;
514 
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;
519 
520  }
521 
524  void
526  {
527  // remove from unique data map
532 
537  }
538 
539  private:
540  amrex::ParticleReal m_bscale;
542  int m_id;
543 
544  int m_ncoef = 0;
545  amrex::ParticleReal* m_cos_h_data = nullptr;
546  amrex::ParticleReal* m_sin_h_data = nullptr;
547  amrex::ParticleReal* m_cos_d_data = nullptr;
548  amrex::ParticleReal* m_sin_d_data = nullptr;
549  };
550 
551 } // namespace impactx
552 
553 #endif // IMPACTX_SOFTSOL_H
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
#define AMREX_GPU_HOST
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
const int[]
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
i
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
s
int nsteps
int count
@ 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
Definition: SoftSol.H:48
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
Definition: thick.H:24
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