Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 12 additions & 38 deletions flopy/mf6/data/mfstructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import numpy as np

from flopy.mf6.inspect import get_solution_packages

from ..mfbase import PackageContainer, StructException

numeric_index_text = (
Expand Down Expand Up @@ -2461,6 +2463,11 @@ def tag_read_as_arrays(self):
package_struct.read_as_arrays = True


def _get_solution_packages():
pkgs = get_solution_packages()
return {k.lower().replace("modflow", ""): "*" for k in pkgs.keys()}


class MFStructure:
"""
Singleton class for accessing the contents of the json structure file
Expand Down Expand Up @@ -2492,7 +2499,9 @@ def __new__(cls, internal_request=False, load_from_dfn_files=False):
cls._instance.sim_struct = None
cls._instance.dimension_dict = {}
cls._instance.load_from_dfn_files = load_from_dfn_files
cls._instance.flopy_dict = {}
cls._instance.flopy_dict = {
"solution_packages": _get_solution_packages()
}

# Read metadata from file
cls._instance.valid = cls._instance.__load_structure()
Expand All @@ -2509,9 +2518,6 @@ def __load_structure(self):
# set up structure classes
self.sim_struct = MFSimulationStructure()

# initialize flopy dict keys
MFStructure().flopy_dict["solution_packages"] = {}

if self.load_from_dfn_files:
mf_dfn = Dfn()
dfn_files = mf_dfn.get_file_list()
Expand Down Expand Up @@ -2542,44 +2548,12 @@ def __load_structure(self):
"parameter_name": line_lst[6],
}
MFStructure().flopy_dict[line_lst[3]] = sp_dict
elif line_lst[2] == "solution_package":
MFStructure().flopy_dict["solution_packages"][
line_lst[3]
] = line_lst[4:]
if len(MFStructure().flopy_dict["solution_packages"]) == 0:
MFStructure().flopy_dict["solution_packages"]["ims"] = ["*"]
warnings.warn(
"Package definition files (dfn) do not define a solution "
"package. This can happen if your dfn files are out of "
"sync. Auto-loaded default IMS solution package metadata."
" In the future auto-loading default metadata will be "
"deprecated.",
DeprecationWarning,
)
# process each file
for file in dfn_files:
self.sim_struct.process_dfn(DfnFile(file))
self.sim_struct.tag_read_as_arrays()
else:
package_list = PackageContainer.package_list()
for package in package_list:
# process header
for entry in package.dfn[0][1:]:
if (
isinstance(entry, list)
and entry[0] == "solution_package"
):
MFStructure().flopy_dict["solution_packages"][
package.package_abbr
] = entry[1:]
# process each package
for package in PackageContainer.package_list():
self.sim_struct.process_dfn(DfnPackage(package))
self.sim_struct.tag_read_as_arrays()

return True

@staticmethod
def __valid_line(line):
if len(line.strip()) > 1 and line[0] != "#":
return True
return False
return True
46 changes: 46 additions & 0 deletions flopy/mf6/inspect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from collections.abc import Mapping


def get_classes(predicate=None) -> Mapping[str, type]:
import flopy.mf6.modflow as modflow
from flopy.utils.inspect import get_classes as _get_classes

return _get_classes(
modflow,
lambda cls: hasattr(cls, "dfn") and (predicate(cls) if predicate else True),
)


def get_multi_packages() -> Mapping[str, type]:
def _filter(cls):
return (
len(cls.dfn) > 0
and len(cls.dfn[0]) >= 2
and cls.dfn[0][1] == "multi-package"
)

return get_classes(_filter)


def get_solution_packages() -> Mapping[str, type]:
def _filter(cls):
return (
len(cls.dfn) > 0
and len(cls.dfn[0]) >= 2
and len(cls.dfn[0][1]) > 0
and cls.dfn[0][1][0] == "solution_package"
)

return get_classes(_filter)


def get_sub_packages() -> Mapping[str, type]:
def _filter(cls):
return (
len(cls.dfn) > 0
and len(cls.dfn[0]) >= 2
and len(cls.dfn[0][1]) > 0
and cls.dfn[0][1][0] == "subpackage"
)

return get_classes(_filter)
8 changes: 8 additions & 0 deletions flopy/utils/inspect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import inspect
from collections.abc import Mapping


def get_classes(module, predicate=None) -> Mapping[str, type]:
"""Find classes in a module which satisfy a predicate."""
classes = inspect.getmembers(module, inspect.isclass)
return {name: cls for name, cls in classes if predicate(cls)}