use sciforge::hub::domain::common::constants::R_GAS;
pub const METALLICHYDROGENBULKMODULUS: f64 = 1.6e11;
pub const MOLECULARHYDROGENBULKMODULUS: f64 = 1.3e9;
pub struct InteriorOceanLayer {
pub name: &'static str,
pub depthkm: f64,
pub thicknesskm: f64,
pub temperaturek: f64,
pub pressuregpa: f64,
pub densitykgm3: f64,
}
impl InteriorOceanLayer {
pub fn soundspeedms(&self) -> f64 {
let bulk = if self.densitykgm3 > 800.0 {
METALLICHYDROGENBULKMODULUS
} else {
MOLECULARHYDROGENBULKMODULUS
};
(bulk / self.densitykgm3).sqrt()
}
pub fn dynamicviscositypas(&self) -> f64 {
let a = 1e-3;
let b = 2500.0;
a * (b / self.temperaturek).exp()
}
pub fn specificvolumem3kg(&self) -> f64 {
if self.densitykgm3.abs() < 1e-30 {
return 0.0;
}
1.0 / self.densitykgm3
}
pub fn thermalexpansioncoeff(&self) -> f64 {
let dt = 1.0;
let alpha = 1e-5 * (self.temperaturek / 300.0);
alpha * dt / dt
}
pub fn adiabatictemperaturegradientkperkm(&self) -> f64 {
let cp = 14300.0;
let alpha = self.thermalexpansioncoeff();
alpha * crate::ONEBARTEMPK * 9.81 / cp * 1000.0
}
pub fn potentialtemperaturek(&self, refdepthkm: f64) -> f64 {
let cp = 14300.0;
let deltaz = (self.depthkm - refdepthkm) * 1000.0;
self.temperaturek + (9.81 * deltaz) / cp
}
pub fn bruntvasalafrequency(&self, drhodz: f64) -> f64 {
if self.densitykgm3.abs() < 1e-30 {
return 0.0;
}
let n2 = -(9.81 / self.densitykgm3) * drhodz;
if n2 > 0.0 { n2.sqrt() } else { 0.0 }
}
pub fn heatcontentjperm2(&self) -> f64 {
let cp = 14300.0;
self.densitykgm3 * cp * self.temperaturek * self.thicknesskm * 1000.0
}
pub fn massperunitareakg(&self) -> f64 {
self.densitykgm3 * self.thicknesskm * 1000.0
}
}
pub fn molecularhydrogenfluid() -> InteriorOceanLayer {
InteriorOceanLayer {
name: "Molecular Hydrogen Fluid",
depthkm: 1000.0,
thicknesskm: 20000.0,
temperaturek: 5000.0,
pressuregpa: 2.0,
densitykgm3: 300.0,
}
}
pub fn metallichydrogenocean() -> InteriorOceanLayer {
InteriorOceanLayer {
name: "Metallic Hydrogen Ocean",
depthkm: 21000.0,
thicknesskm: 40000.0,
temperaturek: 15000.0,
pressuregpa: 200.0,
densitykgm3: 1000.0,
}
}
pub fn rockycorelayer() -> InteriorOceanLayer {
InteriorOceanLayer {
name: "Rocky/Icy Core",
depthkm: 61000.0,
thicknesskm: 8911.0,
temperaturek: 36000.0,
pressuregpa: 4000.0,
densitykgm3: 25000.0,
}
}
pub fn idealgasdensity(pressurepascal: f64, tempk: f64, molarmasskg: f64) -> f64 {
if tempk.abs() < 1e-30 {
return 0.0;
}
pressurepascal * molarmasskg / (R_GAS * tempk)
}