#![doc = include_str!("doc.md")]
#[cfg(feature = "doc")]
pub mod doc;
#[cfg(test)]
pub mod test;
pub mod internal_variables;
mod arruda_boyce;
mod blatz_ko;
mod carroll;
mod eight_chain;
mod fung;
mod gent;
mod hencky;
mod isihara;
mod mooney_rivlin;
mod neo_hookean;
mod ogden;
mod saint_venant_kirchhoff;
mod yeoh;
pub use self::{
arruda_boyce::ArrudaBoyce, blatz_ko::BlatzKo, carroll::Carroll, eight_chain::EightChain,
fung::Fung, gent::Gent, hencky::Hencky, isihara::Isihara, mooney_rivlin::MooneyRivlin,
neo_hookean::NeoHookean, ogden::Ogden, saint_venant_kirchhoff::SaintVenantKirchhoff,
yeoh::Yeoh,
};
use super::{
elastic::{AppliedLoad, Elastic, bcs},
*,
};
use crate::{
math::{
Quantity,
optimize::{EqualityConstraint, FirstOrderOptimization, SecondOrderOptimization},
},
units::EnergyDensity,
};
pub trait Hyperelastic
where
Self: Elastic,
{
fn helmholtz_free_energy_density(
&self,
deformation_gradient: &DeformationGradient,
) -> Result<Quantity<EnergyDensity>, ConstitutiveError>;
}
pub trait FirstOrderMinimize {
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl FirstOrderOptimization<
Quantity<EnergyDensity>,
FirstPiolaKirchhoffStress,
DeformationGradient,
>,
) -> Result<DeformationGradient, ConstitutiveError>;
}
pub trait SecondOrderMinimize {
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl SecondOrderOptimization<
Quantity<EnergyDensity>,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffTangentStiffness,
DeformationGradient,
>,
) -> Result<DeformationGradient, ConstitutiveError>;
}
impl<T> FirstOrderMinimize for T
where
T: Hyperelastic,
{
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl FirstOrderOptimization<
Quantity<EnergyDensity>,
FirstPiolaKirchhoffStress,
DeformationGradient,
>,
) -> Result<DeformationGradient, ConstitutiveError> {
let (matrix, vector) = bcs(applied_load);
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),
)
.map_err(|error| ConstitutiveError::upstream(error, self))
}
}
impl<T> SecondOrderMinimize for T
where
T: Hyperelastic,
{
fn minimize(
&self,
applied_load: AppliedLoad,
solver: impl SecondOrderOptimization<
Quantity<EnergyDensity>,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffTangentStiffness,
DeformationGradient,
>,
) -> Result<DeformationGradient, ConstitutiveError> {
let (matrix, vector) = bcs(applied_load);
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,
)
.map_err(|error| ConstitutiveError::upstream(error, self))
}
}