#![doc = include_str!("doc.md")]
#[cfg(feature = "doc")]
pub mod doc;
#[cfg(test)]
pub mod test;
pub mod internal_variables;
mod arruda_boyce;
mod eight_chain;
mod fung;
mod gent;
mod hencky;
mod mooney_rivlin;
mod neo_hookean;
mod saint_venant_kirchhoff;
mod yeoh;
pub use self::{
arruda_boyce::ArrudaBoyce, eight_chain::EightChain, fung::Fung, gent::Gent, hencky::Hencky,
mooney_rivlin::MooneyRivlin, neo_hookean::NeoHookean,
saint_venant_kirchhoff::SaintVenantKirchhoff, yeoh::Yeoh,
};
use super::{
elastic::{AppliedLoad, Elastic, bcs},
*,
};
use crate::math::optimize::{EqualityConstraint, FirstOrderOptimization, SecondOrderOptimization};
pub trait Hyperelastic
where
Self: Elastic,
{
fn helmholtz_free_energy_density(
&self,
deformation_gradient: &DeformationGradient,
) -> Result<Scalar, ConstitutiveError>;
}
pub trait FirstOrderMinimize {
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl FirstOrderOptimization<Scalar, DeformationGradient>,
) -> Result<DeformationGradient, ConstitutiveError>;
}
pub trait SecondOrderMinimize {
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl SecondOrderOptimization<
Scalar,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffTangentStiffness,
DeformationGradient,
>,
) -> Result<DeformationGradient, ConstitutiveError>;
}
impl<T> FirstOrderMinimize for T
where
T: Hyperelastic,
{
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl FirstOrderOptimization<Scalar, DeformationGradient>,
) -> Result<DeformationGradient, ConstitutiveError> {
let (matrix, vector) = bcs(applied_load);
match solver.minimize(
|deformation_gradient: &DeformationGradient| {
Ok(self.helmholtz_free_energy_density(deformation_gradient)?)
},
|deformation_gradient: &DeformationGradient| {
Ok(self.first_piola_kirchhoff_stress(deformation_gradient)?)
},
DeformationGradient::identity(),
EqualityConstraint::Linear(matrix, vector),
) {
Ok(deformation_gradient) => Ok(deformation_gradient),
Err(error) => Err(ConstitutiveError::Upstream(
format!("{error}"),
format!("{self:?}"),
)),
}
}
}
impl<T> SecondOrderMinimize for T
where
T: Hyperelastic,
{
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl SecondOrderOptimization<
Scalar,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffTangentStiffness,
DeformationGradient,
>,
) -> Result<DeformationGradient, ConstitutiveError> {
let (matrix, vector) = bcs(applied_load);
match solver.minimize(
|deformation_gradient: &DeformationGradient| {
Ok(self.helmholtz_free_energy_density(deformation_gradient)?)
},
|deformation_gradient: &DeformationGradient| {
Ok(self.first_piola_kirchhoff_stress(deformation_gradient)?)
},
|deformation_gradient: &DeformationGradient| {
Ok(self.first_piola_kirchhoff_tangent_stiffness(deformation_gradient)?)
},
DeformationGradient::identity(),
EqualityConstraint::Linear(matrix, vector),
None,
) {
Ok(deformation_gradient) => Ok(deformation_gradient),
Err(error) => Err(ConstitutiveError::Upstream(
format!("{error}"),
format!("{self:?}"),
)),
}
}
}