sciforge-lib 0.0.4

Scientific computing library — mathematics, physics, chemistry, biology, astronomy, geology, meteorology.
Documentation
use crate::constants::R_GAS;
use crate::constants::chemistry::molecules::Molecule;
use crate::constants::chemistry::thermo::heat_capacity::{self, HeatCapacity};
use crate::constants::physics::transport::sutherland::{self, SutherlandCoeffs};
use crate::constants::physics::{P_STD, T_STD};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GasFamily {
    Atmosphere,
    Inert,
    Combustion,
    Fuel,
    Process,
    Refrigerant,
    Industrial,
}

#[derive(Debug, Clone, Copy)]
pub struct Gas {
    pub name: &'static str,
    pub formula: &'static str,
    pub family: GasFamily,
    pub molar_mass_kg_per_mol: f64,
    pub cp_j_kgk_ref: f64,
    pub cv_j_kgk_ref: f64,
    pub density_kg_m3_ref: f64,
    pub temperature_ref_k: f64,
    pub pressure_ref_pa: f64,
    pub sutherland_ref_viscosity_pa_s: f64,
    pub sutherland_ref_temp_k: f64,
    pub sutherland_constant_k: f64,
}

impl Gas {
    pub fn specific_gas_constant_j_kgk(&self) -> f64 {
        R_GAS / self.molar_mass_kg_per_mol
    }

    pub fn gamma(&self) -> f64 {
        self.cp_j_kgk_ref / self.cv_j_kgk_ref
    }

    pub fn density_ideal_kg_m3(&self, pressure_pa: f64, temperature_k: f64) -> f64 {
        pressure_pa / (self.specific_gas_constant_j_kgk() * temperature_k)
    }

    pub fn speed_of_sound_m_s(&self, temperature_k: f64) -> f64 {
        (self.gamma() * self.specific_gas_constant_j_kgk() * temperature_k).sqrt()
    }

    pub fn dynamic_viscosity_pa_s(&self, temperature_k: f64) -> f64 {
        let t = temperature_k;
        let t0 = self.sutherland_ref_temp_k;
        let c = self.sutherland_constant_k;
        self.sutherland_ref_viscosity_pa_s * (t / t0).powf(1.5) * (t0 + c) / (t + c)
    }

    pub fn reynolds_number(
        &self,
        velocity_m_s: f64,
        length_m: f64,
        pressure_pa: f64,
        temperature_k: f64,
    ) -> f64 {
        let rho = self.density_ideal_kg_m3(pressure_pa, temperature_k);
        let mu = self.dynamic_viscosity_pa_s(temperature_k);
        rho * velocity_m_s * length_m / mu
    }

    pub fn from_lib_data(
        molecule: &Molecule,
        cp: &HeatCapacity,
        sutherland: &SutherlandCoeffs,
        family: GasFamily,
    ) -> Self {
        let molar_mass_kg = molecule.molar_mass * 1.0e-3;
        let cp_mass = cp.cp_j_molk_298 / molar_mass_kg;
        let cv_mass = cp.cv_j_molk_298 / molar_mass_kg;
        let t_ref = T_STD;
        let p_ref = P_STD;
        let r_specific = R_GAS / molar_mass_kg;
        let density = p_ref / (r_specific * t_ref);
        Gas {
            name: molecule.name,
            formula: molecule.formula,
            family,
            molar_mass_kg_per_mol: molar_mass_kg,
            cp_j_kgk_ref: cp_mass,
            cv_j_kgk_ref: cv_mass,
            density_kg_m3_ref: density,
            temperature_ref_k: t_ref,
            pressure_ref_pa: p_ref,
            sutherland_ref_viscosity_pa_s: sutherland.mu_ref_pa_s,
            sutherland_ref_temp_k: sutherland.t_ref_k,
            sutherland_constant_k: sutherland.s_k,
        }
    }

    pub fn from_molecule(molecule: &Molecule, family: GasFamily) -> Option<Self> {
        let cp = heat_capacity::by_formula_phase(molecule.formula, "gas")?;
        let suth = sutherland::by_formula(molecule.formula)?;
        Some(Self::from_lib_data(molecule, cp, suth, family))
    }
}

fn preset(formula: &str, family: GasFamily) -> Gas {
    let mol = crate::constants::chemistry::molecules::by_formula(formula)
        .expect("preset molecule must exist in molecules table");
    Gas::from_molecule(mol, family).expect("preset must have heat_capacity + sutherland entries")
}

pub fn dry_air() -> Gas {
    preset("AIR", GasFamily::Atmosphere)
}

pub fn r134a() -> Gas {
    preset("CH2FCF3", GasFamily::Refrigerant)
}

pub fn r32() -> Gas {
    preset("CH2F2", GasFamily::Refrigerant)
}

pub fn r125() -> Gas {
    preset("C2HF5", GasFamily::Refrigerant)
}

pub fn r1234yf() -> Gas {
    preset("C3H2F4", GasFamily::Refrigerant)
}

pub fn r410a() -> Gas {
    preset("R410A", GasFamily::Refrigerant)
}