conspire/domain/cbm/block/node/solid/elastic_viscoplastic/
mod.rs1use 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}