Gitdeeper4's picture
رفع جميع ملفات TSU-WAVE مع YAML
12834b7
"""Shoreline Boundary Stress Parameter (SBSP)
Estimates inundation momentum flux and bore formation at the shoreline transition.
SBSP = Fr² · (H/H_ref) = (u²·H) / (g·H_ref²)
"""
import numpy as np
class ShorelineBoundaryStressParameter:
"""
Shoreline Boundary Stress Parameter - Parameter 6 of 7
Thresholds:
SAFE: SBSP < 0.3 (low inundation stress)
MONITOR: 0.3 ≤ SBSP < 0.7 (moderate inundation)
ALERT: 0.7 ≤ SBSP < 1.2 (high inundation)
CRITICAL: SBSP ≥ 1.2 (supercritical bore)
Run-up regression: R = 19.7 × SBSP − 2.1 [m]
Pearson correlation r = 0.956
"""
def __init__(self, g=9.81, H_ref=1.0):
self.g = g
self.H_ref = H_ref # reference depth for normalization
self.thresholds = {
'safe': 0.3,
'monitor': 0.7,
'alert': 1.2,
'critical': 1.2
}
def compute_froude(self, u, H):
"""Compute Froude number Fr = u/√(gH)
Fr < 1: subcritical flow
Fr = 1: critical flow
Fr > 1: supercritical flow (bore)
Args:
u: flow velocity [m/s]
H: water depth [m]
Returns:
Fr: Froude number
"""
return u / np.sqrt(self.g * H)
def compute_sbsp(self, u, H):
"""Compute Shoreline Boundary Stress Parameter
SBSP = Fr² · (H/H_ref) = (u²·H) / (g·H_ref²)
Args:
u: flow velocity at shoreline [m/s]
H: water depth at shoreline [m]
Returns:
dict with SBSP value, status, and components
"""
Fr = self.compute_froude(u, H)
sbsp = (u**2 * H) / (self.g * self.H_ref**2)
return {
'value': float(sbsp),
'status': self.get_status(sbsp),
'froude': float(Fr),
'flow_regime': self.get_flow_regime(Fr),
'velocity': float(u),
'depth': float(H)
}
def get_status(self, sbsp):
"""Get alert status based on SBSP value"""
if sbsp < self.thresholds['safe']:
return 'SAFE'
elif sbsp < self.thresholds['monitor']:
return 'MONITOR'
elif sbsp < self.thresholds['alert']:
return 'ALERT'
else:
return 'CRITICAL'
def get_flow_regime(self, Fr):
"""Get descriptive flow regime"""
if Fr < 0.8:
return "Subcritical flow"
elif Fr < 1.0:
return "Near-critical flow"
elif Fr < 1.5:
return "Supercritical flow (bore)"
else:
return "Highly supercritical bore"
def estimate_runup(self, sbsp):
"""Estimate run-up from SBSP using validated regression
R = 19.7 × SBSP − 2.1 [m]
Args:
sbsp: SBSP value
Returns:
estimated_runup: estimated run-up height [m]
"""
runup = 19.7 * sbsp - 2.1
return max(0, runup)
def compute_momentum_flux(self, u, H):
"""Compute depth-integrated momentum flux
M = ρ·H·u²
Args:
u: velocity [m/s]
H: depth [m]
Returns:
M: momentum flux [kg·m/s² per m width]
"""
rho = 1025 # seawater density
return rho * H * u**2
def compute_bore_characteristics(self, u, H, eta):
"""Compute hydraulic bore characteristics
Args:
u: velocity [m/s]
H: depth [m]
eta: wave height [m]
Returns:
dict with bore characteristics
"""
Fr = self.compute_froude(u, H)
sbsp = self.compute_sbsp(u, H)
# Bore height ratio (Boussinesq)
if Fr > 1:
# Hydraulic jump / bore
H2_H1 = 0.5 * (np.sqrt(1 + 8*Fr**2) - 1)
else:
H2_H1 = 1.0
return {
'froude': float(Fr),
'sbsp': sbsp,
'bore_formation': Fr > 1.0,
'depth_ratio': float(H2_H1),
'bore_height_m': float(H * (H2_H1 - 1)),
'bore_celerity': float(u / (1 - 1/H2_H1)) if Fr > 1 else None
}
def validate_event(self, u, H, observed_runup):
"""Validate SBSP against observed run-up"""
sbsp_result = self.compute_sbsp(u, H)
predicted_runup = self.estimate_runup(sbsp_result['value'])
error = abs(predicted_runup - observed_runup) / observed_runup * 100
validation = {
'sbsp': sbsp_result,
'predicted_runup': float(predicted_runup),
'observed_runup': observed_runup,
'error_percent': float(error),
'within_15_percent': error < 15,
'bore': self.compute_bore_characteristics(u, H, observed_runup)
}
return validation