aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docs/source/running_cpp/parameters.rst10
-rw-r--r--Examples/Physics_applications/plasma_mirror/inputs_2d2
-rw-r--r--Source/Initialization/PlasmaInjector.cpp18
-rw-r--r--Source/Utils/WarpXUtil.H14
-rw-r--r--Source/Utils/WarpXUtil.cpp20
5 files changed, 48 insertions, 16 deletions
diff --git a/Docs/source/running_cpp/parameters.rst b/Docs/source/running_cpp/parameters.rst
index 49b0d4485..92c5a8e7c 100644
--- a/Docs/source/running_cpp/parameters.rst
+++ b/Docs/source/running_cpp/parameters.rst
@@ -308,6 +308,7 @@ Particle initialization
* ``<species_name>.xmin,ymin,zmin`` (`float`) optional (default unlimited)
When ``<species_name>.xmin`` and ``<species_name>.xmax`` (see below) are set, they delimit the region within which particles are injected.
+ The WarpXParser (see :ref:`running-cpp-parameters-parser`) is used for the right-hand-side, so expressions like ``<species_name>.xmin = "2.+1."`` and/or using user-defined constants are accepted.
The same is applicable in the other directions.
If periodic boundary conditions are used in direction ``i``, then the default (i.e. if the range is not specified) range will be the simulation box, ``[geometry.prob_hi[i], geometry.prob_lo[i]]``.
@@ -395,13 +396,12 @@ Particle initialization
user-defined constant, see above. WARNING: where ``density_function(x,y,z)`` is close to zero, particles will still be injected between ``xmin`` and ``xmax`` etc., with a null weight. This is undesirable because it results in useless computing. To avoid this, see option ``density_min`` below.
* ``<species_name>.density_min`` (`float`) optional (default `0.`)
- Minimum plasma density. No particle is injected where the density is below
- this value.
+ Minimum plasma density. No particle is injected where the density is below this value.
+ The WarpXParser (see :ref:`running-cpp-parameters-parser`) is used for the right-hand-side, so expressions like ``<species_name>.density_min = "2.+1."`` and/or using user-defined constants are accepted.
* ``<species_name>.density_max`` (`float`) optional (default `infinity`)
- Maximum plasma density. The density at each point is the minimum between
- the value given in the profile, and `density_max`.
-
+ Maximum plasma density. The density at each point is the minimum between the value given in the profile, and `density_max`.
+ The WarpXParser (see :ref:`running-cpp-parameters-parser`) is used for the right-hand-side, so expressions like ``<species_name>.density_max = "2.+1."`` and/or using user-defined constants are accepted.
* ``<species_name>.radially_weighted`` (`bool`) optional (default `true`)
Whether particle's weight is varied with their radius. This only applies to cylindrical geometry.
The only valid value is true.
diff --git a/Examples/Physics_applications/plasma_mirror/inputs_2d b/Examples/Physics_applications/plasma_mirror/inputs_2d
index 041df05db..2c8a8f9e2 100644
--- a/Examples/Physics_applications/plasma_mirror/inputs_2d
+++ b/Examples/Physics_applications/plasma_mirror/inputs_2d
@@ -42,7 +42,7 @@ electrons.num_particles_per_cell_each_dim = 2 2
electrons.momentum_distribution_type = "gaussian"
electrons.ux_th = .01
electrons.uz_th = .01
-electrons.zmin = 19.520e-6
+electrons.zmin = "zc-lgrad*log(400)"
electrons.zmax = 25.47931e-6
electrons.profile = parse_density_function
electrons.density_function(x,y,z) = "(z<zp)*nc*exp((z-zc)/lgrad)+(z>=zp)*(z<=zp2)*2.*nc+(z>zp2)*nc*exp(-(z-zc2)/lgrad)"
diff --git a/Source/Initialization/PlasmaInjector.cpp b/Source/Initialization/PlasmaInjector.cpp
index 69aefc47e..2fbc7ad19 100644
--- a/Source/Initialization/PlasmaInjector.cpp
+++ b/Source/Initialization/PlasmaInjector.cpp
@@ -120,15 +120,15 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name)
}
# endif
- pp.query("xmin", xmin);
- pp.query("ymin", ymin);
- pp.query("zmin", zmin);
- pp.query("xmax", xmax);
- pp.query("ymax", ymax);
- pp.query("zmax", zmax);
-
- pp.query("density_min", density_min);
- pp.query("density_max", density_max);
+ queryWithParser(pp, "xmin", xmin);
+ queryWithParser(pp, "ymin", ymin);
+ queryWithParser(pp, "zmin", zmin);
+ queryWithParser(pp, "xmax", xmax);
+ queryWithParser(pp, "ymax", ymax);
+ queryWithParser(pp, "zmax", zmax);
+
+ queryWithParser(pp, "density_min", density_min);
+ queryWithParser(pp, "density_max", density_max);
std::string physical_species_s;
bool species_is_specified = pp.query("species_type", physical_species_s);
diff --git a/Source/Utils/WarpXUtil.H b/Source/Utils/WarpXUtil.H
index d3682be2f..e5a01a44a 100644
--- a/Source/Utils/WarpXUtil.H
+++ b/Source/Utils/WarpXUtil.H
@@ -161,6 +161,20 @@ T trilinear_interp(T x0, T x1,T y0, T y1, T z0, T z1,
*/
WarpXParser makeParser (std::string const& parse_function, std::vector<std::string> const& varnames);
+/**
+ * \brief Similar to amrex::ParmParse::query, but also supports math expressions for the value.
+ *
+ * amrex::ParmParse::query reads a name and a value from the input file. This function does the
+ * same, and applies the WarpXParser to the value, so the user has the choice to specify a value or
+ * a math expression (including user-defined constants).
+ * Only works for amrex::Real numbers, one would need another version for integers etc.
+ *
+ * \param[in] a_pp amrex::ParmParse object
+ * \param[in] str name of the parameter to read
+ * \param[out] val where the value queried and parsed is stored
+ */
+int queryWithParser (amrex::ParmParse& a_pp, char const * const str, amrex::Real& val);
+
namespace WarpXUtilMsg{
/** \brief If is_expression_true is false, this function prints msg and calls amrex::abort()
diff --git a/Source/Utils/WarpXUtil.cpp b/Source/Utils/WarpXUtil.cpp
index 7a584f6e1..4372c132e 100644
--- a/Source/Utils/WarpXUtil.cpp
+++ b/Source/Utils/WarpXUtil.cpp
@@ -190,7 +190,6 @@ void Store_parserString(amrex::ParmParse& pp, std::string query_string,
f.clear();
}
-
WarpXParser makeParser (std::string const& parse_function, std::vector<std::string> const& varnames)
{
WarpXParser parser(parse_function);
@@ -213,6 +212,25 @@ WarpXParser makeParser (std::string const& parse_function, std::vector<std::stri
return parser;
}
+int
+queryWithParser (amrex::ParmParse& a_pp, char const * const str, amrex::Real& val)
+{
+ // call amrex::ParmParse::query, check if the user specified str.
+ std::string tmp_str;
+ int is_specified = a_pp.query(str, tmp_str);
+ if (is_specified)
+ {
+ // If so, create a parser object and apply it to the value provided by the user.
+ std::string str_val;
+ Store_parserString(a_pp, str, str_val);
+
+ auto parser = makeParser(str_val, {});
+ val = parser.eval();
+ }
+ // return the same output as amrex::ParmParse::query
+ return is_specified;
+}
+
/**
* \brief Ensures that the blocks are setup correctly for the RZ spectral solver
* When using the RZ spectral solver, the Hankel transform cannot be