mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-29 19:10:42 +01:00
RubarBE: export weirs and rectangular and circular orifices (ouvrag), and ignore other structure types with a warning
This commit is contained in:
1 parent
357b39758c
commit
5f64362f65
2 files changed
+186
No files matched your search
@@ -175,6 +175,8 @@ class Rubar3(CommandLineSolver):
|
|||||||
saves = self._save_data(values, hydraulics)
|
saves = self._save_data(values, hydraulics)
|
||||||
laterals = self._lateral_data(
|
laterals = self._lateral_data(
|
||||||
study.river, hydraulics, values, hydraulics["warnings"])
|
study.river, hydraulics, values, hydraulics["warnings"])
|
||||||
|
structures = self._structure_data(
|
||||||
|
study.river, hydraulics, hydraulics["warnings"])
|
||||||
except RubarExportError as error:
|
except RubarExportError as error:
|
||||||
self._cancel(qlog, str(error))
|
self._cancel(qlog, str(error))
|
||||||
return False
|
return False
|
||||||
@@ -194,6 +196,7 @@ class Rubar3(CommandLineSolver):
|
|||||||
self._export_devers(study, repertory, qlog, name=name)
|
self._export_devers(study, repertory, qlog, name=name)
|
||||||
if laterals is not None:
|
if laterals is not None:
|
||||||
self._export_hydevs(laterals, trased, repertory, qlog, name=name)
|
self._export_hydevs(laterals, trased, repertory, qlog, name=name)
|
||||||
|
self._export_ouvrag(structures, repertory, qlog, name=name)
|
||||||
self._export_condin(hydraulics, repertory, qlog, name=name)
|
self._export_condin(hydraulics, repertory, qlog, name=name)
|
||||||
self._export_stricklers(hydraulics, repertory, qlog, name=name)
|
self._export_stricklers(hydraulics, repertory, qlog, name=name)
|
||||||
self._export_boundaries(hydraulics, repertory, qlog, name=name)
|
self._export_boundaries(hydraulics, repertory, qlog, name=name)
|
||||||
@@ -630,6 +633,114 @@ class Rubar3(CommandLineSolver):
|
|||||||
|
|
||||||
return [block[:3] for block in blocks]
|
return [block[:3] for block in blocks]
|
||||||
|
|
||||||
|
##############
|
||||||
|
# Structures #
|
||||||
|
##############
|
||||||
|
|
||||||
|
# Pamhyr2 basic structures (those of Mage) with a RubarBE equivalent
|
||||||
|
# (notice, annex 5): weir and rectangular orifice as a weir-orifice D,
|
||||||
|
# circular orifice as O
|
||||||
|
_structure_types = {"S1": "D", "OR": "D", "OC": "O"}
|
||||||
|
# Loading elevation of a weir that never loads (default of Pamhyr2)
|
||||||
|
_no_loading = 9999.999
|
||||||
|
# nou1Dmax, noe1Dmax (variables.f90)
|
||||||
|
_max_structures = 50
|
||||||
|
_max_elementary = 10
|
||||||
|
|
||||||
|
def _structure_data(self, river, hydraulics, warnings):
|
||||||
|
"""Structures of OUVRAG (rubar_init.f90, LOUVR1D). A Pamhyr2
|
||||||
|
structure sits on a section: RubarBE structure on this single
|
||||||
|
interface, with reference -2 (the discharge is that of the
|
||||||
|
structure only), as for Mage. Disabled structures are skipped, as
|
||||||
|
for Mage. Return [(rk, [(type, L, zd, zm, coefficient), ...]), ...]
|
||||||
|
sorted from upstream. Raise RubarExportError with a user message"""
|
||||||
|
trad = RunSolverTranslate()
|
||||||
|
edge = hydraulics["edge"]
|
||||||
|
sections = {id(p) for p in hydraulics["profiles"]}
|
||||||
|
|
||||||
|
structures = {}
|
||||||
|
for hs in river.hydraulic_structures.lst:
|
||||||
|
if (hs.is_deleted() or not hs.enabled
|
||||||
|
or hs.input_reach is None or hs.input_section is None
|
||||||
|
or hs.input_reach != edge):
|
||||||
|
continue
|
||||||
|
if id(hs.input_section) not in sections:
|
||||||
|
raise RubarExportError(trad["structure_section"].format(
|
||||||
|
name=hs.name, reach=edge.name))
|
||||||
|
|
||||||
|
# Basic structures without RubarBE equivalent are not taken
|
||||||
|
# into account: the user is warned
|
||||||
|
lines = []
|
||||||
|
for bhs in hs.basic_structures:
|
||||||
|
if not bhs.enabled or bhs.is_deleted():
|
||||||
|
continue
|
||||||
|
if bhs.type not in self._structure_types:
|
||||||
|
warnings.append(trad["structure_type_ignored"].format(
|
||||||
|
name=self._basic_label(hs, bhs), type=bhs.type))
|
||||||
|
continue
|
||||||
|
lines.append(self._elementary_structure(hs, bhs))
|
||||||
|
if not lines:
|
||||||
|
warnings.append(trad["structure_empty_ignored"].format(
|
||||||
|
name=hs.name))
|
||||||
|
continue
|
||||||
|
if len(lines) > self._max_elementary:
|
||||||
|
raise RubarExportError(trad["structure_too_many"].format(
|
||||||
|
name=hs.name, count=len(lines),
|
||||||
|
maximum=self._max_elementary))
|
||||||
|
|
||||||
|
rk = self._section_rk(hs.input_section)
|
||||||
|
if rk in structures:
|
||||||
|
raise RubarExportError(trad["structure_same_section"].format(
|
||||||
|
first=structures[rk][1], second=hs.name, rk=f"{rk:g}"))
|
||||||
|
structures[rk] = (lines, hs.name)
|
||||||
|
|
||||||
|
if len(structures) > self._max_structures:
|
||||||
|
raise RubarExportError(trad["structure_too_many_structures"]
|
||||||
|
.format(count=len(structures),
|
||||||
|
maximum=self._max_structures))
|
||||||
|
return [(rk, structures[rk][0]) for rk in sorted(structures)]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _basic_label(hs, bhs):
|
||||||
|
return f"{bhs.name or bhs.type} ({hs.name})"
|
||||||
|
|
||||||
|
def _elementary_structure(self, hs, bhs):
|
||||||
|
"""RubarBE line of a basic structure of a type of _structure_types:
|
||||||
|
(type, L, zd, zm, coefficient) for D (zm: loading elevation),
|
||||||
|
(type, L, zd, D, coefficient) for O (L: pipe length, none in
|
||||||
|
Pamhyr2: 0, a thin wall orifice)"""
|
||||||
|
trad = RunSolverTranslate()
|
||||||
|
label = self._basic_label(hs, bhs)
|
||||||
|
values = [float(v.value) for v in bhs.parameters]
|
||||||
|
if bhs.type == "S1":
|
||||||
|
width, elevation, coefficient = values
|
||||||
|
line = ("D", width, elevation, self._no_loading, coefficient)
|
||||||
|
elif bhs.type == "OR":
|
||||||
|
width, elevation, loading, coefficient, maximal = values
|
||||||
|
if maximal < self._no_loading:
|
||||||
|
raise RubarExportError(trad["structure_maximal_loading"]
|
||||||
|
.format(name=label))
|
||||||
|
line = ("D", width, elevation, loading, coefficient)
|
||||||
|
else:
|
||||||
|
diameter, elevation, siltation, coefficient = values
|
||||||
|
if siltation != 0:
|
||||||
|
raise RubarExportError(trad["structure_siltation"].format(
|
||||||
|
name=label))
|
||||||
|
line = ("O", 0.0, elevation, diameter, coefficient)
|
||||||
|
|
||||||
|
kind, size, zd, zm, coefficient = line
|
||||||
|
if (size <= 0 if kind == "D" else zm <= 0) or coefficient <= 0:
|
||||||
|
raise RubarExportError(trad["structure_invalid"].format(
|
||||||
|
name=label))
|
||||||
|
if kind == "D" and zm <= zd:
|
||||||
|
raise RubarExportError(trad["structure_loading_below"].format(
|
||||||
|
name=label))
|
||||||
|
# Fixed columns (A1, A9, 4F10.0)
|
||||||
|
if any(len(f"{v:10.3f}") > 10 for v in line[1:]):
|
||||||
|
raise RubarExportError(trad["structure_format"].format(
|
||||||
|
name=label))
|
||||||
|
return line
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# Saves #
|
# Saves #
|
||||||
#########
|
#########
|
||||||
@@ -1149,6 +1260,23 @@ class Rubar3(CommandLineSolver):
|
|||||||
lines += [f"{q!r} {t!r}\n" for t, q in data]
|
lines += [f"{q!r} {t!r}\n" for t, q in data]
|
||||||
self._write_parameters(repertory, f"hydevs.{name}", lines)
|
self._write_parameters(repertory, f"hydevs.{name}", lines)
|
||||||
|
|
||||||
|
def _export_ouvrag(self, structures, repertory, qlog, name="0"):
|
||||||
|
"""OUVRAG (notice annex 1, rubar_init.f90, LOUVR1D): per
|
||||||
|
structure, upstream abscissa, reference and reach, downstream
|
||||||
|
abscissa, number of basic structures and reach, then one line per
|
||||||
|
basic structure in (A1, A9, 4F10.0). Written, possibly empty, so
|
||||||
|
that a previous OUVRAG of the directory is not used"""
|
||||||
|
if qlog is not None:
|
||||||
|
qlog.put("Export OUVRAG file")
|
||||||
|
lines = []
|
||||||
|
for rk, elementary in structures:
|
||||||
|
lines.append(f"{rk:11.3f} {-2:4d} {1:4d}\n")
|
||||||
|
lines.append(f"{rk:11.3f} {len(elementary):4d} {1:4d}\n")
|
||||||
|
for kind, size, zd, zm, coefficient in elementary:
|
||||||
|
lines.append(f"{kind}{'':9}{size:10.3f}{zd:10.3f}"
|
||||||
|
f"{zm:10.3f}{coefficient:10.3f}\n")
|
||||||
|
self._write_parameters(repertory, f"ouvrag.{name}", lines)
|
||||||
|
|
||||||
def _export_stricklers(self, hydraulics, repertory, qlog, name="0"):
|
def _export_stricklers(self, hydraulics, repertory, qlog, name="0"):
|
||||||
"""FROT (minor bed) and FROT2 (medium bed): LM, then one Strickler
|
"""FROT (minor bed) and FROT2 (medium bed): LM, then one Strickler
|
||||||
per cell (notice, annex 1)"""
|
per cell (notice, annex 1)"""
|
||||||
|
|||||||
@@ -129,6 +129,64 @@ class RunSolverTranslate(PamhyrTranslate):
|
|||||||
"Export cancelled: several {kind} boundary conditions at node "
|
"Export cancelled: several {kind} boundary conditions at node "
|
||||||
"{node}."
|
"{node}."
|
||||||
)
|
)
|
||||||
|
self._dict["structure_section"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: the section of hydraulic structure {name} is "
|
||||||
|
"not a profile of reach {reach}."
|
||||||
|
)
|
||||||
|
self._dict["structure_empty_ignored"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Hydraulic structure {name} has no enabled basic structure "
|
||||||
|
"that RubarBE takes into account: it is ignored."
|
||||||
|
)
|
||||||
|
self._dict["structure_too_many"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: hydraulic structure {name} has {count} "
|
||||||
|
"enabled basic structures, RubarBE accepts at most {maximum}."
|
||||||
|
)
|
||||||
|
self._dict["structure_too_many_structures"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: {count} hydraulic structures, RubarBE accepts "
|
||||||
|
"at most {maximum}."
|
||||||
|
)
|
||||||
|
self._dict["structure_same_section"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: hydraulic structures {first} and {second} are "
|
||||||
|
"on the same section (rk {rk}). Put their basic structures in a "
|
||||||
|
"single hydraulic structure."
|
||||||
|
)
|
||||||
|
self._dict["structure_type_ignored"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Basic structure {name} of type {type} has no RubarBE "
|
||||||
|
"equivalent: it is not taken into account. RubarBE accepts "
|
||||||
|
"discharge weirs (S1), rectangular orifices (OR) and circular "
|
||||||
|
"orifices (OC)."
|
||||||
|
)
|
||||||
|
self._dict["structure_maximal_loading"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: rectangular orifice {name}: RubarBE has no "
|
||||||
|
"maximal loading elevation. Leave it at 9999.999."
|
||||||
|
)
|
||||||
|
self._dict["structure_siltation"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: circular orifice {name}: RubarBE has no "
|
||||||
|
"siltation height. Set it to 0."
|
||||||
|
)
|
||||||
|
self._dict["structure_invalid"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: basic structure {name} must have a width (or "
|
||||||
|
"diameter) > 0 and a discharge coefficient > 0."
|
||||||
|
)
|
||||||
|
self._dict["structure_loading_below"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: basic structure {name}: the loading elevation "
|
||||||
|
"must be above the weir elevation."
|
||||||
|
)
|
||||||
|
self._dict["structure_format"] = _translate(
|
||||||
|
"Solver",
|
||||||
|
"Export cancelled: a value of basic structure {name} does not fit "
|
||||||
|
"the 10 columns of RubarBE (3 decimals)."
|
||||||
|
)
|
||||||
self._dict["lateral_empty_ignored"] = _translate(
|
self._dict["lateral_empty_ignored"] = _translate(
|
||||||
"Solver",
|
"Solver",
|
||||||
"Lateral contribution {name} on reach {reach} has no value: it "
|
"Lateral contribution {name} on reach {reach} has no value: it "
|
||||||
|
|||||||
Reference in new issue
Block a user