Skip to main content

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

1use 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}