Skip to content

Commit 6f5ff76

Browse files
authored
refactor: generalize exchange detection (#100)
check for "X-X" pattern to find like-model exchanges without hardcoding exchange names
1 parent b547a56 commit 6f5ff76

5 files changed

Lines changed: 36 additions & 36 deletions

File tree

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from .apimodel import ApiMbase
2-
from .pakbase import ListPackage
32

43

54
class ApiExchange(ApiMbase):
65
"""
7-
ApiExchange class for GWF-GWF packages and container to access the
8-
simulation level GWF-GWF, MVR, and GNC packages
6+
ApiExchange class for exchange packages (e.g. GWF-GWF, GWT-GWT) and
7+
container to access simulation level exchange, MVR, and GNC packages
98
109
Parameters
1110
----------
@@ -16,9 +15,4 @@ class ApiExchange(ApiMbase):
1615
"""
1716

1817
def __init__(self, mf6, name):
19-
pkg_types = {
20-
"gwf-gwf": ListPackage,
21-
"gwt-gwt": ListPackage,
22-
"gwe-gwe": ListPackage,
23-
}
24-
super().__init__(mf6, name, pkg_types)
18+
super().__init__(mf6, name)

modflowapi/extensions/apimodel.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22

3+
from ..util import is_exg
34
from .datamodel import get_package_type, gridshape
45
from .pakbase import AdvancedPackage, ArrayPackage, ListPackage, package_factory
56

@@ -15,7 +16,8 @@ class ApiMbase:
1516
name : str
1617
modflow model name. ex. "GWF_1", "GWF-GWF_1"
1718
pkg_types : None, dict
18-
optional dictionary of package types and ApiPackage class types
19+
optional dictionary of package types and ApiPackage class types,
20+
used to override the default package class selection
1921
"""
2022

2123
def __init__(self, mf6, name, pkg_types=None):
@@ -56,11 +58,9 @@ def _set_package_names(self):
5658
if addr.endswith("PACKAGE_TYPE") and tmp[0] == self.name:
5759
pak_types[tmp[1]] = self.mf6.get_value(addr)[0]
5860
elif tmp[0] == self.name and len(tmp) == 2:
59-
if tmp[0].startswith("GWF-GWF"):
60-
pak_types[tmp[0]] = "GWF-GWF"
61-
pak_types.pop("dis", None)
62-
elif tmp[0].startswith("GWT-GWT"):
63-
pak_types[tmp[0]] = "GWT-GWT"
61+
pkg_type = tmp[0].rsplit("_", 1)[0]
62+
if is_exg(pkg_type):
63+
pak_types[tmp[0]] = pkg_type
6464
pak_types.pop("dis", None)
6565

6666
self._pak_type = list(pak_types.values())
@@ -72,18 +72,15 @@ def _create_package_list(self):
7272
"""
7373
for ix, pkg_name in enumerate(self._pkg_names):
7474
pkg_type = self._pak_type[ix].lower()
75-
if self._pkg_types is None:
76-
basepackage = get_package_type(pkg_type)
75+
if self._pkg_types is not None and pkg_type in self._pkg_types:
76+
basepackage = self._pkg_types[pkg_type]
77+
elif is_exg(pkg_type):
78+
basepackage = ListPackage
7779
else:
78-
if pkg_type in self._pkg_types:
79-
basepackage = self._pkg_types[pkg_type]
80-
else:
81-
basepackage = AdvancedPackage
80+
basepackage = get_package_type(pkg_type)
8281

8382
package = package_factory(pkg_type, basepackage)
84-
adj_pkg_name = "".join(pkg_type.split("-"))
85-
86-
if adj_pkg_name.lower() in ("gwfgwf", "gwtgwt"):
83+
if is_exg(pkg_type):
8784
adj_pkg_name = ""
8885
else:
8986
adj_pkg_name = pkg_name

modflowapi/extensions/apisimulation.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22

3+
from ..util import is_exg
34
from .apiexchange import ApiExchange
45
from .apimodel import ApiMbase, ApiModel
56
from .pakbase import ApiSlnPackage, ListPackage, ScalarPackage, package_factory
@@ -49,7 +50,7 @@ def __getattr__(self, item):
4950
return super().__getattribute__(item)
5051

5152
def __repr__(self):
52-
s = self.__doc__
53+
s = self.__doc__ or ""
5354
s += f"Number of models: {len(self._models)}:\n"
5455
for name, obj in self._models.items():
5556
s += f"\t{name} : {type(obj)}\n"
@@ -147,7 +148,7 @@ def model_names(self):
147148
@property
148149
def exchange_names(self):
149150
"""
150-
Returns a list of exchange GWF-GWF names
151+
Returns a list of exchange names (e.g. "GWF-GWF_1")
151152
"""
152153
if self._exchanges.keys():
153154
return list(self._exchanges.keys())
@@ -240,13 +241,13 @@ def get_model(self, model_id=None):
240241

241242
def get_exchange(self, exchange_name=None):
242243
"""
243-
Get a GWF-GWF "model" and all associated simulation level package
244-
data (ex. GNC, MVR)
244+
Get an exchange and all associated simulation level package data
245+
(ex. GNC, MVR)
245246
246247
Parameters
247248
----------
248249
exchange_name : str
249-
name of the GWF-GWF exchange package
250+
name of the exchange package (e.g. "GWF-GWF_1")
250251
251252
Returns
252253
-------
@@ -367,10 +368,10 @@ def load(mf6):
367368
# get the exchanges
368369
exchange_names = []
369370
for variable in variables:
370-
if variable.startswith("GWF-GWF") or variable.startswith("GWT-GWT"):
371-
exchange_name = variable.split("/")[0]
372-
if exchange_name not in exchange_names:
373-
exchange_names.append(exchange_name)
371+
exchange_name = variable.split("/")[0]
372+
name = exchange_name.rsplit("_", 1)[0]
373+
if is_exg(name) and exchange_name not in exchange_names:
374+
exchange_names.append(exchange_name)
374375

375376
# sim_packages: tdis, gwf-gwf, sln
376377
exchanges = {}

modflowapi/modflowapi.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from os import PathLike
2+
13
from xmipy import XmiWrapper
24

35
from .util import amend_libmf6_path
@@ -16,8 +18,8 @@ class ModflowApi(XmiWrapper):
1618

1719
def __init__(
1820
self,
19-
lib_path: str,
20-
lib_dependency: str = None,
21+
lib_path: str | PathLike,
22+
lib_dependency: str | None = None,
2123
working_directory: str = ".",
2224
timing: bool = False,
2325
logger_level: int | str = 0,

modflowapi/util.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
from os import PathLike
12
from pathlib import Path
23
from platform import system
34

45

5-
def amend_libmf6_path(path) -> str:
6+
def amend_libmf6_path(path: str | PathLike) -> str:
67
ext = Path(path).suffix
78
path = str(path)
89
os = system().lower()
@@ -19,3 +20,8 @@ def amend_libmf6_path(path) -> str:
1920
elif os == "darwin" and not ext:
2021
path += ".dylib"
2122
return path
23+
24+
25+
def is_exg(pkg_type: str):
26+
parts = pkg_type.split("-")
27+
return len(parts) == 2 and parts[0] == parts[1]

0 commit comments

Comments
 (0)