Skip to content

Commit

Permalink
slinging dictionaries no longer
Browse files Browse the repository at this point in the history
  • Loading branch information
wpbonelli committed Sep 27, 2024
1 parent 3f42cec commit b6005f9
Show file tree
Hide file tree
Showing 18 changed files with 960 additions and 476 deletions.
4 changes: 2 additions & 2 deletions .docs/code.rst
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ Contents:
.. toctree::
:maxdepth: 4

./source/flopy.mf6.utils.createpackages.rst
./source/flopy.mf6.utils.generate_classes.rst
./source/flopy.mf6.createpackages.rst
./source/flopy.mf6.generate_classes.rst


Previous Versions of MODFLOW
Expand Down
12 changes: 6 additions & 6 deletions .docs/md/generate_classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ MODFLOW 6 input continues to evolve as new models, packages, and options are dev
The FloPy classes for MODFLOW 6 are largely generated by a utility which converts DFN files in a modflow6 repository on GitHub or on the local machine into Python source files in your local FloPy install. For instance (output much abbreviated):

```bash
$ python -m flopy.mf6.utils.generate_classes
$ python -m flopy.mf6.generate_classes



Expand Down Expand Up @@ -55,7 +55,7 @@ Similar functionality is available within Python, e.g.:
The `generate_classes()` function has several optional parameters.

```bash
$ python -m flopy.mf6.utils.generate_classes -h
$ python -m flopy.mf6.generate_classes -h
usage: generate_classes.py [-h] [--owner OWNER] [--repo REPO] [--ref REF]
[--dfnpath DFNPATH] [--no-backup]

Expand All @@ -79,19 +79,19 @@ options:

For example, use the develop branch instead:
```bash
$ python -m flopy.mf6.utils.generate_classes --ref develop
$ python -m flopy.mf6.generate_classes --ref develop
```
use a fork of modflow6:
```bash
$ python -m flopy.mf6.utils.generate_classes --owner your-username --ref your-branch
$ python -m flopy.mf6.generate_classes --owner your-username --ref your-branch
```
maybe your fork has a different name:
```bash
$ python -m flopy.mf6.utils.generate_classes --owner your-username --repo your-modflow6 --ref your-branch
$ python -m flopy.mf6.generate_classes --owner your-username --repo your-modflow6 --ref your-branch
```
local copy of the repo:
```bash
$ python -m flopy.mf6.utils.generate_classes --dfnpath ../your/dfn/path
$ python -m flopy.mf6.generate_classes --dfnpath ../your/dfn/path
```

Branch names, commit hashes, or tags may be provided to `ref`.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ jobs:
subset: triangle

- name: Update package classes
run: python -m flopy.mf6.utils.generate_classes --ref develop --no-backup
run: python -m flopy.mf6.generate_classes --ref develop --no-backup

- name: Run tests
working-directory: autotest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
subset: triangle

- name: Update FloPy packages
run: python -m flopy.mf6.utils.generate_classes --ref develop --no-backup
run: python -m flopy.mf6.generate_classes --ref develop --no-backup

- name: Run example tests
working-directory: autotest
Expand Down
91 changes: 50 additions & 41 deletions autotest/test_createpackages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,84 @@
from modflow_devtools.misc import run_cmd

from autotest.conftest import get_project_root_path
from flopy.mf6.utils.createpackages import (
from flopy.mf6.createpackages import (
TEMPLATE_ENV,
TemplateType,
generate_components,
get_src_name,
ContextType,
DefinitionName,
generate_targets,
get_template_context,
load_dfn,
)
from flopy.mf6.utils.dfn import load_dfn
from flopy.mf6.mfpackage import MFPackage

PROJ_ROOT = get_project_root_path()
DFNS_PATH = PROJ_ROOT / "flopy" / "mf6" / "data" / "dfn"
DFN_PATH = PROJ_ROOT / "flopy" / "mf6" / "data" / "dfn"
DFNS = [
dfn
for dfn in DFNS_PATH.glob("*.dfn")
for dfn in DFN_PATH.glob("*.dfn")
if dfn.stem not in ["common", "flopy"]
]


@pytest.mark.parametrize("dfn", DFNS)
def test_load_dfn(dfn):
dfn_path = DFN_PATH / dfn
with open(dfn_path, "r") as f:
definition = load_dfn(f)


# only test packages for which we know the
# expected consolidated number of variables
# expected number of consolidated variables
@pytest.mark.parametrize(
"dfn, n_flat, n_nested", [("gwf-ic", 2, 2), ("prt-prp", 40, 18)]
"dfn, n_flat, n_params", [("gwf-ic", 2, 6), ("prt-prp", 40, 22)]
)
def test_get_template_context(dfn, n_flat, n_nested):
component, subcomponent = dfn.split("-")

with open(DFNS_PATH / "common.dfn") as f:
common_vars, _ = load_dfn(f)
def test_get_template_context(dfn, n_flat, n_params):
dfn_name = DefinitionName(*dfn.split("-"))

with open(DFNS_PATH / "flopy.dfn") as f:
flopy_vars, _ = load_dfn(f)
with open(DFN_PATH / "common.dfn") as f:
common, _ = load_dfn(f)

with open(DFNS_PATH / f"{dfn}.dfn") as f:
variables, metadata = load_dfn(f)
with open(DFN_PATH / f"{dfn}.dfn") as f:
definition = load_dfn(f)

context = get_template_context(
component, subcomponent, common_vars, flopy_vars, variables, metadata
dfn_name,
MFPackage,
common,
definition,
)
assert context["component"] == component
assert context["subcomponent"] == subcomponent
assert len(context["variables"]) == n_nested
assert context["name"] == dfn_name
assert len(context["parameters"]) == n_params
assert len(context["dfn"]) == n_flat + 1 # +1 for metadata


@pytest.mark.parametrize("dfn", [dfn.stem for dfn in DFNS])
def test_render_template(dfn, function_tmpdir):
component, subcomponent = dfn.split("-")
context_name = f"{component}{subcomponent}"
template_type = TemplateType.from_pair(component, subcomponent).value
template = TEMPLATE_ENV.get_template(f"{template_type}.jinja")

with open(DFNS_PATH / "common.dfn") as f:
common_vars, _ = load_dfn(f)

with open(DFNS_PATH / "flopy.dfn") as f:
flopy_vars, _ = load_dfn(f)

with open(DFNS_PATH / f"{dfn}.dfn", "r") as f:
variables, metadata = load_dfn(f)

context = get_template_context(
component, subcomponent, common_vars, flopy_vars, variables, metadata
)
dfn_name = DefinitionName(*dfn.split("-"))
context_type = ContextType.from_dfn_name(dfn_name)
template = TEMPLATE_ENV.get_template("context.jinja")

with open(DFN_PATH / "common.dfn") as f:
common, _ = load_dfn(f)

with open(DFN_PATH / f"{dfn}.dfn", "r") as f:
definition = load_dfn(f)

context = {
"context": context_type.value,
**get_template_context(
dfn_name,
context_type.base,
common,
definition,
),
}
source = template.render(**context)
source_path = function_tmpdir / get_src_name(component, subcomponent)
source_path = function_tmpdir / dfn_name.target
with open(source_path, "w") as f:
f.write(source)
run_cmd("ruff", "format", source_path, verbose=True)


def test_generate_components(function_tmpdir):
generate_components(function_tmpdir, verbose=True)
generate_targets(DFN_PATH, function_tmpdir, verbose=True)
15 changes: 0 additions & 15 deletions autotest/test_dfn.py

This file was deleted.

2 changes: 1 addition & 1 deletion autotest/test_generate_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def test_generate_classes_from_github_refs(
out, err, ret = run_cmd(
str(python),
"-m",
"flopy.mf6.utils.generate_classes",
"flopy.mf6.generate_classes",
"--owner",
owner,
"--repo",
Expand Down
2 changes: 1 addition & 1 deletion docs/make_release.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ As described above, making a release manually involves the following steps:

- Run `python scripts/update_version.py -v <semver>` to update the version number stored in `version.txt` and `flopy/version.py`. For an approved release use the `--approve` flag.

- Update MODFLOW 6 dfn files in the repository and MODFLOW 6 package classes by running `python -m flopy.mf6.utils.generate_classes --ref master --no-backup`
- Update MODFLOW 6 dfn files in the repository and MODFLOW 6 package classes by running `python -m flopy.mf6.generate_classes --ref master --no-backup`

- Run `ruff check .` and `ruff format .` from the project root.

Expand Down
2 changes: 1 addition & 1 deletion docs/mf6_dev_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file provides an overview of how FloPy for MODFLOW 6 (FPMF6) works under th
Package Meta-Data and Package Files
-----------------------------------------------

FPMF6 uses meta-data files located in flopy/mf6/data/dfn to define the model and package types supported by MODFLOW 6. When additional model and package types are added to MODFLOW 6, additional meta-data files can be added to this folder and flopy/mf6/utils/createpackages.py can be run to add new packages to the FloPy library. createpackages.py uses flopy/mf6/data/mfstructure.py to read meta-data files (*.dfn) and use that meta-data to create the package files found in flopy/mf6/modflow (do not directly modify any of the files in this folder, they are all automatically generated). The automatically generated package files contain an interface for accessing package data and data documentation generated from the meta-data files. Additionally, meta-data describing package data types and shapes is stored in the dfn attribute. flopy/mf6/data/mfstructure.py can load structure information using the dfn attribute (instead of loading it from the meta-data files). This allows for flopy to be installed without the dfn files.
FPMF6 uses meta-data files located in flopy/mf6/data/dfn to define the model and package types supported by MODFLOW 6. When additional model and package types are added to MODFLOW 6, additional meta-data files can be added to this folder and flopy/mf6/createpackages.py can be run to add new packages to the FloPy library. createpackages.py uses flopy/mf6/data/mfstructure.py to read meta-data files (*.dfn) and use that meta-data to create the package files found in flopy/mf6/modflow (do not directly modify any of the files in this folder, they are all automatically generated). The automatically generated package files contain an interface for accessing package data and data documentation generated from the meta-data files. Additionally, meta-data describing package data types and shapes is stored in the dfn attribute. flopy/mf6/data/mfstructure.py can load structure information using the dfn attribute (instead of loading it from the meta-data files). This allows for flopy to be installed without the dfn files.

All meta-data can be accessed from the flopy.mf6.data.mfstructure.MFStructure class. This is a singleton class, meaning only one instance of this class can be created. The class contains a sim_struct attribute (which is a flopy.mf6.data.mfstructure.MFSimulationStructure object) which contains all of the meta-data for all package files. Meta-data is stored in a structured format. MFSimulationStructure contains MFModelStructure and MFInputFileStructure objects, which contain the meta-data for each model type and each "simulation-level" package (tdis, ims, ...). MFModelStructure contains model specific meta-data and a MFInputFileStructure object for each package in that model. MFInputFileStructure contains package specific meta-data and a MFBlockStructure object for each block contained in the package file. MFBlockStructure contains block specific meta-data and a MFDataStructure object for each data structure defined in the block, and MFDataStructure contains data structure specific meta-data and a MFDataItemStructure object for each data item contained in the data structure. Data structures define the structure of data that is naturally grouped together, for example, the data in a numpy recarray. Data item structures define the structure of specific pieces of data, for example, a single column of a numpy recarray. The meta-data defined in these classes provides all the information FloPy needs to read and write MODFLOW 6 package and name files, create the Flopy interface, and check the data for various constraints.

Expand Down
Loading

0 comments on commit b6005f9

Please sign in to comment.