sciforge 0.0.3

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

pub fn electric_field_point_charge(q: f64, r: [f64; 3]) -> [f64; 3] {
    let r_mag = (r[0] * r[0] + r[1] * r[1] + r[2] * r[2]).sqrt();
    if r_mag < 1e-30 {
        return [0.0; 3];
    }
    let e_mag = K_COULOMB * q / (r_mag * r_mag);
    [
        e_mag * r[0] / r_mag,
        e_mag * r[1] / r_mag,
        e_mag * r[2] / r_mag,
    ]
}

pub fn electric_potential_point(q: f64, r: f64) -> f64 {
    K_COULOMB * q / r
}

pub fn magnetic_field_wire(current: f64, r: f64) -> f64 {
    MU_0 * current / (2.0 * std::f64::consts::PI * r)
}

pub fn magnetic_field_solenoid(n_per_length: f64, current: f64) -> f64 {
    MU_0 * n_per_length * current
}

pub fn magnetic_field_loop(current: f64, radius: f64, z: f64) -> f64 {
    MU_0 * current * radius * radius / (2.0 * (radius * radius + z * z).powf(1.5))
}

pub fn biot_savart_segment(current: f64, dl: [f64; 3], r: [f64; 3]) -> [f64; 3] {
    let r_mag = (r[0] * r[0] + r[1] * r[1] + r[2] * r[2]).sqrt();
    if r_mag < 1e-30 {
        return [0.0; 3];
    }
    let cross = [
        dl[1] * r[2] - dl[2] * r[1],
        dl[2] * r[0] - dl[0] * r[2],
        dl[0] * r[1] - dl[1] * r[0],
    ];
    let factor = MU_0 * current / (4.0 * std::f64::consts::PI * r_mag.powi(3));
    [factor * cross[0], factor * cross[1], factor * cross[2]]
}

pub fn lorentz_force(q: f64, v: [f64; 3], e: [f64; 3], b: [f64; 3]) -> [f64; 3] {
    let vxb = [
        v[1] * b[2] - v[2] * b[1],
        v[2] * b[0] - v[0] * b[2],
        v[0] * b[1] - v[1] * b[0],
    ];
    [
        q * (e[0] + vxb[0]),
        q * (e[1] + vxb[1]),
        q * (e[2] + vxb[2]),
    ]
}

pub fn poynting_vector(e: [f64; 3], b: [f64; 3]) -> [f64; 3] {
    let inv_mu0 = 1.0 / MU_0;
    [
        inv_mu0 * (e[1] * b[2] - e[2] * b[1]),
        inv_mu0 * (e[2] * b[0] - e[0] * b[2]),
        inv_mu0 * (e[0] * b[1] - e[1] * b[0]),
    ]
}

pub fn energy_density_em(e: [f64; 3], b: [f64; 3]) -> f64 {
    let e_sq = e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
    let b_sq = b[0] * b[0] + b[1] * b[1] + b[2] * b[2];
    0.5 * EPSILON_0 * e_sq + 0.5 * b_sq / MU_0
}

pub fn electric_dipole_field(p: [f64; 3], r: [f64; 3]) -> [f64; 3] {
    let r_mag = (r[0] * r[0] + r[1] * r[1] + r[2] * r[2]).sqrt();
    if r_mag < 1e-30 {
        return [0.0; 3];
    }
    let r5 = r_mag.powi(5);
    let r3 = r_mag.powi(3);
    let p_dot_r = p[0] * r[0] + p[1] * r[1] + p[2] * r[2];
    let factor = 1.0 / (4.0 * std::f64::consts::PI * EPSILON_0);
    [
        factor * (3.0 * p_dot_r * r[0] / r5 - p[0] / r3),
        factor * (3.0 * p_dot_r * r[1] / r5 - p[1] / r3),
        factor * (3.0 * p_dot_r * r[2] / r5 - p[2] / r3),
    ]
}

pub fn magnetic_dipole_field(m: [f64; 3], r: [f64; 3]) -> [f64; 3] {
    let r_mag = (r[0] * r[0] + r[1] * r[1] + r[2] * r[2]).sqrt();
    if r_mag < 1e-30 {
        return [0.0; 3];
    }
    let r5 = r_mag.powi(5);
    let r3 = r_mag.powi(3);
    let m_dot_r = m[0] * r[0] + m[1] * r[1] + m[2] * r[2];
    let factor = MU_0 / (4.0 * std::f64::consts::PI);
    [
        factor * (3.0 * m_dot_r * r[0] / r5 - m[0] / r3),
        factor * (3.0 * m_dot_r * r[1] / r5 - m[1] / r3),
        factor * (3.0 * m_dot_r * r[2] / r5 - m[2] / r3),
    ]
}

pub fn capacitance_parallel_plate(area: f64, distance: f64, epsilon_r: f64) -> f64 {
    epsilon_r * EPSILON_0 * area / distance
}

pub fn inductance_solenoid(n_turns: f64, length: f64, area: f64) -> f64 {
    MU_0 * n_turns * n_turns * area / length
}

pub fn cyclotron_frequency(charge: f64, mass: f64, b: f64) -> f64 {
    charge.abs() * b / mass
}

pub fn larmor_radius(mass: f64, v_perp: f64, charge: f64, b: f64) -> f64 {
    mass * v_perp / (charge.abs() * b)
}

pub fn plasma_frequency(number_density: f64, mass: f64, charge: f64) -> f64 {
    (number_density * charge * charge / (EPSILON_0 * mass)).sqrt()
}

pub fn debye_length(temperature: f64, number_density: f64, charge: f64) -> f64 {
    use crate::constants::K_B;
    (EPSILON_0 * K_B * temperature / (number_density * charge * charge)).sqrt()
}