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 {
21  AMREX_GPU_HOST_DEVICE
22  amrex::XDim3
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 
36  AMREX_GPU_HOST_DEVICE
37  amrex::XDim3
38  getPositionUnitBox (int /*i_part*/, int /*ref_fac*/,
39  amrex::RandomEngine const& engine) const noexcept
40  {
41  using namespace amrex::literals;
42  if (dir == 0) return amrex::XDim3{0._rt, amrex::Random(engine), amrex::Random(engine)};
43 #if (defined WARPX_DIM_RZ)
44  if (dir == 1) return amrex::XDim3{amrex::Random(engine), 0._rt, 0._rt};
45 #else
46  if (dir == 1) return amrex::XDim3{amrex::Random(engine), 0._rt, amrex::Random(engine)};
47 #endif
48  else return amrex::XDim3{amrex::Random(engine), amrex::Random(engine), 0._rt};
49  }
50 private:
51  int dir;
52 };
53 
54 // struct whose getPositionUnitBox returns x, y and z for a particle with
55 // regular distribution inside a unit cell.
57 {
58  InjectorPositionRegular (amrex::Dim3 const& a_ppc) noexcept : ppc(a_ppc) {}
59 
60  // i_part: particle number within the cell, required to evenly space
61  // particles within the cell.
62  // ref_fac: the number of particles evenly-spaced within a cell
63  // is a_ppc*(ref_fac**AMREX_SPACEDIM).
64  AMREX_GPU_HOST_DEVICE
65  amrex::XDim3
66  getPositionUnitBox (int const i_part, int const ref_fac,
67  amrex::RandomEngine const&) const noexcept
68  {
69  using namespace amrex;
70 
71  int const nx = ref_fac*ppc.x;
72  int const ny = ref_fac*ppc.y;
73 #if (defined WARPX_DIM_3D) || (defined WARPX_DIM_RZ)
74  int const nz = ref_fac*ppc.z;
75 #else
76  int const nz = 1;
77 #endif
78  int const ix_part = i_part / (ny*nz); // written this way backward compatibility
79  int const iz_part = (i_part-ix_part*(ny*nz)) / ny;
80  int const iy_part = (i_part-ix_part*(ny*nz)) - ny*iz_part;
81  return XDim3{
82  (0.5_rt + ix_part) / nx,
83  (0.5_rt + iy_part) / ny,
84  (0.5_rt + iz_part) / nz
85  };
86  }
87 private:
88  amrex::Dim3 ppc;
89 };
90 
91 // Base struct for position injector.
92 // InjectorPosition contains a union (called Object) that holds any one
93 // instance of:
94 // - InjectorPositionRandom : to generate random distribution;
95 // - InjectorPositionRegular: to generate regular distribution.
96 // The choice is made at runtime, depending in the constructor called.
97 // This mimics virtual functions.
99 {
100  // This constructor stores a InjectorPositionRandom in union object.
102  amrex::Real a_xmin, amrex::Real a_xmax,
103  amrex::Real a_ymin, amrex::Real a_ymax,
104  amrex::Real a_zmin, amrex::Real a_zmax)
105  : type(Type::random),
106  object(t),
107  xmin(a_xmin), xmax(a_xmax),
108  ymin(a_ymin), ymax(a_ymax),
109  zmin(a_zmin), zmax(a_zmax)
110  { }
111 
112  // This constructor stores a InjectorPositionRandomPlane in union object.
114  amrex::Real a_xmin, amrex::Real a_xmax,
115  amrex::Real a_ymin, amrex::Real a_ymax,
116  amrex::Real a_zmin, amrex::Real a_zmax,
117  int const& a_dir)
118  : type(Type::randomplane),
119  object(t, a_dir),
120  xmin(a_xmin), xmax(a_xmax),
121  ymin(a_ymin), ymax(a_ymax),
122  zmin(a_zmin), zmax(a_zmax)
123  { }
124 
125  // This constructor stores a InjectorPositionRegular in union object.
127  amrex::Real a_xmin, amrex::Real a_xmax,
128  amrex::Real a_ymin, amrex::Real a_ymax,
129  amrex::Real a_zmin, amrex::Real a_zmax,
130  amrex::Dim3 const& a_ppc)
131  : type(Type::regular),
132  object(t, a_ppc),
133  xmin(a_xmin), xmax(a_xmax),
134  ymin(a_ymin), ymax(a_ymax),
135  zmin(a_zmin), zmax(a_zmax)
136  { }
137 
138  // Explicitly prevent the compiler from generating copy constructors
139  // and copy assignment operators.
140  InjectorPosition (InjectorPosition const&) = delete;
141  InjectorPosition (InjectorPosition&&) = delete;
142  void operator= (InjectorPosition const&) = delete;
143  void operator= (InjectorPosition &&) = delete;
144 
145  // call getPositionUnitBox from the object stored in the union
146  // (the union is called Object, and the instance is called object).
147  AMREX_GPU_HOST_DEVICE
148  amrex::XDim3
149  getPositionUnitBox (int const i_part, int const ref_fac,
150  amrex::RandomEngine const& engine) const noexcept
151  {
152  switch (type)
153  {
154  case Type::regular:
155  {
156  return object.regular.getPositionUnitBox(i_part, ref_fac, engine);
157  }
158  case Type::randomplane:
159  {
160  return object.randomplane.getPositionUnitBox(i_part, ref_fac, engine);
161  }
162  default:
163  {
164  return object.random.getPositionUnitBox(i_part, ref_fac, engine);
165  }
166  };
167  }
168 
169  // bool: whether position specified is within bounds.
170  AMREX_GPU_HOST_DEVICE
171  bool
172  insideBounds (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
173  {
174  return (x < xmax and x >= xmin and
175  y < ymax and y >= ymin and
176  z < zmax and z >= zmin);
177  }
178 
179  // bool: whether the region defined by lo and hi overaps with the plasma region
180  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
181  bool
182  overlapsWith (const amrex::XDim3& lo, const amrex::XDim3& hi) const noexcept
183  {
184  return ! ( (xmin > hi.x) || (xmax < lo.x)
185  || (ymin > hi.y) || (ymax < lo.y)
186  || (zmin > hi.z) || (zmax < lo.z) );
187  }
188 
189 private:
190  enum struct Type { random, randomplane, regular };
192 
193  // An instance of union Object constructs and stores any one of
194  // the objects declared (random or regular).
195  union Object {
196  Object (InjectorPositionRandom*) noexcept : random() {}
197  Object (InjectorPositionRandomPlane*, int const& a_dir) noexcept
198  : randomplane(a_dir) {}
199  Object (InjectorPositionRegular*, amrex::Dim3 const& a_ppc) noexcept
200  : regular(a_ppc) {}
204  };
206 
207  amrex::Real xmin, xmax;
208  amrex::Real ymin, ymax;
209  amrex::Real zmin, zmax;
210 };
211 
212 #endif
int dir
Definition: InjectorPosition.H:51
InjectorPositionRegular regular
Definition: InjectorPosition.H:203
def x
Definition: read_lab_particles.py:25
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:101
Object(InjectorPositionRandom *) noexcept
Definition: InjectorPosition.H:196
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:126
Object(InjectorPositionRandomPlane *, int const &a_dir) noexcept
Definition: InjectorPosition.H:197
Definition: InjectorPosition.H:195
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:208
InjectorPositionRandomPlane randomplane
Definition: InjectorPosition.H:202
def z
Definition: read_lab_particles.py:26
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool overlapsWith(const amrex::XDim3 &lo, const amrex::XDim3 &hi) const noexcept
Definition: InjectorPosition.H:182
amrex::Real xmin
Definition: InjectorPosition.H:207
Type type
Definition: InjectorPosition.H:191
InjectorPositionRegular(amrex::Dim3 const &a_ppc) noexcept
Definition: InjectorPosition.H:58
AMREX_GPU_HOST_DEVICE bool insideBounds(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorPosition.H:172
Definition: InjectorPosition.H:19
InjectorPositionRandom random
Definition: InjectorPosition.H:201
type
Definition: run_alltests_1node.py:67
amrex::Real zmin
Definition: InjectorPosition.H:209
Type
Definition: InjectorPosition.H:190
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:113
Object object
Definition: InjectorPosition.H:205
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int const i_part, int const ref_fac, amrex::RandomEngine const &) const noexcept
Definition: InjectorPosition.H:66
Definition: InjectorPosition.H:56
Definition: InjectorPosition.H:32
Object(InjectorPositionRegular *, amrex::Dim3 const &a_ppc) noexcept
Definition: InjectorPosition.H:199
Definition: InjectorPosition.H:98
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:149
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int, int, amrex::RandomEngine const &engine) const noexcept
Definition: InjectorPosition.H:38
Definition: BreitWheelerEngineWrapper.H:35
amrex::Dim3 ppc
Definition: InjectorPosition.H:88