conspire/domain/vem/block/solid/viscoelastic/
mod.rs1use crate::{
2 constitutive::solid::viscoelastic::Viscoelastic,
3 domain::{ElementModelError, solid::viscoelastic::ViscoelasticElements},
4 vem::{
5 NodalCoordinates, NodalVelocities,
6 block::{
7 Block,
8 element::{VirtualElementError, solid::viscoelastic::ViscoelasticVirtualElement},
9 solid::{NodalDampingsSolid, NodalForcesSolid},
10 },
11 },
12};
13
14impl<C, F> ViscoelasticElements<3> for Block<C, F>
15where
16 C: Viscoelastic,
17 F: ViscoelasticVirtualElement<C>,
18{
19 fn nodal_forces_into(
20 &self,
21 nodal_coordinates: &NodalCoordinates,
22 nodal_velocities: &NodalVelocities,
23 nodal_forces: &mut NodalForcesSolid,
24 ) -> Result<(), ElementModelError> {
25 self.elements()
26 .iter()
27 .zip(self.elements_nodes())
28 .try_for_each(|(element, nodes)| {
29 element
30 .nodal_forces(
31 self.constitutive_model(),
32 &Self::element_coordinates(nodal_coordinates, nodes),
33 &Self::element_coordinates(nodal_velocities, nodes),
34 )?
35 .into_iter()
36 .zip(nodes)
37 .for_each(|(nodal_force, &node)| nodal_forces[node] += nodal_force);
38 Ok::<(), VirtualElementError>(())
39 })
40 .map_err(|error| ElementModelError::upstream(error, self))
41 }
42 fn nodal_stiffnesses_into(
43 &self,
44 nodal_coordinates: &NodalCoordinates,
45 nodal_velocities: &NodalVelocities,
46 nodal_stiffnesses: &mut NodalDampingsSolid,
47 ) -> Result<(), ElementModelError> {
48 self.elements()
49 .iter()
50 .zip(self.elements_nodes())
51 .try_for_each(|(element, nodes)| {
52 element
53 .nodal_stiffnesses(
54 self.constitutive_model(),
55 &Self::element_coordinates(nodal_coordinates, nodes),
56 &Self::element_coordinates(nodal_velocities, nodes),
57 )?
58 .into_iter()
59 .zip(nodes)
60 .for_each(|(object, &node_a)| {
61 object
62 .into_iter()
63 .zip(nodes)
64 .for_each(|(nodal_stiffness, &node_b)| {
65 nodal_stiffnesses[node_a][node_b] += nodal_stiffness
66 })
67 });
68 Ok::<(), VirtualElementError>(())
69 })
70 .map_err(|error| ElementModelError::upstream(error, self))
71 }
72}