diff --git a/src/Model/InitialConditions/InitialConditions.py b/src/Model/InitialConditions/InitialConditions.py index c295e24e..d0ca7160 100644 --- a/src/Model/InitialConditions/InitialConditions.py +++ b/src/Model/InitialConditions/InitialConditions.py @@ -256,6 +256,17 @@ class Data(SQLSubModel): ) return new + def cloned_for(self, reach, section): + return Data( + name=self._name, + comment=self._comment, + section=section, + discharge=self._discharge, + height=self._height, + reach=reach, + status=self._status, + ) + @property def name(self): return self._name @@ -505,6 +516,20 @@ class InitialConditions(SQLSubModel): for data in self._data: data.set_as_deleted() + def _splited_for(self, reach, sections): + new = InitialConditions(reach=reach, status=self._status) + + new._data = [ + data.cloned_for(reach, sections[data["section"]]) + for data in self.data + if data["section"] in sections + ] + + if len(new._data) != 0: + new.modified() + + return new + def generate_growing_constant_depth(self, height: float, compute_discharge: bool): profiles = self._reach.reach.profiles.copy() diff --git a/src/Model/InitialConditions/InitialConditionsDict.py b/src/Model/InitialConditions/InitialConditionsDict.py index 15403e90..5d66fc8d 100644 --- a/src/Model/InitialConditions/InitialConditionsDict.py +++ b/src/Model/InitialConditions/InitialConditionsDict.py @@ -88,3 +88,28 @@ class InitialConditionsDict(PamhyrModelDict): new = InitialConditions(reach=reach, status=self._status) self.set(reach, new) return new + + def split_reach(self, reach, profile, reach1, reach2): + if reach not in self._dict: + return + + profiles = reach.reach.profiles + split_index = profiles.index(profile) + + sections1 = dict(zip( + profiles[:split_index + 1], + reach1.reach.profiles + )) + sections2 = dict(zip( + profiles[split_index:], + reach2.reach.profiles + )) + + self.set( + reach1, + self._dict[reach]._splited_for(reach1, sections1) + ) + self.set( + reach2, + self._dict[reach]._splited_for(reach2, sections2) + ) diff --git a/src/Model/River.py b/src/Model/River.py index 882a844f..0e29be45 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -979,4 +979,8 @@ Last export at: @date.""" self._add_edge(r1) self._add_edge(r2) + self._initial_conditions.split_reach( + reach, profile, r1, r2 + ) + return r1, r2 diff --git a/src/Model/test_Model.py b/src/Model/test_Model.py index f09cbc8f..56a7728f 100644 --- a/src/Model/test_Model.py +++ b/src/Model/test_Model.py @@ -287,3 +287,89 @@ class RiverTestCase(unittest.TestCase): edges = river.edges() self.assertEqual(edges[0], e0) self.assertEqual(edges[1], e1) + + def test_split_reach_splits_initial_conditions(self): + status = StudyStatus() + river = River(status=status) + node1 = river.add_node() + node2 = river.add_node(x=40.0) + reach = river.add_edge(node1, node2) + + profiles = [] + for index in range(5): + profile = reach.reach.insert(index) + profile.rk = index * 10.0 + profile.insert(0) + profiles.append(profile) + + initial_conditions = river.initial_conditions.get(reach) + for index, profile in enumerate(profiles): + data = initial_conditions.new_from_data( + profile.rk, + discharge=100.0 + index, + elevation=10.0 + index, + ) + initial_conditions.insert(index, data) + + reach1, reach2 = river._split_reach(reach, profiles[2]) + conditions1 = river.initial_conditions.get(reach1).data + conditions2 = river.initial_conditions.get(reach2).data + + self.assertEqual( + [data["discharge"] for data in conditions1], + [100.0, 101.0, 102.0] + ) + self.assertEqual( + [data["discharge"] for data in conditions2], + [102.0, 103.0, 104.0] + ) + self.assertEqual( + [data["section"] for data in conditions1], + reach1.reach.profiles + ) + self.assertEqual( + [data["section"] for data in conditions2], + reach2.reach.profiles + ) + self.assertTrue(all( + data._reach is reach1 for data in conditions1 + )) + self.assertTrue(all( + data._reach is reach2 for data in conditions2 + )) + + def test_split_reach_keeps_partial_initial_conditions_in_scope(self): + status = StudyStatus() + river = River(status=status) + node1 = river.add_node() + node2 = river.add_node(x=40.0) + reach = river.add_edge(node1, node2) + + profiles = [] + for index in range(5): + profile = reach.reach.insert(index) + profile.rk = index * 10.0 + profile.insert(0) + profiles.append(profile) + + initial_conditions = river.initial_conditions.get(reach) + for index in (1, 3): + data = initial_conditions.new_from_data( + profiles[index].rk, + discharge=100.0 + index, + elevation=10.0 + index, + ) + initial_conditions.insert(len(initial_conditions.data), data) + + reach1, reach2 = river._split_reach(reach, profiles[2]) + + self.assertEqual( + [data["discharge"] + for data in river.initial_conditions.get(reach1).data], + [101.0] + ) + self.assertEqual( + [data["discharge"] + for data in river.initial_conditions.get(reach2).data], + [103.0] + )