use sciforge::hub::domain::geology::petrology::{
differentiation_index, liquidus_temperature, mg_number, solidus_depression,
total_alkali_silica, viscosity_arrhenius,
};
pub struct Magma {
pub sio2_wt_percent: f64,
pub na2o_wt_percent: f64,
pub k2o_wt_percent: f64,
pub mgo_wt_percent: f64,
pub feo_wt_percent: f64,
pub h2o_wt_percent: f64,
pub temperature_c: f64,
}
impl Magma {
pub fn basaltic() -> Self {
Self {
sio2_wt_percent: 49.0,
na2o_wt_percent: 2.5,
k2o_wt_percent: 0.5,
mgo_wt_percent: 8.0,
feo_wt_percent: 10.0,
h2o_wt_percent: 1.0,
temperature_c: 1200.0,
}
}
pub fn andesitic() -> Self {
Self {
sio2_wt_percent: 58.0,
na2o_wt_percent: 3.5,
k2o_wt_percent: 1.5,
mgo_wt_percent: 4.0,
feo_wt_percent: 7.0,
h2o_wt_percent: 3.0,
temperature_c: 1000.0,
}
}
pub fn rhyolitic() -> Self {
Self {
sio2_wt_percent: 72.0,
na2o_wt_percent: 4.0,
k2o_wt_percent: 4.0,
mgo_wt_percent: 0.5,
feo_wt_percent: 2.0,
h2o_wt_percent: 5.0,
temperature_c: 800.0,
}
}
pub fn mg_number(&self) -> f64 {
mg_number(self.mgo_wt_percent, self.feo_wt_percent)
}
pub fn total_alkali(&self) -> f64 {
total_alkali_silica(
self.na2o_wt_percent + self.k2o_wt_percent,
self.sio2_wt_percent,
)
}
pub fn liquidus_temp_c(&self) -> f64 {
liquidus_temperature(self.sio2_wt_percent, self.h2o_wt_percent, 1000.0)
}
pub fn viscosity_pa_s(&self) -> f64 {
let temp_k = self.temperature_c + crate::CELSIUS_TO_KELVIN;
let a = crate::VISCOSITY_SHAW_A;
let ea = crate::EA_VISCOSITY_MAGMA;
viscosity_arrhenius(a, ea, temp_k)
}
pub fn solidus_depression_c(&self) -> f64 {
solidus_depression(self.h2o_wt_percent, 1000.0, 1.0)
}
pub fn differentiation_idx(&self) -> f64 {
differentiation_index(
self.sio2_wt_percent,
self.na2o_wt_percent,
self.k2o_wt_percent,
0.0,
)
}
}
pub fn volcanic_explosivity_index(ejecta_volume_km3: f64) -> u8 {
if ejecta_volume_km3 < 1e-6 {
0
} else if ejecta_volume_km3 < 1e-4 {
1
} else if ejecta_volume_km3 < 1e-3 {
2
} else if ejecta_volume_km3 < 1e-2 {
3
} else if ejecta_volume_km3 < 0.1 {
4
} else if ejecta_volume_km3 < 1.0 {
5
} else if ejecta_volume_km3 < 10.0 {
6
} else if ejecta_volume_km3 < 100.0 {
7
} else {
8
}
}