Skip to main content

conspire/domain/cbm/block/node/solid/elastic_viscoplastic/
mod.rs

1use super::{super::Node, SolidElement};
2use crate::{
3    constitutive::{ConstitutiveError, solid::elastic_viscoplastic::ElasticViscoplastic},
4    domain::{
5        NodalCoordinates,
6        block::element::solid::viscoplastic::{ViscoplasticEvolution, ViscoplasticStateVariables},
7    },
8    math::{
9        ContractSecondFourthWithFirst, Current, Differentiable, Tensor, TensorRank1, TensorRank2,
10    },
11    units::{Force, ForcePerLength},
12};
13
14pub use crate::domain::block::element::solid::elastic_viscoplastic::ElasticViscoplasticElement;
15
16type NodalForce = TensorRank1<3, Current, Force>;
17type NodalStiffness = TensorRank2<3, Current, Current, ForcePerLength>;
18
19impl<C, Y> ElasticViscoplasticElement<C, 1, Y> for Node
20where
21    C: ElasticViscoplastic<Y>,
22    Y: Differentiable + Tensor,
23{
24    type Forces = Vec<NodalForce>;
25    type Stiffnesses = Vec<Vec<NodalStiffness>>;
26    type Error = ConstitutiveError;
27    fn nodal_forces(
28        &self,
29        constitutive_model: &C,
30        nodal_coordinates: &NodalCoordinates<3>,
31        state_variables: &ViscoplasticStateVariables<1, Y>,
32    ) -> Result<Vec<NodalForce>, ConstitutiveError> {
33        let (deformation_gradient_p, _) = (&state_variables[0]).into();
34        let first_piola_kirchhoff_stress = constitutive_model.first_piola_kirchhoff_stress(
35            &self.deformation_gradients(nodal_coordinates),
36            deformation_gradient_p,
37        )?;
38        Ok(self
39            .gradient_vectors()
40            .iter()
41            .map(|gradient_vector| (&first_piola_kirchhoff_stress * gradient_vector) * self.volume)
42            .collect())
43    }
44    fn nodal_stiffnesses(
45        &self,
46        constitutive_model: &C,
47        nodal_coordinates: &NodalCoordinates<3>,
48        state_variables: &ViscoplasticStateVariables<1, Y>,
49    ) -> Result<Vec<Vec<NodalStiffness>>, ConstitutiveError> {
50        let (deformation_gradient_p, _) = (&state_variables[0]).into();
51        let first_piola_kirchhoff_tangent_stiffness = constitutive_model
52            .first_piola_kirchhoff_tangent_stiffness(
53                &self.deformation_gradients(nodal_coordinates),
54                deformation_gradient_p,
55            )?;
56        Ok(self
57            .gradient_vectors()
58            .iter()
59            .map(|gradient_vector_a| {
60                self.gradient_vectors()
61                    .iter()
62                    .map(|gradient_vector_b| {
63                        first_piola_kirchhoff_tangent_stiffness
64                            .contract_second_fourth_with_first(gradient_vector_a, gradient_vector_b)
65                            * self.volume
66                    })
67                    .collect()
68            })
69            .collect())
70    }
71    fn state_variables_evolution(
72        &self,
73        constitutive_model: &C,
74        nodal_coordinates: &NodalCoordinates<3>,
75        state_variables: &ViscoplasticStateVariables<1, Y>,
76    ) -> Result<ViscoplasticEvolution<1, Y>, ConstitutiveError> {
77        Ok([constitutive_model.state_variables_evolution(
78            &self.deformation_gradients(nodal_coordinates),
79            &state_variables[0],
80        )?]
81        .into())
82    }
83}