Skip to content

Commit 7740165

Browse files
authored
ic and oc looking better. several fixes. (#143)
1 parent ca25f69 commit 7740165

File tree

5 files changed

+62
-46
lines changed

5 files changed

+62
-46
lines changed

flopy4/mf6/codec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
lstrip_blocks=True,
1414
)
1515
JINJA_ENV.filters["blocks"] = filters.blocks
16-
JINJA_ENV.filters["field_kind"] = filters.field_type
16+
JINJA_ENV.filters["field_type"] = filters.field_type
1717
JINJA_ENV.filters["field_value"] = filters.field_value
1818
JINJA_ENV.filters["array_delay"] = filters.array_delay
1919
JINJA_ENV.filters["array2string"] = filters.array2string

flopy4/mf6/filters.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,20 @@
66
from modflow_devtools.dfn import Dfn, Field
77
from numpy.typing import NDArray
88

9+
from flopy4.mf6.spec import block_sort_key
10+
911

1012
def blocks(dfn: Dfn) -> dict:
11-
return {k: v for k, v in dfn.items() if k not in Dfn.__annotations__}
13+
"""
14+
Get blocks from an MF6 input definition. Anything not an
15+
explicitly defined key in the `Dfn` typed dict is a block.
16+
"""
17+
return dict(
18+
sorted(
19+
{k: v for k, v in dfn.items() if k not in Dfn.__annotations__}.items(),
20+
key=block_sort_key,
21+
)
22+
)
1223

1324

1425
def field_type(field: Field) -> str:
@@ -25,17 +36,26 @@ def field_value(ctx, field: Field):
2536
return getattr(ctx["data"], field["name"])
2637

2738

28-
def array_delay(value: xr.DataArray):
29-
"""Yield chunks (lines) from a Dask array."""
30-
# TODO: Determine a good chunk size,
31-
# because if the underlying array is only numpy, it will stay one block.
32-
for chunk in value.chunk():
39+
def array_delay(value: xr.DataArray, chunks=None):
40+
"""
41+
Yield chunks from an array. Each chunk becomes a line in the file.
42+
If the array is not already chunked, it is chunked using the given
43+
chunk size. If no chunk size is provided, the entire array becomes
44+
a single chunk.
45+
"""
46+
if value.chunks is None:
47+
chunk_shape = chunks or {dim: size for dim, size in zip(value.dims, value.shape)}
48+
value = value.chunk(chunk_shape)
49+
for chunk in value.data.blocks:
3350
yield chunk.compute()
3451

3552

3653
def array2string(value: NDArray) -> str:
3754
"""Convert an array to a string."""
38-
return np.array2string(value, separator=" ")[1:-1] # remove brackets
55+
s = np.array2string(value, separator=" ")
56+
if value.shape != ():
57+
s = s[1:-1] # remove brackets
58+
return s.replace("'", "").replace('"', "") # remove quotes
3959

4060

4161
def is_dict(value: Any) -> bool:

flopy4/mf6/spec.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def array(
119119
Block = dict[str, Attribute]
120120

121121

122-
def _block_sort_key(item) -> int:
122+
def block_sort_key(item: tuple[str, dict]) -> int:
123123
k, _ = item
124124
if k == "options":
125125
return 0
@@ -153,7 +153,7 @@ def blocks_dict(cls) -> dict[str, Block]:
153153
if block not in blocks:
154154
blocks[block] = {}
155155
blocks[block][k] = v
156-
return dict(sorted(blocks.items(), key=_block_sort_key))
156+
return dict(sorted(blocks.items(), key=block_sort_key))
157157

158158

159159
def fields(cls) -> list[Attribute]:

flopy4/mf6/templates/blocks.jinja

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{% import 'macros.jinja' as macros with context %}
22
{% for block_name, block_ in (dfn|blocks).items() %}
33
BEGIN {{ block_name }}
4-
{% for field in block_.values() %}
4+
{% for field in block_.values() -%}
55
{{ macros.field(field) }}
6-
{% endfor %}
6+
{%- endfor %}
77
END {{ block_name }}
8+
89
{% endfor %}

flopy4/mf6/templates/macros.jinja

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,54 @@
11
{% macro field(field) %}
2-
{% set kind = field|field_kind %}
3-
{% if kind == 'attr' %}
4-
{% if field.type|is_dict %}{{ record(field) }}{% else %}{{ scalar(field) }}
5-
{% endif %}
6-
{% elif kind in ['array', 'coord'] %}
7-
{{ array(field) }}
8-
{% elif kind == 'dim' %}
2+
{% set type = field|field_type %}
3+
{% if type in ['keyword', 'integer', 'double precision', 'string'] %}
94
{{ scalar(field) }}
10-
{% elif kind == 'child' %}
11-
{# TODO #}
12-
{% endif -%}
13-
{%- endmacro %}
5+
{% elif type == 'record' %}
6+
{{ record(field) }}
7+
{% elif type == 'keystring' %}
8+
{{ keystring(field) }}
9+
{% elif type == 'recarray' %}
10+
{{ recarray(field) }}
11+
{% endif %}
12+
{% endmacro %}
1413

15-
{% macro scalar(field) -%}
14+
{% macro scalar(field) %}
1615
{% set value = field|field_value %}
1716
{% if value is not none %}{{ field.name }} {{ value }}{% endif %}
18-
{%- endmacro %}
17+
{% endmacro %}
1918

20-
{% macro keystring(field) %} {# union #}
21-
{% for item in (field|field_value).items() %}
19+
{% macro keystring(field) %}
20+
{% for item in (field|field_value).values() -%}
2221
{{ field(item) }}
23-
{% endfor %}
24-
{%- endmacro %}
22+
{%- endfor %}
23+
{% endmacro %}
2524

2625
{% macro record(field) %}
27-
{% for item in field|field_value %}
28-
{% if item.tagged %}{{ item.name }} {% endif %}{{ field(field) }}
29-
{% endfor %}
30-
{%- endmacro %}
26+
{% for item in (field|field_value).values() -%}
27+
{% if item.tagged %}{{ item.name }} {% endif %}{{ field(item) }}
28+
{%- endfor %}
29+
{% endmacro %}
3130

32-
{% macro array(field, how="internal") %}
31+
{% macro recarray(field, how="internal") %}
3332
{% if how == "layered constant" %}
3433
{{ field.name }} LAYERED
3534
{% for val in field|field_value %}
3635
CONSTANT
3736
{% endfor %}
38-
{% elif how == "constant" %}
37+
{%- elif how == "constant" %}
3938
{{ field.name }} CONSTANT {{ field|field_value }}
40-
{% elif how == "layered" %}
39+
{%- elif how == "layered" %}
4140
{% if layered %}
4241
{{ field.name }}{% for val in field|field_value %} {{ val }}{% endfor %}
4342
{% endif %}
44-
{% elif how == "internal" %}
43+
{%- elif how == "internal" %}
4544
{{ field.name }} {{ internal_array(field) }}
46-
{% elif how == "external" %}
45+
{%- elif how == "external" %}
4746
{{ field.name}} OPEN/CLOSE {{ field|field_value }}
4847
{% endif %}
49-
{%- endmacro %}
48+
{% endmacro %}
5049

5150
{% macro internal_array(field) %}
52-
{% for chunk in field|field_value|array_delay %}
51+
{% for chunk in field|field_value|array_delay -%}
5352
{{ chunk|array2string }}
54-
{% endfor %}
55-
{%- endmacro %}
56-
57-
{% macro list(field) %}
58-
{# TODO #}
59-
{%- endmacro %}
53+
{%- endfor %}
54+
{% endmacro %}

0 commit comments

Comments
 (0)