Skip to main content

conspire/constitutive/fluid/hyperviscous/newtonian/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        ConstitutiveError,
7        fluid::{
8            hyperviscous::{Hyperviscous, TWO_THIRDS},
9            viscous::Viscous,
10        },
11    },
12    math::{ContractWith, IDENTITY, Quantity, Rank2, TensorRank4},
13    mechanics::{
14        CauchyRateTangentStiffness, CauchyStress, DeformationGradient, DeformationGradientRate,
15    },
16    units::{Dissipation, Viscosity},
17};
18
19#[doc = include_str!("doc.md")]
20#[derive(Clone, Debug)]
21pub struct Newtonian {
22    /// The bulk viscosity $`\zeta`$.
23    pub bulk_viscosity: Quantity<Viscosity>,
24    /// The shear viscosity $`\eta`$.
25    pub shear_viscosity: Quantity<Viscosity>,
26}
27
28impl Viscous for Newtonian {
29    fn bulk_viscosity(&self) -> Quantity<Viscosity> {
30        self.bulk_viscosity
31    }
32    fn shear_viscosity(&self) -> Quantity<Viscosity> {
33        self.shear_viscosity
34    }
35    #[doc = include_str!("viscous_cauchy_stress.md")]
36    fn viscous_cauchy_stress(
37        &self,
38        deformation_gradient: &DeformationGradient,
39        deformation_gradient_rate: &DeformationGradientRate,
40    ) -> Result<CauchyStress, ConstitutiveError> {
41        let jacobian = deformation_gradient.determinant();
42        let velocity_gradient = deformation_gradient_rate * deformation_gradient.inverse();
43        let (deviatoric_strain_rate, strain_rate_trace) =
44            ((&velocity_gradient + velocity_gradient.transpose()) * 0.5).deviatoric_and_trace();
45        Ok(
46            deviatoric_strain_rate * (2.0 * self.shear_viscosity() / jacobian)
47                + IDENTITY * (self.bulk_viscosity() * strain_rate_trace / jacobian),
48        )
49    }
50    #[doc = include_str!("viscous_cauchy_rate_tangent_stiffness.md")]
51    fn viscous_cauchy_rate_tangent_stiffness(
52        &self,
53        deformation_gradient: &DeformationGradient,
54        _: &DeformationGradientRate,
55    ) -> Result<CauchyRateTangentStiffness, ConstitutiveError> {
56        let jacobian = deformation_gradient.determinant();
57        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
58        let scaled_deformation_gradient_inverse_transpose =
59            &deformation_gradient_inverse_transpose * (self.shear_viscosity() / jacobian);
60        Ok(
61            TensorRank4::dyad_ik_jl(&IDENTITY, &scaled_deformation_gradient_inverse_transpose)
62                + TensorRank4::dyad_il_jk(
63                    &scaled_deformation_gradient_inverse_transpose,
64                    &IDENTITY,
65                )
66                + TensorRank4::dyad_ij_kl(
67                    &(IDENTITY
68                        * ((self.bulk_viscosity() - TWO_THIRDS * self.shear_viscosity())
69                            / jacobian)),
70                    &deformation_gradient_inverse_transpose,
71                ),
72        )
73    }
74}
75
76impl Hyperviscous for Newtonian {
77    #[doc = include_str!("viscous_dissipation.md")]
78    fn viscous_dissipation(
79        &self,
80        deformation_gradient: &DeformationGradient,
81        deformation_gradient_rate: &DeformationGradientRate,
82    ) -> Result<Quantity<Dissipation>, ConstitutiveError> {
83        let velocity_gradient = deformation_gradient_rate * deformation_gradient.inverse();
84        let strain_rate = (&velocity_gradient + velocity_gradient.transpose()) * 0.5;
85        let strain_rate_trace = strain_rate.trace();
86        Ok(
87            (&strain_rate * self.shear_viscosity()).contract_with(&strain_rate)
88                + (self.bulk_viscosity() - TWO_THIRDS * self.shear_viscosity())
89                    * strain_rate_trace
90                    * strain_rate_trace
91                    * 0.5,
92        )
93    }
94}