Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Issue #765 gwt gwt exchanges #800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
10a8555
Merge branch 'master' into issue_#764_modelsplit_auxiliary_variables
luitjansl Jan 23, 2024
fdade86
work started
luitjansl Jan 24, 2024
fb61e4d
now works with well
luitjansl Jan 24, 2024
c70e696
formatting
luitjansl Jan 24, 2024
2193d3c
formatting
luitjansl Jan 24, 2024
bf3d5f2
Merge branch 'master' into issue_#764_modelsplit_auxiliary_variables
luitjansl Jan 24, 2024
feef11a
formatting and fixing tests
luitjansl Jan 24, 2024
385f312
expanded test
luitjansl Jan 24, 2024
707aad8
formatting
luitjansl Jan 24, 2024
1327e0f
ruff checks
luitjansl Jan 25, 2024
70df416
review comments
luitjansl Jan 25, 2024
40e4f7a
review comments
luitjansl Jan 25, 2024
4bd7f4b
formatting
luitjansl Jan 25, 2024
fb9d94e
Merge branch 'master' into issue_#764_modelsplit_auxiliary_variables
luitjansl Jan 25, 2024
0827789
review comments
luitjansl Jan 25, 2024
2ebe1e5
Merge branch 'imod_#746_slice_model_transport' into issue_#765_add_gw…
luitjansl Jan 26, 2024
f2731dc
started adding test
luitjansl Jan 26, 2024
f6d3892
Merge branch 'imod_#746_slice_model_transport' into issue_#765_add_gw…
luitjansl Jan 26, 2024
f5f682a
started adding test
luitjansl Jan 26, 2024
accc041
Merge branch 'issue_#764_modelsplit_auxiliary_variables' into issue_#…
luitjansl Jan 26, 2024
48fcb58
split method now doesn't crash on transport model
luitjansl Jan 26, 2024
866f6a2
adding package and template for gwtgwt
luitjansl Jan 26, 2024
b007ada
work in progress
luitjansl Jan 29, 2024
855bb05
Merge branch 'master' into issue_#765_add_gwtgwt
luitjansl Jan 29, 2024
3f43218
Merge branch 'master' into issue_#765_add_gwtgwt
luitjansl Jan 29, 2024
9bfa03e
work in progress
luitjansl Jan 29, 2024
ed98bd7
Merge branch 'imod_#746_slice_model_transport' into model_splitting_t…
luitjansl Jan 29, 2024
b86aea7
Merge branch 'model_splitting_transport_feature' into issue_#765_add_…
luitjansl Jan 29, 2024
eef6081
adding gwfgwt packages
luitjansl Jan 29, 2024
b024376
Merge branch 'issue_#765_add_gwtgwt' into issue_#788_gwf-gwt_exchanges
luitjansl Jan 29, 2024
b64b59b
fixed tests
luitjansl Jan 30, 2024
a4743e0
now can write the model
luitjansl Jan 30, 2024
32455cc
adding tests
luitjansl Jan 30, 2024
bfce7a9
formatting
luitjansl Jan 30, 2024
7b3ebef
cleanup
luitjansl Jan 30, 2024
3bb9a2c
type hints
luitjansl Jan 30, 2024
61e0091
Merge branch 'model_splitting_transport_feature' into issue_#788_gwf-…
luitjansl Jan 30, 2024
ff13c9f
cleanup
luitjansl Jan 30, 2024
bbdfb23
cleanup
luitjansl Jan 30, 2024
1028866
Merge branch 'issue_#788_gwf-gwt_exchanges' into issue_#765_gwt_gwt_e…
luitjansl Jan 31, 2024
6267c03
Update imod/tests/test_mf6/test_mf6_simulation.py
luitjansl Jan 31, 2024
580ed42
started work
luitjansl Jan 31, 2024
7b20d02
Update imod/mf6/simulation.py
luitjansl Jan 31, 2024
74b1b6f
review comment
luitjansl Jan 31, 2024
18f2998
review comment
luitjansl Jan 31, 2024
c92df59
skips gwfgwt exchanges when setting options
luitjansl Jan 31, 2024
a6cbd18
Merge branch 'issue_#788_gwf-gwt_exchanges' into issue_#765_gwt_gwt_e…
luitjansl Jan 31, 2024
2410958
first model runs
luitjansl Jan 31, 2024
8ae078c
added test for output check
luitjansl Feb 1, 2024
10bcc8c
formatting
luitjansl Feb 1, 2024
929a17c
Merge branch 'model_splitting_transport_feature' into issue_#765_gwt_…
luitjansl Feb 1, 2024
616802e
Merge branch 'model_splitting_transport_feature' into issue_#765_gwt_…
luitjansl Feb 1, 2024
41dc3bf
fix build error
luitjansl Feb 1, 2024
181d7d8
function for geometric dataframe
luitjansl Feb 1, 2024
74ba292
type hints
luitjansl Feb 1, 2024
df50f22
cleanup
luitjansl Feb 1, 2024
9410c30
Update imod/mf6/gwtgwt.py
luitjansl Feb 2, 2024
3481c6d
review comments
luitjansl Feb 2, 2024
5139fff
Update imod/mf6/simulation.py
luitjansl Feb 2, 2024
4f17342
review comments
luitjansl Feb 2, 2024
e3cfe8d
fix failing tests
luitjansl Feb 2, 2024
d3021a1
Merge branch 'model_splitting_transport_feature' into issue_#765_gwt_…
luitjansl Feb 5, 2024
71d55e4
cleanup
luitjansl Feb 5, 2024
2df1dc5
formatting
luitjansl Feb 5, 2024
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
2 changes: 1 addition & 1 deletion imod/mf6/exchangebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from imod.mf6.package import Package

_pkg_id_to_type = {"gwfgwf": "GWF6-GWF6", "gwfgwt": "GWF6-GWT6"}
_pkg_id_to_type = {"gwfgwf": "GWF6-GWF6", "gwfgwt": "GWF6-GWT6", "gwtgwt": "GWT6-GWT6"}


class ExchangeBase(Package):
Expand Down
92 changes: 92 additions & 0 deletions imod/mf6/gwtgwt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from typing import Optional

import cftime
import numpy as np
import xarray as xr

from imod.mf6.auxiliary_variables import expand_transient_auxiliary_variables
from imod.mf6.exchangebase import ExchangeBase
from imod.mf6.package import Package
from imod.typing import GridDataArray


class GWTGWT(ExchangeBase):
"""
This package is for writing an exchange file, used for splitting up a model
into different submodels (that can be solved in parallel). It (usually)
is not instantiated by users, but created by the "split" method of the
simulation class.
"""

_auxiliary_data = {"auxiliary_data": "variable"}
_pkg_id = "gwtgwt"
_template = Package._initialize_template(_pkg_id)

def __init__(
self,
transport_model_id1: str,
transport_model_id2: str,
flow_model_id1: str,
flow_model_id2: str,
cell_id1: xr.DataArray,
cell_id2: xr.DataArray,
layer: xr.DataArray,
cl1: xr.DataArray,
cl2: xr.DataArray,
hwva: xr.DataArray,
angldegx: Optional[xr.DataArray] = None,
cdist: Optional[xr.DataArray] = None,
):
dict_dataset = {
"cell_id1": cell_id1,
"cell_id2": cell_id2,
"layer": layer,
"model_name_1": transport_model_id1,
"model_name_2": transport_model_id2,
"flow_model_name_1": flow_model_id1,
"flow_model_name_2": flow_model_id2,
"ihc": xr.DataArray(np.ones_like(cl1, dtype=int)),
"cl1": cl1,
"cl2": cl2,
"hwva": hwva,
}
super().__init__(dict_dataset)

auxiliary_variables = [var for var in [angldegx, cdist] if var is not None]
if auxiliary_variables:
self.dataset["auxiliary_data"] = xr.merge(auxiliary_variables).to_array(
name="auxiliary_data"
)
expand_transient_auxiliary_variables(self)

def set_options(
self,
print_input: Optional[bool] = None,
print_flows: Optional[bool] = None,
save_flows: Optional[bool] = None,
adv_scheme: Optional[str] = None,
dsp_xt3d_off: Optional[bool] = None,
dsp_xt3d_rhs: Optional[bool] = None,
):
self.dataset["print_input"] = print_input
self.dataset["print_flows"] = print_flows
self.dataset["save_flows"] = save_flows
self.dataset["adv_scheme"] = adv_scheme
self.dataset["dsp_xt3d_off"] = dsp_xt3d_off
self.dataset["dsp_xt3d_rhs"] = dsp_xt3d_rhs

def clip_box(
self,
time_min: Optional[cftime.datetime | np.datetime64 | str] = None,
time_max: Optional[cftime.datetime | np.datetime64 | str] = None,
layer_min: Optional[int] = None,
layer_max: Optional[int] = None,
x_min: Optional[float] = None,
x_max: Optional[float] = None,
y_min: Optional[float] = None,
y_max: Optional[float] = None,
top: Optional[GridDataArray] = None,
bottom: Optional[GridDataArray] = None,
state_for_boundary: Optional[GridDataArray] = None,
) -> Package:
raise NotImplementedError("this package cannot be clipped")
110 changes: 77 additions & 33 deletions imod/mf6/multimodel/exchange_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import xarray as xr

from imod.mf6.gwfgwf import GWFGWF
from imod.mf6.gwtgwt import GWTGWT
from imod.mf6.multimodel.modelsplitter import PartitionInfo
from imod.mf6.utilities.grid import get_active_domain_slice, to_cell_idx
from imod.typing import GridDataArray
Expand Down Expand Up @@ -144,50 +145,93 @@ def create_gwfgwf_exchanges(
for model_id2, connected_domain_pair in grouped_connected_models.groupby(
"cell_label2"
):
model_id1 = int(model_id1)
model_id2 = int(model_id2)
mapping1 = (
self._global_to_local_mapping[model_id1]
.drop(columns=["local_idx"])
.rename(
columns={"global_idx": "cell_idx1", "local_cell_id": "cell_id1"}
connected_cells_dataset = (
self._collect_geometric_constants_connected_cells(
model_id1, model_id2, connected_domain_pair, layers
)
)

mapping2 = (
self._global_to_local_mapping[model_id2]
.drop(columns=["local_idx"])
.rename(
columns={"global_idx": "cell_idx2", "local_cell_id": "cell_id2"}
exchanges.append(
GWFGWF(
f"{model_name}_{model_id1}",
f"{model_name}_{model_id2}",
**connected_cells_dataset,
)
)

connected_cells = (
connected_domain_pair.merge(mapping1)
.merge(mapping2)
.filter(
[
"cell_id1",
"cell_id2",
"cl1",
"cl2",
"hwva",
"angldegx",
"cdist",
]
)
)
return exchanges

def _collect_geometric_constants_connected_cells(
self,
model_id1: int,
model_id2: int,
connected_domain_pair: pd.DataFrame,
layers: GridDataArray,
) -> xr.Dataset:
mapping1 = (
self._global_to_local_mapping[model_id1]
.drop(columns=["local_idx"])
.rename(columns={"global_idx": "cell_idx1", "local_cell_id": "cell_id1"})
)

mapping2 = (
self._global_to_local_mapping[model_id2]
.drop(columns=["local_idx"])
.rename(columns={"global_idx": "cell_idx2", "local_cell_id": "cell_id2"})
)

connected_cells = pd.merge(layers, connected_cells, how="cross")
connected_cells = (
connected_domain_pair.merge(mapping1)
.merge(mapping2)
.filter(
[
"cell_id1",
"cell_id2",
"cl1",
"cl2",
"hwva",
"angldegx",
"cdist",
]
)
)

connected_cells_dataset = self._to_xarray(connected_cells)
connected_cells = pd.merge(layers, connected_cells, how="cross")

_adjust_gridblock_indexing(connected_cells_dataset)
connected_cells_dataset = self._to_xarray(connected_cells)

_adjust_gridblock_indexing(connected_cells_dataset)

return connected_cells_dataset

def create_gwtgwt_exchanges(
self, transport_model_name: str, flow_model_name: str, layers: GridDataArray
) -> list[GWTGWT]:
layers = layers.to_dataframe().filter(["layer"])

connected_cells_with_geometric_info = pd.merge(
self._connected_cells, self._geometric_information
)

exchanges = []
for (
model_id1,
grouped_connected_models,
) in connected_cells_with_geometric_info.groupby("cell_label1"):
for model_id2, connected_domain_pair in grouped_connected_models.groupby(
"cell_label2"
):
connected_cells_dataset = (
self._collect_geometric_constants_connected_cells(
model_id1, model_id2, connected_domain_pair, layers
)
)
exchanges.append(
GWFGWF(
f"{model_name}_{model_id1}",
f"{model_name}_{model_id2}",
GWTGWT(
f"{transport_model_name}_{model_id1}",
f"{transport_model_name}_{model_id2}",
f"{flow_model_name}_{model_id1}",
f"{flow_model_name}_{model_id2}",
**connected_cells_dataset,
)
)
Expand Down
2 changes: 1 addition & 1 deletion imod/mf6/pkgbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from imod.typing.grid import GridDataArray, GridDataset, merge_with_dictionary

TRANSPORT_PACKAGES = ("adv", "dsp", "ssm", "mst", "ist", "src")
EXCHANGE_PACKAGES = ("gwfgwf", "gwfgwt")
EXCHANGE_PACKAGES = ("gwfgwf", "gwfgwt", "gwtgwt")


class PackageBase(IPackageBase, abc.ABC):
Expand Down
29 changes: 23 additions & 6 deletions imod/mf6/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import imod.mf6.exchangebase
from imod.mf6.gwfgwf import GWFGWF
from imod.mf6.gwfgwt import GWFGWT
from imod.mf6.gwtgwt import GWTGWT
from imod.mf6.ims import Solution
from imod.mf6.model import Modflow6Model
from imod.mf6.model_gwf import GroundwaterFlowModel
Expand Down Expand Up @@ -822,7 +823,6 @@ def get_exchange_relationships(self):
if is_split(self):
for exchange in self["split_exchanges"]:
result.append(exchange.get_specification())

return result

def get_models_of_type(self, modeltype):
Expand Down Expand Up @@ -912,6 +912,16 @@ def split(self, submodel_labels: xr.DataArray) -> Modflow6Simulation:
"Unable to split simulation. Splitting can only be done on simulations that haven't been split."
)

flow_models = self.get_models_of_type("gwf6")
transport_models = self.get_models_of_type("gwt6")
if any(transport_models) and len(flow_models) != 1:
raise ValueError(
"splitting of simulations with more (or less) than 1 flow model currently not supported, if a transport model is present"
)

if not any(flow_models) and not any(transport_models):
raise ValueError("a simulation without any models cannot be split.")

original_models = get_models(self)
original_packages = get_packages(self)

Expand Down Expand Up @@ -941,12 +951,16 @@ def split(self, submodel_labels: xr.DataArray) -> Modflow6Simulation:
new_simulation[solution_name].add_model_to_solution(new_model_name)

exchanges = []
for model_name, model in original_models.items():
if isinstance(model, GroundwaterFlowModel):
exchanges += exchange_creator.create_gwfgwf_exchanges(
model_name, model.domain.layer
)

for flow_model_name, flow_model in flow_models.items():
exchanges += exchange_creator.create_gwfgwf_exchanges(
flow_model_name, flow_model.domain.layer
)
if any(transport_models):
for tpt_model_name in transport_models:
exchanges += exchange_creator.create_gwtgwt_exchanges(
tpt_model_name, flow_model_name, model.domain.layer
)
new_simulation._add_modelsplit_exchanges(exchanges)
new_simulation._set_exchange_options()

Expand Down Expand Up @@ -1014,6 +1028,9 @@ def _set_exchange_options(self):
xt3d=model_1["npf"].get_xt3d_option(),
newton=model_1.is_use_newton(),
)
elif isinstance(exchange, GWTGWT):
# TODO: issue #747
continue

def _filter_inactive_cells_from_exchanges(self) -> None:
for ex in self["split_exchanges"]:
Expand Down
37 changes: 37 additions & 0 deletions imod/templates/mf6/exg-gwtgwt.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# this file contains the exchanges from model {{model_name_1}} to model {{model_name_2}}

begin options
gwfmodelname1 {{flow_model_name_1}}
gwfmodelname2 {{flow_model_name_2}}
{% if auxiliary is defined %} auxiliary {{auxiliary|join(" ")}}
{% endif -%}
{%- if print_input is defined -%} print_input
{% endif -%}
{%- if print_flows is defined -%} print_flows
{% endif -%}
{%- if save_flows is defined -%} save_flows
{% endif -%}
{%- if adv_scheme is defined -%} adv_scheme {{adv_scheme}}
{% endif -%}
{%- if dsp_xt3d_off is defined -%} dsp_xt3d_off
{% endif -%}
{%- if dsp_xt3d_rhs is defined -%} dsp_xt3d_rhs
{% endif -%}
{%- if mvt is defined -%} mvt6 filein {{mvt}}
{% endif -%}
{%- if obs is defined -%} obs6 filein {{obs}}
{% endif -%}
end options
{% set nexg = layer | length %}
begin dimensions
nexg {{nexg}}
end dimensions

begin exchangedata
# first 3 (structured) or 2 (unstructured) columns are the exchange boundary cell indices in the numbering local to {{model_name_1}}
# second 3 (structured) or 2 (unstructured) columns are the exchange boundary cell indices in the numbering local to {{model_name_2}}
# followed by columns ihc, cl1, cl2, hwva and auxiliary variables, if any
{%- for i in range(nexg) %}
{{layer[i]}} {{cell_id1[i]|join(" ")}} {{layer[i]}} {{cell_id2[i]|join(" ")}} {{ihc[i]}} {{cl1[i]}} {{cl2[i]}} {{hwva[i]}} {%- if auxiliary_data is defined %} {{auxiliary_data.T[i]|join(" ")}}{% endif %}
{%- endfor %}
end exchangedata
10 changes: 5 additions & 5 deletions imod/tests/fixtures/flow_transport_simulation_fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,16 @@ def flow_transport_simulation():
print_option="summary",
csv_output=False,
no_ptc=True,
outer_dvclose=1.0e-4,
outer_dvclose=1.0e-6,
outer_maximum=500,
under_relaxation=None,
inner_dvclose=1.0e-4,
inner_rclose=0.001,
inner_maximum=100,
inner_dvclose=1.0e-6,
inner_rclose=0.0001,
inner_maximum=200,
linear_acceleration="bicgstab",
scaling_method=None,
reordering_method=None,
relaxation_factor=0.97,
relaxation_factor=0.9,
)

duration = pd.to_timedelta("2000d")
Expand Down
Loading