pub struct InteriorOceanEndpoint {
pub wind_speed_m_s: f64,
pub wind_direction: [f64; 2],
pub pressure_gpa: f64,
pub temperature_k: f64,
pub density_kg_m3: f64,
pub ior: f64,
pub absorption_coefficients_rgb_m: [f64; 3],
pub grid_size: u32,
pub patch_size_m: f64,
pub surface_gravity_m_s2: f64,
}
impl InteriorOceanEndpoint {
pub fn metallic_hydrogen() -> Self {
Self {
wind_speed_m_s: crate::MAXWINDSMS,
wind_direction: [1.0, 0.0],
pressure_gpa: 400.0,
temperature_k: 10_000.0,
density_kg_m3: 1_000.0,
ior: 1.20,
absorption_coefficients_rgb_m: [0.8, 0.85, 0.9],
grid_size: 256,
patch_size_m: 200_000.0,
surface_gravity_m_s2: *crate::SURFACEGRAVITY,
}
}
pub fn fresnel_r0(&self) -> f64 {
((self.ior - 1.0) / (self.ior + 1.0)).powi(2)
}
pub fn wave_amplitude(&self) -> f64 {
let w = self.wind_speed_m_s.max(0.1);
let grav = self.surface_gravity_m_s2;
let alpha_pm = 8.1e-3;
let beta_pm = 0.74;
let omega_p = grav / w;
let pm_peak = alpha_pm * grav * grav / omega_p.powi(5)
* (-beta_pm * (grav / (omega_p * w)).powi(4)).exp();
let ocean_dx = self.patch_size_m / self.grid_size as f64;
let nyquist_k = std::f64::consts::PI / ocean_dx;
let k_peak = omega_p * omega_p / grav;
(2.0 * pm_peak / k_peak.min(nyquist_k))
.sqrt()
.clamp(0.01, 50.0)
}
pub fn depth_color(&self, depth: f64) -> [f64; 3] {
let d = depth.min(500.0);
[
(-self.absorption_coefficients_rgb_m[0] * d).exp(),
(-self.absorption_coefficients_rgb_m[1] * d).exp(),
(-self.absorption_coefficients_rgb_m[2] * d).exp(),
]
}
}