conspire/constitutive/solid/hyperelastic/
mod.rs1#![doc = include_str!("doc.md")]
6
7#[cfg(feature = "doc")]
8pub mod doc;
9
10#[cfg(test)]
11pub mod test;
12
13pub mod internal_variables;
14
15mod arruda_boyce;
16mod fung;
17mod gent;
18mod hencky;
19mod mooney_rivlin;
20mod neo_hookean;
21mod saint_venant_kirchhoff;
22mod yeoh;
23
24pub use self::{
25 arruda_boyce::ArrudaBoyce, fung::Fung, gent::Gent, hencky::Hencky, mooney_rivlin::MooneyRivlin,
26 neo_hookean::NeoHookean, saint_venant_kirchhoff::SaintVenantKirchhoff, yeoh::Yeoh,
27};
28use super::{
29 elastic::{AppliedLoad, Elastic, bcs},
30 *,
31};
32use crate::math::optimize::{EqualityConstraint, FirstOrderOptimization, SecondOrderOptimization};
33
34pub trait Hyperelastic
36where
37 Self: Elastic,
38{
39 fn helmholtz_free_energy_density(
45 &self,
46 deformation_gradient: &DeformationGradient,
47 ) -> Result<Scalar, ConstitutiveError>;
48}
49
50pub trait FirstOrderMinimize {
52 fn minimize(
58 &self,
59 applied_load: AppliedLoad,
60 solver: impl FirstOrderOptimization<Scalar, DeformationGradient>,
61 ) -> Result<DeformationGradient, ConstitutiveError>;
62}
63
64pub trait SecondOrderMinimize {
66 fn minimize(
72 &self,
73 applied_load: AppliedLoad,
74 solver: impl SecondOrderOptimization<
75 Scalar,
76 FirstPiolaKirchhoffStress,
77 FirstPiolaKirchhoffTangentStiffness,
78 DeformationGradient,
79 >,
80 ) -> Result<DeformationGradient, ConstitutiveError>;
81}
82
83impl<T> FirstOrderMinimize for T
84where
85 T: Hyperelastic,
86{
87 fn minimize(
88 &self,
89 applied_load: AppliedLoad,
90 solver: impl FirstOrderOptimization<Scalar, DeformationGradient>,
91 ) -> Result<DeformationGradient, ConstitutiveError> {
92 let (matrix, vector) = bcs(applied_load);
93 match solver.minimize(
94 |deformation_gradient: &DeformationGradient| {
95 Ok(self.helmholtz_free_energy_density(deformation_gradient)?)
96 },
97 |deformation_gradient: &DeformationGradient| {
98 Ok(self.first_piola_kirchhoff_stress(deformation_gradient)?)
99 },
100 DeformationGradient::identity(),
101 EqualityConstraint::Linear(matrix, vector),
102 ) {
103 Ok(deformation_gradient) => Ok(deformation_gradient),
104 Err(error) => Err(ConstitutiveError::Upstream(
105 format!("{error}"),
106 format!("{self:?}"),
107 )),
108 }
109 }
110}
111
112impl<T> SecondOrderMinimize for T
113where
114 T: Hyperelastic,
115{
116 fn minimize(
117 &self,
118 applied_load: AppliedLoad,
119 solver: impl SecondOrderOptimization<
120 Scalar,
121 FirstPiolaKirchhoffStress,
122 FirstPiolaKirchhoffTangentStiffness,
123 DeformationGradient,
124 >,
125 ) -> Result<DeformationGradient, ConstitutiveError> {
126 let (matrix, vector) = bcs(applied_load);
127 match solver.minimize(
128 |deformation_gradient: &DeformationGradient| {
129 Ok(self.helmholtz_free_energy_density(deformation_gradient)?)
130 },
131 |deformation_gradient: &DeformationGradient| {
132 Ok(self.first_piola_kirchhoff_stress(deformation_gradient)?)
133 },
134 |deformation_gradient: &DeformationGradient| {
135 Ok(self.first_piola_kirchhoff_tangent_stiffness(deformation_gradient)?)
136 },
137 DeformationGradient::identity(),
138 EqualityConstraint::Linear(matrix, vector),
139 None,
140 ) {
141 Ok(deformation_gradient) => Ok(deformation_gradient),
142 Err(error) => Err(ConstitutiveError::Upstream(
143 format!("{error}"),
144 format!("{self:?}"),
145 )),
146 }
147 }
148}