WarpX
InjectorPosition.H
Go to the documentation of this file.
1 /* Copyright 2019 Axel Huebl, David Grote, Maxence Thevenet
2  * Weiqun Zhang
3  *
4  * This file is part of WarpX.
5  *
6  * License: BSD-3-Clause-LBNL
7  */
8 #ifndef WARPX_INJECTOR_POSITION_H_
9 #define WARPX_INJECTOR_POSITION_H_
10 
11 #include "InjectorPosition_fwd.H"
12 
13 #include <AMReX_Dim3.H>
14 #include <AMReX_Gpu.H>
15 #include <AMReX_Utility.H>
16 
17 // struct whose getPositionUnitBox returns x, y and z for a particle with
18 // random distribution inside a unit cell.
20 {
21  [[nodiscard]]
24  getPositionUnitBox (int /*i_part*/, amrex::IntVect const /*ref_fac*/,
25  amrex::RandomEngine const& engine) const noexcept
26  {
27  return amrex::XDim3{amrex::Random(engine), amrex::Random(engine), amrex::Random(engine)};
28  }
29 };
30 
31 // struct whose getPositionUnitBox returns x, y and z for a particle with
32 // random distribution on a plane inside a unit cell.
34 {
35  InjectorPositionRandomPlane (int const& a_dir) noexcept : dir(a_dir) {}
36 
37  [[nodiscard]]
40  getPositionUnitBox (int /*i_part*/, amrex::IntVect const /*ref_fac*/,
41  amrex::RandomEngine const& engine) const noexcept
42  {
43  using namespace amrex::literals;
44 #if ((defined WARPX_DIM_3D) || (defined WARPX_DIM_RZ))
45  // In RZ, the 3 components of the `XDim3` vector below correspond to r, theta, z respectively
46  if (dir == 0) { return amrex::XDim3{0._rt, amrex::Random(engine), amrex::Random(engine)}; }
47  if (dir == 1) { return amrex::XDim3{amrex::Random(engine), 0._rt, amrex::Random(engine)}; }
48  else { return amrex::XDim3{amrex::Random(engine), amrex::Random(engine), 0._rt}; }
49 #elif (defined(WARPX_DIM_XZ))
50  // In 2D, the 2 first components of the `XDim3` vector below correspond to x and z
51  if (dir == 0) { return amrex::XDim3{0._rt, amrex::Random(engine), 0._rt}; }
52  if (dir == 1) { return amrex::XDim3{amrex::Random(engine), amrex::Random(engine), 0._rt}; }
53  else { return amrex::XDim3{amrex::Random(engine), 0._rt, 0._rt }; }
54 #elif (defined(WARPX_DIM_1D_Z))
55  // In 2D, the first components of the `XDim3` vector below correspond to z
56  if (dir == 0) { return amrex::XDim3{amrex::Random(engine), 0._rt, 0._rt}; }
57  if (dir == 1) { return amrex::XDim3{amrex::Random(engine), 0._rt, 0._rt}; }
58  else { return amrex::XDim3{0._rt, 0._rt, 0._rt}; }
59 #endif
60  }
61 private:
62  int dir;
63 };
64 
65 // struct whose getPositionUnitBox returns x, y and z for a particle with
66 // regular distribution inside a unit cell.
68 {
69  InjectorPositionRegular (amrex::Dim3 const& a_ppc) noexcept : ppc(a_ppc) {}
70 
71  // i_part: particle number within the cell, required to evenly space
72  // particles within the cell.
73  // ref_fac: the number of particles evenly-spaced within a cell
74  // is a_ppc*(ref_fac**AMREX_SPACEDIM).
75  [[nodiscard]]
78  getPositionUnitBox (int const i_part, amrex::IntVect const ref_fac,
79  amrex::RandomEngine const&) const noexcept
80  {
81  using namespace amrex;
82 
83 #if (defined WARPX_DIM_3D)
84  int const nx = ref_fac[0]*ppc.x;
85  int const ny = ref_fac[1]*ppc.y;
86  int const nz = ref_fac[2]*ppc.z;
87 #elif (defined WARPX_DIM_RZ)
88  int const nx = ref_fac[0]*ppc.x;
89  int const ny = ref_fac[1]*ppc.y;
90  int const nz = ppc.z; // Number of particles in theta ; no refinement
91 #elif (defined WARPX_DIM_XZ)
92  int const nx = ref_fac[0]*ppc.x;
93  int const ny = ref_fac[1]*ppc.y;
94  int const nz = 1;
95 #elif (defined WARPX_DIM_1D_Z)
96  int const nx = ref_fac[0]*ppc.x;
97  int const ny = 1;
98  int const nz = 1;
99 #endif
100  int const ix_part = i_part / (ny*nz); // written this way backward compatibility
101  int const iz_part = (i_part-ix_part*(ny*nz)) / ny;
102  int const iy_part = (i_part-ix_part*(ny*nz)) - ny*iz_part;
103  return XDim3{
104  (0.5_rt + ix_part) / nx,
105  (0.5_rt + iy_part) / ny,
106  (0.5_rt + iz_part) / nz
107  };
108  }
109 private:
111 };
112 
113 // Base struct for position injector.
114 // InjectorPosition contains a union (called Object) that holds any one
115 // instance of:
116 // - InjectorPositionRandom : to generate random distribution;
117 // - InjectorPositionRegular: to generate regular distribution.
118 // The choice is made at runtime, depending in the constructor called.
119 // This mimics virtual functions.
121 {
122  // This constructor stores a InjectorPositionRandom in union object.
124  amrex::Real a_xmin, amrex::Real a_xmax,
125  amrex::Real a_ymin, amrex::Real a_ymax,
126  amrex::Real a_zmin, amrex::Real a_zmax)
127  : type(Type::random),
128  object(t),
129  xmin(a_xmin), xmax(a_xmax),
130  ymin(a_ymin), ymax(a_ymax),
131  zmin(a_zmin), zmax(a_zmax)
132  { }
133 
134  // This constructor stores a InjectorPositionRandomPlane in union object.
136  amrex::Real a_xmin, amrex::Real a_xmax,
137  amrex::Real a_ymin, amrex::Real a_ymax,
138  amrex::Real a_zmin, amrex::Real a_zmax,
139  int const& a_dir)
140  : type(Type::randomplane),
141  object(t, a_dir),
142  xmin(a_xmin), xmax(a_xmax),
143  ymin(a_ymin), ymax(a_ymax),
144  zmin(a_zmin), zmax(a_zmax)
145  { }
146 
147  // This constructor stores a InjectorPositionRegular in union object.
149  amrex::Real a_xmin, amrex::Real a_xmax,
150  amrex::Real a_ymin, amrex::Real a_ymax,
151  amrex::Real a_zmin, amrex::Real a_zmax,
152  amrex::Dim3 const& a_ppc)
153  : type(Type::regular),
154  object(t, a_ppc),
155  xmin(a_xmin), xmax(a_xmax),
156  ymin(a_ymin), ymax(a_ymax),
157  zmin(a_zmin), zmax(a_zmax)
158  { }
159 
160  ~InjectorPosition () = default;
161 
162  // Explicitly prevent the compiler from generating copy constructors
163  // and copy assignment operators.
166  void operator= (InjectorPosition const&) = delete;
167  void operator= (InjectorPosition &&) = delete;
168 
169  // call getPositionUnitBox from the object stored in the union
170  // (the union is called Object, and the instance is called object).
171  [[nodiscard]]
174  getPositionUnitBox (int const i_part, amrex::IntVect const ref_fac,
175  amrex::RandomEngine const& engine) const noexcept
176  {
177  switch (type)
178  {
179  case Type::regular:
180  {
181  return object.regular.getPositionUnitBox(i_part, ref_fac, engine);
182  }
183  case Type::randomplane:
184  {
185  return object.randomplane.getPositionUnitBox(i_part, ref_fac, engine);
186  }
187  default:
188  {
189  return object.random.getPositionUnitBox(i_part, ref_fac, engine);
190  }
191  };
192  }
193 
194  /* \brief Flags whether the point (x, y, z) is inside the plasma region
195  * or on the lower boundary
196  * \param x, y, z the point to check
197  * \returns bool flag
198  */
199  [[nodiscard]]
201  bool
202  insideBounds (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
203  {
204  return (x < xmax and x >= xmin and
205  y < ymax and y >= ymin and
206  z < zmax and z >= zmin);
207  }
208 
209  /* \brief Flags whether the point (x, y, z) is inside the plasma region
210  * or on the lower or upper boundary
211  * \param x, y, z the point to check
212  * \returns bool flag
213  */
214  [[nodiscard]]
216  bool
217  insideBoundsInclusive (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
218  {
219  return (x <= xmax and x >= xmin and
220  y <= ymax and y >= ymin and
221  z <= zmax and z >= zmin);
222  }
223 
224  // bool: whether the region defined by lo and hi overlaps with the plasma region
225  [[nodiscard]]
227  bool
228  overlapsWith (const amrex::XDim3& lo, const amrex::XDim3& hi) const noexcept
229  {
230  return ( (xmin <= hi.x) && (xmax >= lo.x)
231  && (ymin <= hi.y) && (ymax >= lo.y)
232  && (zmin <= hi.z) && (zmax >= lo.z) );
233  }
234 
235 private:
236  enum struct Type { random, randomplane, regular };
238 
239  // An instance of union Object constructs and stores any one of
240  // the objects declared (random or regular).
241  union Object {
242  Object (InjectorPositionRandom*) noexcept : random() {}
243  Object (InjectorPositionRandomPlane*, int const& a_dir) noexcept
244  : randomplane(a_dir) {}
245  Object (InjectorPositionRegular*, amrex::Dim3 const& a_ppc) noexcept
246  : regular(a_ppc) {}
250  };
252 
253  amrex::Real xmin, xmax;
254  amrex::Real ymin, ymax;
255  amrex::Real zmin, zmax;
256 };
257 
258 #endif //WARPX_INJECTOR_POSITION_H_
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
integer, parameter, public regular
Real Random()
type
Definition: run_alltests_1node.py:72
xmin
Definition: stencil.py:424
xmax
Definition: stencil.py:425
nx
Definition: stencil.py:423
Definition: InjectorPosition.H:121
InjectorPosition(InjectorPositionRandom *t, amrex::Real a_xmin, amrex::Real a_xmax, amrex::Real a_ymin, amrex::Real a_ymax, amrex::Real a_zmin, amrex::Real a_zmax)
Definition: InjectorPosition.H:123
amrex::Real ymax
Definition: InjectorPosition.H:254
Object object
Definition: InjectorPosition.H:251
Type
Definition: InjectorPosition.H:236
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool overlapsWith(const amrex::XDim3 &lo, const amrex::XDim3 &hi) const noexcept
Definition: InjectorPosition.H:228
InjectorPosition(InjectorPositionRandomPlane *t, amrex::Real a_xmin, amrex::Real a_xmax, amrex::Real a_ymin, amrex::Real a_ymax, amrex::Real a_zmin, amrex::Real a_zmax, int const &a_dir)
Definition: InjectorPosition.H:135
AMREX_GPU_HOST_DEVICE bool insideBounds(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorPosition.H:202
amrex::Real zmax
Definition: InjectorPosition.H:255
AMREX_GPU_HOST_DEVICE bool insideBoundsInclusive(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorPosition.H:217
Type type
Definition: InjectorPosition.H:237
InjectorPosition(InjectorPositionRegular *t, amrex::Real a_xmin, amrex::Real a_xmax, amrex::Real a_ymin, amrex::Real a_ymax, amrex::Real a_zmin, amrex::Real a_zmax, amrex::Dim3 const &a_ppc)
Definition: InjectorPosition.H:148
InjectorPosition(InjectorPosition &&)=delete
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int const i_part, amrex::IntVect const ref_fac, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:174
InjectorPosition(InjectorPosition const &)=delete
amrex::Real xmax
Definition: InjectorPosition.H:253
~InjectorPosition()=default
Definition: InjectorPosition.H:20
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int, amrex::IntVect const, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:24
Definition: InjectorPosition.H:34
int dir
Definition: InjectorPosition.H:62
InjectorPositionRandomPlane(int const &a_dir) noexcept
Definition: InjectorPosition.H:35
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int, amrex::IntVect const, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:40
Definition: InjectorPosition.H:68
InjectorPositionRegular(amrex::Dim3 const &a_ppc) noexcept
Definition: InjectorPosition.H:69
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int const i_part, amrex::IntVect const ref_fac, amrex::RandomEngine const &) const noexcept
Definition: InjectorPosition.H:78
amrex::Dim3 ppc
Definition: InjectorPosition.H:110
Definition: InjectorPosition.H:241
Object(InjectorPositionRandom *) noexcept
Definition: InjectorPosition.H:242
InjectorPositionRegular regular
Definition: InjectorPosition.H:249
InjectorPositionRandom random
Definition: InjectorPosition.H:247
InjectorPositionRandomPlane randomplane
Definition: InjectorPosition.H:248
Object(InjectorPositionRandomPlane *, int const &a_dir) noexcept
Definition: InjectorPosition.H:243
Object(InjectorPositionRegular *, amrex::Dim3 const &a_ppc) noexcept
Definition: InjectorPosition.H:245