aboutsummaryrefslogtreecommitdiff
path: root/Source/PlasmaInjector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/PlasmaInjector.cpp')
-rw-r--r--Source/PlasmaInjector.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/Source/PlasmaInjector.cpp b/Source/PlasmaInjector.cpp
new file mode 100644
index 000000000..027bb5b57
--- /dev/null
+++ b/Source/PlasmaInjector.cpp
@@ -0,0 +1,208 @@
+#include "PlasmaInjector.H"
+
+#include <sstream>
+
+#include <WarpXConst.H>
+#include <AMReX.H>
+
+using namespace amrex;
+
+namespace {
+ void StringParseAbortMessage(const std::string& var,
+ const std::string& name) {
+ std::stringstream stringstream;
+ std::string string;
+ stringstream << var << " string '" << name << "' not recognized.";
+ string = stringstream.str();
+ amrex::Abort(string.c_str());
+ }
+
+ Real parseChargeName(const std::string& name) {
+ if (name == "q_e") {
+ return PhysConst::q_e;
+ } else {
+ StringParseAbortMessage("Charge", name);
+ return 0.0;
+ }
+ }
+
+ Real parseChargeString(const std::string& name) {
+ if(name.substr(0, 1) == "-")
+ return -1.0 * parseChargeName(name.substr(1, name.size() - 1));
+ return parseChargeName(name);
+ }
+
+ Real parseMassString(const std::string& name) {
+ if (name == "m_e") {
+ return PhysConst::m_e;
+ } else if (name == "m_p"){
+ return PhysConst::m_p;
+ } else {
+ StringParseAbortMessage("Mass", name);
+ return 0.0;
+ }
+ }
+}
+
+ConstantDensityProfile::ConstantDensityProfile(Real density)
+ : _density(density)
+{}
+
+Real ConstantDensityProfile::getDensity(Real x, Real y, Real z) const
+{
+ return _density;
+}
+
+CustomDensityProfile::CustomDensityProfile(const std::string& species_name)
+{
+ ParmParse pp(species_name);
+ pp.getarr("custom_profile_params", params);
+}
+
+ConstantMomentumDistribution::ConstantMomentumDistribution(Real ux,
+ Real uy,
+ Real uz)
+ : _ux(ux), _uy(uy), _uz(uz)
+{}
+
+void ConstantMomentumDistribution::getMomentum(vec3& u) {
+ u[0] = _ux;
+ u[1] = _uy;
+ u[2] = _uz;
+}
+
+GaussianRandomMomentumDistribution::GaussianRandomMomentumDistribution(Real ux_m,
+ Real uy_m,
+ Real uz_m,
+ Real u_th)
+ : _ux_m(ux_m), _uy_m(uy_m), _uz_m(uz_m), _u_th(u_th),
+ momentum_distribution(0.0, u_th)
+{
+}
+
+void GaussianRandomMomentumDistribution::getMomentum(vec3& u) {
+ Real ux_th = momentum_distribution(generator);
+ Real uy_th = momentum_distribution(generator);
+ Real uz_th = momentum_distribution(generator);
+ u[0] = _ux_m + ux_th;
+ u[1] = _uy_m + uy_th;
+ u[2] = _uz_m + uz_th;
+}
+
+PlasmaInjector::PlasmaInjector(int ispecies, const std::string& name)
+ : species_id(ispecies), species_name(name)
+{
+ ParmParse pp(species_name);
+
+ // parse charge and mass
+ std::string charge_s;
+ pp.get("charge", charge_s);
+ std::transform(charge_s.begin(),
+ charge_s.end(),
+ charge_s.begin(),
+ ::tolower);
+ charge = parseChargeString(charge_s);
+
+ std::string mass_s;
+ pp.get("mass", mass_s);
+ std::transform(mass_s.begin(),
+ mass_s.end(),
+ mass_s.begin(),
+ ::tolower);
+ mass = parseMassString(mass_s);
+
+ // parse plasma boundaries
+ xmin = std::numeric_limits<amrex::Real>::lowest();
+ ymin = std::numeric_limits<amrex::Real>::lowest();
+ zmin = std::numeric_limits<amrex::Real>::lowest();
+
+ xmax = std::numeric_limits<amrex::Real>::max();
+ ymax = std::numeric_limits<amrex::Real>::max();
+ zmax = std::numeric_limits<amrex::Real>::max();
+
+ pp.query("xmin", xmin);
+ pp.query("ymin", ymin);
+ pp.query("zmin", zmin);
+ pp.query("xmax", xmax);
+ pp.query("ymax", ymax);
+ pp.query("zmax", zmax);
+
+ // parse density information
+ std::string rho_prof_s;
+ pp.get("profile", rho_prof_s);
+ std::transform(rho_prof_s.begin(),
+ rho_prof_s.end(),
+ rho_prof_s.begin(),
+ ::tolower);
+ if (rho_prof_s == "constant") {
+ Real density;
+ pp.get("density", density);
+ rho_prof.reset(new ConstantDensityProfile(density));
+ } else if (rho_prof_s == "custom") {
+ rho_prof.reset(new CustomDensityProfile(species_name));
+ } else {
+ StringParseAbortMessage("Density profile type", rho_prof_s);
+ }
+ pp.get("num_particles_per_cell", num_particles_per_cell);
+
+ // parse momentum information
+ std::string mom_dist_s;
+ pp.get("momentum_distribution_type", mom_dist_s);
+ std::transform(mom_dist_s.begin(),
+ mom_dist_s.end(),
+ mom_dist_s.begin(),
+ ::tolower);
+ if (mom_dist_s == "constant") {
+ Real ux = 0.;
+ Real uy = 0.;
+ Real uz = 0.;
+ pp.query("ux", ux);
+ pp.query("uy", uy);
+ pp.query("uz", uz);
+ mom_dist.reset(new ConstantMomentumDistribution(ux, uy, uz));
+ } else if (mom_dist_s == "gaussian") {
+ Real ux_m = 0.;
+ Real uy_m = 0.;
+ Real uz_m = 0.;
+ Real u_th = 0.;
+ pp.query("ux_m", ux_m);
+ pp.query("uy_m", uy_m);
+ pp.query("uz_m", uz_m);
+ pp.query("u_th", u_th);
+ mom_dist.reset(new GaussianRandomMomentumDistribution(ux_m, uy_m, uz_m, u_th));
+ } else {
+ StringParseAbortMessage("Momentum distribution type", mom_dist_s);
+ }
+
+ // get injection style
+ pp.get("injection_style", injection_style);
+ std::transform(injection_style.begin(),
+ injection_style.end(),
+ injection_style.begin(),
+ ::tolower);
+ if (injection_style == "nrandomnormal" or
+ injection_style == "nrandomuniformpercell" or
+ injection_style == "ndiagpercell") {
+ return;
+ } else {
+ StringParseAbortMessage("Injection style", injection_style);
+ }
+}
+
+void PlasmaInjector::getMomentum(vec3& u) {
+ mom_dist->getMomentum(u);
+ u[0] *= PhysConst::c;
+ u[1] *= PhysConst::c;
+ u[2] *= PhysConst::c;
+}
+
+bool PlasmaInjector::insideBounds(Real x, Real y, Real z) {
+ if (x >= xmax || x < xmin ||
+ y >= ymax || y < ymin ||
+ z >= zmax || z < zmin ) return false;
+ return true;
+}
+
+Real PlasmaInjector::getDensity(Real x, Real y, Real z) {
+ return rho_prof->getDensity(x, y, z);
+}