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*/, int /*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*/, int /*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, int const ref_fac,
76  amrex::RandomEngine const&) const noexcept
77  {
78  using namespace amrex;
79 
80  int const nx = ref_fac*ppc.x;
81  int const ny = ref_fac*ppc.y;
82 #if (defined WARPX_DIM_3D) || (defined WARPX_DIM_RZ)
83  int const nz = ref_fac*ppc.z;
84 #else
85  int const nz = 1;
86 #endif
87  int const ix_part = i_part / (ny*nz); // written this way backward compatibility
88  int const iz_part = (i_part-ix_part*(ny*nz)) / ny;
89  int const iy_part = (i_part-ix_part*(ny*nz)) - ny*iz_part;
90  return XDim3{
91  (0.5_rt + ix_part) / nx,
92  (0.5_rt + iy_part) / ny,
93  (0.5_rt + iz_part) / nz
94  };
95  }
96 private:
98 };
99 
100 // Base struct for position injector.
101 // InjectorPosition contains a union (called Object) that holds any one
102 // instance of:
103 // - InjectorPositionRandom : to generate random distribution;
104 // - InjectorPositionRegular: to generate regular distribution.
105 // The choice is made at runtime, depending in the constructor called.
106 // This mimics virtual functions.
108 {
109  // This constructor stores a InjectorPositionRandom in union object.
111  amrex::Real a_xmin, amrex::Real a_xmax,
112  amrex::Real a_ymin, amrex::Real a_ymax,
113  amrex::Real a_zmin, amrex::Real a_zmax)
114  : type(Type::random),
115  object(t),
116  xmin(a_xmin), xmax(a_xmax),
117  ymin(a_ymin), ymax(a_ymax),
118  zmin(a_zmin), zmax(a_zmax)
119  { }
120 
121  // This constructor stores a InjectorPositionRandomPlane in union object.
123  amrex::Real a_xmin, amrex::Real a_xmax,
124  amrex::Real a_ymin, amrex::Real a_ymax,
125  amrex::Real a_zmin, amrex::Real a_zmax,
126  int const& a_dir)
127  : type(Type::randomplane),
128  object(t, a_dir),
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 InjectorPositionRegular 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  amrex::Dim3 const& a_ppc)
140  : type(Type::regular),
141  object(t, a_ppc),
142  xmin(a_xmin), xmax(a_xmax),
143  ymin(a_ymin), ymax(a_ymax),
144  zmin(a_zmin), zmax(a_zmax)
145  { }
146 
147  // Explicitly prevent the compiler from generating copy constructors
148  // and copy assignment operators.
149  InjectorPosition (InjectorPosition const&) = delete;
150  InjectorPosition (InjectorPosition&&) = delete;
151  void operator= (InjectorPosition const&) = delete;
152  void operator= (InjectorPosition &&) = delete;
153 
154  // call getPositionUnitBox from the object stored in the union
155  // (the union is called Object, and the instance is called object).
158  getPositionUnitBox (int const i_part, int const ref_fac,
159  amrex::RandomEngine const& engine) const noexcept
160  {
161  switch (type)
162  {
163  case Type::regular:
164  {
165  return object.regular.getPositionUnitBox(i_part, ref_fac, engine);
166  }
167  case Type::randomplane:
168  {
169  return object.randomplane.getPositionUnitBox(i_part, ref_fac, engine);
170  }
171  default:
172  {
173  return object.random.getPositionUnitBox(i_part, ref_fac, engine);
174  }
175  };
176  }
177 
178  // bool: whether position specified is within bounds.
180  bool
181  insideBounds (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
182  {
183  return (x < xmax and x >= xmin and
184  y < ymax and y >= ymin and
185  z < zmax and z >= zmin);
186  }
187 
188  // bool: whether the region defined by lo and hi overaps with the plasma region
190  bool
191  overlapsWith (const amrex::XDim3& lo, const amrex::XDim3& hi) const noexcept
192  {
193  return ! ( (xmin > hi.x) || (xmax < lo.x)
194  || (ymin > hi.y) || (ymax < lo.y)
195  || (zmin > hi.z) || (zmax < lo.z) );
196  }
197 
198 private:
199  enum struct Type { random, randomplane, regular };
201 
202  // An instance of union Object constructs and stores any one of
203  // the objects declared (random or regular).
204  union Object {
205  Object (InjectorPositionRandom*) noexcept : random() {}
206  Object (InjectorPositionRandomPlane*, int const& a_dir) noexcept
207  : randomplane(a_dir) {}
208  Object (InjectorPositionRegular*, amrex::Dim3 const& a_ppc) noexcept
209  : regular(a_ppc) {}
213  };
215 
216  amrex::Real xmin, xmax;
217  amrex::Real ymin, ymax;
218  amrex::Real zmin, zmax;
219 };
220 
221 #endif
int dir
Definition: InjectorPosition.H:60
InjectorPositionRegular regular
Definition: InjectorPosition.H:212
integer, parameter, public regular
Real Random()
def x
Definition: read_lab_particles.py:26
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:110
Object(InjectorPositionRandom *) noexcept
Definition: InjectorPosition.H:205
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:135
Object(InjectorPositionRandomPlane *, int const &a_dir) noexcept
Definition: InjectorPosition.H:206
Definition: InjectorPosition.H:204
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int, int, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:23
amrex::Real ymin
Definition: InjectorPosition.H:217
InjectorPositionRandomPlane randomplane
Definition: InjectorPosition.H:211
def z
Definition: read_lab_particles.py:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool overlapsWith(const amrex::XDim3 &lo, const amrex::XDim3 &hi) const noexcept
Definition: InjectorPosition.H:191
amrex::Real xmin
Definition: InjectorPosition.H:216
Type type
Definition: InjectorPosition.H:200
#define AMREX_FORCE_INLINE
InjectorPositionRegular(amrex::Dim3 const &a_ppc) noexcept
Definition: InjectorPosition.H:67
AMREX_GPU_HOST_DEVICE bool insideBounds(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorPosition.H:181
Definition: InjectorPosition.H:19
#define AMREX_GPU_HOST_DEVICE
InjectorPositionRandom random
Definition: InjectorPosition.H:210
type
Definition: run_alltests_1node.py:72
amrex::Real zmin
Definition: InjectorPosition.H:218
Type
Definition: InjectorPosition.H:199
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:122
Object object
Definition: InjectorPosition.H:214
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int const i_part, int const ref_fac, amrex::RandomEngine const &) const noexcept
Definition: InjectorPosition.H:75
Definition: InjectorPosition.H:65
int dir
Definition: InjectorPosition.H:32
Object(InjectorPositionRegular *, amrex::Dim3 const &a_ppc) noexcept
Definition: InjectorPosition.H:208
Definition: InjectorPosition.H:107
InjectorPositionRandomPlane(int const &a_dir) noexcept
Definition: InjectorPosition.H:34
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int const i_part, int const ref_fac, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:158
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int, int, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:38
amrex::Dim3 ppc
Definition: InjectorPosition.H:97