Skip to content

Commit 1f62b39

Browse files
committed
more lark
1 parent aece5bd commit 1f62b39

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

flopy4/mf6/__init__.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
from typing import Optional
55

66
import numpy as np
7-
from attr import field
87
from attrs import define
98
from numpy.typing import NDArray
10-
from xattree import ROOT, array, dim, xattree
9+
from xattree import ROOT, array, dim, field, xattree
1110

1211
__all__ = [
1312
"Component",
@@ -54,6 +53,12 @@ class Exchange(Package):
5453

5554
@xattree
5655
class Tdis(Package):
56+
@define
57+
class PeriodData:
58+
perlen: float
59+
nstp: int
60+
tsmult: float
61+
5762
nper: int = dim(
5863
name="per",
5964
default=1,
@@ -66,6 +71,11 @@ class Tdis(Package):
6671
start_date_time: Optional[datetime] = field(
6772
default=None, metadata={"block": "options"}
6873
)
74+
# perioddata: NDArray[np.object_] = array(
75+
# PeriodData,
76+
# dims=("per",),
77+
# metadata={"block": "perioddata"},
78+
# )
6979
perlen: NDArray[np.floating] = array(
7080
default=1.0,
7181
dims=("per",),

flopy4/mf6/io/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"""
8686

8787

88-
def make_parser(cls: type, **kwargs) -> Lark:
88+
def make_parser(cls: type, extra_params=None, **kwargs) -> Lark:
8989
"""
9090
Create a parser for the MODFLOW 6 input language with the given
9191
parameter and block specification.
@@ -100,7 +100,8 @@ def make_parser(cls: type, **kwargs) -> Lark:
100100
if not has_xats(cls):
101101
raise ValueError(f"Class '{cls.__name__}' is not a `xattree`.")
102102
spec = cls.__xattree__["spec"].flat
103-
params = "|".join(['"' + n + '"i' for n in spec.keys()])
103+
pnames = list(spec.keys()) + (extra_params or [])
104+
params = "|".join(['"' + n + '"i' for n in pnames])
104105
blocks = set([xat.metadata.get("block", None) for xat in spec.values()])
105106
blocks.discard(None)
106107
# temp hack, TODO detect list blocks as blocks with a single

test/test_lark.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,46 @@
1+
from pathlib import Path
2+
3+
import flopy
14
from lark import Lark
25

3-
from flopy4.mf6.gwf.oc import Oc
4-
from flopy4.mf6.io import make_parser
6+
from flopy4.mf6 import Tdis
7+
from flopy4.mf6.io import MF6Transformer, make_parser
58

69

710
def test_make_parser():
8-
parser = make_parser(Oc)
11+
parser = make_parser(Tdis)
912
assert isinstance(parser, Lark)
13+
14+
15+
def readme_example(name: str, workspace: Path) -> flopy.mf6.MFSimulation:
16+
sim = flopy.mf6.MFSimulation(
17+
sim_name=name, sim_ws=workspace, exe_name="mf6"
18+
)
19+
tdis = flopy.mf6.ModflowTdis(sim)
20+
ims = flopy.mf6.ModflowIms(sim)
21+
gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)
22+
dis = flopy.mf6.ModflowGwfdis(gwf, nrow=10, ncol=10)
23+
ic = flopy.mf6.ModflowGwfic(gwf)
24+
npf = flopy.mf6.ModflowGwfnpf(gwf, save_specific_discharge=True)
25+
chd = flopy.mf6.ModflowGwfchd(
26+
gwf, stress_period_data=[[(0, 0, 0), 1.0], [(0, 9, 9), 0.0]]
27+
)
28+
budget_file = name + ".bud"
29+
head_file = name + ".hds"
30+
oc = flopy.mf6.ModflowGwfoc(
31+
gwf,
32+
budget_filerecord=budget_file,
33+
head_filerecord=head_file,
34+
saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
35+
)
36+
return sim
37+
38+
39+
def test_parse(tmp_path):
40+
sim = readme_example("test", Path(tmp_path))
41+
sim.write_simulation()
42+
parser = make_parser(Tdis)
43+
transformer = MF6Transformer()
44+
with open(tmp_path / "test.tdis", "r") as f:
45+
tree = parser.parse(f.read())
46+
data = transformer.transform(tree)

0 commit comments

Comments
 (0)