conspire/domain/fem/block/solid/hyperviscoelastic/
mod.rs1use crate::{
2 constitutive::solid::hyperviscoelastic::Hyperviscoelastic,
3 fem::{
4 NodalCoordinates,
5 block::{
6 Block, FiniteElementBlockError,
7 element::solid::hyperviscoelastic::HyperviscoelasticFiniteElement,
8 solid::elastic_hyperviscous::ElasticHyperviscousFiniteElementBlock,
9 },
10 },
11 math::Scalar,
12};
13
14pub trait HyperviscoelasticFiniteElementBlock<
15 C,
16 F,
17 const G: usize,
18 const M: usize,
19 const N: usize,
20 const P: usize,
21> where
22 C: Hyperviscoelastic,
23 F: HyperviscoelasticFiniteElement<C, G, M, N, P>,
24 Self: ElasticHyperviscousFiniteElementBlock<C, F, G, M, N, P>,
25{
26 fn helmholtz_free_energy(
27 &self,
28 nodal_coordinates: &NodalCoordinates,
29 ) -> Result<Scalar, FiniteElementBlockError>;
30}
31
32impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize>
33 HyperviscoelasticFiniteElementBlock<C, F, G, M, N, P> for Block<C, F, G, M, N, P>
34where
35 C: Hyperviscoelastic,
36 F: HyperviscoelasticFiniteElement<C, G, M, N, P>,
37 Self: ElasticHyperviscousFiniteElementBlock<C, F, G, M, N, P>,
38{
39 fn helmholtz_free_energy(
40 &self,
41 nodal_coordinates: &NodalCoordinates,
42 ) -> Result<Scalar, FiniteElementBlockError> {
43 match self
44 .elements()
45 .iter()
46 .zip(self.connectivity())
47 .map(|(element, nodes)| {
48 element.helmholtz_free_energy(
49 self.constitutive_model(),
50 &Self::element_coordinates(nodal_coordinates, nodes),
51 )
52 })
53 .sum()
54 {
55 Ok(helmholtz_free_energy) => Ok(helmholtz_free_energy),
56 Err(error) => Err(FiniteElementBlockError::Upstream(
57 format!("{error}"),
58 format!("{self:?}"),
59 )),
60 }
61 }
62}