Skip to main content

conspire/constitutive/solid/hyperelastic/
mod.rs

1//! Hyperelastic solid constitutive models.
2//!
3//! ---
4//!
5#![doc = include_str!("doc.md")]
6
7#[cfg(feature = "doc")]
8pub mod doc;
9
10#[cfg(test)]
11pub mod test;
12
13#[cfg(feature = "autodiff")]
14pub mod autodiff;
15
16pub mod internal_variables;
17
18mod arruda_boyce;
19mod blatz_ko;
20mod carroll;
21mod eight_chain;
22mod fung;
23mod gent;
24mod hencky;
25mod isihara;
26mod mooney_rivlin;
27mod neo_hookean;
28mod ogden;
29mod saint_venant_kirchhoff;
30mod yeoh;
31
32pub use self::{
33    arruda_boyce::ArrudaBoyce, blatz_ko::BlatzKo, carroll::Carroll, eight_chain::EightChain,
34    fung::Fung, gent::Gent, hencky::Hencky, isihara::Isihara, mooney_rivlin::MooneyRivlin,
35    neo_hookean::NeoHookean, ogden::Ogden, saint_venant_kirchhoff::SaintVenantKirchhoff,
36    yeoh::Yeoh,
37};
38use super::{
39    elastic::{AppliedLoad, Elastic, bcs},
40    *,
41};
42use crate::{
43    math::{
44        Quantity,
45        optimize::{EqualityConstraint, FirstOrderOptimization, SecondOrderOptimization},
46    },
47    units::EnergyDensity,
48};
49
50/// Required methods for hyperelastic solid constitutive models.
51pub trait Hyperelastic
52where
53    Self: Elastic,
54{
55    /// Calculates and returns the Helmholtz free energy density.
56    ///
57    /// ```math
58    /// a = a(\mathbf{F})
59    /// ```
60    fn helmholtz_free_energy_density(
61        &self,
62        deformation_gradient: &DeformationGradient,
63    ) -> Result<Quantity<EnergyDensity>, ConstitutiveError>;
64}
65
66/// First-order minimization methods for elastic solid constitutive models.
67pub trait FirstOrderMinimize {
68    /// Solve for the unknown components of the deformation gradient under an applied load.
69    ///
70    /// ```math
71    /// \Pi(\mathbf{F},\boldsymbol{\lambda}) = a(\mathbf{F}) - \boldsymbol{\lambda}:(\mathbf{F} - \mathbf{F}_0) - \mathbf{P}_0:\mathbf{F}
72    /// ```
73    fn minimize(
74        &self,
75        applied_load: AppliedLoad,
76        solver: impl FirstOrderOptimization<
77            Quantity<EnergyDensity>,
78            FirstPiolaKirchhoffStress,
79            DeformationGradient,
80        >,
81    ) -> Result<DeformationGradient, ConstitutiveError>;
82}
83
84/// Second-order minimization methods for elastic solid constitutive models.
85pub trait SecondOrderMinimize {
86    /// Solve for the unknown components of the deformation gradient under an applied load.
87    ///
88    /// ```math
89    /// \Pi(\mathbf{F},\boldsymbol{\lambda}) = a(\mathbf{F}) - \boldsymbol{\lambda}:(\mathbf{F} - \mathbf{F}_0) - \mathbf{P}_0:\mathbf{F}
90    /// ```
91    fn minimize(
92        &self,
93        applied_load: AppliedLoad,
94        solver: impl SecondOrderOptimization<
95            Quantity<EnergyDensity>,
96            FirstPiolaKirchhoffStress,
97            FirstPiolaKirchhoffTangentStiffness,
98            DeformationGradient,
99        >,
100    ) -> Result<DeformationGradient, ConstitutiveError>;
101}
102
103impl<T> FirstOrderMinimize for T
104where
105    T: Hyperelastic,
106{
107    fn minimize(
108        &self,
109        applied_load: AppliedLoad,
110        solver: impl FirstOrderOptimization<
111            Quantity<EnergyDensity>,
112            FirstPiolaKirchhoffStress,
113            DeformationGradient,
114        >,
115    ) -> Result<DeformationGradient, ConstitutiveError> {
116        let (matrix, vector) = bcs(applied_load);
117        solver
118            .minimize(
119                |deformation_gradient: &DeformationGradient| {
120                    Ok(self.helmholtz_free_energy_density(deformation_gradient)?)
121                },
122                |deformation_gradient: &DeformationGradient| {
123                    Ok(self.first_piola_kirchhoff_stress(deformation_gradient)?)
124                },
125                DeformationGradient::identity(),
126                EqualityConstraint::Linear(matrix, vector),
127            )
128            .map_err(|error| ConstitutiveError::upstream(error, self))
129    }
130}
131
132impl<T> SecondOrderMinimize for T
133where
134    T: Hyperelastic,
135{
136    fn minimize(
137        &self,
138        applied_load: AppliedLoad,
139        solver: impl SecondOrderOptimization<
140            Quantity<EnergyDensity>,
141            FirstPiolaKirchhoffStress,
142            FirstPiolaKirchhoffTangentStiffness,
143            DeformationGradient,
144        >,
145    ) -> Result<DeformationGradient, ConstitutiveError> {
146        let (matrix, vector) = bcs(applied_load);
147        solver
148            .minimize(
149                |deformation_gradient: &DeformationGradient| {
150                    Ok(self.helmholtz_free_energy_density(deformation_gradient)?)
151                },
152                |deformation_gradient: &DeformationGradient| {
153                    Ok(self.first_piola_kirchhoff_stress(deformation_gradient)?)
154                },
155                |deformation_gradient: &DeformationGradient| {
156                    Ok(self.first_piola_kirchhoff_tangent_stiffness(deformation_gradient)?)
157                },
158                DeformationGradient::identity(),
159                EqualityConstraint::Linear(matrix, vector),
160                None,
161            )
162            .map_err(|error| ConstitutiveError::upstream(error, self))
163    }
164}