use sciforge::hub::domain::common::constants::{EARTH_RADIUS, R_GAS, SIGMA_SB};
use sciforge::hub::domain::physics::thermodynamics::clausius_clapeyron;
use sciforge::hub::prelude::constants::elements::atomic_mass;
pub const OCEANSURFACEAREAM2: f64 = 3.61e14;
pub const MEANOCEANDEPTHM: f64 = 3688.0;
pub const OCEANVOLUMEM3: f64 = 1.335e18;
pub const MEANSALINITYPSU: f64 = 35.0;
pub const SEAWATERDENSITY: f64 = 1025.0;
pub struct OceanLayer {
pub name: &'static str,
pub depthrangem: (f64, f64),
pub meantemperaturec: f64,
pub meansalinitypsu: f64,
}
impl OceanLayer {
pub fn densitykgm3(&self) -> f64 {
let t = self.meantemperaturec;
let s = self.meansalinitypsu;
999.842594 + 6.793952e-2 * t - 9.095290e-3 * t * t + 1.001685e-4 * t * t * t + 0.824493 * s
- 4.0899e-3 * t * s
}
pub fn pressureatdepth(&self, depthm: f64) -> f64 {
SEAWATERDENSITY * *crate::SURFACEGRAVITY * depthm
}
pub fn soundspeedms(&self) -> f64 {
let t = self.meantemperaturec;
let s = self.meansalinitypsu;
let d = (self.depthrangem.0 + self.depthrangem.1) / 2.0;
1449.2 + 4.6 * t - 0.055 * t * t
+ 0.00029 * t * t * t
+ (1.34 - 0.01 * t) * (s - 35.0)
+ 0.016 * d
}
}
pub fn surfacemixedlayer() -> OceanLayer {
OceanLayer {
name: "Surface Mixed Layer",
depthrangem: (0.0, 200.0),
meantemperaturec: 17.0,
meansalinitypsu: 35.0,
}
}
pub fn thermocline() -> OceanLayer {
OceanLayer {
name: "Thermocline",
depthrangem: (200.0, 1000.0),
meantemperaturec: 8.0,
meansalinitypsu: 34.8,
}
}
pub fn deepocean() -> OceanLayer {
OceanLayer {
name: "Deep Ocean",
depthrangem: (1000.0, 4000.0),
meantemperaturec: 2.0,
meansalinitypsu: 34.7,
}
}
pub fn thermohalineoverturningratesv() -> f64 {
17.0
}
pub fn oceanheatcontentj(tempanomalyk: f64, depthm: f64) -> f64 {
SEAWATERDENSITY * crate::CPSEAWATER * OCEANSURFACEAREAM2 * depthm * tempanomalyk
}
pub fn sealevelrisethermalm(tempanomalyk: f64, depthm: f64) -> f64 {
let expansioncoeff = 2.0e-4;
expansioncoeff * tempanomalyk * depthm
}
pub fn surfacelongwaveradiationwm2(sstc: f64, emissivity: f64) -> f64 {
let tk = sstc + crate::CELSIUSTOKELVIN;
emissivity * SIGMA_SB * tk.powi(4)
}
pub fn oceanareafromfraction(fraction: f64) -> f64 {
4.0 * std::f64::consts::PI * EARTH_RADIUS * EARTH_RADIUS * fraction
}
pub fn vaporpressureoverocean(sstc: f64) -> f64 {
let pref = crate::VAPORPRESSURE0C;
let tref = crate::CELSIUSTOKELVIN;
let t2 = sstc + crate::CELSIUSTOKELVIN;
let lvap = *crate::LVAPORIZATION;
clausius_clapeyron(pref, tref, t2, lvap)
}
pub fn dissolvedgashenry(partialpressurepa: f64, temperaturec: f64, henryconstmolm3pa: f64) -> f64 {
let tk = temperaturec + crate::CELSIUSTOKELVIN;
let correction = (-2400.0 * (1.0 / tk - 1.0 / 298.15) / R_GAS).exp();
henryconstmolm3pa * partialpressurepa * correction
}
pub fn naclmolarmass() -> f64 {
(atomic_mass(11) + atomic_mass(17)) * 1e-3
}
pub fn naclmolality35psu() -> f64 {
0.035 / naclmolarmass()
}