Skip to content

Commit 2f3879c

Browse files
authored
steal sim run from imod-python, stub write on base component (#135)
Close #132. Also simplify how Component implements MutableMapping, it can just use children from xattree
1 parent 5dfdda3 commit 2f3879c

File tree

6 files changed

+84
-77
lines changed

6 files changed

+84
-77
lines changed

docs/examples/quickstart.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
save_budget={"*": "all"},
3131
)
3232

33+
sim.run(verbose=True)
34+
3335
# check CHD
3436
assert chd.data["head"][0, 0] == 1.0
3537
assert chd.data.head.sel(per=0)[99] == 0.0

flopy4/mf6/component.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,22 @@ class Component(ABC, MutableMapping):
1313
def __attrs_init_subclass__(cls):
1414
COMPONENTS[cls.__name__.lower()] = cls
1515

16-
def __attrs_post_init__(self):
17-
self._where = type(self).__xattree__["where"]
18-
1916
def __getitem__(self, key):
20-
data = getattr(self, self._where)
21-
return data.children[key]
17+
return self.children[key] # type: ignore
2218

2319
def __setitem__(self, key, value):
24-
data = getattr(self, self._where)
25-
if key in data.children:
26-
data.update({key: value})
27-
else:
28-
data = data.assign({key: value})
29-
setattr(self, self._where, data)
20+
self.children[key] = value # type: ignore
3021

3122
def __delitem__(self, key):
32-
data = getattr(self, self._where)
33-
data = data.drop_nodes(key)
34-
setattr(self, self._where, data)
23+
del self.children[key] # type: ignore
3524

3625
def __iter__(self):
37-
data = getattr(self, self._where)
38-
return iter(data.children)
26+
return iter(self.children) # type: ignore
3927

4028
def __len__(self):
41-
data = getattr(self, self._where)
42-
return len(data.children)
29+
return len(self.children) # type: ignore
30+
31+
def write(self) -> None:
32+
# TODO: write with jinja to file
33+
for child in self.children.values(): # type: ignore
34+
child.write()

flopy4/mf6/simulation.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
from os import PathLike
12
from pathlib import Path
23

34
from flopy.discretization.modeltime import ModelTime
5+
from modflow_devtools.misc import run_cmd, set_dir
46
from xattree import field, xattree
57

68
from flopy4.mf6.component import Component
@@ -31,3 +33,15 @@ class Simulation(Component):
3133
@property
3234
def time(self) -> ModelTime:
3335
return self.tdis.to_time()
36+
37+
def run(self, exe: str | PathLike = "mf6", verbose: bool = False) -> None:
38+
"""Run the simulation using the given executable."""
39+
if self.path is None:
40+
raise ValueError(f"Simulation {self.name} has no workspace path.")
41+
with set_dir(self.path):
42+
stdout, stderr, retcode = run_cmd(exe, verbose=verbose)
43+
if retcode != 0:
44+
raise RuntimeError(
45+
f"Simulation {self.name}: {exe} failed to run with returncode " # type: ignore
46+
f"{retcode}, and error message:\n\n{stdout + stderr} "
47+
)

0 commit comments

Comments
 (0)