Skip to content

Commit a63a48a

Browse files
committed
add lkt/lke to codegen
1 parent 13c5bc6 commit a63a48a

37 files changed

Lines changed: 2687 additions & 83 deletions

flopy4/mf6/codec/writer/filters.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,21 @@ def dataset2list(value: xr.Dataset):
256256
return
257257

258258
combined_mask: Any = None
259+
spatial_da = None # a non-aux DataArray for deriving spatial dims/mask
259260
for name, first in value.data_vars.items():
260-
mask = nonempty(first)
261-
combined_mask = mask if combined_mask is None else combined_mask | mask
261+
if "naux" in first.dims:
262+
# nonempty gives (spatial..., naux) bool array; collapse naux with any()
263+
mask = nonempty(first).any(axis=-1)
264+
else:
265+
mask = nonempty(first)
266+
spatial_da = first
267+
combined_mask = mask if combined_mask is None else (combined_mask | mask)
262268
if combined_mask is None or not np.any(combined_mask):
263269
return
264270

265-
spatial_dims = [d for d in first.dims if d in ("nlay", "nrow", "ncol", "nodes")]
271+
if spatial_da is None:
272+
spatial_da = first
273+
spatial_dims = [d for d in spatial_da.dims if d in ("nlay", "nrow", "ncol", "nodes")]
266274
has_spatial_dims = len(spatial_dims) > 0
267275
indices = np.where(combined_mask)
268276
for i in range(len(indices[0])):
@@ -287,7 +295,10 @@ def dataset2list(value: xr.Dataset):
287295
else:
288296
row2.append(val + 1)
289297
else:
290-
row2.append(val)
298+
if hasattr(val, "ndim") and val.ndim > 0:
299+
row2.extend(float(v) for v in np.asarray(val).flat)
300+
else:
301+
row2.append(val)
291302
if has_spatial_dims:
292303
cellid = tuple(idx[i] + 1 for idx in indices)
293304
yield tuple(cellid) + tuple(row2)

flopy4/mf6/component.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from flopy4.mf6.write_context import WriteContext
1616
from flopy4.uio import IO, Loader, Writer
1717

18-
COMPONENTS = {}
18+
COMPONENTS: dict[str, type] = {}
1919
"""MF6 component registry."""
2020

2121

flopy4/mf6/converter/egress/unstructure.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,21 @@ def _hack_structured_grid_dims(
101101
"nlay": range(structured_grid_dims["nlay"]),
102102
"ncpl": range(structured_grid_dims["ncpl"]),
103103
}
104+
else:
105+
# No structured grid decomposition available — keep nodes dim as-is.
106+
return value
104107

105108
if "nper" in value.dims:
106109
shape.insert(0, value.sizes["nper"])
107110
dims.insert(0, "nper")
108111
coords = {"nper": value.coords["nper"], **coords}
109112

113+
if "naux" in value.dims:
114+
naux = value.sizes["naux"]
115+
shape.append(naux)
116+
dims.append("naux")
117+
coords["naux"] = range(naux)
118+
110119
return xr.DataArray(
111120
value.data.reshape(shape),
112121
dims=dims,
@@ -352,12 +361,31 @@ def _unstructure_array_component(value: Component) -> dict[str, Any]:
352361
for kper, block in period_blocks.items():
353362
key = f"period {kper + 1}"
354363
for arr_name, val in block.items():
355-
if not np.all(val == FILL_DNODATA):
364+
# G/A variant aux: split naux-dimensioned array into one readarray
365+
# block per auxiliary variable, named by value.auxiliary.
366+
if arr_name == "aux" and isinstance(val, xr.DataArray) and "naux" in val.dims:
367+
_aux = getattr(value, "auxiliary", None)
368+
if _aux is not None and hasattr(_aux, "values"):
369+
aux_names = [str(n) for n in _aux.values.tolist()]
370+
else:
371+
aux_names = list(_aux or [])
372+
for k in range(val.sizes["naux"]):
373+
aux_slice = val.isel(naux=k)
374+
if not np.all(aux_slice.values == FILL_DNODATA):
375+
if key not in blocks:
376+
blocks[key] = {}
377+
name = aux_names[k] if k < len(aux_names) else f"aux{k}"
378+
blocks[key][name] = aux_slice
379+
elif not np.all(val == FILL_DNODATA):
356380
if key not in blocks:
357381
blocks[key] = {}
358382
blocks[key][arr_name] = val
359383

360-
return {name: block for name, block in blocks.items() if name != "period"}
384+
return {
385+
name: block
386+
for name, block in blocks.items()
387+
if name != "period" and not name.startswith("__")
388+
}
361389

362390

363391
# Block names that MF6 rejects if present but empty.
@@ -467,6 +495,17 @@ def _unstructure_component(value: Component) -> dict[str, Any]:
467495
if block_name in _LIST_BLOCK_NAMES:
468496
current_block = blocks.get(block_name, {})
469497
if current_block:
498+
# Expand any 2D DataArrays (e.g. aux with shape (nlakes, naux)) into
499+
# separate per-column 1D DataArrays so the Dataset stays uniformly 1D.
500+
expanded: dict[str, Any] = {}
501+
for name, v in current_block.items():
502+
if isinstance(v, xr.DataArray) and v.ndim == 2:
503+
for j in range(v.shape[1]):
504+
expanded[f"{name}_{j}"] = v.isel({v.dims[1]: j})
505+
else:
506+
expanded[name] = v
507+
current_block = expanded
508+
470509
das = [v for v in current_block.values() if isinstance(v, xr.DataArray)]
471510
if das and len(das) == len(current_block):
472511
first_dim = das[0].dims[0] if das[0].dims else None

0 commit comments

Comments
 (0)