WarpX
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 INJECTOR_DENSITY_H_
10 #define INJECTOR_DENSITY_H_
11 
12 #include "Utils/WarpXConst.H"
13 
14 #include <AMReX.H>
15 #include <AMReX_Array.H>
16 #include <AMReX_GpuQualifiers.H>
17 #include <AMReX_Math.H>
18 #include <AMReX_Parser.H>
19 #include <AMReX_REAL.H>
20 
21 #include <cmath>
22 #include <string>
23 
24 // struct whose getDensity returns constant density.
26 {
27  InjectorDensityConstant (amrex::Real a_rho) noexcept : m_rho(a_rho) {}
28 
30  amrex::Real
31  getDensity (amrex::Real, amrex::Real, amrex::Real) const noexcept
32  {
33  return m_rho;
34  }
35 
36 private:
37  amrex::Real m_rho;
38 };
39 
40 // struct whose getDensity returns local density computed from parser.
42 {
44  : m_parser(a_parser) {}
45 
47  amrex::Real
48  getDensity (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
49  {
50  return m_parser(x,y,z);
51  }
52 
54 };
55 
56 // struct whose getDensity returns local density computed from predefined profile.
58 {
59  InjectorDensityPredefined (std::string const& a_species_name) noexcept;
60 
61  void clear ();
62 
64  amrex::Real
65  getDensity (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
66  {
67  // Choices for profile are:
68  // - parabolic_channel
69  switch (profile)
70  {
72  {
73  // These are cast as double to ensure sufficient precision in the
74  // initialized profile density profile; without these, single and
75  // double precision versions of the executable can show disagreement
76  // From testing, it seems that (for at least some setups), it is only
77  // necessary to case n0 as double to get good agreement between single
78  // and double precision, but just in case, all are cast as double.
79  const double z_start = p[0];
80  const double ramp_up = p[1];
81  const double plateau = p[2];
82  const double ramp_down = p[3];
83  const double rc = p[4];
84  const double n0 = p[5];
85  const double kp = PhysConst::q_e/PhysConst::c
86  *std::sqrt( n0/(PhysConst::m_e*PhysConst::ep0) );
87  double n;
88 
89  // Longitudinal profile, normalized to 1
90  if ((z-z_start)>=0 and
91  (z-z_start)<ramp_up ) {
92  n = 0.5*(1.-std::cos(MathConst::pi*(z-z_start)/ramp_up));
93  } else if ((z-z_start)>=ramp_up and
94  (z-z_start)< ramp_up+plateau ) {
95  n = 1.;
96  } else if ((z-z_start)>=ramp_up+plateau and
97  (z-z_start)< ramp_up+plateau+ramp_down) {
98  n = 0.5*(1.+std::cos(MathConst::pi*((z-z_start)-ramp_up-plateau)/ramp_down));
99  } else {
100  n = 0.;
101  }
102  // Multiply by transverse profile, and physical density
103  n *= n0*(1.+4.*(x*x+y*y)/(kp*kp*rc*rc*rc*rc));
104  return static_cast<amrex::Real>(n);
105  }
106  default:
107  amrex::Abort("InjectorDensityPredefined: how did we get here?");
108  return amrex::Real(0.0);
109  }
110  }
111 
112 private:
113  enum struct Profile { null, parabolic_channel };
116 };
117 
118 // Base struct for density injector.
119 // InjectorDensity contains a union (called Object) that holds any one
120 // instance of:
121 // - InjectorDensityConstant : to generate constant density;
122 // - InjectorDensityParser : to generate density from parser;
123 // - InjectorDensityPredefined: to generate density from predefined profile;
124 // The choice is made at runtime, depending in the constructor called.
125 // This mimics virtual functions.
127 {
128  // This constructor stores a InjectorDensityConstant in union object.
129  InjectorDensity (InjectorDensityConstant* t, amrex::Real a_rho)
130  : type(Type::constant),
131  object(t,a_rho)
132  { }
133 
134  // This constructor stores a InjectorDensityParser in union object.
136  : type(Type::parser),
137  object(t,a_parser)
138  { }
139 
140  // This constructor stores a InjectorDensityPredefined in union object.
141  InjectorDensity (InjectorDensityPredefined* t, std::string const& a_species_name)
142  : type(Type::predefined),
143  object(t,a_species_name)
144  { }
145 
146  // Explicitly prevent the compiler from generating copy constructors
147  // and copy assignment operators.
148  InjectorDensity (InjectorDensity const&) = delete;
150  void operator= (InjectorDensity const&) = delete;
151  void operator= (InjectorDensity &&) = delete;
152 
153  // Default destructor
154  ~InjectorDensity () = default;
155 
156  void clear ();
157 
158  // call getDensity from the object stored in the union
159  // (the union is called Object, and the instance is called object).
161  amrex::Real
162  getDensity (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
163  {
164  switch (type)
165  {
166  case Type::parser:
167  {
168  return object.parser.getDensity(x,y,z);
169  }
170  case Type::constant:
171  {
172  return object.constant.getDensity(x,y,z);
173  }
174  case Type::predefined:
175  {
176  return object.predefined.getDensity(x,y,z);
177  }
178  default:
179  {
180  amrex::Abort("InjectorDensity: unknown type");
181  return 0.0;
182  }
183  }
184  }
185 
186 private:
187  enum struct Type { constant, predefined, parser };
189 
190  // An instance of union Object constructs and stores any one of
191  // the objects declared (constant or parser or predefined).
192  union Object {
193  Object (InjectorDensityConstant*, amrex::Real a_rho) noexcept
194  : constant(a_rho) {}
196  : parser(a_parser) {}
197  Object (InjectorDensityPredefined*, std::string const& a_species_name) noexcept
198  : predefined(a_species_name) {}
202  };
204 };
205 
206 // In order for InjectorDensity to be trivially copyable, its destructor
207 // must be trivial. So we have to rely on a custom deleter for unique_ptr.
209  void operator () (InjectorDensity* p) const {
210  if (p) {
211  p->clear();
212  delete p;
213  }
214  }
215 };
216 
217 #endif
#define AMREX_GPU_HOST_DEVICE
static constexpr auto c
vacuum speed of light [m/s]
Definition: constant.H:44
static constexpr auto ep0
vacuum permittivity: dielectric permittivity of vacuum [F/m]
Definition: constant.H:46
static constexpr auto m_e
electron mass [kg]
Definition: constant.H:52
static constexpr auto q_e
elementary charge [C]
Definition: constant.H:50
void Abort(const std::string &msg)
int n
Definition: run_libensemble_on_warpx.py:70
Definition: InjectorDensity.H:26
InjectorDensityConstant(amrex::Real a_rho) noexcept
Definition: InjectorDensity.H:27
amrex::Real m_rho
Definition: InjectorDensity.H:37
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real, amrex::Real, amrex::Real) const noexcept
Definition: InjectorDensity.H:31
Definition: InjectorDensity.H:208
void operator()(InjectorDensity *p) const
Definition: InjectorDensity.H:209
Definition: InjectorDensity.H:127
~InjectorDensity()=default
Type type
Definition: InjectorDensity.H:188
InjectorDensity(InjectorDensityPredefined *t, std::string const &a_species_name)
Definition: InjectorDensity.H:141
Type
Definition: InjectorDensity.H:187
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:162
InjectorDensity(InjectorDensityConstant *t, amrex::Real a_rho)
Definition: InjectorDensity.H:129
Object object
Definition: InjectorDensity.H:203
InjectorDensity(InjectorDensityParser *t, amrex::ParserExecutor< 3 > const &a_parser)
Definition: InjectorDensity.H:135
InjectorDensity(InjectorDensity const &)=delete
void clear()
Definition: InjectorDensity.cpp:22
InjectorDensity(InjectorDensity &&)=delete
Definition: InjectorDensity.H:42
InjectorDensityParser(amrex::ParserExecutor< 3 > const &a_parser) noexcept
Definition: InjectorDensity.H:43
amrex::ParserExecutor< 3 > m_parser
Definition: InjectorDensity.H:53
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorDensity.H:48
Definition: InjectorDensity.H:58
InjectorDensityPredefined(std::string const &a_species_name) noexcept
Definition: InjectorDensity.cpp:40
Profile profile
Definition: InjectorDensity.H:114
Profile
Definition: InjectorDensity.H:113
amrex::GpuArray< amrex::Real, 6 > p
Definition: InjectorDensity.H:115
void clear()
Definition: InjectorDensity.cpp:70
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorDensity.H:65
Definition: InjectorDensity.H:192
InjectorDensityConstant constant
Definition: InjectorDensity.H:199
Object(InjectorDensityParser *, amrex::ParserExecutor< 3 > const &a_parser) noexcept
Definition: InjectorDensity.H:195
InjectorDensityPredefined predefined
Definition: InjectorDensity.H:201
InjectorDensityParser parser
Definition: InjectorDensity.H:200
Object(InjectorDensityPredefined *, std::string const &a_species_name) noexcept
Definition: InjectorDensity.H:197
Object(InjectorDensityConstant *, amrex::Real a_rho) noexcept
Definition: InjectorDensity.H:193