diff --git a/src/Model/Friction/Friction.py b/src/Model/Friction/Friction.py index d49de8f850d91e313ad3e785ca76a0bc2f778596..1a68db0784c6d302e7976cada9843383335d05c7 100644 --- a/src/Model/Friction/Friction.py +++ b/src/Model/Friction/Friction.py @@ -209,6 +209,9 @@ class Friction(SQLSubModel): self._status.modified() + def __contains__(self, kp): + return self.contains_kp(kp) + def contains_kp(self, kp): return ( self._begin_kp <= kp <= self._end_kp diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py index 782556532d374f8c58c2bdc0ea3453cf1a7d3839..974f68093af941c2f1c7855eab8d36d52d6f54c7 100644 --- a/src/Model/Geometry/Reach.py +++ b/src/Model/Geometry/Reach.py @@ -365,10 +365,14 @@ class Reach(SQLSubModel): return 0.0 def inter_profiles_kp(self): - res_kp = [self.profile(0).kp] + profiles = sorted(self.profiles, key=lambda p: p.kp) + first = profiles[0] + last = profiles[-1] - profiles = iter(self.profiles) - previous = next(profile) + res_kp = [first.kp] + + profiles = iter(profiles) + previous = next(profiles) for profile in profiles: prev = previous.kp @@ -381,7 +385,7 @@ class Reach(SQLSubModel): previous = profile - res_kp.append(self.profile(len(self) - 1).kp) + res_kp.append(last.kp) return res_kp # Sediment Layers diff --git a/src/Solver/RubarBE.py b/src/Solver/RubarBE.py index d32e0fdba01fd98dcea061f225449ddaeaf9ae1a..bdef669135668b827ddb2e3736bb51dbb08fb804 100644 --- a/src/Solver/RubarBE.py +++ b/src/Solver/RubarBE.py @@ -29,6 +29,7 @@ from Model.Results.River.River import River, Reach, Profile logger = logging.getLogger() + class RubarBE(CommandLineSolver): _type = "rubarbe" @@ -134,7 +135,19 @@ class RubarBE(CommandLineSolver): name = self._study.name return f"{name}.TRA" - def _export_donnee(self, study, repertory, files, qlog, name="0"): + + def export(self, study, repertory, qlog=None): + self._study = study + name = study.name.replace(" ", "_") + + self._export_donnee(study, repertory, qlog, name=name) + self._export_ts(study, repertory, qlog, name=name) + self._export_geomac_i(study, repertory, qlog, name=name) + self._export_mail(study, repertory, qlog, name=name) + self._export_tps(study, repertory, qlog, name=name) + self._export_stricklers(study, repertory, qlog, name=name) + + def _export_donnee(self, study, repertory, qlog, name="0"): if qlog is not None: qlog.put("Export DONNEE file") @@ -144,14 +157,17 @@ class RubarBE(CommandLineSolver): ), "w+" ) as f: params = filter( - lambda p: "rubarbe_sediment_" not in p[0], - study.river.get_params(self.type).parameters + lambda p: "rubarbe_sediment_" not in p.name, + study.river.get_params(self._type).parameters ) + it = iter(params) line = 0 while line < 29: - lh, value = next(it) + param = next(it) + name = param.name + value = param.value if value != "": # Value format @@ -166,13 +182,13 @@ class RubarBE(CommandLineSolver): value = "O" if value == "y" else "N" # Write value - f.write(f"{lh:<50}{value}") + f.write(f"{name:<50}{value}") # Add values of 'rubarbe_iodebord' and # 'rubarbe_iostockage' - if lh == "rubarbe_iodev": - _, v2 = next(it) - _, v3 = next(it) + if name == "rubarbe_iodev": + v2 = next(it).value + v3 = next(it).value f.write(f"{v2}{v3}") @@ -181,7 +197,7 @@ class RubarBE(CommandLineSolver): line += 1 - def _export_ts(self, study, repertory, files, qlog, name="0"): + def _export_ts(self, study, repertory, qlog, name="0"): if qlog is not None: qlog.put("Export TS file") @@ -190,31 +206,40 @@ class RubarBE(CommandLineSolver): repertory, f"ts.{name}" ), "w+" ) as f: + def float_format(string): + if "." in string: + return f"{float(string):>10.0f}" + return "" + params = filter( - lambda p: "rubarbe_sediment_" in p[0], + lambda p: "rubarbe_sediment_" in p.name, study.river.get_params(self.type).parameters ) it = iter(params) line = 0 while line < 20: - lh, value = next(it) + param = next(it) + name = param.name + value = param.value if value != "": # Value format if value.count('.') == 1: - value = f"{float(value):>10.0f}" + value = f"{float_format(value)}" + else: + value = f"{value:>10}" # Write value - f.write(f"{lh:<50}{value}") + f.write(f"{name:<50}{value}") # Add values of 'rubarbe_iodebord' and # 'rubarbe_iostockage' - if lh == "rubarbe_sediment_mult_1": - _, m2 = f"{float(next(it)):>10.0f}" - _, m3 = f"{float(next(it)):>10.0f}" - _, m4 = f"{float(next(it)):>10.0f}" - _, m5 = f"{float(next(it)):>10.0f}" + if name == "rubarbe_sediment_mult_1": + m2 = f"{float_format(next(it).value)}" + m3 = f"{float_format(next(it).value)}" + m4 = f"{float_format(next(it).value)}" + m5 = f"{float_format(next(it).value)}" f.write(f"{m2}{m3}{m4}{m5}") @@ -223,7 +248,7 @@ class RubarBE(CommandLineSolver): line += 1 - def _export_geomac_i(self, study, repertory, files, qlog, name="0"): + def _export_geomac_i(self, study, repertory, qlog, name="0"): if qlog is not None: qlog.put("Export GEOMAC-i file") @@ -241,15 +266,18 @@ class RubarBE(CommandLineSolver): ind = 1 for profile in reach.profiles: - kp = profile.get_kp() + kp = profile.kp n_points = len(profile) f.write(f"{ind:>4} {kp:>11.3f} {n_points:>4}\n") for point in profile.points: label = point.name.lower() - if label[0] == "r": - label = label[1].upper() + if label != "": + if label[0] == "r": + label = label[1].upper() + else: + label = lable[0] y = point.y z = point.z @@ -258,7 +286,7 @@ class RubarBE(CommandLineSolver): tmcs = 0.0 f.write( - f"{label[0]} {y:>11.5f}" + + f"{label} {y:>11.5f}" + f"{z:>13.5f}{dcs:>15.10f}" + f"{scs:>15.10f}{tmcs:>15.5f}" + "\n" @@ -266,7 +294,7 @@ class RubarBE(CommandLineSolver): ind += 1 - def _export_mail(self, study, repertory, files, qlog, name="0"): + def _export_mail(self, study, repertory, qlog, name="0"): if qlog is not None: qlog.put("Export MAIL file") @@ -276,11 +304,12 @@ class RubarBE(CommandLineSolver): ), "w+" ) as f: for edge in study.river.enable_edges(): - lm = len(edge) + 1 + reach = edge.reach + lm = len(reach) + 1 f.write(f"{lm:>13}\n") - for mails in [edge.reach.inter_profiles_kp(), - edge.reach.profiles.get_kp()]: + for mails in [reach.inter_profiles_kp(), + reach.get_kp()]: ind = 0 for mail in mails: f.write(f"{mail:15.3f}") @@ -292,13 +321,13 @@ class RubarBE(CommandLineSolver): if ind % 3 != 0: f.write("\n") - def _export_stricklers(self, study, repertory, files, qlog, name="0"): - self._export_frot(study, repertory, files, qlog, name="0", version="") - self._export_frot(study, repertory, files, qlog, name="0", version="2") + def _export_stricklers(self, study, repertory, qlog, name="0"): + self._export_frot(study, repertory, qlog, name=name, version="") + self._export_frot(study, repertory, qlog, name=name, version="2") - def _export_frot(self, study, repertory, files, qlog, name="0", version=""): + def _export_frot(self, study, repertory, qlog, name="0", version=""): if qlog is not None: - qlog.put("Export FROT file") + qlog.put(f"Export FROT{version} file") with open( os.path.join( @@ -306,26 +335,20 @@ class RubarBE(CommandLineSolver): ), "w+" ) as f: for edge in study.river.enable_edges(): - lm = len(edge) + 1 + reach = edge.reach + lm = len(reach) + 1 f.write(f"{lm:>6}\n") - # TODO: Take in consideration begin and end Stricklers - f_i = list( - map( - lambda f: (f.begin_kp, f.end_kp, f.begin_strickler), - reach.frictions - ) - ) - def get_stricklers_from_kp(kp): return next( map( lambda s: ( - s[2].medium if version == "2" - else s[2].minor + s.begin_strickler.medium if version == "2" + else s.begin_strickler.minor ), filter( - lambda f: f.contains_kp(kp), f_i + lambda f: kp in f, + edge.frictions.lst ) ) ) @@ -339,7 +362,7 @@ class RubarBE(CommandLineSolver): ind += 1 f.write("\n") - def _export_tps(self, study, repertory, files, qlog, name="0"): + def _export_tps(self, study, repertory, qlog, name="0"): if qlog is not None: qlog.put("Export TPS file") @@ -348,16 +371,22 @@ class RubarBE(CommandLineSolver): repertory, f"tps.{name}" ), "w+" ) as f: - for reach in study.river.enable_edges(): + for edge in study.river.enable_edges(): + reach = edge.reach + f.write(f"0.0\n") - ics = study.river.initial_conditions.get(reach) + ics = study.river.initial_conditions.get(edge) data = self._export_tps_init_data(ics) - profiles = edge.reach.profiles + profiles = reach.profiles first = profiles[0] last = profiles[-1] + if first.kp not in data or last.kp not in data: + logger.error("Study initial condition is not fully defined") + return + f_h_s = self._export_tps_profile_height_speed(first, data) l_h_s = self._export_tps_profile_height_speed(last, data) @@ -366,10 +395,14 @@ class RubarBE(CommandLineSolver): ind = 2 it = iter(profiles) - prev = next(profiles) + prev = next(it) prev_h, prev_s = f_h_s for profile in it: + if profile.kp not in data: + ind += 1 + continue + cur_h, cur_s = self._export_tps_profile_height_speed( profile, data ) @@ -378,7 +411,7 @@ class RubarBE(CommandLineSolver): h = (prev_h + cur_h) / 2 s = (prev_s + cur_s) / 2 - f.write(f"{ind:>5} {h} {s}") + f.write(f"{ind:>5} {h} {s}\n") prev_h, prev_s = cur_h, cur_s ind += 1 @@ -390,11 +423,7 @@ class RubarBE(CommandLineSolver): def _export_tps_init_data(self, ics): data = {} - for ic in ics: - d = ic.data - if len(d) == 0: - continue - + for d in ics.data: data[d['kp']] = ( d['elevation'], d['discharge'], @@ -406,7 +435,7 @@ class RubarBE(CommandLineSolver): z = data[profile.kp][0] q = data[profile.kp][1] - heiglt = z - profile.z_min() - speed = profile.seed(q, z) + height = z - profile.z_min() + speed = profile.speed(q, z) return height, speed diff --git a/src/Solver/Solvers.py b/src/Solver/Solvers.py index 5ba4205f4526cb13ced07cad66c84805aacf584c..c173588fffeaf0a80e767423e3cdf3c4d2002204 100644 --- a/src/Solver/Solvers.py +++ b/src/Solver/Solvers.py @@ -22,6 +22,7 @@ from Solver.GenericSolver import GenericSolver from Solver.Mage import ( Mage7, Mage8, MageFake7, ) +from Solver.RubarBE import RubarBE _translate = QCoreApplication.translate @@ -30,6 +31,7 @@ solver_long_name = { # "mage7": "Mage v7", "mage8": "Mage v8", # "mage_fake7": "Mage fake v7", + "rubarbe": "RubarBE", } solver_type_list = { @@ -37,4 +39,5 @@ solver_type_list = { # "mage7": Mage7, "mage8": Mage8, # "mage_fake7": MageFake7, + "rubarbe": RubarBE, }