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