Skip to content

Commit 7e36ebe

Browse files
author
wpbonelli
committed
quickstart is so close
1 parent 7885fc7 commit 7e36ebe

File tree

7 files changed

+49
-30
lines changed

7 files changed

+49
-30
lines changed

docs/examples/quickstart.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,32 @@
55
from flopy.discretization.modeltime import ModelTime
66
from flopy.discretization.structuredgrid import StructuredGrid
77

8-
from flopy4.mf6.gwf import Chd, Gwf, Npf, Oc
8+
from flopy4.mf6.gwf import Chd, Gwf, Ic, Npf, Oc
99
from flopy4.mf6.ims import Ims
1010
from flopy4.mf6.simulation import Simulation
1111

1212
name = "quickstart"
1313
workspace = Path(__file__).parent / name
1414
time = ModelTime(perlen=[1.0], nstp=[1])
15-
grid = StructuredGrid(nlay=1, nrow=10, ncol=10)
15+
grid = StructuredGrid(
16+
nlay=1,
17+
nrow=10,
18+
ncol=10,
19+
delr=1.0 * np.ones(10),
20+
delc=1.0 * np.ones(10),
21+
top=1.0 * np.ones((10, 10)),
22+
botm=0.0 * np.ones((1, 10, 10)),
23+
)
1624
sim = Simulation(name=name, workspace=workspace, tdis=time)
17-
ims = Ims(parent=sim)
1825
gwf_name = "mymodel"
26+
ims = Ims(parent=sim, models=[gwf_name]) # temporary hack
1927
gwf = Gwf(parent=sim, name=gwf_name, save_flows=True, dis=grid)
2028
npf = Npf(parent=gwf, save_specific_discharge=True)
2129
chd = Chd(
2230
parent=gwf,
2331
head={0: {(0, 0, 0): 1.0, (0, 9, 9): 0.0}},
2432
)
33+
ic = Ic(parent=gwf, strt=1.0)
2534
oc = Oc(
2635
parent=gwf,
2736
budget_file=f"{gwf.name}.bud",
@@ -30,18 +39,15 @@
3039
save_budget={0: "all"},
3140
)
3241

33-
# sim.write()
42+
sim.write()
3443
sim.run(verbose=True)
3544

36-
# check CHD
3745
assert chd.data["head"][0, 0] == 1.0
3846
assert chd.data.head.sel(per=0)[99] == 0.0
3947
assert np.allclose(chd.data.head[:, 1:99], np.full(98, 1e30))
4048

41-
# check DIS
4249
assert gwf.dis.data.botm.sel(lay=0, col=0, row=0) == 0.0
4350

44-
# check OC
4551
assert oc.data["save_head"][0] == "all"
4652
assert oc.data.save_head.sel(per=0) == "all"
4753

flopy4/mf6/converter.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from flopy4.mf6.exchange import Exchange
1414
from flopy4.mf6.model import Model
1515
from flopy4.mf6.package import Package
16+
from flopy4.mf6.solution import Solution
1617
from flopy4.mf6.spec import fields_dict, get_blocks
1718

1819

@@ -45,9 +46,10 @@ def _get_binding_type(component: Component) -> str:
4546
def _get_binding_terms(component: Component) -> tuple[str, ...] | None:
4647
if isinstance(component, Exchange):
4748
return (component.exgmnamea, component.exgmnameb) # type: ignore
49+
elif isinstance(component, Solution):
50+
return tuple(component.models)
4851
elif isinstance(component, (Model, Package)):
4952
return (component.name,) # type: ignore
50-
# TODO solutions
5153
return None
5254

5355
return cls(
@@ -178,7 +180,18 @@ def unstructure_component(value: Component) -> dict[str, Any]:
178180
_attach_field_metadata(dataset, type(value), list(block.keys()))
179181
blocks[f"{block_name} {kper + 1}"] = {block_name: dataset}
180182

181-
return {name: block for name, block in blocks.items() if block}
183+
# make sure options block always comes first
184+
if "options" in blocks:
185+
options_block = blocks.pop("options")
186+
blocks = {"options": options_block, **blocks}
187+
188+
# total temporary hack! manually set solutiongroup 1. still need to support multiple..
189+
if "solutiongroup" in blocks:
190+
sg = blocks["solutiongroup"]
191+
blocks["solutiongroup 1"] = sg
192+
del blocks["solutiongroup"]
193+
194+
return {name: block for name, block in blocks.items() if name != "period"}
182195

183196

184197
def _make_converter() -> Converter:

flopy4/mf6/gwf/__init__.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ def convert_grid(value):
3131

3232
@xattree
3333
class Gwf(Model):
34+
@define
35+
class NewtonOptions:
36+
newton: bool = field()
37+
under_relaxation: bool = field()
38+
3439
@define
3540
class Output:
3641
parent: "Gwf" = attrs.field(repr=False)
@@ -51,6 +56,14 @@ def budget(self):
5156
self.parent.parent.workspace / f"{self.parent.name}.dis.grb",
5257
)
5358

59+
_list: Optional[str] = field(block="options", default=None)
60+
print_input: bool = field(block="options", default=False)
61+
print_flows: bool = field(block="options", default=False)
62+
save_flows: bool = field(block="options", default=False)
63+
newtonoptions: Optional[NewtonOptions] = field(block="options", default=None)
64+
nc_mesh2d_filerecord: Optional[Path] = field(block="options", default=None)
65+
nc_structured_filerecord: Optional[Path] = field(block="options", default=None)
66+
nc_filerecord: Optional[Path] = field(block="options", default=None)
5467
dis: Dis = field(converter=convert_grid, block="packages")
5568
ic: Ic = field(block="packages")
5669
oc: Oc = field(block="packages")
@@ -62,20 +75,6 @@ def budget(self):
6275
default=attrs.Factory(lambda self: Gwf.Output(self), takes_self=True)
6376
)
6477

65-
@define
66-
class NewtonOptions:
67-
newton: bool = field()
68-
under_relaxation: bool = field()
69-
70-
list: Optional[str] = field(block="options", default=None)
71-
print_input: bool = field(block="options", default=False)
72-
print_flows: bool = field(block="options", default=False)
73-
save_flows: bool = field(block="options", default=False)
74-
newtonoptions: Optional[NewtonOptions] = field(block="options", default=None)
75-
nc_mesh2d_filerecord: Optional[Path] = field(block="options", default=None)
76-
nc_structured_filerecord: Optional[Path] = field(block="options", default=None)
77-
nc_filerecord: Optional[Path] = field(block="options", default=None)
78-
7978
@property
8079
def grid(self) -> Grid:
8180
return self.dis.to_grid()

flopy4/mf6/gwf/ic.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
from flopy4.mf6.spec import array, field
99

1010

11-
@xattree
11+
@xattree(kw_only=True)
1212
class Ic(Package):
13+
export_array_ascii: bool = field(block="options", default=False)
14+
export_array_netcdf: bool = field(block="options", default=False)
1315
strt: NDArray[np.float64] = array(
14-
block="packagedata",
16+
block="griddata",
1517
dims=("nnodes",),
1618
default=1.0,
1719
converter=Converter(dict_to_array, takes_self=True, takes_field=True),
1820
)
19-
export_array_ascii: bool = field(block="options", default=False)
20-
export_array_netcdf: bool = field(block="options", default=False)

flopy4/mf6/ims.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
class Ims(Solution):
1313
solution_package: ClassVar[Sln] = Sln(abbr="ims", pattern="*")
1414

15-
print_option: bool = field(block="options", default=False)
15+
print_option: Optional[str] = field(block="options", default=None)
1616
complexity: str = field(block="options", default="simple")
1717
csv_outer_output_file: Optional[Path] = field(default=None, block="options")
1818
csv_inner_output_file: Optional[Path] = field(block="options", default=None)

flopy4/mf6/simulation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def convert_time(value):
2323

2424
@xattree
2525
class Simulation(Context):
26+
tdis: Tdis = field(converter=convert_time, block="timing")
2627
models: dict[str, Model] = field(block="models")
2728
exchanges: dict[str, Exchange] = field(block="exchanges")
2829
solutions: dict[str, Solution] = field(block="solutiongroup")
29-
tdis: Tdis = field(converter=convert_time, block="timing")
3030
filename: str = field(default="mfsim.nam", init=False)
3131

3232
def __attrs_post_init__(self):

flopy4/mf6/solution.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from abc import ABC
22

3+
import attrs
34
from xattree import xattree
45

56
from flopy4.mf6.package import Package
67

78

89
@xattree
910
class Solution(Package, ABC):
10-
pass
11+
models: list[str] = attrs.field()

0 commit comments

Comments
 (0)