Skip to main content

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

1use crate::{
2    constitutive::solid::elastic_viscoplastic::ElasticViscoplastic,
3    domain::{
4        ElementModelError,
5        block::solid::viscoplastic::{ViscoplasticEvolution, ViscoplasticStateVariables},
6        solid::elastic_viscoplastic::ElasticViscoplasticElements,
7    },
8    math::{Differentiable, Tensor},
9    vem::{
10        NodalCoordinates,
11        block::{
12            Block,
13            element::{
14                VirtualElementError, solid::elastic_viscoplastic::ElasticViscoplasticVirtualElement,
15            },
16            solid::{NodalForcesSolid, NodalStiffnessesSolid},
17        },
18    },
19};
20use std::array::from_fn;
21
22impl<C, F, Y> ElasticViscoplasticElements<ViscoplasticStateVariables<1, Y>, 3> for Block<C, F>
23where
24    C: ElasticViscoplastic<Y>,
25    F: ElasticViscoplasticVirtualElement<C, Y>,
26    Y: Differentiable + Tensor,
27{
28    fn initial_state(&self) -> ViscoplasticStateVariables<1, Y> {
29        self.elements()
30            .iter()
31            .map(|_| from_fn(|_| self.constitutive_model().initial_state()).into())
32            .collect()
33    }
34    fn nodal_forces_into(
35        &self,
36        nodal_coordinates: &NodalCoordinates,
37        state_variables: &ViscoplasticStateVariables<1, Y>,
38        nodal_forces: &mut NodalForcesSolid,
39    ) -> Result<(), ElementModelError> {
40        self.elements()
41            .iter()
42            .zip(self.elements_nodes())
43            .zip(state_variables)
44            .try_for_each(|((element, nodes), state_variables_element)| {
45                element
46                    .nodal_forces(
47                        self.constitutive_model(),
48                        &Self::element_coordinates(nodal_coordinates, nodes),
49                        state_variables_element,
50                    )?
51                    .into_iter()
52                    .zip(nodes)
53                    .for_each(|(nodal_force, &node)| nodal_forces[node] += nodal_force);
54                Ok::<(), VirtualElementError>(())
55            })
56            .map_err(|error| ElementModelError::upstream(error, self))
57    }
58    fn nodal_stiffnesses_into(
59        &self,
60        nodal_coordinates: &NodalCoordinates,
61        state_variables: &ViscoplasticStateVariables<1, Y>,
62        nodal_stiffnesses: &mut NodalStiffnessesSolid,
63    ) -> Result<(), ElementModelError> {
64        self.elements()
65            .iter()
66            .zip(self.elements_nodes())
67            .zip(state_variables)
68            .try_for_each(|((element, nodes), state_variables_element)| {
69                element
70                    .nodal_stiffnesses(
71                        self.constitutive_model(),
72                        &Self::element_coordinates(nodal_coordinates, nodes),
73                        state_variables_element,
74                    )?
75                    .into_iter()
76                    .zip(nodes)
77                    .for_each(|(object, &node_a)| {
78                        object
79                            .into_iter()
80                            .zip(nodes)
81                            .for_each(|(nodal_stiffness, &node_b)| {
82                                nodal_stiffnesses[node_a][node_b] += nodal_stiffness
83                            })
84                    });
85                Ok::<(), VirtualElementError>(())
86            })
87            .map_err(|error| ElementModelError::upstream(error, self))
88    }
89    fn state_variables_evolution(
90        &self,
91        nodal_coordinates: &NodalCoordinates,
92        state_variables: &ViscoplasticStateVariables<1, Y>,
93    ) -> Result<ViscoplasticEvolution<1, Y>, ElementModelError> {
94        self.elements()
95            .iter()
96            .zip(self.elements_nodes())
97            .zip(state_variables)
98            .map(|((element, nodes), element_state_variables)| {
99                element.state_variables_evolution(
100                    self.constitutive_model(),
101                    &Self::element_coordinates(nodal_coordinates, nodes),
102                    element_state_variables,
103                )
104            })
105            .collect::<Result<_, VirtualElementError>>()
106            .map_err(|error| ElementModelError::upstream(error, self))
107    }
108}