Skip to content
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

fix(mover.py::get_sfr_package_connections): circular SFR Mover connections edge case #104

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading