Gitdeeper4's picture
رفع جميع ملفات TSU-WAVE مع YAML
12834b7
"""Hydrodynamic Front Stability Index (HFSI)
Quantifies wave front stability via the Boussinesq parameter.
The primary early-warning indicator for tsunami breaking.
HFSI = tanh(Bo) = tanh[H³ / (η·λ²)]
"""
import numpy as np
class HydrodynamicFrontStabilityIndex:
"""
Hydrodynamic Front Stability Index - Parameter 3 of 7
Thresholds:
SAFE: HFSI > 0.80 (highly stable dispersive propagation)
MONITOR: 0.60 < HFSI ≤ 0.80 (weakly unstable)
ALERT: 0.40 < HFSI ≤ 0.60 (strongly unstable)
CRITICAL: HFSI ≤ 0.40 (breaking imminent)
Instability onset validated at h/H₀ = 0.42 ± 0.05
"""
def __init__(self):
self.thresholds = {
'safe': 0.80,
'monitor': 0.60,
'alert': 0.40,
'critical': 0.40
}
self.instability_onset = 0.42 # h/H₀ threshold
def compute_boussinesq(self, H, eta, wavelength):
"""Compute Boussinesq parameter
Bo = H³ / (η·λ²)
Bo >> 1: Dispersion dominates (stable)
Bo ~ 1: Transitional
Bo << 1: Nonlinearity dominates (unstable)
Args:
H: water depth [m]
eta: wave amplitude [m]
wavelength: wavelength [m]
Returns:
Bo: Boussinesq parameter
"""
return H**3 / (eta * wavelength**2 + 1e-10)
def compute_hfsi(self, H, eta, wavelength):
"""Compute Hydrodynamic Front Stability Index
HFSI = tanh(Bo)
Args:
H: water depth [m]
eta: wave amplitude [m]
wavelength: wavelength [m]
Returns:
dict with HFSI value, status, and components
"""
Bo = self.compute_boussinesq(H, eta, wavelength)
hfsi = np.tanh(Bo)
# Compute h/H ratio for instability check
h_H_ratio = eta / H
return {
'value': float(hfsi),
'status': self.get_status(hfsi),
'boussinesq': float(Bo),
'h_H_ratio': float(h_H_ratio),
'instability_detected': h_H_ratio > self.instability_onset,
'stability': self._describe_stability(Bo)
}
def get_status(self, hfsi):
"""Get alert status based on HFSI value"""
if hfsi > self.thresholds['safe']:
return 'SAFE'
elif hfsi > self.thresholds['monitor']:
return 'MONITOR'
elif hfsi > self.thresholds['alert']:
return 'ALERT'
else:
return 'CRITICAL'
def _describe_stability(self, Bo):
"""Describe stability regime based on Boussinesq parameter"""
if Bo > 10:
return "HIGHLY STABLE - Dispersion dominates"
elif Bo > 1:
return "STABLE - Dispersive propagation"
elif Bo > 0.1:
return "TRANSITIONAL - Weakly nonlinear"
else:
return "UNSTABLE - Nonlinearity dominates"
def compute_breaking_criterion(self, H, eta, wavelength):
"""Compute wave breaking criterion
Breaking condition: u_crest ≥ c_wave
Breaking depth: H_break ≈ 1.28·η_max
Returns:
dict with breaking indicators
"""
hfsi_result = self.compute_hfsi(H, eta, wavelength)
h_H_ratio = eta / H
# Breaking imminent when HFSI < 0.40 or h/H > 0.42
breaking_imminent = (hfsi_result['value'] < 0.40) or (h_H_ratio > 0.42)
# Breaking depth estimate
H_break = 1.28 * eta
return {
'breaking_imminent': breaking_imminent,
'h_H_ratio': float(h_H_ratio),
'instability_threshold': self.instability_onset,
'hfsi': hfsi_result['value'],
'estimated_breaking_depth': float(H_break),
'time_to_break': self._estimate_time_to_break(hfsi_result['value'])
}
def _estimate_time_to_break(self, hfsi):
"""Estimate time to breaking based on HFSI value"""
if hfsi > 0.60:
return "> 30 minutes"
elif hfsi > 0.40:
return "15-30 minutes"
elif hfsi > 0.20:
return "5-15 minutes"
else:
return "< 5 minutes - IMMINENT"
def validate_event(self, H, eta, wavelength, observed_breaking=False):
"""Validate HFSI against observed data"""
result = self.compute_hfsi(H, eta, wavelength)
breaking = self.compute_breaking_criterion(H, eta, wavelength)
validation = {
'hfsi': result,
'breaking_analysis': breaking,
'validation': {}
}
# Check against observed breaking
if observed_breaking:
predicted_breaking = breaking['breaking_imminent']
validation['validation']['observed_breaking'] = observed_breaking
validation['validation']['predicted_breaking'] = predicted_breaking
validation['validation']['correct'] = (predicted_breaking == observed_breaking)
return validation