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