Skip to content

Commit

Permalink
fix(mover.py::get_sfr_package_connections): when two outlets are conn…
Browse files Browse the repository at this point in the history
…ected across a LGR model interface and the connection threshold distance is large, a circular or double connection going both ways between the two models may result, which can prevent the Mover Package from converging in the simulation. This issue was fixed by adding a check for double connections, and then only retaining the connection with the smallest distance (which should always be correct if the flowline input to the SFR Package was digitized correctly).
  • Loading branch information
aleaf committed Jan 3, 2025
1 parent a211059 commit 0b77526
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
32 changes: 30 additions & 2 deletions mfsetup/mover.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def neighbors(i, j):
# make the connections
parent_to_inset = dict()
inset_to_parent = dict()
# record connection distances
# for breaking circular routing cases
parent_to_inset_distances = dict()
inset_to_parent_distances = dict()
for _, r in reach_data1.iterrows():
# check for connections to the other model
# if the next reach is in another cell
Expand All @@ -120,9 +124,11 @@ def neighbors(i, j):
# consider this each to be an outlet
reach_end = Point(r['geometry'].coords[-1])
distances = reach_end.distance(reach_data2['reach_start'])
if np.min(distances) < distance_threshold:
min_distance = np.min(distances)
if min_distance < distance_threshold:
next_reach = reach_data2.iloc[np.argmin(distances)]
parent_to_inset[r['rno']] = next_reach['rno']
parent_to_inset_distances[r['rno']] = min_distance
# next reach is somewhere else in the parent model
else:
continue
Expand All @@ -144,12 +150,34 @@ def neighbors(i, j):
# consider this each to be an outlet
reach_end = Point(r['geometry'].coords[-1])
distances = reach_end.distance(reach_data1['reach_start'])
if np.min(distances) < distance_threshold:
min_distance = np.min(distances)
if min_distance < distance_threshold:
next_reach = reach_data1.iloc[np.argmin(distances)]
inset_to_parent[r['rno']] = next_reach['rno']
inset_to_parent_distances[r['rno']] = min_distance
# next reach is somewhere else in this model
else:
continue
# check for circular connections (going both ways between two models)
# retain connection with the smallest distance
delete_parent_to_inset_items = set()
for parent_reach, inset_reach in parent_to_inset.items():
if parent_reach in inset_to_parent.values():
parent_to_inset_distance = parent_to_inset_distances[parent_reach]
inset_to_parent_distance = inset_to_parent_distances[inset_reach]
if inset_to_parent_distance < parent_to_inset_distance:
delete_parent_to_inset_items.add(parent_reach)
elif parent_to_inset_distance < inset_to_parent_distance:
del inset_to_parent[inset_reach]
else:
raise ValueError("Circular connection between SFR Packages in the Mover Package input.\n"
f"Connection distance between the end of parent reach {parent_reach} "
f"in parent model and start of inset reach {inset_reach} in inset model "
f"is equal to\nthe distance between the end of inset reach {inset_reach} "
f"and start of parent reach {parent_reach}.\nCheck input linework."
)
for parent_reach in delete_parent_to_inset_items:
del parent_to_inset[parent_reach]
return parent_to_inset, inset_to_parent


Expand Down
8 changes: 8 additions & 0 deletions mfsetup/tests/test_lgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,14 @@ def test_mover_get_sfr_package_connections(pleasant_lgr_setup_from_yaml):
# {inset_reach: parent_reach, ...}
assert to_parent == {29: 13, 41: 1}

# test for no circular connections when two outlets are connected
# and distance_threshold is large
parent_reach_data.loc[parent_reach_data['rno'] == list(to_parent.values())[0], 'outreach'] = 0
to_inset, to_parent = get_sfr_package_connections(
gwfgwf_exchangedata,
parent_reach_data, inset_reach_data, distance_threshold=1e4)
assert not any(to_inset)


def test_meandering_sfr_connections(shellmound_cfg, project_root_path, tmpdir):
"""Test for SFR routing continuity in LGR cases
Expand Down
4 changes: 4 additions & 0 deletions mfsetup/tests/test_mover.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""Test functions in the mover.py module. See test_lgr.py for
a test of the test_mover_get_sfr_package_connections function.
"""
from copy import deepcopy

import pytest
Expand Down

0 comments on commit 0b77526

Please sign in to comment.