Skip to content

Commit

Permalink
fix(SFR Package water mover setup for LGR models): apparently the mov…
Browse files Browse the repository at this point in the history
…er package file reference was not getting written to the GWFGWF Exchange file in at least some cases. Integrate GWFGWF and Mover setup; pass gwfgwf object instance to ModflowMvr constructor and add test for reference in gwfgwf file.
  • Loading branch information
aleaf committed Sep 10, 2024
1 parent c10c32d commit a9de5b4
Showing 4 changed files with 41 additions and 24 deletions.
40 changes: 22 additions & 18 deletions mfsetup/mf6model.py
Original file line number Diff line number Diff line change
@@ -479,6 +479,7 @@ def _update_top_botm_external_files(self):


def setup_lgr_exchanges(self):

for inset_name, inset_model in self.inset.items():

# update cell information for computing any bottom exchanges
@@ -511,23 +512,19 @@ def setup_lgr_exchanges(self):

# arguments to ModflowGwfgwf
kwargs = {'exgtype': 'gwf6-gwf6',
'exgmnamea': self.name,
'exgmnameb': inset_name,
'nexg': nexg,
'auxiliary': [('angldegx', 'cdist')],
'exchangedata': active_exchangelist
}
# add water mover files if there's a mover package
# not sure if one mover file can be used for multiple exchange files or not
# if separate (simulation) water mover files are needed,
# than this would have to be restructured
if 'mvr' in self.simulation.package_key_dict:
if inset_name in self.simulation.mvr.packages.array['mname']:
kwargs['mvr_filerecord'] = self.simulation.mvr.filename
'exgmnamea': self.name,
'exgmnameb': inset_name,
'nexg': nexg,
'auxiliary': [('angldegx', 'cdist')],
'exchangedata': active_exchangelist
}
kwargs = get_input_arguments(kwargs, mf6.ModflowGwfgwf)

# set up the exchange package
kwargs = get_input_arguments(kwargs, mf6.ModflowGwfgwf)
gwfe = mf6.ModflowGwfgwf(self.simulation, **kwargs)
gwfgwf = mf6.ModflowGwfgwf(self.simulation, **kwargs)

# set up a Mover Package if needed
self.setup_simulation_mover(gwfgwf)


def setup_dis(self, **kwargs):
@@ -921,11 +918,17 @@ def setup_ims(self):
print("finished in {:.2f}s\n".format(time.time() - t0))
return ims

def setup_simulation_mover(self):
def setup_simulation_mover(self, gwfgwf):
"""Set up the MODFLOW-6 water mover package at the simulation level.
Automate set-up of the mover between SFR packages in LGR parent and inset models.
todo: automate set-up of mover between SFR and lakes (within a model).
Parameters
----------
gwfgwf : Flopy :class:`~flopy.mf6.modflow.mfgwfgwf.ModflowGwfgwf` package instance
Notes
------
Other uses of the water mover need to be configured manually using flopy.
"""
package = 'mvr'
@@ -937,7 +940,8 @@ def setup_simulation_mover(self):
if self.inset is not None:
for inset_name, inset in self.inset.items():
if inset.get_package('sfr'):
inset_perioddata = get_mover_sfr_package_input(self, inset)
inset_perioddata = get_mover_sfr_package_input(
self, inset, gwfgwf.exchangedata.array)
perioddata_dfs.append(inset_perioddata)
# for each SFR reach with a connection
# to a reach in another model
@@ -977,7 +981,7 @@ def setup_simulation_mover(self):
kwargs['packages'] = list(packages)
kwargs['perioddata'] = {0: perioddata.values.tolist()} # assumes that input for period 0 applies to all periods
kwargs = get_input_arguments(kwargs, mf6.ModflowGwfmvr)
mvr = mf6.ModflowMvr(self.simulation, **kwargs)
mvr = mf6.ModflowMvr(gwfgwf, **kwargs)
print("finished in {:.2f}s\n".format(time.time() - t0))
return mvr
else:
2 changes: 0 additions & 2 deletions mfsetup/mfmodel.py
Original file line number Diff line number Diff line change
@@ -1701,7 +1701,6 @@ def setup_sfr(self, **kwargs):
observations_input['data'] = observations_input[key]
kwargs = get_input_arguments(observations_input.copy(), sfr.add_observations)
obsdata = sfr.add_observations(**kwargs)
j=2
# resample observations to model stress periods; write to table

# write reach and segment data tables
@@ -1837,7 +1836,6 @@ def setup_from_cfg(cls, cfg, verbose=False):
if v._is_lgr:
v.setup_packages()
m.setup_lgr_exchanges()
m.setup_simulation_mover()

print('finished setting up model in {:.2f}s'.format(time.time() - t0))
print('\n{}'.format(m))
14 changes: 12 additions & 2 deletions mfsetup/mover.py
Original file line number Diff line number Diff line change
@@ -153,13 +153,23 @@ def neighbors(i, j):
return parent_to_inset, inset_to_parent


def get_mover_sfr_package_input(parent, inset, convert_to_zero_based=True):
def get_mover_sfr_package_input(parent, inset, gwfgwf_exchangedata):
"""Set up the MODFLOW-6 water mover package at the simulation level.
Automate set-up of the mover between SFR packages in LGR parent and inset models.
todo: automate set-up of mover between SFR and lakes (within a model).
Parameters
----------
gwfgwf_exchangedata : flopy recarray or pandas DataFrame
Exchange data from the GWFGWF package
(listing cell connections between two groundwater flow models).
"""

grid_spacing = parent.dis.delc.array[0]
connections = []
# use 2x grid spacing for distance threshold
# because reaches could be small fragments in opposite corners of two adjacent cells
to_inset, to_parent = get_sfr_package_connections(parent.simulation.gwfgwf.exchangedata.array,
to_inset, to_parent = get_sfr_package_connections(gwfgwf_exchangedata,
parent.sfrdata.reach_data,
inset.sfrdata.reach_data,
distance_threshold=2*grid_spacing)
9 changes: 7 additions & 2 deletions mfsetup/tests/test_lgr.py
Original file line number Diff line number Diff line change
@@ -243,6 +243,11 @@ def test_setup_mover(pleasant_lgr_setup_from_yaml):
for model in m, m.inset['plsnt_lgr_inset']:
options = read_mf6_block(model.sfr.filename, 'options')
assert 'mover' in options
# verify that the mover file is referenced in the gwfgwf file
gwfgwf_file = Path(m._abs_model_ws, m.simulation.gwfgwf.filename)
with open(gwfgwf_file) as src:
contents = src.read()
assert m.simulation.mvr.filename in contents


def test_lgr_parent_bcs_in_lgr_area(pleasant_vertical_lgr_setup_from_yaml):
@@ -300,8 +305,9 @@ def test_mover_get_sfr_package_connections(pleasant_lgr_setup_from_yaml):

parent_reach_data = m.sfrdata.reach_data
inset_reach_data = inset_model.sfrdata.reach_data
gwfgwf_exchangedata = m.simulation.gwfgwf.exchangedata.array
to_inset, to_parent = get_sfr_package_connections(
m.simulation.gwfgwf.exchangedata.array,
gwfgwf_exchangedata,
parent_reach_data, inset_reach_data, distance_threshold=200)
assert len(to_inset) == 0
# verify that the last reaches in the two segments are keys
@@ -388,7 +394,6 @@ def test_meandering_sfr_connections(shellmound_cfg, project_root_path, tmpdir):
v.setup_dis()
v.setup_sfr()
gwfgwf = m.setup_lgr_exchanges()
mvr = m.setup_simulation_mover()

# just test the connections for period 0
exchangedata = pd.DataFrame(m.simulation.mvr.perioddata.array[0])

0 comments on commit a9de5b4

Please sign in to comment.