WarpX
Loading...
Searching...
No Matches
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
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) || (defined WARPX_DIM_RCYLINDER) || (defined WARPX_DIM_RSPHERE))
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) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE))
55 // In 1D, the first components of the `XDim3` vector below correspond to the first dimension,
56 // z for 1D Cartesian, and r for 1D cylindrical and spherical.
57 if (dir == 0) { return amrex::XDim3{amrex::Random(engine), 0._rt, 0._rt}; }
58 if (dir == 1) { return amrex::XDim3{amrex::Random(engine), 0._rt, 0._rt}; }
59 else { return amrex::XDim3{0._rt, 0._rt, 0._rt}; }
60#endif
61 }
62private:
63 int dir;
64};
65
66// struct whose getPositionUnitBox returns x, y and z for a particle with
67// regular distribution inside a unit cell.
69{
70 InjectorPositionRegular (amrex::Dim3 const& a_ppc) noexcept : ppc(a_ppc) {}
71
72 // i_part: particle number within the cell, required to evenly space
73 // particles within the cell.
74 // ref_fac: the number of particles evenly-spaced within a cell
75 // is a_ppc*(ref_fac**AMREX_SPACEDIM).
76 [[nodiscard]]
79 getPositionUnitBox (int const i_part, amrex::IntVect const ref_fac,
80 amrex::RandomEngine const&) const noexcept
81 {
82 using namespace amrex;
83
84#if (defined WARPX_DIM_3D)
85 int const nx = ref_fac[0]*ppc.x;
86 int const ny = ref_fac[1]*ppc.y;
87 int const nz = ref_fac[2]*ppc.z;
88#elif (defined WARPX_DIM_RZ)
89 int const nx = ref_fac[0]*ppc.x;
90 int const ny = ref_fac[1]*ppc.y;
91 int const nz = ppc.z; // Number of particles in theta ; no refinement
92#elif (defined WARPX_DIM_RCYLINDER)
93 int const nx = ref_fac[0]*ppc.x;
94 int const ny = ppc.y;
95 int const nz = 1;
96#elif (defined WARPX_DIM_RSPHERE)
97 int const nx = ref_fac[0]*ppc.x;
98 int const ny = ppc.y; // Number of particles in theta ; no refinement
99 int const nz = ppc.z; // Number of particles in phi ; no refinement
100#elif (defined WARPX_DIM_XZ)
101 int const nx = ref_fac[0]*ppc.x;
102 int const ny = ref_fac[1]*ppc.y;
103 int const nz = 1;
104#elif (defined WARPX_DIM_1D_Z)
105 int const nx = ref_fac[0]*ppc.x;
106 int const ny = 1;
107 int const nz = 1;
108#endif
109 int const ix_part = i_part / (ny*nz); // written this way backward compatibility
110 int const iz_part = (i_part-ix_part*(ny*nz)) / ny;
111 int const iy_part = (i_part-ix_part*(ny*nz)) - ny*iz_part;
112 return XDim3{
113 (0.5_rt + ix_part) / nx,
114 (0.5_rt + iy_part) / ny,
115 (0.5_rt + iz_part) / nz
116 };
117 }
118private:
120};
121
122// Base struct for position injector.
123// InjectorPosition contains a union (called Object) that holds any one
124// instance of:
125// - InjectorPositionRandom : to generate random distribution;
126// - InjectorPositionRegular: to generate regular distribution.
127// The choice is made at runtime, depending in the constructor called.
128// This mimics virtual functions.
130{
131 // This constructor stores a InjectorPositionRandom 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 : type(Type::random),
137 object(t),
138 xmin(a_xmin), xmax(a_xmax),
139 ymin(a_ymin), ymax(a_ymax),
140 zmin(a_zmin), zmax(a_zmax)
141 { }
142
143 // This constructor stores a InjectorPositionRandomPlane in union object.
145 amrex::Real a_xmin, amrex::Real a_xmax,
146 amrex::Real a_ymin, amrex::Real a_ymax,
147 amrex::Real a_zmin, amrex::Real a_zmax,
148 int const& a_dir)
150 object(t, a_dir),
151 xmin(a_xmin), xmax(a_xmax),
152 ymin(a_ymin), ymax(a_ymax),
153 zmin(a_zmin), zmax(a_zmax)
154 { }
155
156 // This constructor stores a InjectorPositionRegular in union object.
158 amrex::Real a_xmin, amrex::Real a_xmax,
159 amrex::Real a_ymin, amrex::Real a_ymax,
160 amrex::Real a_zmin, amrex::Real a_zmax,
161 amrex::Dim3 const& a_ppc)
162 : type(Type::regular),
163 object(t, a_ppc),
164 xmin(a_xmin), xmax(a_xmax),
165 ymin(a_ymin), ymax(a_ymax),
166 zmin(a_zmin), zmax(a_zmax)
167 { }
168
169 ~InjectorPosition () = default;
170
171 // Explicitly prevent the compiler from generating copy constructors
172 // and copy assignment operators.
175 void operator= (InjectorPosition const&) = delete;
176 void operator= (InjectorPosition &&) = delete;
177
178 // call getPositionUnitBox from the object stored in the union
179 // (the union is called Object, and the instance is called object).
180 [[nodiscard]]
183 getPositionUnitBox (int const i_part, amrex::IntVect const ref_fac,
184 amrex::RandomEngine const& engine) const noexcept
185 {
186 switch (type)
187 {
188 case Type::regular:
189 {
190 return object.regular.getPositionUnitBox(i_part, ref_fac, engine);
191 }
193 {
194 return object.randomplane.getPositionUnitBox(i_part, ref_fac, engine);
195 }
196 default:
197 {
198 return object.random.getPositionUnitBox(i_part, ref_fac, engine);
199 }
200 };
201 }
202
203 /* \brief Flags whether the point (x, y, z) is inside the plasma region
204 * or on the lower boundary
205 * \param x, y, z the point to check
206 * \returns bool flag
207 */
208 [[nodiscard]]
210 bool
211 insideBounds (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 /* \brief Flags whether the point (x, y, z) is inside the plasma region
219 * or on the lower or upper boundary
220 * \param x, y, z the point to check
221 * \returns bool flag
222 */
223 [[nodiscard]]
225 bool
226 insideBoundsInclusive (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
227 {
228 return (x <= xmax and x >= xmin and
229 y <= ymax and y >= ymin and
230 z <= zmax and z >= zmin);
231 }
232
233 // bool: whether the region defined by lo and hi overlaps with the plasma region
234 [[nodiscard]]
236 bool
237 overlapsWith (const amrex::XDim3& lo, const amrex::XDim3& hi) const noexcept
238 {
239 return ( (xmin <= hi.x) && (xmax >= lo.x)
240 && (ymin <= hi.y) && (ymax >= lo.y)
241 && (zmin <= hi.z) && (zmax >= lo.z) );
242 }
243
244private:
245 enum struct Type { random, randomplane, regular };
247
248 // An instance of union Object constructs and stores any one of
249 // the objects declared (random or regular).
261
262 amrex::Real xmin, xmax;
263 amrex::Real ymin, ymax;
264 amrex::Real zmin, zmax;
265};
266
267#endif //WARPX_INJECTOR_POSITION_H_
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
Real Random()
IntVectND< 3 > IntVect
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:132
amrex::Real ymax
Definition InjectorPosition.H:263
Object object
Definition InjectorPosition.H:260
Type
Definition InjectorPosition.H:245
@ random
Definition InjectorPosition.H:245
@ randomplane
Definition InjectorPosition.H:245
@ regular
Definition InjectorPosition.H:245
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool overlapsWith(const amrex::XDim3 &lo, const amrex::XDim3 &hi) const noexcept
Definition InjectorPosition.H:237
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:144
amrex::Real xmin
Definition InjectorPosition.H:262
AMREX_GPU_HOST_DEVICE bool insideBounds(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition InjectorPosition.H:211
amrex::Real ymin
Definition InjectorPosition.H:263
amrex::Real zmax
Definition InjectorPosition.H:264
AMREX_GPU_HOST_DEVICE bool insideBoundsInclusive(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition InjectorPosition.H:226
Type type
Definition InjectorPosition.H:246
void operator=(InjectorPosition const &)=delete
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:157
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:183
InjectorPosition(InjectorPosition const &)=delete
amrex::Real zmin
Definition InjectorPosition.H:264
amrex::Real xmax
Definition InjectorPosition.H:262
~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:63
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:69
InjectorPositionRegular(amrex::Dim3 const &a_ppc) noexcept
Definition InjectorPosition.H:70
AMREX_GPU_HOST_DEVICE amrex::XDim3 getPositionUnitBox(int const i_part, amrex::IntVect const ref_fac, amrex::RandomEngine const &) const noexcept
Definition InjectorPosition.H:79
amrex::Dim3 ppc
Definition InjectorPosition.H:119
Definition InjectorPosition.H:250
Object(InjectorPositionRandom *) noexcept
Definition InjectorPosition.H:251
InjectorPositionRegular regular
Definition InjectorPosition.H:258
InjectorPositionRandom random
Definition InjectorPosition.H:256
InjectorPositionRandomPlane randomplane
Definition InjectorPosition.H:257
Object(InjectorPositionRandomPlane *, int const &a_dir) noexcept
Definition InjectorPosition.H:252
Object(InjectorPositionRegular *, amrex::Dim3 const &a_ppc) noexcept
Definition InjectorPosition.H:254