diff --git a/Docs/sphinx_documentation/source/Basics.rst b/Docs/sphinx_documentation/source/Basics.rst index fa08217c88a..90ef2869fae 100644 --- a/Docs/sphinx_documentation/source/Basics.rst +++ b/Docs/sphinx_documentation/source/Basics.rst @@ -668,6 +668,21 @@ entries in an inputs file: hydro.cfl = 0.9 my_string = "A String" +You can also remove the effect of having defined an input parameter at all using the +``UNSET`` directive (parameters that are merely overridden will still be caught by +:cpp:`pp.contains()` checks in code). Specifying ``keyword = 5`` in an input file and +then ``UNSET = keyword`` subsequently in the input file or from the command line +completely removes ``keyword`` from the ParmParse table. Multiple keywords can +be removed simultaneously (``UNSET = key1 key2 key3``). if using the ``UNSET`` +directive with TOML-like input files, note that full parameter names must be used +even if the UNSET falls within a TOML table: + +.. code-block:: none + + [x] + a = 1 # Same as x.a = 1 at the root level + + UNSET = x.a # full name required to remove x.a entry Setting Defaults via an Environment Variable -------------------------------------------- diff --git a/Src/Base/AMReX_ParmParse.H b/Src/Base/AMReX_ParmParse.H index 99b03d962c3..64b765f3636 100644 --- a/Src/Base/AMReX_ParmParse.H +++ b/Src/Base/AMReX_ParmParse.H @@ -1773,6 +1773,9 @@ public: //! keyword for files to load static std::string const FileKeyword; + //! keyword for removing entries from the table + static std::string const UnsetKeyword; + static std::string ParserPrefix; [[nodiscard]] std::string const& getPrefix () const; diff --git a/Src/Base/AMReX_ParmParse.cpp b/Src/Base/AMReX_ParmParse.cpp index d0d033c6713..b99c9348aef 100644 --- a/Src/Base/AMReX_ParmParse.cpp +++ b/Src/Base/AMReX_ParmParse.cpp @@ -40,6 +40,7 @@ namespace { } std::string const ParmParse::FileKeyword = "FILE"; +std::string const ParmParse::UnsetKeyword = "UNSET"; std::string ParmParse::ParserPrefix; ParmParse::ParmParse (std::string prefix, std::string parser_prefix) @@ -772,6 +773,15 @@ addDefn (std::string& def, std::vector& val, read_file(fname, tab); g_toml_table_key = std::move(prev_toml_table_key); } + // + // Check if this defn is an unset directive. + // + else if ( def == ParmParse::UnsetKeyword ) + { + for (auto const& key : val) { + tab.erase(key); + } + } else { std::string key; diff --git a/Tests/ParmParse/inputs b/Tests/ParmParse/inputs index b578c3b0514..90eaaf6c876 100644 --- a/Tests/ParmParse/inputs +++ b/Tests/ParmParse/inputs @@ -156,3 +156,13 @@ macro.use_gpu.spacedim = 3 # endif #endif + +# UNSET directive tests +unset_me = 123 +UNSET = unset_me + +unset_multi_a = 1 +unset_multi_b = 2 +UNSET = unset_multi_a unset_multi_b + +unset_kept = 77 diff --git a/Tests/ParmParse/main.cpp b/Tests/ParmParse/main.cpp index e345a3eba1c..46015c4f446 100644 --- a/Tests/ParmParse/main.cpp +++ b/Tests/ParmParse/main.cpp @@ -335,6 +335,21 @@ int main(int argc, char* argv[]) int n = pp.countname("string-for-testing-addfile"); AMREX_ALWAYS_ASSERT(n==3 && s == "string for testing addfile"); } + { // UNSET directive + ParmParse pp; + // "unset_me" is defined then immediately unset in the inputs file + int v = -1; + int found = pp.query("unset_me", v); + AMREX_ALWAYS_ASSERT(found == 0); + // "unset_multi_a" and "unset_multi_b" are unset together in inputs + found = pp.query("unset_multi_a", v); + AMREX_ALWAYS_ASSERT(found == 0); + found = pp.query("unset_multi_b", v); + AMREX_ALWAYS_ASSERT(found == 0); + // "unset_kept" is NOT unset, so it should still be present + pp.get("unset_kept", v); + AMREX_ALWAYS_ASSERT(v == 77); + } { amrex::Print() << "SUCCESS\n"; }