diff --git a/Make.Microphysics b/Make.Microphysics index 31c39d4224..a6b7ece9de 100644 --- a/Make.Microphysics +++ b/Make.Microphysics @@ -159,7 +159,7 @@ $(MICROPHYSICS_AUTO_SOURCE_DIR)/extern_parameters.H: $(EXTERN_PARAMETERS) $(EXTE @if [ ! -d $(MICROPHYSICS_AUTO_SOURCE_DIR) ]; then mkdir -p $(MICROPHYSICS_AUTO_SOURCE_DIR); fi $(MICROPHYSICS_HOME)/util/build_scripts/write_probin.py \ --cxx_prefix $(MICROPHYSICS_AUTO_SOURCE_DIR)/extern \ - --pa "$(EXTERN_PARAMETERS)" --use_namespace + --pa "$(EXTERN_PARAMETERS)" # for debugging test_extern_params: $(MICROPHYSICS_AUTO_SOURCE_DIR)/extern_parameters.cpp diff --git a/unit_test/test_parameters/GNUmakefile b/unit_test/test_parameters/GNUmakefile new file mode 100644 index 0000000000..eabf245c05 --- /dev/null +++ b/unit_test/test_parameters/GNUmakefile @@ -0,0 +1,33 @@ +PRECISION = DOUBLE +PROFILE = FALSE + +DEBUG = FALSE + +DIM = 3 + +COMP = gnu + +USE_MPI = FALSE +USE_OMP = FALSE + +USE_REACT = TRUE + +EBASE = main + +BL_NO_FORT = TRUE + +# define the location of the Microphysics top directory +MICROPHYSICS_HOME := ../.. + +# This sets the EOS directory +EOS_DIR := helmholtz + +# This sets the network directory +NETWORK_DIR := aprox19 + +EXTERN_SEARCH += . .. + +Bpack := ./Make.package +Blocs := . + +include $(MICROPHYSICS_HOME)/unit_test/Make.unit_test diff --git a/unit_test/test_parameters/Make.package b/unit_test/test_parameters/Make.package new file mode 100644 index 0000000000..ae69aae30f --- /dev/null +++ b/unit_test/test_parameters/Make.package @@ -0,0 +1,3 @@ +CEXE_sources += main.cpp + +CEXE_headers += test_parameters.H diff --git a/unit_test/test_parameters/_parameters b/unit_test/test_parameters/_parameters new file mode 100644 index 0000000000..ef2035f844 --- /dev/null +++ b/unit_test/test_parameters/_parameters @@ -0,0 +1,11 @@ +@namespace: unit_test + +dens_min real 1.e6 +dens_max real 1.e9 +temp_min real 1.e6 +temp_max real 1.e12 + +small_temp real 1.e4 +small_dens real 1.e-4 + +test_string string "test" diff --git a/unit_test/test_parameters/inputs b/unit_test/test_parameters/inputs new file mode 100644 index 0000000000..06b299516c --- /dev/null +++ b/unit_test/test_parameters/inputs @@ -0,0 +1,4 @@ +unit_test.test_string = "this is a C++ string" +eos.eos_input_is_constant = 0 + +amr.probin = probin diff --git a/unit_test/test_parameters/main.cpp b/unit_test/test_parameters/main.cpp new file mode 100644 index 0000000000..03a3054f24 --- /dev/null +++ b/unit_test/test_parameters/main.cpp @@ -0,0 +1,47 @@ +#include +#include +#include + +#include +#include +#include + + +using namespace amrex; + +#include +#include + +#include +#include + +int main (int argc, char* argv[]) +{ + amrex::Initialize(argc, argv); + + main_main(); + + amrex::Finalize(); + return 0; +} + +void main_main () +{ + + // do the runtime parameter initializations and microphysics inits + if (ParallelDescriptor::IOProcessor()) { + std::cout << "reading extern runtime parameters ..." << std::endl; + } + + ParmParse ppa("amr"); + + auto params = init_unit_test(); + + std::cout << "in C++" << std::endl; + + std::cout << " eos_input_is_constant = " << eos_rp::eos_input_is_constant << " " << params.eos.eos_input_is_constant << std::endl; + std::cout << " test_string = " << unit_test_rp::test_string << " " << params.unit_test.test_string << std::endl; + std::cout << " dens_min = " << unit_test_rp::dens_min << " " << params.unit_test.dens_min << std::endl; + std::cout << " nonaka_file = " << integrator_rp::nonaka_file << " " << params.integrator.nonaka_file << std::endl; + +} diff --git a/unit_test/test_parameters/test_parameters.H b/unit_test/test_parameters/test_parameters.H new file mode 100644 index 0000000000..9f80145133 --- /dev/null +++ b/unit_test/test_parameters/test_parameters.H @@ -0,0 +1,6 @@ +#ifndef TEST_EOS_H +#define TEST_EOS_H + +void main_main(); + +#endif diff --git a/unit_test/unit_test.H b/unit_test/unit_test.H index 0ca5dc3c35..648efc47f1 100644 --- a/unit_test/unit_test.H +++ b/unit_test/unit_test.H @@ -4,11 +4,12 @@ void write_job_info(const std::string& dir); AMREX_INLINE -void +extern_t init_unit_test() { // now sync with C++ and read in the C++ parameters - init_extern_parameters(); + auto params = init_extern_parameters(); + return params; } #endif diff --git a/util/build_scripts/runtime_parameters.py b/util/build_scripts/runtime_parameters.py index 7641e29502..b74834d889 100755 --- a/util/build_scripts/runtime_parameters.py +++ b/util/build_scripts/runtime_parameters.py @@ -173,11 +173,11 @@ def get_query_struct_string(self, struct_name="params", class_name=None): ostr += f" amrex::Vector<{self.get_cxx_decl()}> {self.name}_tmp({self.size}, {self.default_format()});\n" ostr += f" if (pp.queryarr(\"{self.name}\", {self.name}_tmp, 0, {self.size})) {{\n" ostr += f" for (int n = 0; n < {self.size}; n++) {{\n" - ostr += f" {cname}{struct_name}.{self.namespace}{self.namespace_suffix}.{self.cpp_var_name}[n] = {self.name}_tmp[n];\n" + ostr += f" {cname}{struct_name}.{self.namespace}.{self.cpp_var_name}[n] = {self.name}_tmp[n];\n" ostr += " }\n\n" ostr += " }\n\n" else: - ostr += f"pp.query(\"{self.name}\", {cname}{struct_name}.{self.namespace}{self.namespace_suffix}.{self.cpp_var_name});\n" + ostr += f"pp.query(\"{self.name}\", {cname}{struct_name}.{self.namespace}.{self.cpp_var_name});\n" return ostr diff --git a/util/build_scripts/write_probin.py b/util/build_scripts/write_probin.py index 1b2371cc3d..1e9aebee55 100755 --- a/util/build_scripts/write_probin.py +++ b/util/build_scripts/write_probin.py @@ -24,6 +24,7 @@ import argparse import os import sys +import warnings import runtime_parameters @@ -64,7 +65,7 @@ def get_next_line(fin): return line[:pos] -def parse_param_file(params_list, param_file, use_namespace=False): +def parse_param_file(params_list, param_file): """read all the parameters in a given parameter file and add valid parameters to the params list. """ @@ -72,11 +73,11 @@ def parse_param_file(params_list, param_file, use_namespace=False): namespace = None try: - f = open(param_file, "r") - except IOError: + f = open(param_file) + except OSError: sys.exit(f"write_probin.py: ERROR: file {param_file} does not exist") - else: - print(f"write_probin.py: working on parameter file {param_file}...") + + print(f"write_probin.py: working on parameter file {param_file}...") line = get_next_line(f) @@ -111,18 +112,13 @@ def parse_param_file(params_list, param_file, use_namespace=False): err = 1 continue - if use_namespace: - skip_namespace_in_declare = False - else: - skip_namespace_in_declare = True - current_param = runtime_parameters.Param(name, dtype, default, namespace=namespace, namespace_suffix="_rp", - skip_namespace_in_declare=skip_namespace_in_declare) + skip_namespace_in_declare=False) try: current_param.priority = int(fields[3]) - except: + except IndexError: pass skip = 0 @@ -159,8 +155,7 @@ def abort(outfile): sys.exit(1) -def write_probin(param_files, - out_file, use_namespace, cxx_prefix): +def write_probin(param_files, out_file, cxx_prefix): """ write_probin will read through the list of parameter files and output the new out_file """ @@ -173,7 +168,7 @@ def write_probin(param_files, # read the parameters defined in the parameter files for f in param_files: - err = parse_param_file(params, f, use_namespace=use_namespace) + err = parse_param_file(params, f) if err: abort(out_file) @@ -188,19 +183,18 @@ def write_probin(param_files, with open(ofile, "w") as fout: fout.write(CXX_HEADER) - fout.write(f" void init_{cxx_base}_parameters();\n\n") + fout.write(f"#include <{cxx_base}_type.H>\n\n") + fout.write(f" {cxx_base}_t init_{cxx_base}_parameters();\n\n") for nm in sorted(namespaces): params_in_nm = [q for q in params if q.namespace == nm] - if use_namespace: - fout.write(f" namespace {nm}_rp {{\n") + fout.write(f" namespace {nm}_rp {{\n") for p in params_in_nm: fout.write(f" {p.get_declare_string(with_extern=True)}") - if use_namespace: - fout.write(" }\n") + fout.write(" }\n") fout.write(CXX_FOOTER) @@ -211,7 +205,7 @@ def write_probin(param_files, for p in params: fout.write(p.get_job_info_test()) - # finally the C++ initialization routines + # now the C++ initialization routines ofile = f"{cxx_prefix}_parameters.cpp" with open(ofile, "w") as fout: @@ -225,20 +219,22 @@ def write_probin(param_files, for nm in sorted(namespaces): params_in_nm = [q for q in params if q.namespace == nm] - if use_namespace: - fout.write(f" namespace {nm}_rp {{\n") + fout.write(f" namespace {nm}_rp {{\n") for p in params_in_nm: fout.write(f" {p.get_declare_string()}") - if use_namespace: - fout.write(" }\n") + fout.write(" }\n") fout.write("\n") - fout.write(f" void init_{cxx_base}_parameters() {{\n") + fout.write(f" {cxx_base}_t init_{cxx_base}_parameters() {{\n") # we need access to _rt - fout.write(" using namespace amrex;\n\n") + fout.write(" using namespace amrex;\n\n") + + # create the struct that will hold all the parameters -- this is what + # we will return + fout.write(f" {cxx_base}_t params;\n\n") # now write the parmparse code to get the value from the C++ # inputs. this will overwrite @@ -255,26 +251,58 @@ def write_probin(param_files, fout.write(f" amrex::ParmParse pp(\"{nm}\");\n") for p in params_nm: fout.write(f" {p.get_default_string()}") - fout.write(f" {p.get_query_string()}\n") + fout.write(f" {p.get_query_string()}") + fout.write(f" {p.get_query_struct_string(struct_name='params')}\n") fout.write(" }\n") + fout.write(" return params;\n\n") + fout.write(" }\n") + # finally, a single file that contains all of the parameter structs + + ofile = f"{cxx_prefix}_type.H" + with open(ofile, "w") as fout: + fout.write(f"#ifndef {cxx_base.upper()}_TYPE_H\n") + fout.write(f"#define {cxx_base.upper()}_TYPE_H\n\n") + fout.write("using namespace amrex::literals;\n\n") + + for nm in sorted(namespaces): + params_nm = [q for q in params if q.namespace == nm] + + fout.write(f"struct {nm}_param_t {{\n") + for p in params_nm: + fout.write(p.get_struct_entry()) + fout.write("};\n\n") + + # now the parent struct + + fout.write(f"struct {cxx_base}_t {{\n") + for nm in namespaces: + fout.write(f" {nm}_param_t {nm};\n") + fout.write("};\n\n") + + fout.write("#endif\n") + + def main(): parser = argparse.ArgumentParser() parser.add_argument('-o', type=str, default="", help='out_file') parser.add_argument('--pa', type=str, help='parameter files') parser.add_argument('--use_namespaces', action="store_true", - help="put parameters in namespaces") + help="[deprecated] put parameters in namespaces") parser.add_argument('--cxx_prefix', type=str, default="extern", help="a name to use in the C++ file names") args = parser.parse_args() + if args.use_namespaces: + warnings.warn("the --use_namespaces option will be removed in the future", DeprecationWarning) + param_files = args.pa.split() - write_probin(param_files, args.o, args.use_namespaces, args.cxx_prefix) + write_probin(param_files, args.o, args.cxx_prefix) if __name__ == "__main__": main()