"""Wave Front Celerity Coefficient (WCC) Measures departure from linear shallow-water propagation speed, indicating onset of nonlinear wave regime. WCC = c_observed / c₀ c_NL = √(gH) · [1 + 3η/4H − π²H²/6λ²] """ import numpy as np class WaveCelerityCoefficient: """ Wave Front Celerity Coefficient - Parameter 1 of 7 Thresholds: SAFE: WCC < 1.35 MONITOR: 1.35 ≤ WCC < 1.50 ALERT: 1.50 ≤ WCC < 1.58 CRITICAL: WCC ≥ 1.58 """ def __init__(self, g=9.81): self.g = g self.thresholds = { 'safe': 1.35, 'alert': 1.50, 'critical': 1.58 } def compute_linear_celerity(self, H): """Linear shallow-water celerity c₀ = √(gH) Args: H: water depth [m] Returns: c0: linear wave celerity [m/s] """ return np.sqrt(self.g * H) def compute_nonlinear_celerity(self, H, eta, wavelength): """Nonlinear celerity with Boussinesq correction c_NL = c₀·[1 + 3η/4H − π²H²/6λ²] Args: H: water depth [m] eta: wave amplitude [m] wavelength: wavelength [m] Returns: c_nl: nonlinear wave celerity [m/s] """ c0 = self.compute_linear_celerity(H) # Nonlinear correction terms nonlinear_term = 1 + (3*eta)/(4*H) dispersive_term = (np.pi**2 * H**2)/(6 * wavelength**2) correction = nonlinear_term - dispersive_term return c0 * correction def compute_wcc(self, H, eta, wavelength, c_observed=None): """Compute Wave Front Celerity Coefficient Args: H: water depth [m] eta: wave amplitude [m] wavelength: wavelength [m] c_observed: observed celerity [m/s] (optional) Returns: dict with WCC value, status, and components """ c0 = self.compute_linear_celerity(H) if c_observed is None: c_observed = self.compute_nonlinear_celerity(H, eta, wavelength) wcc = c_observed / c0 return { 'value': float(wcc), 'status': self.get_status(wcc), 'c0': float(c0), 'c_observed': float(c_observed), 'nonlinear_correction': float(c_observed / c0) } def get_status(self, wcc): """Get alert status based on WCC value""" if wcc < self.thresholds['safe']: return 'SAFE' elif wcc < self.thresholds['alert']: return 'MONITOR' elif wcc < self.thresholds['critical']: return 'ALERT' else: return 'CRITICAL' def compute_ursell(self, H, eta, wavelength): """Compute Ursell number for wave regime classification Ur = (H/η)·(λ/H)² Ur << 1: Linear dispersive (deep ocean) Ur ~ O(1): Weakly nonlinear (Boussinesq shelf) Ur >> 1: Fully nonlinear (shallow inner shelf) Args: H: water depth [m] eta: wave amplitude [m] wavelength: wavelength [m] Returns: Ur: Ursell number """ return (H/eta) * (wavelength/H)**2 def validate_event(self, H, eta, wavelength, c_observed): """Validate WCC against observed data""" result = self.compute_wcc(H, eta, wavelength, c_observed) # Additional validation metrics c0 = result['c0'] c_nl_theory = self.compute_nonlinear_celerity(H, eta, wavelength) validation = { 'wcc': result, 'c0_theoretical': c0, 'c_nl_theoretical': c_nl_theory, 'c_observed': c_observed, 'error': abs(c_nl_theory - c_observed) / c_observed * 100, 'ursell': self.compute_ursell(H, eta, wavelength) } return validation