Source code for openeurotop.overtopping

"""
Méthodes de calcul du franchissement de vagues selon EurOtop (2018)
"""

import numpy as np
from openeurotop.constants import (
    G, DEG_TO_RAD,
    A_TALUS_NON_DEFERLEMENT, B_TALUS_NON_DEFERLEMENT, C_TALUS_NON_DEFERLEMENT,
    A_TALUS_DEFERLEMENT, B_TALUS_DEFERLEMENT,
    A_MUR_VERTICAL, B_MUR_VERTICAL,
    XI_TRANSITION
)
from openeurotop.wave_parameters import iribarren_number, wave_length_deep_water
from openeurotop.reduction_factors import (
    gamma_f_roughness, gamma_beta_obliquity, gamma_b_berm
)


[docs] def digue_talus(Hm0, Tm_10, h, Rc, alpha_deg, gamma_b=1.0, gamma_f=1.0, gamma_beta=1.0, method="auto", g=G): """ Calcul du débit de franchissement moyen pour une digue à talus Formules principales d'EurOtop 2018 : - Conditions non-déferlantes (plunging) : q proportionnel à exp(-b*Rc/Hm0) - Conditions déferlantes (surging) : q proportionnel à exp(-c*Rc/(Hm0*ξ)) Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale moyenne Tm-1,0 (s) h : float Profondeur d'eau au pied de l'ouvrage (m) Rc : float Revanche (freeboard) - hauteur de crête au-dessus du SWL (m) alpha_deg : float Angle de pente du talus (degrés) gamma_b : float, optional Facteur de réduction pour berme (défaut: 1.0) gamma_f : float, optional Facteur de réduction pour rugosité (défaut: 1.0) gamma_beta : float, optional Facteur de réduction pour obliquité (défaut: 1.0) method : str, optional Méthode de calcul : "auto", "non_deferlement", "deferlement", "both" g : float, optional Accélération de la pesanteur (m/s²) Returns ------- float or dict Débit de franchissement moyen q (m³/s/m) Si method="both", retourne dict avec les deux valeurs References ---------- EurOtop (2018) - Equations 5.1 et 5.2 """ # Calcul du nombre d'Iribarren xi = iribarren_number(alpha_deg, Hm0, Tm_10, g) # Facteur de réduction combiné gamma = gamma_b * gamma_f * gamma_beta # Revanche adimensionnelle Rc_star = Rc / (Hm0 * gamma) # Formule pour conditions non-déferlantes (plunging/breaking waves) # q / sqrt(g*Hm0³) = a * exp(-b * Rc/(γ*Hm0)) q_plunging = (A_TALUS_NON_DEFERLEMENT * np.sqrt(g * Hm0**3) * np.exp(-B_TALUS_NON_DEFERLEMENT * Rc_star)) # Formule pour conditions déferlantes (surging waves) # q / sqrt(g*Hm0³) = a * ξ * exp(-c * Rc/(ξ*γ*Hm0)) if xi > 0: Rc_star_surging = Rc / (Hm0 * gamma * xi) q_surging = (A_TALUS_DEFERLEMENT * xi * np.sqrt(g * Hm0**3) * np.exp(-B_TALUS_DEFERLEMENT * Rc_star_surging)) else: q_surging = 0.0 # Sélection de la méthode if method == "non_deferlement": return q_plunging elif method == "deferlement": return q_surging elif method == "both": return { "q_plunging": q_plunging, "q_surging": q_surging, "q_min": min(q_plunging, q_surging), "xi": xi } else: # method == "auto" # Prendre le minimum des deux formules return min(q_plunging, q_surging)
[docs] def digue_talus_detailed(Hm0, Tm_10, h, Rc, alpha_deg, type_revetement="lisse", beta_deg=0.0, B_berm=0.0, h_berm=0.0, g=G): """ Calcul détaillé du franchissement pour digue à talus avec calcul automatique des facteurs de réduction Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale moyenne Tm-1,0 (s) h : float Profondeur d'eau (m) Rc : float Revanche (m) alpha_deg : float Angle de pente (degrés) type_revetement : str, optional Type de revêtement (voir gamma_f_roughness) beta_deg : float, optional Angle d'obliquité des vagues (degrés) B_berm : float, optional Largeur de berme (m) h_berm : float, optional Hauteur de berme (m) g : float, optional Accélération de la pesanteur (m/s²) Returns ------- dict Dictionnaire avec q et tous les paramètres calculés """ # Calcul des facteurs de réduction gamma_f = gamma_f_roughness(type_revetement) gamma_beta = gamma_beta_obliquity(beta_deg) gamma_b = gamma_b_berm(Rc, Hm0, B_berm, h_berm, gamma_f) # Calcul du débit q = digue_talus(Hm0, Tm_10, h, Rc, alpha_deg, gamma_b, gamma_f, gamma_beta, "auto", g) # Nombre d'Iribarren xi = iribarren_number(alpha_deg, Hm0, Tm_10, g) return { "q": q, "Hm0": Hm0, "Tm_10": Tm_10, "Rc": Rc, "alpha_deg": alpha_deg, "xi": xi, "gamma_f": gamma_f, "gamma_beta": gamma_beta, "gamma_b": gamma_b, "gamma_total": gamma_f * gamma_beta * gamma_b, "Rc_Hm0": Rc / Hm0 }
[docs] def mur_vertical(Hm0, Tm_10, h, Rc, h_structure=None, impulsive=True, g=G): """ Calcul du franchissement pour un mur vertical Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale (s) h : float Profondeur d'eau au pied du mur (m) Rc : float Revanche (m) h_structure : float, optional Hauteur totale de la structure (m). Si None, h_structure = h + Rc impulsive : bool, optional Si True, considère les conditions impulsives g : float, optional Accélération de la pesanteur (m/s²) Returns ------- float Débit de franchissement q (m³/s/m) References ---------- EurOtop (2018) - Section 5.3 """ if h_structure is None: h_structure = h + Rc # Paramètres adimensionnels d_star = h / Hm0 hm0_Lm_10 = Hm0 / wave_length_deep_water(Tm_10, g) # Revanche relative Rc_Hm0 = Rc / Hm0 # Formule générale pour mur vertical # q / sqrt(g*Hm0³) = a * exp(-b * Rc/Hm0) q = (A_MUR_VERTICAL * np.sqrt(g * Hm0**3) * np.exp(-B_MUR_VERTICAL * Rc_Hm0)) # Correction pour faible profondeur if d_star < 3.0: # Réduction pour faible profondeur factor = max(0.5, d_star / 3.0) q *= factor # Correction pour conditions impulsives if impulsive and d_star < 0.3: # Augmentation pour impacts impulsifs q *= 1.5 return q
[docs] def structure_composite(Hm0, Tm_10, h, Rc, alpha_lower_deg, h_transition, gamma_f_lower=1.0, gamma_f_upper=1.0, gamma_beta=1.0, g=G): """ Calcul du franchissement pour une structure composite (talus en partie basse + mur vertical en partie haute) Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale (s) h : float Profondeur d'eau (m) Rc : float Revanche totale (m) alpha_lower_deg : float Angle de pente de la partie basse (degrés) h_transition : float Hauteur de transition entre talus et mur (m au-dessus du SWL) gamma_f_lower : float, optional Facteur de rugosité partie basse gamma_f_upper : float, optional Facteur de rugosité partie haute (mur) gamma_beta : float, optional Facteur d'obliquité g : float, optional Accélération de la pesanteur (m/s²) Returns ------- float Débit de franchissement q (m³/s/m) References ---------- EurOtop (2018) - Section 5.4 """ # Calcul du nombre d'Iribarren pour la pente inférieure xi = iribarren_number(alpha_lower_deg, Hm0, Tm_10, g) # Hauteur de la partie verticale Rc_vertical = Rc - h_transition if Rc_vertical <= 0: # Pas de partie verticale, structure entièrement en talus return digue_talus(Hm0, Tm_10, h, Rc, alpha_lower_deg, 1.0, gamma_f_lower, gamma_beta, "auto", g) # Facteur de réduction combiné pour partie basse gamma_lower = gamma_f_lower * gamma_beta # Formule composite (approximation) # Utilise une approche pondérée entre talus et mur vertical # Contribution de la partie en talus jusqu'à la transition Rc_talus_equiv = h_transition if Rc_talus_equiv > 0: q_talus = digue_talus(Hm0, Tm_10, h, Rc_talus_equiv, alpha_lower_deg, 1.0, gamma_f_lower, gamma_beta, "auto", g) else: q_talus = np.sqrt(g * Hm0**3) # Valeur de référence élevée # Contribution du mur vertical # Réduction supplémentaire due à la hauteur du mur Rc_vert_star = Rc_vertical / Hm0 q_reduction = np.exp(-2.0 * Rc_vert_star) q = q_talus * q_reduction return q
[docs] def digue_en_enrochement(Hm0, Tm_10, h, Rc, alpha_deg, Dn50, n_layers=2, permeability="permeable", gamma_beta=1.0, g=G): """ Calcul du franchissement pour digue en enrochement Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale (s) h : float Profondeur d'eau (m) Rc : float Revanche (m) alpha_deg : float Angle de pente (degrés) Dn50 : float Diamètre nominal médian des enrochements (m) n_layers : int, optional Nombre de couches (1 ou 2) permeability : str, optional Perméabilité du noyau : "permeable", "impermeable" gamma_beta : float, optional Facteur d'obliquité g : float, optional Accélération de la pesanteur (m/s²) Returns ------- float Débit de franchissement q (m³/s/m) """ # Facteur de rugosité selon le nombre de couches et la perméabilité if n_layers == 1: gamma_f = 0.55 elif n_layers == 2: if permeability == "permeable": gamma_f = 0.50 else: gamma_f = 0.45 else: gamma_f = 0.50 # Calcul standard q = digue_talus(Hm0, Tm_10, h, Rc, alpha_deg, 1.0, gamma_f, gamma_beta, "auto", g) return q
[docs] def promenade_avec_parapet(Hm0, Tm_10, h, Rc_promenade, h_parapet, alpha_deg=90.0, gamma_f=1.0, g=G): """ Calcul du franchissement pour une promenade avec parapet Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale (s) h : float Profondeur d'eau (m) Rc_promenade : float Hauteur de la promenade au-dessus du SWL (m) h_parapet : float Hauteur du parapet (m) alpha_deg : float, optional Pente éventuelle avant la promenade (degrés) gamma_f : float, optional Facteur de rugosité g : float, optional Accélération de la pesanteur (m/s²) Returns ------- float Débit de franchissement q (m³/s/m) """ # Revanche totale Rc_total = Rc_promenade + h_parapet if alpha_deg >= 80: # Structure quasi-verticale q_sans_parapet = mur_vertical(Hm0, Tm_10, h, Rc_promenade, g=g) else: # Structure en talus q_sans_parapet = digue_talus(Hm0, Tm_10, h, Rc_promenade, alpha_deg, 1.0, gamma_f, 1.0, "auto", g) # Réduction due au parapet # Le parapet réduit le franchissement de manière exponentielle if h_parapet > 0: h_parapet_star = h_parapet / Hm0 reduction = np.exp(-1.5 * h_parapet_star) q = q_sans_parapet * reduction else: q = q_sans_parapet return q
[docs] def rubble_mound_breakwater(Hm0, Tm_10, h, Rc, alpha_deg, armor_unit="enrochement", Dn50=None, crest_width=None, g=G): """ Calcul du franchissement pour digue à talus (rubble mound breakwater) avec différents types de carapace Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale (s) h : float Profondeur d'eau (m) Rc : float Revanche (m) alpha_deg : float Angle de pente (degrés) armor_unit : str, optional Type d'unité de carapace Dn50 : float, optional Diamètre nominal (m) crest_width : float, optional Largeur de crête (m) g : float, optional Accélération de la pesanteur (m/s²) Returns ------- float Débit de franchissement q (m³/s/m) """ # Facteur de rugosité selon le type d'armure gamma_f = gamma_f_roughness(armor_unit) # Facteur de berme si largeur de crête significative if crest_width is not None and crest_width > 0: # La crête agit comme une berme gamma_b = gamma_b_berm(Rc, Hm0, crest_width, Rc, gamma_f) else: gamma_b = 1.0 # Calcul standard q = digue_talus(Hm0, Tm_10, h, Rc, alpha_deg, gamma_b, gamma_f, 1.0, "auto", g) return q
[docs] def calcul_volumes_franchissement(q, duree_tempete_heures): """ Calcule les volumes de franchissement à partir du débit moyen Parameters ---------- q : float Débit de franchissement moyen (m³/s/m) duree_tempete_heures : float Durée de la tempête (heures) Returns ------- dict Volumes en différentes unités """ duree_secondes = duree_tempete_heures * 3600 # Volume total par mètre linéaire V_total = q * duree_secondes # m³/m # Volume par mètre de longueur d'ouvrage V_per_m = V_total # m³/m # Convertions pratiques V_liters_per_m = V_total * 1000 # litres/m return { "volume_total_m3_per_m": V_total, "volume_liters_per_m": V_liters_per_m, "debit_moyen_m3_s_m": q, "duree_heures": duree_tempete_heures, "duree_secondes": duree_secondes }
[docs] def discharge_individual_waves(Hm0, Tm_10, h, Rc, alpha_deg, gamma_f=1.0, gamma_beta=1.0, N_waves=1000, g=G): """ Estime la distribution du franchissement par vague individuelle Parameters ---------- Hm0 : float Hauteur significative spectrale (m) Tm_10 : float Période spectrale (s) h : float Profondeur d'eau (m) Rc : float Revanche (m) alpha_deg : float Angle de pente (degrés) gamma_f : float, optional Facteur de rugosité gamma_beta : float, optional Facteur d'obliquité N_waves : int, optional Nombre de vagues pendant la tempête g : float, optional Accélération de la pesanteur (m/s²) Returns ------- dict Statistiques sur le franchissement par vagues """ # Débit moyen q_mean = digue_talus(Hm0, Tm_10, h, Rc, alpha_deg, 1.0, gamma_f, gamma_beta, "auto", g) # Volume moyen par vague V_mean = q_mean * Tm_10 # m³/m par vague # Proportion de vagues franchissantes (formule empirique) Rc_Hm0 = Rc / Hm0 if Rc_Hm0 <= 1.0: P_ow = 1.0 # Toutes les vagues franchissent else: P_ow = np.exp(-0.5 * Rc_Hm0) # Proportion décroissante # Nombre de vagues franchissantes N_overtopping = int(N_waves * P_ow) # Volume moyen par vague franchissante if P_ow > 0: V_per_overtopping_wave = V_mean / P_ow else: V_per_overtopping_wave = 0.0 return { "q_mean": q_mean, "V_mean_per_wave": V_mean, "P_overtopping": P_ow, "N_waves_total": N_waves, "N_overtopping_waves": N_overtopping, "V_per_overtopping_wave": V_per_overtopping_wave }