ImpactX
beamoptic.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: Axel Huebl
8  * License: BSD-3-Clause-LBNL
9  */
10 #ifndef IMPACTX_ELEMENTS_MIXIN_BEAMOPTIC_H
11 #define IMPACTX_ELEMENTS_MIXIN_BEAMOPTIC_H
12 
14 #include "particles/PushAll.H"
15 
16 #include <AMReX_Extension.H> // for AMREX_RESTRICT
17 #include <AMReX_REAL.H>
18 
19 #include <type_traits>
20 
21 
22 namespace impactx::elements
23 {
24 namespace detail
25 {
39  template <typename T_Element>
41  {
44 
57  PushSingleParticle (T_Element element,
58  amrex::ParticleReal* AMREX_RESTRICT part_x,
59  amrex::ParticleReal* AMREX_RESTRICT part_y,
60  amrex::ParticleReal* AMREX_RESTRICT part_t,
61  amrex::ParticleReal* AMREX_RESTRICT part_px,
62  amrex::ParticleReal* AMREX_RESTRICT part_py,
63  amrex::ParticleReal* AMREX_RESTRICT part_pt,
64  uint64_t* AMREX_RESTRICT part_idcpu,
65  RefPart ref_part)
66  : m_element(std::move(element)),
67  m_part_x(part_x), m_part_y(part_y), m_part_t(part_t),
68  m_part_px(part_px), m_part_py(part_py), m_part_pt(part_pt),
69  m_part_idcpu(part_idcpu),
70  m_ref_part(std::move(ref_part))
71  {
72  }
73 
74  PushSingleParticle () = delete;
77  ~PushSingleParticle () = default;
78 
84  void
85  operator() (long i) const
86  {
87  // access SoA Real data
88  // note: an optimizing compiler will eliminate loads of unused parameters
89  amrex::ParticleReal & AMREX_RESTRICT x = m_part_x[i];
90  amrex::ParticleReal & AMREX_RESTRICT y = m_part_y[i];
91  amrex::ParticleReal & AMREX_RESTRICT t = m_part_t[i];
92  amrex::ParticleReal & AMREX_RESTRICT px = m_part_px[i];
93  amrex::ParticleReal & AMREX_RESTRICT py = m_part_py[i];
94  amrex::ParticleReal & AMREX_RESTRICT pt = m_part_pt[i];
95  uint64_t & AMREX_RESTRICT idcpu = m_part_idcpu[i];
96 
97  // push through element
98  m_element(x, y, t, px, py, pt, idcpu, m_ref_part);
99 
100  }
101 
102  private:
103  T_Element const m_element;
104  amrex::ParticleReal* const AMREX_RESTRICT m_part_x;
105  amrex::ParticleReal* const AMREX_RESTRICT m_part_y;
106  amrex::ParticleReal* const AMREX_RESTRICT m_part_t;
107  amrex::ParticleReal* const AMREX_RESTRICT m_part_px;
108  amrex::ParticleReal* const AMREX_RESTRICT m_part_py;
109  amrex::ParticleReal* const AMREX_RESTRICT m_part_pt;
110  uint64_t* const AMREX_RESTRICT m_part_idcpu;
112  };
113 
116  template< typename T_Element >
119  RefPart & AMREX_RESTRICT ref_part,
120  T_Element & element
121  ) {
122  const int np = pti.numParticles();
123 
124  // preparing access to particle data: SoA of Reals
125  auto& soa_real = pti.GetStructOfArrays().GetRealData();
126  amrex::ParticleReal* const AMREX_RESTRICT part_x = soa_real[RealSoA::x].dataPtr();
127  amrex::ParticleReal* const AMREX_RESTRICT part_y = soa_real[RealSoA::y].dataPtr();
128  amrex::ParticleReal* const AMREX_RESTRICT part_t = soa_real[RealSoA::t].dataPtr();
129  amrex::ParticleReal* const AMREX_RESTRICT part_px = soa_real[RealSoA::px].dataPtr();
130  amrex::ParticleReal* const AMREX_RESTRICT part_py = soa_real[RealSoA::py].dataPtr();
131  amrex::ParticleReal* const AMREX_RESTRICT part_pt = soa_real[RealSoA::pt].dataPtr();
132 
133  uint64_t* const AMREX_RESTRICT part_idcpu = pti.GetStructOfArrays().GetIdCPUData().dataPtr();
134 
135  detail::PushSingleParticle<T_Element> const pushSingleParticle(
136  element, part_x, part_y, part_t, part_px, part_py, part_pt, part_idcpu, ref_part);
137  // loop over beam particles in the box
138  amrex::ParallelFor(np, pushSingleParticle);
139  }
140 } // namespace detail
141 
147  template<typename T_Element>
148  struct BeamOptic
149  {
153  int step
154  )
155  {
156  static_assert(
157  std::is_base_of_v<BeamOptic, T_Element>,
158  "BeamOptic can only be used as a mixin class!"
159  );
160 
161  T_Element& element = *static_cast<T_Element*>(this);
162  push_all(pc, element, step);
163  }
164 
174  RefPart & AMREX_RESTRICT ref_part
175  )
176  {
177  static_assert(
178  std::is_base_of_v<BeamOptic, T_Element>,
179  "BeamOptic can only be used as a mixin class!"
180  );
181 
182  T_Element& element = *static_cast<T_Element*>(this);
183  detail::push_all_particles<T_Element>(pti, ref_part, element);
184  }
185  };
186 
187 } // namespace impactx::elements
188 
189 #endif // IMPACTX_ELEMENTS_MIXIN_BEAMOPTIC_H
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_DEVICE
Definition: ImpactXParticleContainer.H:131
Definition: ImpactXParticleContainer.H:96
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... >, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
i
void push_all_particles(ImpactXParticleContainer::iterator &pti, RefPart &AMREX_RESTRICT ref_part, T_Element &element)
Definition: beamoptic.H:117
Definition: alignment.H:23
@ t
fixed t as the independent variable
void push_all(ImpactXParticleContainer &pc, T_Element &element, [[maybe_unused]] int step, [[maybe_unused]] bool omp_parallel=true)
Definition: PushAll.H:32
@ nattribs
the number of attributes above (always last)
Definition: ImpactXParticleContainer.H:78
@ pt
energy deviation, scaled by speed of light * the magnitude of the reference momentum [unitless] (at f...
Definition: ImpactXParticleContainer.H:51
@ y
position in y [m] (at fixed s or t)
Definition: ImpactXParticleContainer.H:47
@ t
time-of-flight ct [m] (at fixed s)
Definition: ImpactXParticleContainer.H:48
@ px
momentum in x, scaled by the magnitude of the reference momentum [unitless] (at fixed s or t)
Definition: ImpactXParticleContainer.H:49
@ nattribs
the number of attributes above (always last)
Definition: ImpactXParticleContainer.H:54
@ py
momentum in y, scaled by the magnitude of the reference momentum [unitless] (at fixed s or t)
Definition: ImpactXParticleContainer.H:50
@ x
position in x [m] (at fixed s or t)
Definition: ImpactXParticleContainer.H:46
Definition: ReferenceParticle.H:30
Definition: beamoptic.H:149
void operator()(ImpactXParticleContainer &pc, int step)
Definition: beamoptic.H:151
amrex::ParticleReal *const AMREX_RESTRICT m_part_t
Definition: beamoptic.H:106
amrex::ParticleReal *const AMREX_RESTRICT m_part_px
Definition: beamoptic.H:107
amrex::ParticleReal *const AMREX_RESTRICT m_part_py
Definition: beamoptic.H:108
T_Element const m_element
Definition: beamoptic.H:103
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void operator()(long i) const
Definition: beamoptic.H:85
PushSingleParticle(PushSingleParticle const &)=default
PushSingleParticle(T_Element element, amrex::ParticleReal *AMREX_RESTRICT part_x, amrex::ParticleReal *AMREX_RESTRICT part_y, amrex::ParticleReal *AMREX_RESTRICT part_t, amrex::ParticleReal *AMREX_RESTRICT part_px, amrex::ParticleReal *AMREX_RESTRICT part_py, amrex::ParticleReal *AMREX_RESTRICT part_pt, uint64_t *AMREX_RESTRICT part_idcpu, RefPart ref_part)
Definition: beamoptic.H:57
amrex::ParticleReal *const AMREX_RESTRICT m_part_pt
Definition: beamoptic.H:109
ImpactXParticleContainer::ParticleType PType
Definition: beamoptic.H:42
amrex::ParticleReal *const AMREX_RESTRICT m_part_x
Definition: beamoptic.H:104
amrex::ParticleReal *const AMREX_RESTRICT m_part_y
Definition: beamoptic.H:105
RefPart const m_ref_part
Definition: beamoptic.H:111
PushSingleParticle(PushSingleParticle &&)=default
uint64_t *const AMREX_RESTRICT m_part_idcpu
Definition: beamoptic.H:110