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