WarpX
Loading...
Searching...
No Matches
InjectorDensity.H
Go to the documentation of this file.
1/* Copyright 2019 Axel Huebl, Maxence Thevenet, Weiqun Zhang
2 * Michael Rowan
3 *
4 *
5 * This file is part of WarpX.
6 *
7 * License: BSD-3-Clause-LBNL
8 */
9#ifndef WARPX_INJECTOR_DENSITY_H_
10#define WARPX_INJECTOR_DENSITY_H_
11
13#include "Utils/WarpXConst.H"
14
15#include <AMReX.H>
16#include <AMReX_Array.H>
17#include <AMReX_BoxArray.H>
18#include <AMReX_DataAllocator.H>
20#include <AMReX_Geometry.H>
21#include <AMReX_GpuQualifiers.H>
22#include <AMReX_Math.H>
23#include <AMReX_Parser.H>
24#include <AMReX_REAL.H>
25#include <AMReX_Vector.H>
26
27#include <cmath>
28#include <functional>
29#include <string>
30
31// struct whose getDensity returns constant density.
33{
34 InjectorDensityConstant (amrex::Real a_rho) noexcept : m_rho(a_rho) {}
35
36 [[nodiscard]]
40 {
41 return m_rho;
42 }
43
44private:
46};
47
48// struct whose getDensity returns local density computed from parser.
50{
52 : m_parser(a_parser) {}
53
54 [[nodiscard]]
58 {
59 return m_parser(x,y,z);
60 }
61
63};
64
65// struct whose getDensity returns local density computed from predefined profile.
67{
68 InjectorDensityPredefined (std::string const& a_species_name);
69
70 void clear ();
71
72 [[nodiscard]]
76 {
77 // Choices for profile are:
78 // - parabolic_channel
79 switch (profile)
80 {
82 {
83 // These are cast as double to ensure sufficient precision in the
84 // initialized profile density profile; without these, single and
85 // double precision versions of the executable can show disagreement
86 // From testing, it seems that (for at least some setups), it is only
87 // necessary to case n0 as double to get good agreement between single
88 // and double precision, but just in case, all are cast as double.
89 const double z_start = p[0];
90 const double ramp_up = p[1];
91 const double plateau = p[2];
92 const double ramp_down = p[3];
93 const double rc = p[4];
94 const double n0 = p[5];
95 const double kp = PhysConst::q_e/PhysConst::c
96 *std::sqrt( n0/(PhysConst::m_e*PhysConst::epsilon_0) );
97 double n;
98
99 // Longitudinal profile, normalized to 1
100 if ((z-z_start)>=0 and
101 (z-z_start)<ramp_up ) {
102 n = 0.5*(1.-std::cos(MathConst::pi*(z-z_start)/ramp_up));
103 } else if ((z-z_start)>=ramp_up and
104 (z-z_start)< ramp_up+plateau ) {
105 n = 1.;
106 } else if ((z-z_start)>=ramp_up+plateau and
107 (z-z_start)< ramp_up+plateau+ramp_down) {
108 n = 0.5*(1.+std::cos(MathConst::pi*((z-z_start)-ramp_up-plateau)/ramp_down));
109 } else {
110 n = 0.;
111 }
112 // Multiply by transverse profile, and physical density
113 n *= n0*(1.+4.*(x*x+y*y)/(kp*kp*rc*rc*rc*rc));
114 return static_cast<amrex::Real>(n);
115 }
116 default:
117 amrex::Abort("InjectorDensityPredefined: how did we get here?");
118 return amrex::Real(0.0);
119 }
120 }
121
122private:
126};
127
128// struct whose getDensity returns density from file.
130{
131 InjectorDensityFromFile (std::string const& a_file_name, amrex::Geometry const& a_geom, bool a_distributed);
132
133 void clear ();
134
135 // This function needs to be called before intializing the density
136 // profile, if the openPMD data are distributed. When the openPMD data
137 // are loaded in the constructor of this class, we do not know the
138 // paricle containers' BoxArray and DistributionMapping yet.
139 void prepare (amrex::BoxArray const& grids,
140 amrex::DistributionMapping const& dmap,
141 amrex::IntVect const& ngrow,
142 std::function<amrex::Real(amrex::Real)> const& get_zlab);
143
144 // This function needs to be called before we do continuous injection of
145 // particles to inform the injector to load the data we need.
146 void prepare (amrex::RealBox const& pbox, int moving_dir, int moving_sign,
147 std::function<amrex::Real(amrex::Real)> const& get_zlab);
148
149 // For distributed data, this function prepares the injector for loading
150 // data in this Box. Here `li` is the local index for the Box in a
151 // particle container.
152 void prepare (int li);
153
154 [[nodiscard]] bool distributed () const;
155
156 [[nodiscard]]
160 {
161#if (AMREX_SPACEDIM < 3)
163#endif
164#if (AMREX_SPACEDIM == 1)
166#elif defined(WARPX_DIM_RZ)
167 return m_external_field_view(amrex::RealVect{std::sqrt(x*x+y*y),z});
168#elif defined(WARPX_DIM_XZ)
170#else
172#endif
173 }
174
175private:
178};
179
180// Base struct for density injector.
181// InjectorDensity contains a union (called Object) that holds any one
182// instance of:
183// - InjectorDensityConstant : to generate constant density;
184// - InjectorDensityParser : to generate density from parser;
185// - InjectorDensityPredefined: to generate density from predefined profile;
186// - InjectorDensityFromFile : to generate density from file;
187// The choice is made at runtime, depending in the constructor called.
188// This mimics virtual functions.
190{
191 // This constructor stores a InjectorDensityConstant in union object.
193 : type(Type::constant),
194 object(t,a_rho)
195 { }
196
197 // This constructor stores a InjectorDensityParser in union object.
199 : type(Type::parser),
200 object(t,a_parser)
201 { }
202
203 // This constructor stores a InjectorDensityPredefined in union object.
204 InjectorDensity (InjectorDensityPredefined* t, std::string const& a_species_name)
205 : type(Type::predefined),
206 object(t,a_species_name)
207 { }
208
209 // This constructor stores a InjectorDensityFromFile in union object.
210 InjectorDensity (InjectorDensityFromFile* t, std::string const& a_file_name,
211 amrex::Geometry const& a_geom, bool a_distributed)
212 : type(Type::fromfile),
213 object(t,a_file_name,a_geom,a_distributed)
214 { }
215
216 // Explicitly prevent the compiler from generating copy constructors
217 // and copy assignment operators.
220 void operator= (InjectorDensity const&) = delete;
221 void operator= (InjectorDensity &&) = delete;
222
223 // Default destructor
224 ~InjectorDensity () = default;
225
226 void clear ();
227
228 void prepare (amrex::BoxArray const& grids,
229 amrex::DistributionMapping const& dmap,
230 amrex::IntVect const& ngrow,
231 std::function<amrex::Real(amrex::Real)> const& get_zlab);
232
233 void prepare (amrex::RealBox const& pbox, int moving_dir, int moving_sign,
234 std::function<amrex::Real(amrex::Real)> const& get_zlab);
235
236 void prepare (int li, InjectorDensity** inj_rho);
237
238 [[nodiscard]] bool needPreparation () const;
239
240 [[nodiscard]] bool distributed () const;
241
242 // call getDensity from the object stored in the union
243 // (the union is called Object, and the instance is called object).
244 [[nodiscard]]
248 {
249 switch (type)
250 {
251 case Type::parser:
252 {
253 return object.parser.getDensity(x,y,z);
254 }
255 case Type::constant:
256 {
257 return object.constant.getDensity(x,y,z);
258 }
259 case Type::predefined:
260 {
261 return object.predefined.getDensity(x,y,z);
262 }
263 case Type::fromfile:
264 {
265 return object.fromfile.getDensity(x,y,z);
266 }
267 default:
268 {
269 amrex::Abort("InjectorDensity: unknown type");
270 return 0.0;
271 }
272 }
273 }
274
275private:
278
279 // An instance of union Object constructs and stores any one of
280 // the objects declared (constant or parser or predefined).
281 union Object {
283 : constant(a_rho) {}
285 : parser(a_parser) {}
286 Object (InjectorDensityPredefined*, std::string const& a_species_name)
287 : predefined(a_species_name) {}
288 Object (InjectorDensityFromFile*, std::string const& a_file_name,
289 amrex::Geometry const& a_geom, bool a_distributed)
290 : fromfile(a_file_name, a_geom, a_distributed) {}
295 };
297#if defined(AMREX_USE_OMP) && !defined(AMREX_USE_GPU)
298 std::unique_ptr<void,amrex::DataDeleter> inj_rho_data;
300#endif
301};
302
303// In order for InjectorDensity to be trivially copyable, its destructor
304// must be trivial. So we have to rely on a custom deleter for unique_ptr.
307 if (p) {
308 p->clear();
309 delete p;
310 }
311 }
312};
313
314#endif //WARPX_INJECTOR_DENSITY_H_
#define AMREX_GPU_HOST_DEVICE
Definition ExternalField.H:183
amrex_real Real
constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:153
constexpr auto epsilon_0
vacuum permittivity: dielectric permittivity of vacuum [F/m]
Definition constant.H:156
constexpr auto m_e
electron mass [kg]
Definition constant.H:165
constexpr auto q_e
elementary charge [C]
Definition constant.H:162
constexpr auto pi
ratio of a circle's circumference to its diameter
Definition constant.H:29
__host__ __device__ void ignore_unused(const Ts &...)
IntVectND< 3 > IntVect
RealVectND< 3 > RealVect
void Abort(const std::string &msg)
Companion class for ExternalFieldReader.
Definition ExternalField.H:84
Definition InjectorDensity.H:33
InjectorDensityConstant(amrex::Real a_rho) noexcept
Definition InjectorDensity.H:34
amrex::Real m_rho
Definition InjectorDensity.H:45
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real, amrex::Real, amrex::Real) const noexcept
Definition InjectorDensity.H:39
Definition InjectorDensity.H:305
void operator()(InjectorDensity *p) const
Definition InjectorDensity.H:306
Definition InjectorDensity.H:130
ExternalFieldReader * m_external_field_reader
Definition InjectorDensity.H:177
bool distributed() const
Definition InjectorDensity.cpp:194
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition InjectorDensity.H:159
void prepare(amrex::BoxArray const &grids, amrex::DistributionMapping const &dmap, amrex::IntVect const &ngrow, std::function< amrex::Real(amrex::Real)> const &get_zlab)
Definition InjectorDensity.cpp:167
void clear()
Definition InjectorDensity.cpp:161
InjectorDensityFromFile(std::string const &a_file_name, amrex::Geometry const &a_geom, bool a_distributed)
Definition InjectorDensity.cpp:152
ExternalFieldView m_external_field_view
Definition InjectorDensity.H:176
Definition InjectorDensity.H:190
amrex::Vector< InjectorDensity * > inj_rho_omp
Definition InjectorDensity.H:299
~InjectorDensity()=default
Type type
Definition InjectorDensity.H:277
InjectorDensity(InjectorDensityPredefined *t, std::string const &a_species_name)
Definition InjectorDensity.H:204
InjectorDensity(InjectorDensityFromFile *t, std::string const &a_file_name, amrex::Geometry const &a_geom, bool a_distributed)
Definition InjectorDensity.H:210
Type
Definition InjectorDensity.H:276
@ parser
Definition InjectorDensity.H:276
@ constant
Definition InjectorDensity.H:276
@ predefined
Definition InjectorDensity.H:276
@ fromfile
Definition InjectorDensity.H:276
void operator=(InjectorDensity const &)=delete
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition InjectorDensity.H:247
InjectorDensity(InjectorDensityConstant *t, amrex::Real a_rho)
Definition InjectorDensity.H:192
std::unique_ptr< void, amrex::DataDeleter > inj_rho_data
Definition InjectorDensity.H:298
Object object
Definition InjectorDensity.H:296
void prepare(amrex::BoxArray const &grids, amrex::DistributionMapping const &dmap, amrex::IntVect const &ngrow, std::function< amrex::Real(amrex::Real)> const &get_zlab)
Definition InjectorDensity.cpp:46
InjectorDensity(InjectorDensityParser *t, amrex::ParserExecutor< 3 > const &a_parser)
Definition InjectorDensity.H:198
bool needPreparation() const
Definition InjectorDensity.cpp:101
InjectorDensity(InjectorDensity const &)=delete
void clear()
Definition InjectorDensity.cpp:23
bool distributed() const
Definition InjectorDensity.cpp:110
InjectorDensity(InjectorDensity &&)=delete
Definition InjectorDensity.H:50
InjectorDensityParser(amrex::ParserExecutor< 3 > const &a_parser) noexcept
Definition InjectorDensity.H:51
amrex::ParserExecutor< 3 > m_parser
Definition InjectorDensity.H:62
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition InjectorDensity.H:57
Definition InjectorDensity.H:67
Profile profile
Definition InjectorDensity.H:124
InjectorDensityPredefined(std::string const &a_species_name)
Definition InjectorDensity.cpp:119
Profile
Definition InjectorDensity.H:123
@ parabolic_channel
Definition InjectorDensity.H:123
@ null
Definition InjectorDensity.H:123
amrex::GpuArray< amrex::Real, 6 > p
Definition InjectorDensity.H:125
void clear()
Definition InjectorDensity.cpp:148
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition InjectorDensity.H:75
Definition InjectorDensity.H:281
InjectorDensityConstant constant
Definition InjectorDensity.H:291
Object(InjectorDensityParser *, amrex::ParserExecutor< 3 > const &a_parser) noexcept
Definition InjectorDensity.H:284
InjectorDensityPredefined predefined
Definition InjectorDensity.H:293
InjectorDensityFromFile fromfile
Definition InjectorDensity.H:294
Object(InjectorDensityFromFile *, std::string const &a_file_name, amrex::Geometry const &a_geom, bool a_distributed)
Definition InjectorDensity.H:288
Object(InjectorDensityPredefined *, std::string const &a_species_name)
Definition InjectorDensity.H:286
InjectorDensityParser parser
Definition InjectorDensity.H:292
Object(InjectorDensityConstant *, amrex::Real a_rho) noexcept
Definition InjectorDensity.H:282