Skip to main content

conspire/constitutive/solid/elastic_viscoplastic/canonical/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        ConstitutiveError,
7        canonical::Canonical,
8        fluid::{
9            plastic::Plastic,
10            viscoplastic::{Viscoplastic, ViscoplasticEvolution, ViscoplasticStateVariables},
11        },
12        solid::{
13            elastic::Elastic,
14            elastic_viscoplastic::{ElasticPlasticOrViscoplastic, ElasticViscoplastic},
15        },
16    },
17    math::{
18        ContractFirstSecondWithSecond, ContractSecondWithFirst, Differentiable, Quantity, Rank2,
19        Scalar, Tensor,
20    },
21    mechanics::{
22        CauchyStress, CauchyTangentStiffness, CauchyTangentStiffnessElastic, DeformationGradient,
23        DeformationGradientPlastic, FirstPiolaKirchhoffStress, FirstPiolaKirchhoffStressElastic,
24        FirstPiolaKirchhoffTangentStiffness, FirstPiolaKirchhoffTangentStiffnessElastic,
25        MandelStressElastic, SecondPiolaKirchhoffStress, SecondPiolaKirchhoffStressElastic,
26        SecondPiolaKirchhoffTangentStiffness, SecondPiolaKirchhoffTangentStiffnessElastic,
27        StretchingRatePlastic,
28    },
29    units::{Dissipation, Rate, Stress},
30};
31
32impl<C1, C2> Plastic for Canonical<C1, C2>
33where
34    C1: Elastic,
35    C2: Plastic,
36{
37    fn initial_yield_stress(&self) -> Quantity<Stress> {
38        self.1.initial_yield_stress()
39    }
40    fn hardening_slope(&self) -> Quantity<Stress> {
41        self.1.hardening_slope()
42    }
43}
44
45impl<C1, C2, Y2> Viscoplastic<Y2> for Canonical<C1, C2>
46where
47    C1: Elastic,
48    C2: Viscoplastic<Y2>,
49    Y2: Differentiable + Tensor,
50{
51    fn initial_state(&self) -> ViscoplasticStateVariables<Y2> {
52        self.1.initial_state()
53    }
54    fn plastic_evolution(
55        &self,
56        mandel_stress: MandelStressElastic,
57        state_variables: &ViscoplasticStateVariables<Y2>,
58    ) -> Result<ViscoplasticEvolution<Y2>, ConstitutiveError> {
59        self.1.plastic_evolution(mandel_stress, state_variables)
60    }
61    fn plastic_stretching_rate(
62        &self,
63        deviatoric_mandel_stress: MandelStressElastic,
64        yield_stress: Quantity<Stress>,
65    ) -> Result<StretchingRatePlastic, ConstitutiveError> {
66        self.1
67            .plastic_stretching_rate(deviatoric_mandel_stress, yield_stress)
68    }
69    fn dissipation_potential(
70        &self,
71        plastic_stretching_rate: StretchingRatePlastic,
72        yield_stress: Quantity<Stress>,
73    ) -> Result<Quantity<Dissipation>, ConstitutiveError> {
74        self.1
75            .dissipation_potential(plastic_stretching_rate, yield_stress)
76    }
77    fn dual_dissipation_potential(
78        &self,
79        deviatoric_mandel_stress: MandelStressElastic,
80        yield_stress: Quantity<Stress>,
81    ) -> Result<Quantity<Dissipation>, ConstitutiveError> {
82        self.1
83            .dual_dissipation_potential(deviatoric_mandel_stress, yield_stress)
84    }
85    fn rate_sensitivity(&self) -> Scalar {
86        self.1.rate_sensitivity()
87    }
88    fn reference_flow_rate(&self) -> Quantity<Rate> {
89        self.1.reference_flow_rate()
90    }
91}
92
93impl<C1, C2> ElasticPlasticOrViscoplastic for Canonical<C1, C2>
94where
95    C1: Elastic,
96    C2: Plastic,
97{
98    fn cauchy_stress(
99        &self,
100        deformation_gradient: &DeformationGradient,
101        deformation_gradient_p: &DeformationGradientPlastic,
102    ) -> Result<CauchyStress, ConstitutiveError> {
103        self.0
104            .cauchy_stress(&(deformation_gradient * deformation_gradient_p.inverse()).into())
105    }
106    fn cauchy_tangent_stiffness(
107        &self,
108        deformation_gradient: &DeformationGradient,
109        deformation_gradient_p: &DeformationGradientPlastic,
110    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
111        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
112        Ok(
113            CauchyTangentStiffnessElastic::from(self.0.cauchy_tangent_stiffness(
114                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
115            )?) * deformation_gradient_p_inverse.transpose(),
116        )
117    }
118    fn first_piola_kirchhoff_stress(
119        &self,
120        deformation_gradient: &DeformationGradient,
121        deformation_gradient_p: &DeformationGradientPlastic,
122    ) -> Result<FirstPiolaKirchhoffStress, ConstitutiveError> {
123        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
124        Ok(
125            FirstPiolaKirchhoffStressElastic::from(self.0.first_piola_kirchhoff_stress(
126                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
127            )?) * deformation_gradient_p_inverse.transpose(),
128        )
129    }
130    fn first_piola_kirchhoff_tangent_stiffness(
131        &self,
132        deformation_gradient: &DeformationGradient,
133        deformation_gradient_p: &DeformationGradientPlastic,
134    ) -> Result<FirstPiolaKirchhoffTangentStiffness, ConstitutiveError> {
135        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
136        let deformation_gradient_p_inverse_transpose = deformation_gradient_p_inverse.transpose();
137        Ok((FirstPiolaKirchhoffTangentStiffnessElastic::from(
138            self.0.first_piola_kirchhoff_tangent_stiffness(
139                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
140            )?,
141        ) * &deformation_gradient_p_inverse_transpose)
142            .contract_second_with_first(&deformation_gradient_p_inverse_transpose))
143    }
144    fn second_piola_kirchhoff_stress(
145        &self,
146        deformation_gradient: &DeformationGradient,
147        deformation_gradient_p: &DeformationGradientPlastic,
148    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
149        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
150        Ok(&deformation_gradient_p_inverse
151            * SecondPiolaKirchhoffStressElastic::from(self.0.second_piola_kirchhoff_stress(
152                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
153            )?)
154            * deformation_gradient_p_inverse.transpose())
155    }
156    fn second_piola_kirchhoff_tangent_stiffness(
157        &self,
158        deformation_gradient: &DeformationGradient,
159        deformation_gradient_p: &DeformationGradientPlastic,
160    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
161        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
162        Ok((SecondPiolaKirchhoffTangentStiffnessElastic::from(
163            self.0.second_piola_kirchhoff_tangent_stiffness(
164                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
165            )?,
166        ) * deformation_gradient_p_inverse.transpose())
167        .contract_first_second_with_second(
168            &deformation_gradient_p_inverse,
169            &deformation_gradient_p_inverse,
170        ))
171    }
172}
173
174impl<C1, C2, Y2> ElasticViscoplastic<Y2> for Canonical<C1, C2>
175where
176    C1: Elastic,
177    C2: Viscoplastic<Y2>,
178    Y2: Differentiable + Tensor,
179{
180}