Skip to main content

conspire/constitutive/solid/elastic_plastic/
mod.rs

1//! Elastic-plastic solid constitutive models.
2
3use crate::{
4    constitutive::{ConstitutiveError, fluid::plastic::Plastic, solid::Solid},
5    math::{ContractFirstSecondWithSecond, ContractSecondWithFirst, IDENTITY, Rank2},
6    mechanics::{
7        CauchyStress, CauchyTangentStiffness, DeformationGradient, DeformationGradientPlastic,
8        FirstPiolaKirchhoffStress, FirstPiolaKirchhoffTangentStiffness, Scalar,
9        SecondPiolaKirchhoffStress, SecondPiolaKirchhoffTangentStiffness,
10    },
11};
12
13/// Possible applied loads.
14pub enum AppliedLoad<'a> {
15    /// Uniaxial stress given $`F_{11}`$.
16    UniaxialStress(fn(Scalar) -> Scalar, &'a [Scalar]),
17    // /// Biaxial stress given $`F_{11}`$ and $`F_{22}`$.
18    // BiaxialStress(fn(Scalar) -> Scalar, fn(Scalar) -> Scalar, &'a [Scalar]),
19}
20
21/// Required methods for elastic-plastic or elastic-viscoplastic solid constitutive models.
22pub trait ElasticPlasticOrViscoplastic
23where
24    Self: Solid + Plastic,
25{
26    /// Calculates and returns the Cauchy stress.
27    ///
28    /// ```math
29    /// \boldsymbol{\sigma} = \boldsymbol{\sigma}_\mathrm{e}
30    /// ```
31    fn cauchy_stress(
32        &self,
33        deformation_gradient: &DeformationGradient,
34        deformation_gradient_p: &DeformationGradientPlastic,
35    ) -> Result<CauchyStress, ConstitutiveError> {
36        Ok(deformation_gradient
37            * self.second_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?
38            * deformation_gradient.transpose()
39            / deformation_gradient.determinant())
40    }
41    /// Calculates and returns the tangent stiffness associated with the Cauchy stress.
42    ///
43    /// ```math
44    /// \boldsymbol{\mathcal{T}} = \boldsymbol{\mathcal{T}}_\mathrm{e}\cdot\mathbf{F}_\mathrm{p}^{-T}
45    /// ```
46    fn cauchy_tangent_stiffness(
47        &self,
48        deformation_gradient: &DeformationGradient,
49        deformation_gradient_p: &DeformationGradientPlastic,
50    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
51        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
52        let cauchy_stress = self.cauchy_stress(deformation_gradient, deformation_gradient_p)?;
53        let some_stress = &cauchy_stress * &deformation_gradient_inverse_transpose;
54        Ok(self
55            .second_piola_kirchhoff_tangent_stiffness(deformation_gradient, deformation_gradient_p)?
56            .contract_first_second_with_second(deformation_gradient, deformation_gradient)
57            / deformation_gradient.determinant()
58            - CauchyTangentStiffness::dyad_ij_kl(
59                &cauchy_stress,
60                &deformation_gradient_inverse_transpose,
61            )
62            + CauchyTangentStiffness::dyad_il_kj(&some_stress, &IDENTITY)
63            + CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, &some_stress))
64    }
65    /// Calculates and returns the first Piola-Kirchhoff stress.
66    ///
67    /// ```math
68    /// \mathbf{P} = \mathbf{P}_\mathrm{e}\cdot\mathbf{F}_\mathrm{p}^{-T}
69    /// ```
70    fn first_piola_kirchhoff_stress(
71        &self,
72        deformation_gradient: &DeformationGradient,
73        deformation_gradient_p: &DeformationGradientPlastic,
74    ) -> Result<FirstPiolaKirchhoffStress, ConstitutiveError> {
75        Ok(
76            self.cauchy_stress(deformation_gradient, deformation_gradient_p)?
77                * deformation_gradient.inverse_transpose()
78                * deformation_gradient.determinant(),
79        )
80    }
81    /// Calculates and returns the tangent stiffness associated with the first Piola-Kirchhoff stress.
82    ///
83    /// ```math
84    /// \mathcal{C}_{iJkL} = \mathcal{C}^\mathrm{e}_{iMkN} F_{MJ}^{\mathrm{p}-T} F_{NL}^{\mathrm{p}-T}
85    /// ```
86    fn first_piola_kirchhoff_tangent_stiffness(
87        &self,
88        deformation_gradient: &DeformationGradient,
89        deformation_gradient_p: &DeformationGradientPlastic,
90    ) -> Result<FirstPiolaKirchhoffTangentStiffness, ConstitutiveError> {
91        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
92        let first_piola_kirchhoff_stress =
93            self.first_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?;
94        Ok(self
95            .cauchy_tangent_stiffness(deformation_gradient, deformation_gradient_p)?
96            .contract_second_with_first(&deformation_gradient_inverse_transpose)
97            * deformation_gradient.determinant()
98            + FirstPiolaKirchhoffTangentStiffness::dyad_ij_kl(
99                &first_piola_kirchhoff_stress,
100                &deformation_gradient_inverse_transpose,
101            )
102            - FirstPiolaKirchhoffTangentStiffness::dyad_il_kj(
103                &first_piola_kirchhoff_stress,
104                &deformation_gradient_inverse_transpose,
105            ))
106    }
107    /// Calculates and returns the second Piola-Kirchhoff stress.
108    ///
109    /// ```math
110    /// \mathbf{S} = \mathbf{F}_\mathrm{p}^{-1}\cdot\mathbf{S}_\mathrm{e}\cdot\mathbf{F}_\mathrm{p}^{-T}
111    /// ```
112    fn second_piola_kirchhoff_stress(
113        &self,
114        deformation_gradient: &DeformationGradient,
115        deformation_gradient_p: &DeformationGradientPlastic,
116    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
117        Ok(deformation_gradient.inverse()
118            * self.first_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?)
119    }
120    /// Calculates and returns the tangent stiffness associated with the second Piola-Kirchhoff stress.
121    ///
122    /// ```math
123    /// \mathcal{G}_{IJkL} = \mathcal{G}^\mathrm{e}_{MNkO} F_{MI}^{\mathrm{p}-T} F_{NJ}^{\mathrm{p}-T} F_{OL}^{\mathrm{p}-T}
124    /// ```
125    fn second_piola_kirchhoff_tangent_stiffness(
126        &self,
127        deformation_gradient: &DeformationGradient,
128        deformation_gradient_p: &DeformationGradientPlastic,
129    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
130        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
131        let deformation_gradient_inverse = deformation_gradient_inverse_transpose.transpose();
132        let second_piola_kirchhoff_stress =
133            self.second_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?;
134        Ok(self
135            .cauchy_tangent_stiffness(deformation_gradient, deformation_gradient_p)?
136            .contract_first_second_with_second(
137                &deformation_gradient_inverse,
138                &deformation_gradient_inverse,
139            )
140            * deformation_gradient.determinant()
141            + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
142                &second_piola_kirchhoff_stress,
143                &deformation_gradient_inverse_transpose,
144            )
145            - SecondPiolaKirchhoffTangentStiffness::dyad_il_kj(
146                &second_piola_kirchhoff_stress,
147                &deformation_gradient_inverse_transpose,
148            )
149            - SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
150                &deformation_gradient_inverse,
151                &second_piola_kirchhoff_stress,
152            ))
153    }
154}
155
156/// Required methods for elastic-plastic solid constitutive models.
157pub trait ElasticPlastic
158where
159    Self: ElasticPlasticOrViscoplastic,
160{
161}