Geometry: ProfileXYZ: Minor optimisation of computation.

opt-result
Pierre-Antoine 2026-07-02 14:56:40 +02:00
parent a61d130baa
commit 1adf24ce77
1 changed files with 37 additions and 30 deletions

View File

@ -875,7 +875,9 @@ class ProfileXYZ(Profile, SQLSubModel):
if z in self._get_water_limits_cache: if z in self._get_water_limits_cache:
return self._get_water_limits_cache[z] return self._get_water_limits_cache[z]
return self.get_water_limits_compute(z) v = self.get_water_limits_compute(z)
return v
def get_water_limits_compute(self, z): def get_water_limits_compute(self, z):
""" """
@ -883,54 +885,59 @@ class ProfileXYZ(Profile, SQLSubModel):
""" """
# Get the index of first point with elevation lesser than water # Get the index of first point with elevation lesser than water
# elevation (for the right and left river side) # elevation (for the right and left river side)
i_left = -1 i_left = next(
i_right = -1 filter(
lambda i: self.point(i).z <= z,
range(self.number_points)
),
-1
)
for i in range(self.number_points): i_right = next(
if self.point(i).z <= z: filter(
i_left = i lambda i: self.point(i).z <= z,
break reversed(range(self.number_points))
),
for i in reversed(range(self.number_points)): -1
if self.point(i).z <= z: )
i_right = i
break
# Interpolate points at river left side # Interpolate points at river left side
if (i_left > 0): if (i_left > 0):
if abs(self.point(i_left - 1).z - self.point(i_left).z) < 1e-20: pi = self.point(i_left)
pt_left = self.point(i_left) pim1 = self.point(i_left - 1)
if abs(pim1.z - pi.z) < 1e-20:
pt_left = pi
else: else:
fact = (z - self.point(i_left).z) / \ fact = (z - pi.z) / (pim1.z - pi.z)
(self.point(i_left - 1).z - self.point(i_left).z) x = pi.x + fact * (pim1.x - pi.x)
x = self.point(i_left).x + fact * \ y = pi.y + fact * (pim1.y - pi.y)
(self.point(i_left - 1).x - self.point(i_left).x)
y = self.point(i_left).y + fact * \
(self.point(i_left - 1).y - self.point(i_left).y)
pt_left = PointXYZ(x=x, y=y, z=z, name="wl_left") pt_left = PointXYZ(x=x, y=y, z=z, name="wl_left")
else: else:
pt_left = self.point(0) pt_left = self.point(0)
# Interpolate points at river right side # Interpolate points at river right side
if (i_right < self.number_points - 1): if (i_right < self.number_points - 1):
if abs(self.point(i_right + 1).z - self.point(i_right).z) < 1e-20: pi = self.point(i_right)
pt_right = self.point(i_right) pip1 = self.point(i_right + 1)
if abs(pip1.z - pi.z) < 1e-20:
pt_right = pi
else: else:
fact = (z - self.point(i_right).z) / \ fact = (z - pi.z) / (pip1.z - pi.z)
(self.point(i_right + 1).z - self.point(i_right).z) x = pi.x + fact * (pip1.x - pi.x)
x = self.point(i_right).x + fact * \ y = pi.y + fact * (pip1.y - pi.y)
(self.point(i_right + 1).x - self.point(i_right).x)
y = self.point(i_right).y + fact * \
(self.point(i_right + 1).y - self.point(i_right).y)
pt_right = PointXYZ(x=x, y=y, z=z, name="wl_right") pt_right = PointXYZ(x=x, y=y, z=z, name="wl_right")
else: else:
pt_right = self.point(self.number_points - 1) pt_right = self.point(self.number_points - 1)
v = (pt_left, pt_right)
# Put results in cache # Put results in cache
self._get_water_limits_cache[z] = (pt_left, pt_right) self._get_water_limits_cache[z] = v
# Create a generator to improve results data reading speed # Create a generator to improve results data reading speed
yield pt_left, pt_right yield v
@timer @timer
def compute_tabulation(self): def compute_tabulation(self):