InitialCond: data copy with correct reach affectation after split

split_reach
Dylan Jeannin 2026-07-23 10:10:56 +02:00
parent 6f5743a030
commit 0c7fecb123
4 changed files with 140 additions and 0 deletions

View File

@ -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()

View File

@ -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)
)

View File

@ -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

View File

@ -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]
)