Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(MfSimulationList): add functionality to parse the mfsim.lst file #2005

Merged
merged 4 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions autotest/test_mfsimlist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import numpy as np
import pytest
from autotest.conftest import get_example_data_path
from modflow_devtools.markers import requires_exe

import flopy
from flopy.mf6 import MFSimulation


def base_model(sim_path):
load_path = get_example_data_path() / "mf6-freyberg"

sim = MFSimulation.load(sim_ws=load_path)
sim.set_sim_path(sim_path)
sim.write_simulation()
sim.run_simulation()

return sim


@pytest.mark.xfail
def test_mfsimlist_nofile(function_tmpdir):
mfsimlst = flopy.mf6.utils.MfSimulationList(function_tmpdir / "fail.lst")


@requires_exe("mf6")
def test_mfsimlist_normal(function_tmpdir):
sim = base_model(function_tmpdir)
mfsimlst = flopy.mf6.utils.MfSimulationList(function_tmpdir / "mfsim.lst")
assert mfsimlst.is_normal_termination, "model did not terminate normally"


@pytest.mark.xfail
def test_mfsimlist_runtime_fail(function_tmpdir):
sim = base_model(function_tmpdir)
mfsimlst = flopy.mf6.utils.MfSimulationList(function_tmpdir / "mfsim.lst")
runtime_sec = mfsimlst.get_runtime(units="abc")


@requires_exe("mf6")
def test_mfsimlist_runtime(function_tmpdir):
sim = base_model(function_tmpdir)
mfsimlst = flopy.mf6.utils.MfSimulationList(function_tmpdir / "mfsim.lst")
for sim_timer in ("elapsed", "formulate", "solution"):
runtime_sec = mfsimlst.get_runtime(simulation_timer=sim_timer)
if not np.isnan(runtime_sec):
runtime_min = mfsimlst.get_runtime(
units="minutes", simulation_timer=sim_timer
)
assert runtime_sec / 60.0 == runtime_min, (
f"model {sim_timer} time conversion from "
+ "sec to minutes does not match"
)

runtime_hrs = mfsimlst.get_runtime(
units="hours", simulation_timer=sim_timer
)
assert runtime_min / 60.0 == runtime_hrs, (
f"model {sim_timer} time conversion from "
+ "minutes to hours does not match"
)


@requires_exe("mf6")
def test_mfsimlist_iterations(function_tmpdir):
it_outer_answer = 13
it_total_answer = 413

sim = base_model(function_tmpdir)
mfsimlst = flopy.mf6.utils.MfSimulationList(function_tmpdir / "mfsim.lst")

it_outer = mfsimlst.get_outer_iterations()
assert it_outer == it_outer_answer, (
f"outer iterations is not equal to {it_outer_answer} "
+ f"({it_outer})"
)

it_total = mfsimlst.get_total_iterations()
assert it_total == it_total_answer, (
f"total iterations is not equal to {it_total_answer} "
+ f"({it_total})"
)


@requires_exe("mf6")
def test_mfsimlist_memory(function_tmpdir):
virtual_answer = 0.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guess this is because virtual memory is only used for mf6 parallel at the moment — once flopy has more parallel support a parallel test case could be added to check virtual memory usage I imagine


sim = base_model(function_tmpdir)
mfsimlst = flopy.mf6.utils.MfSimulationList(function_tmpdir / "mfsim.lst")

total_memory = mfsimlst.get_memory_usage()
assert total_memory > 0.0, (
f"total memory is not greater than 0.0 " + f"({total_memory})"
)

virtual_memory = mfsimlst.get_memory_usage(virtual=True)
if not np.isnan(virtual_memory):
assert virtual_memory == virtual_answer, (
f"virtual memory is not equal to {virtual_answer} "
+ f"({virtual_memory})"
)

non_virtual_memory = mfsimlst.get_non_virtual_memory_usage()
assert total_memory == non_virtual_memory, (
f"total memory ({total_memory}) "
+ f"does not equal non-virtual memory ({non_virtual_memory})"
)
1 change: 1 addition & 0 deletions flopy/mf6/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
from .binarygrid_util import MfGrdFile
from .generate_classes import generate_classes
from .lakpak_utils import get_lak_connections
from .mfsimlistfile import MfSimulationList
from .model_splitter import Mf6Splitter
from .postprocessing import get_residuals, get_structured_faceflows
Loading