sciforge-lib 0.0.4

Scientific computing library — mathematics, physics, chemistry, biology, astronomy, geology, meteorology.
Documentation
use std::f64::consts::PI;

pub fn cutoff_frequency_te_mn(m: u32, n: u32, a_m: f64, b_m: f64) -> f64 {
    let c = crate::constants::C;
    let term = (m as f64 / a_m).powi(2) + (n as f64 / b_m).powi(2);
    0.5 * c * term.sqrt()
}

pub fn cutoff_frequency_tm_mn(m: u32, n: u32, a_m: f64, b_m: f64) -> f64 {
    cutoff_frequency_te_mn(m, n, a_m, b_m)
}

pub fn cutoff_frequency_te10_rectangular(a_m: f64) -> f64 {
    crate::constants::C / (2.0 * a_m)
}

pub fn cutoff_wavelength_rectangular(m: u32, n: u32, a_m: f64, b_m: f64) -> f64 {
    let term = (m as f64 / a_m).powi(2) + (n as f64 / b_m).powi(2);
    2.0 / term.sqrt()
}

pub fn guided_wavelength(free_space_wavelength_m: f64, cutoff_wavelength_m: f64) -> f64 {
    let ratio = (free_space_wavelength_m / cutoff_wavelength_m).powi(2);
    if ratio >= 1.0 {
        f64::INFINITY
    } else {
        free_space_wavelength_m / (1.0 - ratio).sqrt()
    }
}

pub fn phase_velocity_waveguide(
    free_space_wavelength_m: f64,
    cutoff_wavelength_m: f64,
) -> f64 {
    let c = crate::constants::C;
    let ratio = (free_space_wavelength_m / cutoff_wavelength_m).powi(2);
    if ratio >= 1.0 {
        f64::INFINITY
    } else {
        c / (1.0 - ratio).sqrt()
    }
}

pub fn group_velocity_waveguide(
    free_space_wavelength_m: f64,
    cutoff_wavelength_m: f64,
) -> f64 {
    let c = crate::constants::C;
    let ratio = (free_space_wavelength_m / cutoff_wavelength_m).powi(2);
    c * (1.0 - ratio).sqrt()
}

pub fn wave_impedance_te(
    free_space_wavelength_m: f64,
    cutoff_wavelength_m: f64,
) -> f64 {
    let eta_0 = (crate::constants::MU_0 / crate::constants::EPSILON_0).sqrt();
    let ratio = (free_space_wavelength_m / cutoff_wavelength_m).powi(2);
    eta_0 / (1.0 - ratio).sqrt()
}

pub fn wave_impedance_tm(
    free_space_wavelength_m: f64,
    cutoff_wavelength_m: f64,
) -> f64 {
    let eta_0 = (crate::constants::MU_0 / crate::constants::EPSILON_0).sqrt();
    let ratio = (free_space_wavelength_m / cutoff_wavelength_m).powi(2);
    eta_0 * (1.0 - ratio).sqrt()
}

pub fn attenuation_te10_rectangular(
    a_m: f64,
    b_m: f64,
    frequency_hz: f64,
    surface_resistance_ohm: f64,
) -> f64 {
    let fc = crate::constants::C / (2.0 * a_m);
    let f = frequency_hz;
    let eta_0 = (crate::constants::MU_0 / crate::constants::EPSILON_0).sqrt();
    let ratio = (fc / f).powi(2);
    let bracket = 1.0 + 2.0 * b_m / a_m * ratio;
    surface_resistance_ohm / (b_m * eta_0 * (1.0 - ratio).sqrt()) * bracket
}

pub fn surface_resistance(omega_rad_per_s: f64, mu_relative: f64, conductivity_s_per_m: f64) -> f64 {
    let mu = mu_relative * crate::constants::MU_0;
    (omega_rad_per_s * mu / (2.0 * conductivity_s_per_m)).sqrt()
}

pub fn cavity_resonant_frequency_rectangular(
    m: u32,
    n: u32,
    p: u32,
    a_m: f64,
    b_m: f64,
    d_m: f64,
) -> f64 {
    let c = crate::constants::C;
    let term = (m as f64 / a_m).powi(2)
        + (n as f64 / b_m).powi(2)
        + (p as f64 / d_m).powi(2);
    0.5 * c * term.sqrt()
}

pub fn cavity_resonant_frequency_cylindrical_te(
    m: u32,
    n: u32,
    p: u32,
    radius_m: f64,
    length_m: f64,
) -> f64 {
    let chi_prime = match (m, n) {
        (0, 1) => 3.832,
        (1, 1) => 1.841,
        (2, 1) => 3.054,
        (0, 2) => 7.016,
        (1, 2) => 5.331,
        _ => 1.841 + (m as f64) * 1.5 + (n as f64) * 1.0,
    };
    let c = crate::constants::C;
    let term =
        (chi_prime / radius_m).powi(2) + (p as f64 * PI / length_m).powi(2);
    c / (2.0 * PI) * term.sqrt()
}

pub fn quality_factor_cavity(
    stored_energy_j: f64,
    power_loss_w: f64,
    frequency_hz: f64,
) -> f64 {
    2.0 * PI * frequency_hz * stored_energy_j / power_loss_w
}

pub fn quality_factor_loaded(q_unloaded: f64, q_external: f64) -> f64 {
    1.0 / (1.0 / q_unloaded + 1.0 / q_external)
}

pub fn coupling_coefficient(q_unloaded: f64, q_external: f64) -> f64 {
    q_unloaded / q_external
}

pub fn dielectric_filled_waveguide_cutoff(
    cutoff_air_hz: f64,
    epsilon_r: f64,
) -> f64 {
    cutoff_air_hz / epsilon_r.sqrt()
}

pub fn power_handling_capacity(
    breakdown_field_v_per_m: f64,
    a_m: f64,
    b_m: f64,
    cutoff_wavelength_m: f64,
    free_space_wavelength_m: f64,
) -> f64 {
    let eta_0 = (crate::constants::MU_0 / crate::constants::EPSILON_0).sqrt();
    let ratio = (free_space_wavelength_m / cutoff_wavelength_m).powi(2);
    breakdown_field_v_per_m * breakdown_field_v_per_m * a_m * b_m
        * (1.0 - ratio).sqrt()
        / (4.0 * eta_0)
}