sciforge-lib 0.0.4

Scientific computing library — mathematics, physics, chemistry, biology, astronomy, geology, meteorology.
Documentation
use std::sync::OnceLock;

#[derive(Clone, Debug)]
pub struct DecayMode {
    pub mode: &'static str,
    pub branching_ratio: f64,
    pub daughter: Option<&'static str>,
}

#[derive(Clone, Debug)]
pub struct Isotope {
    pub name: &'static str,
    pub symbol: &'static str,
    pub mass_number: u32,
    pub neutrons: u32,
    pub atomic_mass: f64,
    pub half_life: Option<f64>,
    pub half_life_unit: Option<&'static str>,
    pub stable: bool,
    pub decay_modes: Vec<DecayMode>,
    pub natural_abundance: f64,
    pub nuclear_spin: Option<&'static str>,
}

#[derive(Clone, Debug)]
pub struct Element {
    pub symbol: &'static str,
    pub name: &'static str,
    pub atomic_number: u32,
    pub atomic_mass: f64,
    pub electronegativity: Option<f64>,
    pub group: Option<u32>,
    pub period: u32,
    pub category: &'static str,
    pub electron_configuration: &'static str,
    pub isotopes: Vec<Isotope>,
}

mod actinides;
mod alkali_metals;
mod alkaline_earth_metals;
mod halogens;
mod lanthanides;
mod metalloids;
mod noble_gases;
mod nonmetals;
mod post_transition_metals;
mod superheavy_elements;
mod transition_metals;

fn init_elements() -> Vec<Element> {
    vec![
        nonmetals::hydrogen::element(),
        noble_gases::helium::element(),
        alkali_metals::lithium::element(),
        alkaline_earth_metals::beryllium::element(),
        metalloids::boron::element(),
        nonmetals::carbon::element(),
        nonmetals::nitrogen::element(),
        nonmetals::oxygen::element(),
        halogens::fluorine::element(),
        noble_gases::neon::element(),
        alkali_metals::sodium::element(),
        alkaline_earth_metals::magnesium::element(),
        post_transition_metals::aluminium::element(),
        metalloids::silicon::element(),
        nonmetals::phosphorus::element(),
        nonmetals::sulfur::element(),
        halogens::chlorine::element(),
        noble_gases::argon::element(),
        alkali_metals::potassium::element(),
        alkaline_earth_metals::calcium::element(),
        transition_metals::scandium::element(),
        transition_metals::titanium::element(),
        transition_metals::vanadium::element(),
        transition_metals::chromium::element(),
        transition_metals::manganese::element(),
        transition_metals::iron::element(),
        transition_metals::cobalt::element(),
        transition_metals::nickel::element(),
        transition_metals::copper::element(),
        transition_metals::zinc::element(),
        post_transition_metals::gallium::element(),
        metalloids::germanium::element(),
        metalloids::arsenic::element(),
        nonmetals::selenium::element(),
        halogens::bromine::element(),
        noble_gases::krypton::element(),
        alkali_metals::rubidium::element(),
        alkaline_earth_metals::strontium::element(),
        transition_metals::yttrium::element(),
        transition_metals::zirconium::element(),
        transition_metals::niobium::element(),
        transition_metals::molybdenum::element(),
        transition_metals::technetium::element(),
        transition_metals::ruthenium::element(),
        transition_metals::rhodium::element(),
        transition_metals::palladium::element(),
        transition_metals::silver::element(),
        transition_metals::cadmium::element(),
        post_transition_metals::indium::element(),
        post_transition_metals::tin::element(),
        metalloids::antimony::element(),
        metalloids::tellurium::element(),
        halogens::iodine::element(),
        noble_gases::xenon::element(),
        alkali_metals::cesium::element(),
        alkaline_earth_metals::barium::element(),
        lanthanides::lanthanum::element(),
        lanthanides::cerium::element(),
        lanthanides::praseodymium::element(),
        lanthanides::neodymium::element(),
        lanthanides::promethium::element(),
        lanthanides::samarium::element(),
        lanthanides::europium::element(),
        lanthanides::gadolinium::element(),
        lanthanides::terbium::element(),
        lanthanides::dysprosium::element(),
        lanthanides::holmium::element(),
        lanthanides::erbium::element(),
        lanthanides::thulium::element(),
        lanthanides::ytterbium::element(),
        lanthanides::lutetium::element(),
        transition_metals::hafnium::element(),
        transition_metals::tantalum::element(),
        transition_metals::tungsten::element(),
        transition_metals::rhenium::element(),
        transition_metals::osmium::element(),
        transition_metals::iridium::element(),
        transition_metals::platinum::element(),
        transition_metals::gold::element(),
        transition_metals::mercury::element(),
        post_transition_metals::thallium::element(),
        post_transition_metals::lead::element(),
        post_transition_metals::bismuth::element(),
        post_transition_metals::polonium::element(),
        halogens::astatine::element(),
        noble_gases::radon::element(),
        alkali_metals::francium::element(),
        alkaline_earth_metals::radium::element(),
        actinides::actinium::element(),
        actinides::thorium::element(),
        actinides::protactinium::element(),
        actinides::uranium::element(),
        actinides::neptunium::element(),
        actinides::plutonium::element(),
        actinides::americium::element(),
        actinides::curium::element(),
        actinides::berkelium::element(),
        actinides::californium::element(),
        actinides::einsteinium::element(),
        actinides::fermium::element(),
        actinides::mendelevium::element(),
        actinides::nobelium::element(),
        actinides::lawrencium::element(),
        superheavy_elements::rutherfordium::element(),
        superheavy_elements::dubnium::element(),
        superheavy_elements::seaborgium::element(),
        superheavy_elements::bohrium::element(),
        superheavy_elements::hassium::element(),
        superheavy_elements::meitnerium::element(),
        superheavy_elements::darmstadtium::element(),
        superheavy_elements::roentgenium::element(),
        superheavy_elements::copernicium::element(),
        superheavy_elements::nihonium::element(),
        superheavy_elements::flerovium::element(),
        superheavy_elements::moscovium::element(),
        superheavy_elements::livermorium::element(),
        halogens::tennessine::element(),
        noble_gases::oganesson::element(),
    ]
}

fn elements() -> &'static Vec<Element> {
    static ELEMENTS: OnceLock<Vec<Element>> = OnceLock::new();
    ELEMENTS.get_or_init(init_elements)
}

pub fn by_atomic_number(z: u32) -> Option<&'static Element> {
    if (1..=118).contains(&z) {
        Some(&elements()[(z - 1) as usize])
    } else {
        None
    }
}

pub fn all() -> &'static [Element] {
    elements()
}

pub fn by_symbol(sym: &str) -> Option<&'static Element> {
    elements().iter().find(|e| e.symbol == sym)
}

pub fn atomic_mass(z: u32) -> f64 {
    by_atomic_number(z).map_or(0.0, |e| e.atomic_mass)
}

pub fn electronegativity(z: u32) -> Option<f64> {
    by_atomic_number(z).and_then(|e| e.electronegativity)
}