runmat-analysis-fea 0.6.0

Finite element assembly/solve/post scaffolding for RunMat
Documentation
use crate::{FeaContactInterfaceContext, FeaPlasticityConstitutiveContext};

pub fn plasticity_severity(context: Option<&FeaPlasticityConstitutiveContext>) -> f64 {
    let Some(ctx) = context else {
        return 0.0;
    };
    if !ctx.enabled {
        return 0.0;
    }
    let yield_component = (0.012 / ctx.yield_strain.max(1.0e-6)).clamp(0.0, 1.5) / 1.5;
    let hardening_component = (ctx.hardening_modulus_ratio / 0.2).clamp(0.0, 1.5) / 1.5;
    let saturation_component = (ctx.saturation_exponent / 4.0).clamp(0.0, 1.5) / 1.5;
    (0.55 * yield_component + 0.35 * hardening_component + 0.10 * saturation_component)
        .clamp(0.0, 1.0)
}

pub fn contact_severity(context: Option<&FeaContactInterfaceContext>) -> f64 {
    let Some(ctx) = context else {
        return 0.0;
    };
    if !ctx.enabled {
        return 0.0;
    }
    let penetration_component = (ctx.max_penetration_ratio / 0.02).clamp(0.0, 1.5) / 1.5;
    let penalty_component = (1.0 / ctx.penalty_stiffness_scale.max(1.0e-6)).clamp(0.0, 1.5) / 1.5;
    let friction_component = (ctx.friction_coefficient / 0.8).clamp(0.0, 1.5) / 1.5;
    (0.5 * penetration_component + 0.3 * penalty_component + 0.2 * friction_component)
        .clamp(0.0, 1.0)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn nonlinear_coupling_severity_is_bounded() {
        let plastic = FeaPlasticityConstitutiveContext {
            enabled: true,
            yield_strain: 2.0e-4,
            hardening_modulus_ratio: 0.2,
            saturation_exponent: 4.0,
        };
        let contact = FeaContactInterfaceContext {
            enabled: true,
            penalty_stiffness_scale: 0.2,
            max_penetration_ratio: 0.03,
            friction_coefficient: 0.8,
        };
        let p = plasticity_severity(Some(&plastic));
        let c = contact_severity(Some(&contact));
        assert!((0.0..=1.0).contains(&p));
        assert!((0.0..=1.0).contains(&c));
    }
}