conspire 0.6.0

The Rust interface to conspire.
Documentation
macro_rules! test_thermal {
    ($element: ident) => {
        mod thermal_element {
            use super::{N, element};
            use crate::{
                EPSILON,
                constitutive::thermal::conduction::Fourier,
                fem::block::element::{
                    FiniteElementError,
                    thermal::{
                        ElementNodalTemperatures,
                        conduction::{
                            ElementNodalForcesThermal, ElementNodalStiffnessesThermal,
                            ThermalConductionFiniteElement,
                        },
                    },
                },
                math::test::{TestError, assert_eq_from_fd},
            };
            mod finite_difference {
                use super::*;
                const MODEL: Fourier = Fourier {
                    thermal_conductivity: 1.0,
                };
                #[test]
                fn potential() -> Result<(), TestError> {
                    let constitutive_model = MODEL;
                    let element = element();
                    let temperature = ElementNodalTemperatures::from([
                        0.62895714, 0.73331084, 0.3058115, 0.08179408,
                    ]);
                    let mut finite_difference = 0.0;
                    let nodal_forces_fd: ElementNodalForcesThermal<N> = (0..N)
                        .map(|node| {
                            let mut nodal_temperatures = temperature.clone();
                            nodal_temperatures[node] += 0.5 * EPSILON;
                            finite_difference =
                                element.potential(&constitutive_model, &nodal_temperatures)?;
                            nodal_temperatures[node] -= EPSILON;
                            finite_difference -=
                                element.potential(&constitutive_model, &nodal_temperatures)?;
                            Ok(finite_difference / EPSILON)
                        })
                        .collect::<Result<_, FiniteElementError>>()?;
                    assert_eq_from_fd(
                        &nodal_forces_fd,
                        &element.nodal_forces(
                            &constitutive_model,
                            &ElementNodalTemperatures::from(temperature),
                        )?,
                    )
                }
                #[test]
                fn nodal_forces() -> Result<(), TestError> {
                    let constitutive_model = MODEL;
                    let element = element();
                    let temperature = ElementNodalTemperatures::from([
                        0.62895714, 0.73331084, 0.3058115, 0.08179408,
                    ]);
                    let mut finite_difference = 0.0;
                    let nodal_stiffnesses_fd: ElementNodalStiffnessesThermal<N> = (0..N)
                        .map(|node_a| {
                            (0..N)
                                .map(|node_b| {
                                    let mut nodal_temperatures = temperature.clone();
                                    nodal_temperatures[node_b] += 0.5 * EPSILON;
                                    finite_difference = element
                                        .nodal_forces(&constitutive_model, &nodal_temperatures)?
                                        [node_a];
                                    nodal_temperatures[node_b] -= EPSILON;
                                    finite_difference -= element
                                        .nodal_forces(&constitutive_model, &nodal_temperatures)?
                                        [node_a];
                                    Ok(finite_difference / EPSILON)
                                })
                                .collect()
                        })
                        .collect::<Result<_, FiniteElementError>>()?;
                    assert_eq_from_fd(
                        &nodal_stiffnesses_fd,
                        &element.nodal_stiffnesses(
                            &constitutive_model,
                            &ElementNodalTemperatures::from(temperature),
                        )?,
                    )
                }
            }
        }
    };
}
pub(crate) use test_thermal;