sciforge 0.0.3

A comprehensive scientific computing library in pure Rust with zero dependencies
Documentation
use crate::constants::{G, R_GAS};

pub fn magma_viscosity(a: f64, activation_energy: f64, temperature_k: f64) -> f64 {
    a * (activation_energy / (R_GAS * temperature_k)).exp()
}

pub fn magma_buoyancy_force(
    rho_magma: f64,
    rho_crust: f64,
    g_surface: f64,
    chamber_volume: f64,
) -> f64 {
    (rho_crust - rho_magma) * g_surface * chamber_volume
}

pub fn overpressure_threshold(tensile_strength: f64, lithostatic_pressure: f64) -> f64 {
    lithostatic_pressure + tensile_strength
}

pub fn chamber_overpressure(bulk_modulus: f64, volume_injected: f64, chamber_volume: f64) -> f64 {
    bulk_modulus * volume_injected / chamber_volume
}

pub fn effusion_rate(
    overpressure: f64,
    conduit_radius: f64,
    conduit_length: f64,
    viscosity: f64,
) -> f64 {
    std::f64::consts::PI * conduit_radius.powi(4) * overpressure
        / (8.0 * viscosity * conduit_length)
}

pub fn volcanic_explosivity_index(ejecta_volume_km3: f64) -> f64 {
    if ejecta_volume_km3 <= 0.0 {
        return 0.0;
    }
    (ejecta_volume_km3.log10() + 4.0).clamp(0.0, 8.0)
}

pub fn lava_flow_velocity(
    g_surface: f64,
    slope_angle: f64,
    thickness: f64,
    density: f64,
    viscosity: f64,
) -> f64 {
    density * g_surface * slope_angle.sin() * thickness.powi(2) / (3.0 * viscosity)
}

pub fn pyroclastic_column_height(thermal_flux: f64) -> f64 {
    0.258 * thermal_flux.powf(0.25)
}

pub fn seismic_to_eruption_probability(
    cumulative_seismic_moment: f64,
    critical_moment: f64,
    b_value: f64,
) -> f64 {
    let ratio = cumulative_seismic_moment / critical_moment;
    (1.0 - (-b_value * ratio).exp()).clamp(0.0, 1.0)
}

pub fn tidal_triggering_stress(mass_perturber: f64, distance: f64, body_radius: f64) -> f64 {
    2.0 * G * mass_perturber * body_radius / distance.powi(3)
}

pub fn coulomb_failure_stress(
    shear_stress: f64,
    normal_stress: f64,
    pore_pressure: f64,
    friction_coefficient: f64,
    cohesion: f64,
) -> f64 {
    shear_stress - friction_coefficient * (normal_stress - pore_pressure) - cohesion
}

pub fn magma_ascent_velocity(
    density_contrast: f64,
    g_surface: f64,
    conduit_radius: f64,
    viscosity: f64,
) -> f64 {
    density_contrast * g_surface * conduit_radius.powi(2) / (8.0 * viscosity)
}

pub fn volatile_exsolution_depth(saturation_pressure: f64, density: f64, g_surface: f64) -> f64 {
    saturation_pressure / (density * g_surface)
}

pub fn fragmentation_threshold(porosity: f64, vesicularity_critical: f64) -> bool {
    porosity >= vesicularity_critical
}

pub fn tephra_fallout_distance(
    column_height: f64,
    wind_speed: f64,
    particle_settling_velocity: f64,
) -> f64 {
    column_height * wind_speed / particle_settling_velocity
}

pub fn thermal_erosion_rate(
    lava_temperature: f64,
    substrate_solidus: f64,
    lava_velocity: f64,
    thermal_diffusivity: f64,
) -> f64 {
    let superheat = (lava_temperature - substrate_solidus).max(0.0);
    0.001 * superheat * lava_velocity * thermal_diffusivity.sqrt()
}

pub fn degassing_rate(
    volatile_concentration: f64,
    solubility_coefficient: f64,
    pressure: f64,
) -> f64 {
    let saturation = solubility_coefficient * pressure.sqrt();
    (volatile_concentration - saturation).max(0.0)
}

pub fn eruption_energy(ejecta_mass: f64, ejecta_velocity: f64, thermal_energy: f64) -> f64 {
    0.5 * ejecta_mass * ejecta_velocity.powi(2) + thermal_energy
}