conspire/domain/cbm/block/solid/elastic_viscoplastic/
mod.rs1use super::super::{Block, node::solid::elastic_viscoplastic::ElasticViscoplasticElement};
2use crate::{
3 constitutive::{ConstitutiveError, solid::elastic_viscoplastic::ElasticViscoplastic},
4 domain::{
5 ElementModelError, NodalCoordinates,
6 solid::{NodalForcesSolid, NodalStiffnessesSolid},
7 },
8 math::{Differentiable, Tensor},
9};
10
11pub use crate::domain::block::solid::viscoplastic::{
12 ViscoplasticEvolution, ViscoplasticStateVariables,
13};
14pub use crate::domain::solid::elastic_viscoplastic::{
15 ElasticViscoplasticBCs, ElasticViscoplasticElements,
16};
17
18impl<C, Y> ElasticViscoplasticElements<ViscoplasticStateVariables<1, Y>, 3> for Block<C>
19where
20 C: ElasticViscoplastic<Y>,
21 Y: Differentiable + Tensor,
22{
23 fn initial_state(&self) -> ViscoplasticStateVariables<1, Y> {
24 self.nodes
25 .iter()
26 .map(|_| [self.constitutive_model.initial_state()].into())
27 .collect()
28 }
29 fn nodal_forces_into(
30 &self,
31 nodal_coordinates: &NodalCoordinates<3>,
32 state_variables: &ViscoplasticStateVariables<1, Y>,
33 nodal_forces: &mut NodalForcesSolid<3>,
34 ) -> Result<(), ElementModelError> {
35 self.nodes
36 .iter()
37 .zip(state_variables)
38 .try_for_each(|(node, state_variables_node)| {
39 node.nodal_forces(
40 &self.constitutive_model,
41 nodal_coordinates,
42 state_variables_node,
43 )?
44 .into_iter()
45 .zip(node.neighbors())
46 .for_each(|(force, &neighbor)| nodal_forces[neighbor] += force);
47 Ok::<(), ConstitutiveError>(())
48 })
49 .map_err(|error| ElementModelError::upstream(error, self))
50 }
51 fn nodal_stiffnesses_into(
52 &self,
53 nodal_coordinates: &NodalCoordinates<3>,
54 state_variables: &ViscoplasticStateVariables<1, Y>,
55 nodal_stiffnesses: &mut NodalStiffnessesSolid<3>,
56 ) -> Result<(), ElementModelError> {
57 self.nodes
58 .iter()
59 .zip(state_variables)
60 .try_for_each(|(node, state_variables_node)| {
61 node.nodal_stiffnesses(
62 &self.constitutive_model,
63 nodal_coordinates,
64 state_variables_node,
65 )?
66 .into_iter()
67 .zip(node.neighbors())
68 .for_each(|(row, &neighbor_a)| {
69 row.into_iter()
70 .zip(node.neighbors())
71 .for_each(|(block, &neighbor_b)| {
72 nodal_stiffnesses[neighbor_a][neighbor_b] += block
73 })
74 });
75 Ok::<(), ConstitutiveError>(())
76 })
77 .map_err(|error| ElementModelError::upstream(error, self))
78 }
79 fn state_variables_evolution(
80 &self,
81 nodal_coordinates: &NodalCoordinates<3>,
82 state_variables: &ViscoplasticStateVariables<1, Y>,
83 ) -> Result<ViscoplasticEvolution<1, Y>, ElementModelError> {
84 self.nodes
85 .iter()
86 .zip(state_variables)
87 .map(|(node, state_variables_node)| {
88 node.state_variables_evolution(
89 &self.constitutive_model,
90 nodal_coordinates,
91 state_variables_node,
92 )
93 })
94 .collect::<Result<_, ConstitutiveError>>()
95 .map_err(|error| ElementModelError::upstream(error, self))
96 }
97}