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