conspire/constitutive/fluid/viscoplastic/
mod.rs1use crate::{
4 constitutive::{ConstitutiveError, fluid::plastic::Plastic},
5 math::{Rank2, Scalar, Tensor, TensorArray, TensorTuple, TensorTupleVec},
6 mechanics::{DeformationGradientPlastic, MandelStressElastic, StretchingRatePlastic},
7};
8
9pub type ViscoplasticStateVariables<Y> = TensorTuple<DeformationGradientPlastic, Y>;
11
12pub type ViscoplasticStateVariablesHistory<Y> = TensorTupleVec<DeformationGradientPlastic, Y>;
14
15pub trait Viscoplastic<Y>
17where
18 Self: Plastic,
19 Y: Tensor,
20{
21 fn initial_state(&self) -> ViscoplasticStateVariables<Y>;
23 fn plastic_evolution(
29 &self,
30 mandel_stress: MandelStressElastic,
31 state_variables: &ViscoplasticStateVariables<Y>,
32 ) -> Result<ViscoplasticStateVariables<Y>, ConstitutiveError>;
33 fn plastic_stretching_rate(
39 &self,
40 deviatoric_mandel_stress: MandelStressElastic,
41 yield_stress: Scalar,
42 ) -> Result<StretchingRatePlastic, ConstitutiveError> {
43 let magnitude = deviatoric_mandel_stress.norm();
44 if magnitude == 0.0 {
45 Ok(StretchingRatePlastic::zero())
46 } else {
47 Ok(deviatoric_mandel_stress
48 * (self.reference_flow_rate() / magnitude
49 * (magnitude / yield_stress).powf(1.0 / self.rate_sensitivity())))
50 }
51 }
52 fn rate_sensitivity(&self) -> Scalar;
54 fn reference_flow_rate(&self) -> Scalar;
56}
57
58#[derive(Clone, Debug)]
60pub struct ViscoplasticFlow {
61 pub yield_stress: Scalar,
63 pub hardening_slope: Scalar,
65 pub rate_sensitivity: Scalar,
67 pub reference_flow_rate: Scalar,
69}
70
71impl Plastic for ViscoplasticFlow {
72 fn initial_yield_stress(&self) -> Scalar {
73 self.yield_stress
74 }
75 fn hardening_slope(&self) -> Scalar {
76 self.hardening_slope
77 }
78}
79
80impl Viscoplastic<Scalar> for ViscoplasticFlow {
81 fn initial_state(&self) -> ViscoplasticStateVariables<Scalar> {
82 (DeformationGradientPlastic::identity(), 0.0).into()
83 }
84 fn plastic_evolution(
85 &self,
86 mandel_stress: MandelStressElastic,
87 state_variables: &ViscoplasticStateVariables<Scalar>,
88 ) -> Result<ViscoplasticStateVariables<Scalar>, ConstitutiveError> {
89 default_plastic_evolution(self, mandel_stress, state_variables)
90 }
91 fn rate_sensitivity(&self) -> Scalar {
92 self.rate_sensitivity
93 }
94 fn reference_flow_rate(&self) -> Scalar {
95 self.reference_flow_rate
96 }
97}
98
99pub fn default_plastic_evolution<C>(
100 model: &C,
101 mandel_stress: MandelStressElastic,
102 state_variables: &ViscoplasticStateVariables<Scalar>,
103) -> Result<ViscoplasticStateVariables<Scalar>, ConstitutiveError>
104where
105 C: Viscoplastic<Scalar>,
106{
107 let (deformation_gradient_p, &equivalent_plastic_strain) = state_variables.into();
108 let plastic_stretching_rate = model.plastic_stretching_rate(
109 mandel_stress.deviatoric(),
110 model.yield_stress(equivalent_plastic_strain)?,
111 )?;
112 let equivalent_plastic_strain_rate = plastic_stretching_rate.norm();
113 Ok((
114 plastic_stretching_rate * deformation_gradient_p,
115 equivalent_plastic_strain_rate,
116 )
117 .into())
118}