conspire/constitutive/hybrid/elastic_viscoplastic/multiplicative/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        ConstitutiveError,
7        fluid::{plastic::Plastic, viscoplastic::Viscoplastic},
8        hybrid::Multiplicative,
9        solid::{elastic::Elastic, elastic_viscoplastic::ElasticViscoplastic},
10    },
11    math::{
12        ContractFirstSecondIndicesWithSecondIndicesOf, ContractSecondIndexWithFirstIndexOf, Rank2,
13        Scalar,
14    },
15    mechanics::{
16        CauchyStress, CauchyTangentStiffness, CauchyTangentStiffnessElastic, DeformationGradient,
17        DeformationGradientPlastic, FirstPiolaKirchhoffStress, FirstPiolaKirchhoffStressElastic,
18        FirstPiolaKirchhoffTangentStiffness, FirstPiolaKirchhoffTangentStiffnessElastic,
19        SecondPiolaKirchhoffStress, SecondPiolaKirchhoffStressElastic,
20        SecondPiolaKirchhoffTangentStiffness, SecondPiolaKirchhoffTangentStiffnessElastic,
21    },
22};
23
24// impl<C1, C2> Solid for Multiplicative<C1, C2>
25// where
26//     C1: Elastic,
27//     C2: Viscoplastic,
28// {
29//     fn bulk_modulus(&self) -> Scalar {
30//         self.0.bulk_modulus()
31//     }
32//     fn shear_modulus(&self) -> Scalar {
33//         self.0.shear_modulus()
34//     }
35// }
36// You can de-conflict this with elastic/ using specialization if it ever gets stabilized.
37
38impl<C1, C2> Plastic for Multiplicative<C1, C2>
39where
40    C1: Elastic,
41    C2: Viscoplastic,
42{
43    fn initial_yield_stress(&self) -> Scalar {
44        self.1.initial_yield_stress()
45    }
46    fn hardening_slope(&self) -> Scalar {
47        self.1.hardening_slope()
48    }
49}
50
51impl<C1, C2> Viscoplastic for Multiplicative<C1, C2>
52where
53    C1: Elastic,
54    C2: Viscoplastic,
55{
56    fn rate_sensitivity(&self) -> Scalar {
57        self.1.rate_sensitivity()
58    }
59    fn reference_flow_rate(&self) -> Scalar {
60        self.1.reference_flow_rate()
61    }
62}
63
64impl<C1, C2> ElasticViscoplastic for Multiplicative<C1, C2>
65where
66    C1: Elastic,
67    C2: Viscoplastic,
68{
69    fn cauchy_stress(
70        &self,
71        deformation_gradient: &DeformationGradient,
72        deformation_gradient_p: &DeformationGradientPlastic,
73    ) -> Result<CauchyStress, ConstitutiveError> {
74        self.0
75            .cauchy_stress(&(deformation_gradient * deformation_gradient_p.inverse()).into())
76    }
77    fn cauchy_tangent_stiffness(
78        &self,
79        deformation_gradient: &DeformationGradient,
80        deformation_gradient_p: &DeformationGradientPlastic,
81    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
82        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
83        Ok(
84            CauchyTangentStiffnessElastic::from(self.0.cauchy_tangent_stiffness(
85                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
86            )?) * deformation_gradient_p_inverse.transpose(),
87        )
88    }
89    fn first_piola_kirchhoff_stress(
90        &self,
91        deformation_gradient: &DeformationGradient,
92        deformation_gradient_p: &DeformationGradientPlastic,
93    ) -> Result<FirstPiolaKirchhoffStress, ConstitutiveError> {
94        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
95        Ok(
96            FirstPiolaKirchhoffStressElastic::from(self.0.first_piola_kirchhoff_stress(
97                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
98            )?) * deformation_gradient_p_inverse.transpose(),
99        )
100    }
101    fn first_piola_kirchhoff_tangent_stiffness(
102        &self,
103        deformation_gradient: &DeformationGradient,
104        deformation_gradient_p: &DeformationGradientPlastic,
105    ) -> Result<FirstPiolaKirchhoffTangentStiffness, ConstitutiveError> {
106        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
107        let deformation_gradient_p_inverse_transpose = deformation_gradient_p_inverse.transpose();
108        Ok((FirstPiolaKirchhoffTangentStiffnessElastic::from(
109            self.0.first_piola_kirchhoff_tangent_stiffness(
110                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
111            )?,
112        ) * &deformation_gradient_p_inverse_transpose)
113            .contract_second_index_with_first_index_of(&deformation_gradient_p_inverse_transpose))
114    }
115    fn second_piola_kirchhoff_stress(
116        &self,
117        deformation_gradient: &DeformationGradient,
118        deformation_gradient_p: &DeformationGradientPlastic,
119    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
120        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
121        Ok(&deformation_gradient_p_inverse
122            * SecondPiolaKirchhoffStressElastic::from(self.0.second_piola_kirchhoff_stress(
123                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
124            )?)
125            * deformation_gradient_p_inverse.transpose())
126    }
127    fn second_piola_kirchhoff_tangent_stiffness(
128        &self,
129        deformation_gradient: &DeformationGradient,
130        deformation_gradient_p: &DeformationGradientPlastic,
131    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
132        let deformation_gradient_p_inverse = deformation_gradient_p.inverse();
133        Ok((SecondPiolaKirchhoffTangentStiffnessElastic::from(
134            self.0.second_piola_kirchhoff_tangent_stiffness(
135                &(deformation_gradient * &deformation_gradient_p_inverse).into(),
136            )?,
137        ) * deformation_gradient_p_inverse.transpose())
138        .contract_first_second_indices_with_second_indices_of(
139            &deformation_gradient_p_inverse,
140            &deformation_gradient_p_inverse,
141        ))
142    }
143}