conspire 0.7.6

The Rust interface to conspire.
Documentation
use super::*;
use crate::{
    EPSILON,
    math::assert::{Assert, AssertionError, perturbation},
    math::{ContractWith, TensorArray},
};

fn model() -> ViscoplasticFlow {
    ViscoplasticFlow {
        yield_stress: Stress::pascals(2.0),
        hardening_slope: Stress::pascals(1.0),
        rate_sensitivity: 0.25,
        reference_flow_rate: Rate::per_second(0.1),
    }
}

fn deviatoric_mandel_stress() -> MandelStressElastic {
    MandelStressElastic::from([[1.3, 0.7, -0.4], [0.7, -0.9, 1.1], [-0.4, 1.1, -0.4]])
}

#[test]
fn plastic_stretching_rate_from_finite_difference_of_dual_dissipation_potential()
-> Result<(), AssertionError> {
    let model = model();
    let mandel_stress = deviatoric_mandel_stress();
    let yield_stress = model.yield_stress;
    let mut finite_difference = StretchingRatePlastic::zero();
    for i in 0..3 {
        for j in 0..3 {
            let mut plus = deviatoric_mandel_stress();
            plus[i][j] += perturbation(0.5 * EPSILON);
            let mut minus = deviatoric_mandel_stress();
            minus[i][j] -= perturbation(0.5 * EPSILON);
            finite_difference[i][j] = (model.dual_dissipation_potential(plus, yield_stress)?
                - model.dual_dissipation_potential(minus, yield_stress)?)
                / Quantity::<Stress>::new(EPSILON);
        }
    }
    Assert::default().eq_within_fd_tol(
        &model.plastic_stretching_rate(mandel_stress, yield_stress)?,
        &finite_difference,
    )
}

#[test]
fn deviatoric_mandel_stress_from_finite_difference_of_dissipation_potential()
-> Result<(), AssertionError> {
    let model = model();
    let yield_stress = model.yield_stress;
    let plastic_stretching_rate =
        model.plastic_stretching_rate(deviatoric_mandel_stress(), yield_stress)?;
    let mut finite_difference = MandelStressElastic::zero();
    for i in 0..3 {
        for j in 0..3 {
            let mut plus = plastic_stretching_rate.clone();
            plus[i][j] += perturbation(0.5 * EPSILON);
            let mut minus = plastic_stretching_rate.clone();
            minus[i][j] -= perturbation(0.5 * EPSILON);
            finite_difference[i][j] = (model.dissipation_potential(plus, yield_stress)?
                - model.dissipation_potential(minus, yield_stress)?)
                / Quantity::<Rate>::new(EPSILON);
        }
    }
    Assert::default().eq_within_fd_tol(deviatoric_mandel_stress(), &finite_difference)
}

#[test]
fn fenchel_equality() -> Result<(), AssertionError> {
    let model = model();
    let yield_stress = model.yield_stress;
    let plastic_stretching_rate =
        model.plastic_stretching_rate(deviatoric_mandel_stress(), yield_stress)?;
    Assert::default().eq_within_tols(
        model.dissipation_potential(plastic_stretching_rate.clone(), yield_stress)?
            + model.dual_dissipation_potential(deviatoric_mandel_stress(), yield_stress)?,
        &ContractWith::contract_with(&deviatoric_mandel_stress(), &plastic_stretching_rate),
    )
}