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 "Parser/GpuParser.H"
13 #include "CustomDensityProb.H"
14 #include "Utils/WarpXConst.H"
15 
16 #include <AMReX_Gpu.H>
17 #include <AMReX_Dim3.H>
18 
19 // struct whose getDensity returns constant density.
21 {
22  InjectorDensityConstant (amrex::Real a_rho) noexcept : m_rho(a_rho) {}
23 
24  AMREX_GPU_HOST_DEVICE
25  amrex::Real
26  getDensity (amrex::Real, amrex::Real, amrex::Real) const noexcept
27  {
28  return m_rho;
29  }
30 
31 private:
32  amrex::Real m_rho;
33 };
34 
35 // struct whose getDensity returns local density computed from parser.
37 {
38  InjectorDensityParser (WarpXParser const& a_parser) noexcept
39  : m_parser(a_parser) {}
40 
41  AMREX_GPU_HOST_DEVICE
42  amrex::Real
43  getDensity (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
44  {
45  return m_parser(x,y,z);
46  }
47 
48  // InjectorDensityParser constructs this GpuParser from WarpXParser.
50 };
51 
52 // struct whose getDensity returns local density computed from predefined profile.
54 {
55  InjectorDensityPredefined (std::string const& a_species_name) noexcept;
56 
57  void clear ();
58 
59  AMREX_GPU_HOST_DEVICE
60  amrex::Real
61  getDensity (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
62  {
63  // Choices for profile are:
64  // - parabolic_channel
65  switch (profile)
66  {
67  case Profile::parabolic_channel:
68  {
69  // These are cast as double to ensure sufficient precision in the
70  // initialized profile density profile; without these, single and
71  // double precision versions of the executable can show disagreement
72  // From testing, it seems that (for at least some setups), it is only
73  // necessary to case n0 as double to get good agreement between single
74  // and double precision, but just in case, all are cast as double.
75  double z_start = p[0];
76  double ramp_up = p[1];
77  double plateau = p[2];
78  double ramp_down = p[3];
79  double rc = p[4];
80  double n0 = p[5];
81  double n;
82  double kp = PhysConst::q_e/PhysConst::c
83  *std::sqrt( n0/(PhysConst::m_e*PhysConst::ep0) );
84 
85  // Longitudinal profile, normalized to 1
86  if ((z-z_start)>=0 and
87  (z-z_start)<ramp_up ) {
88  n = 0.5*(1.-std::cos(MathConst::pi*(z-z_start)/ramp_up));
89  } else if ((z-z_start)>=ramp_up and
90  (z-z_start)< ramp_up+plateau ) {
91  n = 1.;
92  } else if ((z-z_start)>=ramp_up+plateau and
93  (z-z_start)< ramp_up+plateau+ramp_down) {
94  n = 0.5*(1.+std::cos(MathConst::pi*((z-z_start)-ramp_up-plateau)/ramp_down));
95  } else {
96  n = 0.;
97  }
98  // Multiply by transverse profile, and physical density
99  n *= n0*(1.+4.*(x*x+y*y)/(kp*kp*rc*rc*rc*rc));
100  return n;
101  }
102  default:
103  amrex::Abort("InjectorDensityPredefined: how did we get here?");
104  return 0.0;
105  }
106  }
107 
108 private:
109  enum struct Profile { null, parabolic_channel };
111  amrex::GpuArray<amrex::Real,6> p;
112 };
113 
114 // Base struct for density injector.
115 // InjectorDensity contains a union (called Object) that holds any one
116 // instance of:
117 // - InjectorDensityConstant : to generate constant density;
118 // - InjectorDensityParser : to generate density from parser;
119 // - InjectorDensityCustom : to generate density from custom profile;
120 // - InjectorDensityPredefined: to generate density from predefined profile;
121 // The choice is made at runtime, depending in the constructor called.
122 // This mimics virtual functions.
124 {
125  // This constructor stores a InjectorDensityConstant in union object.
126  InjectorDensity (InjectorDensityConstant* t, amrex::Real a_rho)
127  : type(Type::constant),
128  object(t,a_rho)
129  { }
130 
131  // This constructor stores a InjectorDensityParser in union object.
133  : type(Type::parser),
134  object(t,a_parser)
135  { }
136 
137  // This constructor stores a InjectorDensityCustom in union object.
138  InjectorDensity (InjectorDensityCustom* t, std::string const& a_species_name)
139  : type(Type::custom),
140  object(t,a_species_name)
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;
152  InjectorDensity (InjectorDensity&&) = delete;
153  void operator= (InjectorDensity const&) = delete;
154  void operator= (InjectorDensity &&) = delete;
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).
160  AMREX_GPU_HOST_DEVICE
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::custom:
175  {
176  return object.custom.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, custom, predefined, parser };
193 
194  // An instance of union Object constructs and stores any one of
195  // the objects declared (constant or parser or custom or predefined).
196  union Object {
197  Object (InjectorDensityConstant*, amrex::Real a_rho) noexcept
198  : constant(a_rho) {}
199  Object (InjectorDensityParser*, WarpXParser const& a_parser) noexcept
200  : parser(a_parser) {}
201  Object (InjectorDensityCustom*, std::string const& a_species_name) noexcept
202  : custom(a_species_name) {}
203  Object (InjectorDensityPredefined*, std::string const& a_species_name) noexcept
204  : predefined(a_species_name) {}
209  };
211 };
212 
213 // In order for InjectorDensity to be trivially copyable, its destructor
214 // must be trivial. So we have to rely on a custom deleter for unique_ptr.
216  void operator () (InjectorDensity* p) const {
217  if (p) {
218  p->clear();
219  delete p;
220  }
221  }
222 };
223 
224 #endif
InjectorDensity(InjectorDensityParser *t, WarpXParser const &a_parser)
Definition: InjectorDensity.H:132
Type type
Definition: InjectorDensity.H:192
InjectorDensity(InjectorDensityCustom *t, std::string const &a_species_name)
Definition: InjectorDensity.H:138
GpuParser< 3 > m_parser
Definition: InjectorDensity.H:49
Definition: InjectorDensity.H:196
void clear()
Definition: InjectorDensity.cpp:14
parser
Definition: run_alltests.py:107
Type
Definition: InjectorDensity.H:191
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorDensity.H:43
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorDensity.H:61
def x
Definition: read_lab_particles.py:25
Object(InjectorDensityConstant *, amrex::Real a_rho) noexcept
Definition: InjectorDensity.H:197
Definition: InjectorDensity.H:215
InjectorDensityConstant constant
Definition: InjectorDensity.H:205
Object(InjectorDensityParser *, WarpXParser const &a_parser) noexcept
Definition: InjectorDensity.H:199
amrex::Real m_rho
Definition: InjectorDensity.H:32
def z
Definition: read_lab_particles.py:26
InjectorDensityPredefined predefined
Definition: InjectorDensity.H:208
InjectorDensity(InjectorDensityPredefined *t, std::string const &a_species_name)
Definition: InjectorDensity.H:144
Definition: CustomDensityProb.H:19
Definition: InjectorDensity.H:36
InjectorDensityCustom custom
Definition: InjectorDensity.H:207
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real, amrex::Real, amrex::Real) const noexcept
Definition: InjectorDensity.H:26
int n
Definition: run_libensemble_on_warpx.py:68
Object(InjectorDensityPredefined *, std::string const &a_species_name) noexcept
Definition: InjectorDensity.H:203
Profile profile
Definition: InjectorDensity.H:110
type
Definition: run_alltests_1node.py:67
InjectorDensityParser parser
Definition: InjectorDensity.H:206
Definition: InjectorDensity.H:53
Profile
Definition: InjectorDensity.H:109
Definition: WarpXParser.H:26
amrex::GpuArray< amrex::Real, 6 > p
Definition: InjectorDensity.H:111
Object(InjectorDensityCustom *, std::string const &a_species_name) noexcept
Definition: InjectorDensity.H:201
InjectorDensityConstant(amrex::Real a_rho) noexcept
Definition: InjectorDensity.H:22
Definition: InjectorDensity.H:20
InjectorDensityParser(WarpXParser const &a_parser) noexcept
Definition: InjectorDensity.H:38
Object object
Definition: InjectorDensity.H:210
InjectorDensity(InjectorDensityConstant *t, amrex::Real a_rho)
Definition: InjectorDensity.H:126
Definition: InjectorDensity.H:123
AMREX_GPU_HOST_DEVICE amrex::Real getDensity(amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
Definition: InjectorDensity.H:162