sciforge-lib 0.0.4

Scientific computing library — mathematics, physics, chemistry, biology, astronomy, geology, meteorology.
Documentation
use crate::constants::{C, E_CHARGE, EPSILON_0, MU_0};
use std::f64::consts::PI;

pub fn lorentz_factor(velocity_m_per_s: f64) -> f64 {
    let beta_sq = (velocity_m_per_s / C).powi(2);
    1.0 / (1.0 - beta_sq).sqrt()
}

pub fn beta_factor(velocity_m_per_s: f64) -> f64 {
    velocity_m_per_s / C
}

pub fn e_field_transverse_boost(
    e_perp_v_per_m: f64,
    b_perp_t: f64,
    velocity_m_per_s: f64,
    boost_direction_sign: f64,
) -> f64 {
    let gamma = lorentz_factor(velocity_m_per_s);
    gamma * (e_perp_v_per_m + boost_direction_sign * velocity_m_per_s * b_perp_t)
}

pub fn b_field_transverse_boost(
    b_perp_t: f64,
    e_perp_v_per_m: f64,
    velocity_m_per_s: f64,
    boost_direction_sign: f64,
) -> f64 {
    let gamma = lorentz_factor(velocity_m_per_s);
    gamma * (b_perp_t - boost_direction_sign * velocity_m_per_s * e_perp_v_per_m / (C * C))
}

pub fn doppler_shift_relativistic_em(
    source_frequency_hz: f64,
    velocity_m_per_s: f64,
    angle_rad: f64,
) -> f64 {
    let beta = velocity_m_per_s / C;
    let gamma = 1.0 / (1.0 - beta * beta).sqrt();
    source_frequency_hz / (gamma * (1.0 - beta * angle_rad.cos()))
}

pub fn aberration_angle(angle_source_rad: f64, velocity_m_per_s: f64) -> f64 {
    let beta = velocity_m_per_s / C;
    let cos_t = (angle_source_rad.cos() - beta) / (1.0 - beta * angle_source_rad.cos());
    cos_t.acos()
}

pub fn lienard_wiechert_potential_scalar(
    charge_c: f64,
    distance_m: f64,
    velocity_m_per_s: f64,
    angle_rad: f64,
) -> f64 {
    let beta = velocity_m_per_s / C;
    charge_c / (4.0 * PI * EPSILON_0 * distance_m * (1.0 - beta * angle_rad.cos()))
}

pub fn lienard_wiechert_vector_magnitude(
    charge_c: f64,
    velocity_m_per_s: f64,
    distance_m: f64,
    angle_rad: f64,
) -> f64 {
    let beta = velocity_m_per_s / C;
    MU_0 * charge_c * velocity_m_per_s
        / (4.0 * PI * distance_m * (1.0 - beta * angle_rad.cos()))
}

pub fn larmor_power_relativistic(
    acceleration_m_per_s2_parallel: f64,
    acceleration_m_per_s2_perp: f64,
    velocity_m_per_s: f64,
) -> f64 {
    let gamma = lorentz_factor(velocity_m_per_s);
    let prefactor = E_CHARGE * E_CHARGE / (6.0 * PI * EPSILON_0 * C.powi(3));
    prefactor * gamma.powi(6)
        * (acceleration_m_per_s2_parallel.powi(2)
            + acceleration_m_per_s2_perp.powi(2) / (gamma * gamma))
}

pub fn synchrotron_critical_frequency(
    gamma_lorentz: f64,
    radius_m: f64,
) -> f64 {
    3.0 * gamma_lorentz.powi(3) * C / (4.0 * PI * radius_m)
}

pub fn synchrotron_total_power(
    gamma_lorentz: f64,
    radius_m: f64,
) -> f64 {
    let prefactor = E_CHARGE * E_CHARGE * C / (6.0 * PI * EPSILON_0);
    prefactor * gamma_lorentz.powi(4) / (radius_m * radius_m)
}

pub fn synchrotron_energy_loss_per_turn_ev(
    gamma_lorentz: f64,
    radius_m: f64,
) -> f64 {
    let prefactor = E_CHARGE / (3.0 * EPSILON_0);
    prefactor * gamma_lorentz.powi(4) / radius_m / E_CHARGE
}

pub fn cherenkov_angle(refractive_index: f64, velocity_m_per_s: f64) -> f64 {
    let beta = velocity_m_per_s / C;
    (1.0 / (refractive_index * beta)).acos()
}

pub fn cherenkov_threshold_velocity(refractive_index: f64) -> f64 {
    C / refractive_index
}

pub fn cherenkov_photons_per_unit_length(
    charge_number: f64,
    refractive_index: f64,
    velocity_m_per_s: f64,
    wavelength_min_m: f64,
    wavelength_max_m: f64,
) -> f64 {
    let alpha = crate::constants::ALPHA_FINE;
    let beta = velocity_m_per_s / C;
    let sin2 = 1.0 - 1.0 / (refractive_index * beta).powi(2);
    if sin2 <= 0.0 {
        0.0
    } else {
        2.0 * PI * alpha * charge_number * charge_number * sin2
            * (1.0 / wavelength_min_m - 1.0 / wavelength_max_m)
    }
}

pub fn relativistic_cyclotron_frequency(
    charge_c: f64,
    b_t: f64,
    mass_kg: f64,
    velocity_m_per_s: f64,
) -> f64 {
    let gamma = lorentz_factor(velocity_m_per_s);
    charge_c.abs() * b_t / (gamma * mass_kg)
}

pub fn thomas_precession_frequency(
    acceleration_m_per_s2: f64,
    velocity_m_per_s: f64,
) -> f64 {
    let gamma = lorentz_factor(velocity_m_per_s);
    (gamma * gamma / (gamma + 1.0)) * (acceleration_m_per_s2 * velocity_m_per_s) / (C * C)
}

pub fn invariant_em_field(
    e_v_per_m: f64,
    b_t: f64,
) -> f64 {
    e_v_per_m * e_v_per_m - C * C * b_t * b_t
}

pub fn invariant_e_dot_b(
    ex: f64, ey: f64, ez: f64,
    bx: f64, by: f64, bz: f64,
) -> f64 {
    ex * bx + ey * by + ez * bz
}