diff options
-rw-r--r-- | Docs/source/running_cpp/parameters.rst | 10 | ||||
-rw-r--r-- | Examples/Physics_applications/plasma_mirror/inputs_2d | 2 | ||||
-rw-r--r-- | Source/Initialization/PlasmaInjector.cpp | 18 | ||||
-rw-r--r-- | Source/Utils/WarpXUtil.H | 14 | ||||
-rw-r--r-- | Source/Utils/WarpXUtil.cpp | 20 |
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 |