diff --git a/src/pyopmnearwell/core/pyopmnearwell.py b/src/pyopmnearwell/core/pyopmnearwell.py index 92b872a..efc6b26 100644 --- a/src/pyopmnearwell/core/pyopmnearwell.py +++ b/src/pyopmnearwell/core/pyopmnearwell.py @@ -14,8 +14,40 @@ from pyopmnearwell.utils.writefile import reservoir_files -def main(argv=None) -> None: +def main(argv: list[str] | None = None) -> None: """Main function for the pyopmnearwell executable""" + cmdargs = load_parser(argv) + check_cmdargs(cmdargs) + if int(cmdargs.warnings) == 0: + warnings.filterwarnings("ignore") + file = cmdargs.input + fol = os.path.abspath(cmdargs.output) + mode = cmdargs.mode + dic: dict[str, Any] = { + "pat": os.path.split(os.path.dirname(__file__))[0], + "fol": fol, + "mode": mode, + "write": int(cmdargs.vectors), + "runname": pathlib.Path(file).stem, + } + dic = process_input(dic, file) + os.makedirs(fol, exist_ok=True) + if mode == "single": + dic["fprep"] = fol + dic["foutp"] = fol + else: + dic["fprep"] = f"{fol}/preprocessing" + dic["foutp"] = f"{fol}/output" + if mode in ["all", "deck", "single"]: + os.makedirs(dic["fprep"], exist_ok=True) + reservoir_files(dic) + if mode in ["all", "flow", "single"]: + os.makedirs(dic["foutp"], exist_ok=True) + simulations(dic) + + +def load_parser(argv: list[str] | None) -> argparse.Namespace: + """CLI arguments""" parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description="Main script to run a near-well system with OPM Flow.", @@ -60,30 +92,34 @@ def main(argv=None) -> None: default="0", help="Print Python warnings", ) - cmdargs = vars(parser.parse_known_args(argv)[0]) - if int(cmdargs["warnings"]) == 0: - warnings.filterwarnings("ignore") - file = cmdargs["input"] - fol = os.path.abspath(cmdargs["output"]) - mode = cmdargs["mode"] - dic: dict[str, Any] = { - "pat": os.path.split(os.path.dirname(__file__))[0], - "fol": fol, - "mode": mode, - "write": int(cmdargs["vectors"]), - "runname": pathlib.Path(file).stem, - } - dic = process_input(dic, file) - os.makedirs(fol, exist_ok=True) - if mode == "single": - dic["fprep"] = fol - dic["foutp"] = fol - else: - dic["fprep"] = f"{fol}/preprocessing" - dic["foutp"] = f"{fol}/output" - if mode in ["all", "deck", "single"]: - os.makedirs(dic["fprep"], exist_ok=True) - reservoir_files(dic) - if mode in ["all", "flow", "single"]: - os.makedirs(dic["foutp"], exist_ok=True) - simulations(dic) + return parser.parse_args(argv) + + +def check_cmdargs(cmdargs: argparse.Namespace) -> None: + """Validate command-line arguments. + + The checks cover the input configuration file and output folder. + + Parameters + ---------- + cmdargs + Parsed arguments returned by :mod:`argparse`. + + Raises + ------ + SystemExit + If an argument is invalid. + """ + input_file = cmdargs.input + if not input_file: + print("\nInvalid value for '-i', the input file cannot be empty.\n") + raise SystemExit(1) + if not input_file.lower().endswith(".toml"): + print( + f"\nInvalid extension for input file '-i {input_file}', " + "the valid extension is .toml.\n" + ) + raise SystemExit(1) + if not cmdargs.output: + print("\nInvalid value for '-o', the output folder cannot be empty.\n") + raise SystemExit(1) diff --git a/tests/conftest.py b/tests/conftest.py index ff92bb1..120cf4e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -75,7 +75,7 @@ def fixture_run_main(tmp_path_factory) -> pathlib.Path: shared_dir: pathlib.Path = tmp_path_factory.mktemp("shared") shutil.copy((dirname / "models" / "input").with_suffix(".toml"), shared_dir) os.chdir(shared_dir) - main() + main([]) return shared_dir diff --git a/tests/scripts/docs_all.sh b/tests/scripts/docs_all.sh index b96e5df..1d236ca 100644 --- a/tests/scripts/docs_all.sh +++ b/tests/scripts/docs_all.sh @@ -1 +1,5 @@ -. tests/scripts/docs_hello_world.sh & . tests/scripts/docs_co2_cyclic_injection.sh +. tests/scripts/docs_hello_world.sh & +. tests/scripts/docs_co2_cyclic_injection.sh & +wait + +. tests/scripts/docs_check_outputs.sh diff --git a/tests/scripts/docs_check_outputs.sh b/tests/scripts/docs_check_outputs.sh new file mode 100644 index 0000000..1da01b4 --- /dev/null +++ b/tests/scripts/docs_check_outputs.sh @@ -0,0 +1,25 @@ +files=" +test_outputs/docs_hello_world/hello_world.png +test_outputs/docs_co2_cyclic_injection/co2_gas.gif +" + +missing_file="test_outputs/missing_docs_files.txt" +missing=0 + +rm -f "$missing_file" + +for f in $files; do + if [ ! -f "$f" ]; then + echo "$f" >> "$missing_file" + missing=$((missing + 1)) + fi +done + +if [ "$missing" -eq 0 ]; then + echo "All figures and files exist." + return 0 +else + echo "$missing figure(s) or file(s) missing." + echo "See $missing_file" + return 1 +fi diff --git a/tests/scripts/docs_co2_cyclic_injection.sh b/tests/scripts/docs_co2_cyclic_injection.sh index 7de8abe..932bc64 100644 --- a/tests/scripts/docs_co2_cyclic_injection.sh +++ b/tests/scripts/docs_co2_cyclic_injection.sh @@ -1,9 +1,5 @@ -WHR="test_outputs/co2_cyclic_injection" -if [ ! -d "test_outputs" ]; then - mkdir "test_outputs" -fi -if [ -d $WHR ]; then - rm -rf $WHR -fi -pyopmnearwell -i examples/co2.toml -o $WHR -m single -plopm -i $WHR/CO2 -v sgas -m gif -dpi 1000 -interval 50 -loop 1 -d 10,5 -yformat .0f -f 20 -cnum 6 -t "Cyclic injection" -save $WHR/co2_gas +OUT="test_outputs/docs_co2_cyclic_injection" +. tests/scripts/initialize_output_folders.sh $OUT +. tests/scripts/get_plopm.sh +pyopmnearwell -i examples/co2.toml -o $OUT -m single +plopm -i $OUT/CO2 -v sgas -m gif -dpi 1000 -interval 50 -loop 1 -d 10,5 -yformat .0f -f 20 -cnum 6 -t "Cyclic injection" -save $OUT/co2_gas diff --git a/tests/scripts/docs_hello_world.sh b/tests/scripts/docs_hello_world.sh index cc9e393..2d1512c 100644 --- a/tests/scripts/docs_hello_world.sh +++ b/tests/scripts/docs_hello_world.sh @@ -1,9 +1,5 @@ -WHR="test_outputs/hello_world" -if [ ! -d "test_outputs" ]; then - mkdir "test_outputs" -fi -if [ -d $WHR ]; then - rm -rf $WHR -fi -pyopmnearwell -i examples/h2o.toml -o $WHR -m single -plopm -i $WHR/H2O -v pressure -s ,,1 -t 'Top view at the end of the simulation' -c bwr -xformat .0f -cformat .0f -save $WHR/hello_world +OUT="test_outputs/docs_hello_world" +. tests/scripts/initialize_output_folders.sh $OUT +. tests/scripts/get_plopm.sh +pyopmnearwell -i examples/h2o.toml -o $OUT -m single +plopm -i $OUT/H2O -v pressure -s ,,1 -t 'Top view at the end of the simulation' -c bwr -xformat .0f -cformat .0f -save $OUT/hello_world diff --git a/tests/scripts/get_plopm.sh b/tests/scripts/get_plopm.sh new file mode 100644 index 0000000..e8b13ca --- /dev/null +++ b/tests/scripts/get_plopm.sh @@ -0,0 +1,3 @@ +if ! command -v plopm &> /dev/null; then + pip install git+https://github.com/cssr-tools/plopm.git +fi diff --git a/tests/scripts/initialize_output_folders.sh b/tests/scripts/initialize_output_folders.sh new file mode 100644 index 0000000..49aa983 --- /dev/null +++ b/tests/scripts/initialize_output_folders.sh @@ -0,0 +1,7 @@ +OUTT="$1" +if [ ! -d "test_outputs" ]; then + mkdir "test_outputs" +fi +if [ -n "$OUTT" ] && [ -d "$OUTT" ]; then + rm -rf "$OUTT" +fi diff --git a/tests/scripts/paper_salt-precipitation_all.sh b/tests/scripts/paper_salt-precipitation_all.sh index 5664baa..ce69e82 100644 --- a/tests/scripts/paper_salt-precipitation_all.sh +++ b/tests/scripts/paper_salt-precipitation_all.sh @@ -1,10 +1,37 @@ -WHR="test_outputs/paper_salt_precipitation" -if [ ! -d "test_outputs" ]; then - mkdir "test_outputs" -fi -if [ -d $WHR ]; then - rm -rf $WHR -fi +NCPUS=${1:-16} +OUT="test_outputs/paper_salt_precipitation" +. tests/scripts/initialize_output_folders.sh $OUT +. tests/scripts/get_plopm.sh mkdir "test_outputs/paper_salt_precipitation" -cp -r publications/Impact_of_Intermittency_on_Salt_Precipitation_During_CO2_Injection_2024_SPE/. $WHR -python3 $WHR/case1/run_simulations.py & python3 $WHR/case2/run_simulations.py & python3 $WHR/case3/run_simulations.py & python3 $WHR/case4/run_all.py & wait +cp -r publications/Impact_of_Intermittency_on_Salt_Precipitation_During_CO2_Injection_2024_SPE/. $OUT +sed -i.bak "s/NPRUNS = 16/NPRUNS = $NCPUS/g" $OUT/case4/including_salt_precipitation/run_simulations.py && rm -f $OUT/case4/including_salt_precipitation/run_simulations.py.bak +sed -i.bak "s/NPRUNS = 16/NPRUNS = $NCPUS/g" $OUT/case4/neglecting_salt_precipitation/run_simulations.py && rm -f $OUT/case4/neglecting_salt_precipitation/run_simulations.py.bak +python3 $OUT/case1/run_simulations.py & +python3 $OUT/case2/run_simulations.py & +python3 $OUT/case3/run_simulations.py & +wait +python3 $OUT/case4/run_all.py & +wait + +files=" +$OUT/case1/nca.png +" + +missing_file="test_outputs/missing_publication_files.txt" +missing=0 + +for f in $files; do + if [ ! -f "$f" ]; then + echo "$f" >> "$missing_file" + missing=$((missing + 1)) + fi +done + +if [ "$missing" -eq 0 ]; then + echo "All figures and files exist." + return 0 +else + echo "$missing figure(s) or file(s) missing." + echo "See $missing_file" + return 1 +fi