Skip to content

Commit fb46588

Browse files
mjrenomjreno
authored andcommitted
write format adjustments
1 parent 2b44c3f commit fb46588

File tree

13 files changed

+73
-65
lines changed

13 files changed

+73
-65
lines changed

docs/examples/twri.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import flopy4
1010

1111

12-
def plot_contourf(head, workspace):
12+
def plot_head(head, workspace):
1313
import matplotlib.pyplot as plt
1414

1515
# Plot head results
@@ -101,7 +101,6 @@ def plot_contourf(head, workspace):
101101
# Uniform recharge on the top layer
102102
rch_rate = np.full((nlay, nrow, ncol), flopy4.mf6.constants.FILL_DNODATA)
103103
rate = np.repeat(np.expand_dims(rch_rate, axis=0), repeats=nper, axis=0)
104-
# rate[0, 0, :, :] = 3.0e-8
105104
rate[0, 0, ...] = 3.0e-8
106105
rch = flopy4.mf6.gwf.Rch(recharge=rate.reshape(nper, -1), dims=dims)
107106

@@ -197,7 +196,9 @@ def plot_contourf(head, workspace):
197196
)
198197

199198
# Plot head results
200-
plot_contourf(head, workspace)
199+
plot_head(head, workspace)
200+
201+
# UPDATE SIM for array based inputs
201202

202203
# update simulation with array based inputs
203204
LAYER_NODATA = np.full((nrow, ncol), flopy4.mf6.constants.FILL_DNODATA, dtype=float)
@@ -243,18 +244,19 @@ def plot_contourf(head, workspace):
243244
recharge = np.repeat(np.expand_dims(LAYER_NODATA, axis=0), repeats=nper, axis=0)
244245
recharge[0, ...] = 3.0e-8
245246
# recharge[0, 0, 0] = 3.0e-7
246-
# print(recharge)
247247
# rch = flopy4.mf6.gwf.Rcha(irch=1, recharge=recharge.reshape(nper, -1), dims=dims)
248248
rcha = flopy4.mf6.gwf.Rcha(recharge=recharge.reshape(nper, -1), dims=dims)
249249

250250
# remove list based inputs
251-
del gwf.chd[0]
251+
gwf.chd.remove(chd)
252+
# del gwf.chd[0]
252253
del gwf.drn[0]
253254
del gwf.wel[0]
254255
del gwf.rch[0]
255256

256257
# add array based inputs
257-
gwf.chdg = [chdg]
258+
# gwf.chdg = [chdg]
259+
gwf.chd = [chdg]
258260
gwf.drng = [drng]
259261
gwf.welg = [welg]
260262
gwf.rcha = [rcha]
@@ -263,7 +265,6 @@ def plot_contourf(head, workspace):
263265
workspace = Path(__file__).parent / "twri2"
264266
workspace.mkdir(parents=True, exist_ok=True)
265267
sim.workspace = workspace
266-
sim.__attrs_post_init__()
267268

268269
sim.write()
269270
sim.run()
@@ -275,4 +276,4 @@ def plot_contourf(head, workspace):
275276
)
276277

277278
# Plot head results
278-
plot_contourf(head, workspace)
279+
plot_head(head, workspace)

flopy4/mf6/codec/writer/filters.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from flopy4.mf6.constants import FILL_DNODATA
1212

13-
ArrayHow = Literal["constant", "internal", "external", "layered internal"]
13+
ArrayHow = Literal["constant", "internal", "external", "layered constant", "layered internal"]
1414

1515

1616
def array_how(value: xr.DataArray) -> ArrayHow:
@@ -29,6 +29,14 @@ def array_how(value: xr.DataArray) -> ArrayHow:
2929
if value.ndim <= 2:
3030
return "internal"
3131
if value.ndim == 3:
32+
layer_const = True
33+
for layer in range(value.shape[0]):
34+
val_layer = value.isel(nlay=layer)
35+
if val_layer.max() != val_layer.min():
36+
layer_const = False
37+
break
38+
if layer_const:
39+
return "layered constant"
3240
return "layered internal"
3341
raise ValueError(f"Arrays with ndim > 3 are not supported, got ndim={value.ndim}")
3442

flopy4/mf6/codec/writer/templates/macros.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
{{ inset }}CONSTANT {{ value|array2const }}
3636
{% elif how == "layered constant" %}
3737
{% for layer in value -%}
38-
{{ inset }}CONSTANT {{ layer|array2const }}
38+
{{ "\n" ~ inset }}CONSTANT {{ layer|array2const }}
3939
{%- endfor %}
4040
{% elif how == "layered internal" %}
4141
{% for layer in value %}

flopy4/mf6/context.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,29 @@
1010
from flopy4.utils import to_path
1111

1212

13+
def update_child_attr(instance, attribute, new_value):
14+
"""
15+
Generalized function to update child attribute (e.g. workspace).
16+
17+
Args:
18+
instance: The model instance
19+
attribute: The attribute being set (from attrs on_setattr)
20+
new_value: The new value being set
21+
22+
Returns:
23+
The new_value (unchanged)
24+
"""
25+
26+
for child in instance.children.values(): # type: ignore
27+
if hasattr(child, attribute.name):
28+
setattr(child, attribute.name, new_value)
29+
30+
return new_value
31+
32+
1333
@xattree
1434
class Context(Component, ABC):
15-
workspace: Path = field(default=None, converter=to_path)
35+
workspace: Path = field(default=None, converter=to_path, on_setattr=update_child_attr)
1636

1737
def __attrs_post_init__(self):
1838
super().__attrs_post_init__()

flopy4/mf6/converter/unstructure.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,16 @@ def _unstructure_block_param(
188188
field_name == "auxiliary" and hasattr(field_value, "values") and field_value is not None
189189
):
190190
blocks[block_name][field_name] = tuple(field_value.values.tolist())
191-
case xr.DataArray() if "nper" in field_value.dims:
191+
case xr.DataArray():
192192
has_spatial_dims = any(
193193
dim in field_value.dims for dim in ["nlay", "nrow", "ncol", "ncpl", "nodes"]
194194
)
195195
if has_spatial_dims:
196196
field_value = _hack_structured_grid_dims(
197197
field_value,
198-
structured_grid_dims=value.parent.data.dims, # type: ignore
198+
structured_grid_dims=value.data.dims, # type: ignore
199199
)
200-
if block_name == "period":
200+
if "nper" in field_value.dims and block_name == "period":
201201
if not np.issubdtype(field_value.dtype, np.number):
202202
dat = _hack_period_non_numeric(field_name, field_value)
203203
for n, v in dat.items():
@@ -209,15 +209,13 @@ def _unstructure_block_param(
209209
}
210210
else:
211211
blocks[block_name][field_name] = field_value
212-
213212
case _:
214213
blocks[block_name][field_name] = field_value
215214

216215

217216
def unstructure_component(value: Component) -> dict[str, Any]:
218217
xatspec = xattree.get_xatspec(type(value))
219218
if "readarraygrid" in xatspec.attrs or "readasarrays" in xatspec.attrs:
220-
# return _unstructure_array_component(value)
221219
return _unstructure_array_component(value)
222220
else:
223221
return _unstructure_component(value)
@@ -273,7 +271,6 @@ def _unstructure_component(value: Component) -> dict[str, Any]:
273271
data = xattree.asdict(value)
274272

275273
# create child component binding blocks
276-
# TODO: this can add certain block keys out of order
277274
blocks.update(_make_binding_blocks(value))
278275

279276
# process blocks in order, unstructuring fields as needed,
@@ -331,7 +328,7 @@ def _unstructure_component(value: Component) -> dict[str, Any]:
331328

332329
# TODO: this fixes out of order blocks (e.g. model namefile) from
333330
# blocks.update() child binding call above
334-
# blocks = dict(sorted(blocks.items(), key=block_sort_key))
331+
blocks = dict(sorted(blocks.items(), key=block_sort_key))
335332

336333
# total temporary hack! manually set solutiongroup 1.
337334
# TODO still need to support multiple..

flopy4/mf6/gwf/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def budget(self):
100100
chd: list[Chd] = field(block="packages")
101101
chdg: list[Chdg] = field(block="packages")
102102
# chd: List[Union[Chd, Chdg]] = field(block="packages", factory=List)
103+
# chd: List[Union[Chd, Chdg]] = field(block="packages")
103104
drn: list[Drn] = field(block="packages")
104105
drng: list[Drng] = field(block="packages")
105106
rch: list[Rch] = field(block="packages")

flopy4/mf6/gwf/chdg.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22
from typing import ClassVar, Optional
33

44
import numpy as np
5-
6-
# from attrs import Converter
75
from numpy.typing import NDArray
86
from xattree import xattree
97

10-
# from flopy4.mf6.converter import structure_array
118
from flopy4.mf6.package import Package
129
from flopy4.mf6.spec import array, field, path
1310
from flopy4.mf6.utils.grid import update_maxbound
@@ -36,7 +33,6 @@ class Chdg(Package):
3633
"nodes",
3734
),
3835
default=None,
39-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
4036
on_setattr=update_maxbound,
4137
)
4238
aux: Optional[NDArray[np.float64]] = array(
@@ -46,6 +42,5 @@ class Chdg(Package):
4642
"nodes",
4743
),
4844
default=None,
49-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
5045
on_setattr=update_maxbound,
5146
)

flopy4/mf6/gwf/dis.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,15 @@ class Dis(Package):
7575
scope="gwf",
7676
init=False,
7777
)
78+
ncpl: int = dim(
79+
coord="lnode",
80+
scope="gwf",
81+
init=False,
82+
)
7883

7984
def __attrs_post_init__(self):
8085
self.nodes = self.ncol * self.nrow * self.nlay
86+
self.ncpl = self.ncol * self.nrow
8187
super().__attrs_post_init__()
8288

8389
def to_grid(self) -> StructuredGrid:

flopy4/mf6/gwf/drng.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22
from typing import ClassVar, Optional
33

44
import numpy as np
5-
6-
# from attrs import Converter
75
from numpy.typing import NDArray
86
from xattree import xattree
97

10-
# from flopy4.mf6.converter import structure_array
118
from flopy4.mf6.package import Package
129
from flopy4.mf6.spec import array, field, path
1310
from flopy4.mf6.utils.grid import update_maxbound
@@ -37,7 +34,6 @@ class Drng(Package):
3734
"nodes",
3835
),
3936
default=None,
40-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
4137
on_setattr=update_maxbound,
4238
)
4339
cond: Optional[NDArray[np.float64]] = array(
@@ -47,7 +43,6 @@ class Drng(Package):
4743
"nodes",
4844
),
4945
default=None,
50-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
5146
on_setattr=update_maxbound,
5247
)
5348
aux: Optional[NDArray[np.float64]] = array(
@@ -57,6 +52,5 @@ class Drng(Package):
5752
"nodes",
5853
),
5954
default=None,
60-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
6155
on_setattr=update_maxbound,
6256
)

flopy4/mf6/gwf/rcha.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,11 @@
22
from typing import ClassVar, Optional
33

44
import numpy as np
5-
6-
# from attrs import Converter
75
from numpy.typing import NDArray
86
from xattree import xattree
97

10-
# from flopy4.mf6.converter import structure_array
118
from flopy4.mf6.package import Package
129
from flopy4.mf6.spec import array, field, path
13-
14-
# from flopy4.mf6.utils.grid import update_maxbound
1510
from flopy4.utils import to_path
1611

1712

@@ -31,16 +26,13 @@ class Rcha(Package):
3126
obs_filerecord: Optional[Path] = path(
3227
block="options", default=None, converter=to_path, inout="fileout"
3328
)
34-
# maxbound: Optional[int] = field(block="dimensions", default=None, init=False)
3529
irch: Optional[NDArray[np.int64]] = array(
3630
block="period",
3731
dims=(
3832
"nper",
3933
"ncpl",
4034
),
4135
default=None,
42-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
43-
# on_setattr=update_maxbound,
4436
)
4537
recharge: Optional[NDArray[np.float64]] = array(
4638
block="period",
@@ -49,8 +41,6 @@ class Rcha(Package):
4941
"ncpl",
5042
),
5143
default=None,
52-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
53-
# on_setattr=update_maxbound,
5444
)
5545
aux: Optional[NDArray[np.float64]] = array(
5646
block="period",
@@ -59,6 +49,4 @@ class Rcha(Package):
5949
"ncpl",
6050
),
6151
default=None,
62-
# converter=Converter(structure_array, takes_self=True, takes_field=True),
63-
# on_setattr=update_maxbound,
6452
)

0 commit comments

Comments
 (0)