conspire/constitutive/fluid/viscoplastic/
mod.rs1use crate::{
4 constitutive::{ConstitutiveError, fluid::plastic::Plastic},
5 math::{Scalar, Tensor, TensorArray},
6 mechanics::{MandelStressElastic, StretchingRatePlastic},
7};
8
9const TWO_THIRDS: Scalar = 2.0 / 3.0;
10
11pub trait Viscoplastic
13where
14 Self: Plastic,
15{
16 fn plastic_stretching_rate(
22 &self,
23 deviatoric_mandel_stress_e: MandelStressElastic,
24 yield_stress: Scalar,
25 ) -> Result<StretchingRatePlastic, ConstitutiveError> {
26 let magnitude = deviatoric_mandel_stress_e.norm();
27 if magnitude == 0.0 {
28 Ok(StretchingRatePlastic::zero())
29 } else {
30 Ok(deviatoric_mandel_stress_e
31 * (self.reference_flow_rate() / magnitude
32 * (magnitude / yield_stress).powf(1.0 / self.rate_sensitivity())))
33 }
34 }
35 fn rate_sensitivity(&self) -> Scalar;
37 fn reference_flow_rate(&self) -> Scalar;
39 fn yield_stress_evolution(
45 &self,
46 plastic_stretching_rate: &StretchingRatePlastic,
47 ) -> Result<Scalar, ConstitutiveError> {
48 Ok(self.hardening_slope() * plastic_stretching_rate.norm() * TWO_THIRDS.sqrt())
49 }
50}
51
52#[derive(Clone, Debug)]
54pub struct ViscoplasticFlow {
55 pub initial_yield_stress: Scalar,
57 pub hardening_slope: Scalar,
59 pub rate_sensitivity: Scalar,
61 pub reference_flow_rate: Scalar,
63}
64
65impl Plastic for ViscoplasticFlow {
66 fn initial_yield_stress(&self) -> Scalar {
67 self.initial_yield_stress
68 }
69 fn hardening_slope(&self) -> Scalar {
70 self.hardening_slope
71 }
72}
73
74impl Viscoplastic for ViscoplasticFlow {
75 fn rate_sensitivity(&self) -> Scalar {
76 self.rate_sensitivity
77 }
78 fn reference_flow_rate(&self) -> Scalar {
79 self.reference_flow_rate
80 }
81}