-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
More complete draft of an array conversion function to expand sparse dictionary representations to a full array. Also some housekeeping, move things into their own modules. Conversion function still needs testing, only the barest minimum here.
- Loading branch information
Showing
21 changed files
with
552 additions
and
567 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +0,0 @@ | ||
from abc import ABC | ||
from datetime import datetime | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
import numpy as np | ||
from attrs import define | ||
from numpy.typing import NDArray | ||
from xattree import ROOT, array, dim, field, xattree | ||
|
||
__all__ = [ | ||
"Component", | ||
"Package", | ||
"Model", | ||
"Simulation", | ||
"Solution", | ||
"Exchange", | ||
"COMPONENTS", | ||
] | ||
|
||
COMPONENTS = {} | ||
"""MF6 component registry.""" | ||
|
||
|
||
class Component(ABC): | ||
@classmethod | ||
def __attrs_init_subclass__(cls): | ||
COMPONENTS[cls.__name__.lower()] = cls | ||
|
||
|
||
@define | ||
class Package(Component): | ||
pass | ||
|
||
|
||
@define | ||
class Model(Component): | ||
pass | ||
|
||
|
||
@define | ||
class Solution(Package): | ||
pass | ||
|
||
|
||
@define | ||
class Exchange(Package): | ||
exgtype: type = field() | ||
exgfile: Path = field() | ||
exgmnamea: Optional[str] = field(default=None) | ||
exgmnameb: Optional[str] = field(default=None) | ||
|
||
|
||
@xattree | ||
class Tdis(Package): | ||
@define | ||
class PeriodData: | ||
perlen: float | ||
nstp: int | ||
tsmult: float | ||
|
||
nper: int = dim( | ||
name="per", | ||
default=1, | ||
scope=ROOT, | ||
metadata={"block": "dimensions"}, | ||
) | ||
time_units: Optional[str] = field( | ||
default=None, metadata={"block": "options"} | ||
) | ||
start_date_time: Optional[datetime] = field( | ||
default=None, metadata={"block": "options"} | ||
) | ||
# perioddata: NDArray[np.object_] = array( | ||
# PeriodData, | ||
# dims=("per",), | ||
# metadata={"block": "perioddata"}, | ||
# ) | ||
perlen: NDArray[np.floating] = array( | ||
default=1.0, | ||
dims=("per",), | ||
metadata={"block": "perioddata"}, | ||
) | ||
nstp: NDArray[np.integer] = array( | ||
default=1, | ||
dims=("per",), | ||
metadata={"block": "perioddata"}, | ||
) | ||
tsmult: NDArray[np.floating] = array( | ||
default=1.0, | ||
dims=("per",), | ||
metadata={"block": "perioddata"}, | ||
) | ||
|
||
|
||
@xattree | ||
class Simulation(Component): | ||
models: dict[str, Model] = field() | ||
exchanges: dict[str, Exchange] = field() | ||
solutions: dict[str, Solution] = field() | ||
tdis: Tdis = field() | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from abc import ABC | ||
|
||
COMPONENTS = {} | ||
"""MF6 component registry.""" | ||
|
||
|
||
class Component(ABC): | ||
@classmethod | ||
def __attrs_init_subclass__(cls): | ||
COMPONENTS[cls.__name__.lower()] = cls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import numpy as np | ||
|
||
FILL_DEFAULT = np.nan | ||
FILL_DNODATA = 1e30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
|
||
import numpy as np | ||
from numpy.typing import NDArray | ||
from xattree import _get_xatspec | ||
|
||
from flopy4.mf6.constants import FILL_DNODATA | ||
|
||
|
||
def convert_array(value, self_, field) -> NDArray: | ||
if not isinstance(value, dict): | ||
# if not a dict, assume it's a numpy array | ||
# and let xarray deal with it if it isn't | ||
return value | ||
|
||
# get spec | ||
spec = _get_xatspec(type(self_)) | ||
field = spec.arrays[field.name] | ||
if not field.dims: | ||
raise ValueError(f"Field {field} missing dims") | ||
|
||
# resolve dims | ||
explicit_dims = self_.__dict__.get("dims", {}) | ||
inherited_dims = self_.parent.data.dims if self_.parent else {} | ||
dims = inherited_dims | explicit_dims | ||
shape = [dims.get(d, d) for d in field.dims] | ||
unresolved = [d for d in shape if isinstance(d, str)] | ||
if any(unresolved): | ||
raise ValueError(f"Couldn't resolve dims: {unresolved}") | ||
|
||
# create array | ||
a = np.full(shape, fill_value=FILL_DNODATA, dtype=field.dtype) | ||
|
||
def _get_nn(cellid): | ||
match len(cellid): | ||
case 1: | ||
return cellid[0] | ||
case 2: | ||
k, j = cellid | ||
return k * dims["ncpl"] + j | ||
case 3: | ||
k, i, j = cellid | ||
return k * dims["row"] * dims["col"] + i * dims["col"] + j | ||
case _: | ||
raise ValueError(f"Invalid cellid: {cellid}") | ||
|
||
# populate array. TODO: is there a way to do this | ||
# without hardcoding awareness of kper and cellid? | ||
if "per" in dims: | ||
for kper, period in value.items(): | ||
if kper == "*": | ||
kper = 0 | ||
match len(shape): | ||
case 1: | ||
a[kper] = value | ||
case _: | ||
for cellid, v in period.items(): | ||
nn = _get_nn(cellid) | ||
a[kper, nn] = v | ||
if kper == "*": | ||
break | ||
else: | ||
for cellid, v in value.items(): | ||
nn = _get_nn(cellid) | ||
a[nn] = v | ||
|
||
return a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
from attrs import define | ||
from xattree import field | ||
|
||
from flopy4.mf6.package import Package | ||
|
||
|
||
@define | ||
class Exchange(Package): | ||
exgtype: type = field() | ||
exgfile: Path = field() | ||
exgmnamea: Optional[str] = field(default=None) | ||
exgmnameb: Optional[str] = field(default=None) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.