Source code for deltares_coastal_structures_toolbox.functions.structural.stability_toe_berm.etemadshahidi2021

# SPDX-License-Identifier: GPL-3.0-or-later
import numpy as np
import numpy.typing as npt

import deltares_coastal_structures_toolbox.functions.core_physics as core_physics
import deltares_coastal_structures_toolbox.functions.core_utility as core_utility


[docs] def check_validity( Hs: float | npt.NDArray[np.float64] = np.nan, Tmm10: float | npt.NDArray[np.float64] = np.nan, h: float | npt.NDArray[np.float64] = np.nan, ht: float | npt.NDArray[np.float64] = np.nan, Bt: float | npt.NDArray[np.float64] = np.nan, Dn50: float | npt.NDArray[np.float64] = np.nan, m: float | npt.NDArray[np.float64] = np.nan, Nod: float | npt.NDArray[np.float64] = np.nan, cot_alpha_armour_slope: float | npt.NDArray[np.float64] = np.nan, rho_armour: float | npt.NDArray[np.float64] = np.nan, rho_water: float = 1025.0, ): """Check the parameter values vs the validity range of the Etemad-Shahidi et al. (2021) formula. For all parameters supplied, their values are checked versus the range of test conditions specified by Etemad-Shahidi et al. (2021) in Table 3. When parameters are nan (by default), they are not checked. For more details see Etemad-Shahidi et al. (2021), available here: https://doi.org/10.1016/j.coastaleng.2020.103835 Parameters ---------- Hs : float | npt.NDArray[np.float64], optional Significant wave height (m), by default np.nan Tmm10 : float | npt.NDArray[np.float64], optional Spectral wave period Tm-1,0 (s), by default np.nan h : float | npt.NDArray[np.float64], optional Water depth (m), by default np.nan ht : float | npt.NDArray[np.float64], optional Water depth above the toe (m), by default np.nan Bt : float | npt.NDArray[np.float64], optional Width of toe structure (m), by default np.nan Dn50 : float | npt.NDArray[np.float64], optional Nominal rock diameter (m), by default np.nan m : float | npt.NDArray[np.float64], optional Tangent of the foreshore slope, by default np.nan Nod : float | npt.NDArray[np.float64], optional Damage parameter (-), by default np.nan cot_alpha_armour_slope : float | npt.NDArray[np.float64], optional Cotangent of the front-side armour slope of the structure (-), by default np.nan rho_armour : float | npt.NDArray[np.float64], optional Armour rock density (kg/m^3), by default np.nan rho_water : float, optional Water density (kg/m^3), by default 1025.0 """ if not np.any(np.isnan(cot_alpha_armour_slope)): core_utility.check_variable_validity_range( "Armour slope cot_alpha_armour_slope", "Etemad-Shahidi et al. (2021)", cot_alpha_armour_slope, 1.5, 2.0, ) if not np.any(np.isnan(Hs)) and not np.any(np.isnan(Tmm10)): smm10 = core_physics.calculate_wave_steepness_s(H=Hs, Tmm10=Tmm10) core_utility.check_variable_validity_range( "Wave steepness sm-1,0", "Etemad-Shahidi et al. (2021)", smm10, 0.009, 0.061, ) if not np.any(np.isnan(h)) and not np.any(np.isnan(ht)): core_utility.check_variable_validity_range( "Relative water depth above the toe ht/h", "Etemad-Shahidi et al. (2021)", ht / h, 0.39, 0.88, ) if not np.any(np.isnan(Hs)) and not np.any(np.isnan(ht)): core_utility.check_variable_validity_range( "Relative water depth above the toe ht/Hs", "Etemad-Shahidi et al. (2021)", ht / Hs, 0.48, 2.58, ) if not np.any(np.isnan(Dn50)) and not np.any(np.isnan(ht)): core_utility.check_variable_validity_range( "Relative water depth above the toe ht/Dn50", "Etemad-Shahidi et al. (2021)", ht / Dn50, 1.97, 23.40, ) if not np.any(np.isnan(Hs)) and not np.any(np.isnan(ht)): core_utility.check_variable_validity_range( "Relative toe width Bt/Hs", "Etemad-Shahidi et al. (2021)", Bt / Hs, 0.17, 1.92, ) if not np.any(np.isnan(h)) and not np.any(np.isnan(Hs)): core_utility.check_variable_validity_range( "Relative water depth h/Hs", "Etemad-Shahidi et al. (2021)", h / Hs, 1.22, 3.0, ) if not np.any(np.isnan(Hs)) and not np.any(np.isnan(Dn50)): Ns = core_physics.calculate_stability_number_Ns( H=Hs, D=Dn50, rho_rock=rho_armour, rho_water=rho_water ) core_utility.check_variable_validity_range( "Stability number Ns", "Etemad-Shahidi et al. (2021)", Ns, 1.58, 10.0, ) if not np.any(np.isnan(rho_armour)): Delta = core_physics.calculate_buoyant_density_Delta( rho_rock=rho_armour, rho_water=rho_water ) core_utility.check_variable_validity_range( "Buoyant density Delta", "Etemad-Shahidi et al. (2021)", Delta, 1.65, 1.75, ) if not np.any(np.isnan(m)): core_utility.check_variable_validity_range( "Foreshore slope m", "Etemad-Shahidi et al. (2021)", m, 0.02, 0.10, ) if not np.any(np.isnan(Nod)): core_utility.check_variable_validity_range( "Damage parameter Nod", "Etemad-Shahidi et al. (2021)", Nod, 0.5, 3.79, ) return
[docs] def calculate_damage_Nod( Hs: float | npt.NDArray[np.float64], Tmm10: float | npt.NDArray[np.float64], h: float | npt.NDArray[np.float64], ht: float | npt.NDArray[np.float64], Bt: float | npt.NDArray[np.float64], m: float | npt.NDArray[np.float64], Dn50: float | npt.NDArray[np.float64], rho_rock: float | npt.NDArray[np.float64], rho_water: float = 1025.0, g: float = 9.81, c1: float = 1.2, c2: float = 11.2, c3: float = 7.0 / 4.0, c4: float = 1.0 / 6.0, c5: float = 2.0 / 5.0, c6: float = -1.0 / 10.0, c7: float = 3.7, ) -> float | npt.NDArray[np.float64]: """Calculate damage number Nod for toe structure using Etemad-Shahidi et al. (2021) Here, Eq. 8 of Etemad-Shahidi et al. (2021) is implemented. For more details see Etemad-Shahidi et al. (2021), available here: https://doi.org/10.1016/j.coastaleng.2020.103835 Parameters ---------- Hs : float | npt.NDArray[np.float64] Significant wave height (m) Tmm10 : float | npt.NDArray[np.float64] Spectral wave period Tm-1,0 (s) h : float | npt.NDArray[np.float64] Water depth (m) ht : float | npt.NDArray[np.float64] Water depth above the toe (m) Bt : float | npt.NDArray[np.float64] Width of toe structure (m) m : float | npt.NDArray[np.float64] Tangent of the foreshore slope Dn50 : float | npt.NDArray[np.float64] Nominal rock diameter (m) rho_rock : float | npt.NDArray[np.float64] Rock density (kg/m^3) rho_water : float Water density (kg/m^3), by default 1025.0 g : float, optional Gravitational constant (m/s^2), by default 9.81 c1 : float, optional Coefficient in the toe stability formula, by default 1.2 c2 : float, optional Coefficient in the toe stability formula, by default 11.2 c3 : float, optional Coefficient in the toe stability formula, by default 7.0/4.0 c4 : float, optional Coefficient in the toe stability formula, by default 1.0/6.0 c5 : float, optional Coefficient in the toe stability formula, by default 2.0/5.0 c6 : float, optional Coefficient in the toe stability formula, by default -1.0/10.0 c7 : float, optional Coefficient in the toe stability formula, by default 3.7 Returns ------- float | npt.NDArray[np.float64] The damage parameter Nod (-) """ smm10 = core_physics.calculate_wave_steepness_s(H=Hs, T=Tmm10, g=g) Ns = core_physics.calculate_stability_number_Ns( H=Hs, D=Dn50, rho_rock=rho_rock, rho_water=rho_water, ) Nod = np.power( (Ns - c1) * (1.0 / c2) * np.power(ht / h, -c3) * np.power(smm10, -c4) * np.power(Bt / Hs, -c6) * (1.0 / (1.0 - c7 * m)), 1.0 / c5, ) check_validity(Hs=Hs, ht=ht) return Nod
[docs] def calculate_nominal_diameter_Dn50( Hs: float | npt.NDArray[np.float64], Tmm10: float | npt.NDArray[np.float64], h: float | npt.NDArray[np.float64], ht: float | npt.NDArray[np.float64], Bt: float | npt.NDArray[np.float64], Nod: float | npt.NDArray[np.float64], m: float | npt.NDArray[np.float64], rho_rock: float | npt.NDArray[np.float64], rho_water: float = 1025.0, g: float = 9.81, c1: float = 1.2, c2: float = 11.2, c3: float = 7.0 / 4.0, c4: float = 1.0 / 6.0, c5: float = 2.0 / 5.0, c6: float = -1.0 / 10.0, c7: float = 3.7, ) -> float | npt.NDArray[np.float64]: """Calculate the nominal rock diameter Dn50 for toe stability using Etemad-Shahidi et al. (2021) Here, Eq. 8 of Etemad-Shahidi et al. (2021) is implemented. For more details see Etemad-Shahidi et al. (2021), available here: https://doi.org/10.1016/j.coastaleng.2020.103835 Parameters ---------- Hs : float | npt.NDArray[np.float64] Significant wave height (m) Tmm10 : float | npt.NDArray[np.float64] Spectral wave period Tm-1,0 (s) h : float | npt.NDArray[np.float64] Water depth (m) ht : float | npt.NDArray[np.float64] Water depth above the toe (m) Bt : float | npt.NDArray[np.float64] Width of toe structure (m) Nod : float | npt.NDArray[np.float64] Damage parameter (-) m : float | npt.NDArray[np.float64] Tangent of the foreshore slope rho_rock : float | npt.NDArray[np.float64] Rock density (kg/m^3) rho_water : float Water density (kg/m^3), by default 1025.0 g : float, optional Gravitational constant (m/s^2), by default 9.81 c1 : float, optional Coefficient in the toe stability formula, by default 1.2 c2 : float, optional Coefficient in the toe stability formula, by default 11.2 c3 : float, optional Coefficient in the toe stability formula, by default 7.0/4.0 c4 : float, optional Coefficient in the toe stability formula, by default 1.0/6.0 c5 : float, optional Coefficient in the toe stability formula, by default 2.0/5.0 c6 : float, optional Coefficient in the toe stability formula, by default -1.0/10.0 c7 : float, optional Coefficient in the toe stability formula, by default 3.7 Returns ------- float | npt.NDArray[np.float64] The nominal rock diameter Dn50 (m) """ Delta = core_physics.calculate_buoyant_density_Delta( rho_rock=rho_rock, rho_water=rho_water ) smm10 = core_physics.calculate_wave_steepness_s(H=Hs, T=Tmm10, g=g) Dn50 = (Hs / Delta) * np.power( c1 + c2 * np.power(ht / h, c3) * np.power(smm10, c4) * np.power(Nod, c5) * np.power(Bt / Hs, c6) * (1.0 - c7 * m), -1.0, ) check_validity(Hs=Hs, ht=ht) return Dn50
[docs] def calculate_significant_wave_height_Hs( Tmm10: float | npt.NDArray[np.float64], h: float | npt.NDArray[np.float64], ht: float | npt.NDArray[np.float64], Bt: float | npt.NDArray[np.float64], Nod: float | npt.NDArray[np.float64], m: float | npt.NDArray[np.float64], Dn50: float | npt.NDArray[np.float64], rho_rock: float | npt.NDArray[np.float64], rho_water: float = 1025.0, g: float = 9.81, c1: float = 1.2, c2: float = 11.2, c3: float = 7.0 / 4.0, c4: float = 1.0 / 6.0, c5: float = 2.0 / 5.0, c6: float = -1.0 / 10.0, c7: float = 3.7, smm10_init: float = 0.03, max_iter: int = 1000, ) -> float | npt.NDArray[np.float64]: """Calculate the maximum significant wave height Hs for toe stability using Etemad-Shahidi et al. (2021) Here, Eq. 8 of Etemad-Shahidi et al. (2021) is implemented. Note that the Hs needs to be solved iteratively. For more details see Etemad-Shahidi et al. (2021), available here: https://doi.org/10.1016/j.coastaleng.2020.103835 Parameters ---------- Tmm10 : float | npt.NDArray[np.float64] Spectral wave period Tm-1,0 (s) h : float | npt.NDArray[np.float64] Water depth (m) ht : float | npt.NDArray[np.float64] Water depth above the toe (m) Bt : float | npt.NDArray[np.float64] Width of toe structure (m) Nod : float | npt.NDArray[np.float64] Damage parameter (-) m : float | npt.NDArray[np.float64] Tangent of the foreshore slope Dn50 : float | npt.NDArray[np.float64] Nominal rock diameter (m) rho_rock : float | npt.NDArray[np.float64] Rock density (kg/m^3) rho_water : float Water density (kg/m^3), by default 1025.0 g : float, optional Gravitational constant (m/s^2), by default 9.81 c1 : float, optional Coefficient in the toe stability formula, by default 1.2 c2 : float, optional Coefficient in the toe stability formula, by default 11.2 c3 : float, optional Coefficient in the toe stability formula, by default 7.0/4.0 c4 : float, optional Coefficient in the toe stability formula, by default 1.0/6.0 c5 : float, optional Coefficient in the toe stability formula, by default 2.0/5.0 c6 : float, optional Coefficient in the toe stability formula, by default -1.0/10.0 c7 : float, optional Coefficient in the toe stability formula, by default 3.7 smm10_init : float, optional Initial wave steepness sm-1,0 (-) for the iterative solution, by default 0.03 max_iter : int, optional Maximum number of iterations, by default 1000 Returns ------- float | npt.NDArray[np.float64] The significant wave height Hs (m) """ Delta = core_physics.calculate_buoyant_density_Delta( rho_rock=rho_rock, rho_water=rho_water ) n_iter = 0 Hs_init = smm10_init * np.power(Tmm10, 2) * g / (2 * np.pi) Hs = Hs_init smm10 = smm10_init Hs_diff = np.inf Hs_prev = Hs_init while np.max(Hs_diff) > 1e-3 and n_iter < max_iter: Hs = ( Delta * Dn50 * ( c1 + c2 * np.power(ht / h, c3) * np.power(smm10, c4) * np.power(Nod, c5) * np.power(Bt / Hs, c6) * (1.0 - c7 * m) ) ) Hs_diff = np.abs(Hs - Hs_prev) Hs_prev = Hs smm10 = core_physics.calculate_wave_steepness_s(H=Hs, T=Tmm10, g=g) return Hs