conspire/domain/vem/block/solid/hyperelastic_viscoplastic/
mod.rs1use crate::{
2 constitutive::solid::hyperelastic_viscoplastic::HyperelasticViscoplastic,
3 domain::{
4 ElementModelError,
5 block::solid::viscoplastic::ViscoplasticStateVariables,
6 solid::{
7 elastic_viscoplastic::ElasticViscoplasticElements,
8 hyperelastic_viscoplastic::HyperelasticViscoplasticElements,
9 },
10 },
11 math::{Differentiable, Quantity, Tensor},
12 units::Energy,
13 vem::{
14 NodalCoordinates,
15 block::{
16 Block,
17 element::{
18 VirtualElementError,
19 solid::hyperelastic_viscoplastic::HyperelasticViscoplasticVirtualElement,
20 },
21 },
22 },
23};
24
25impl<C, F, Y> HyperelasticViscoplasticElements<ViscoplasticStateVariables<1, Y>, 3> for Block<C, F>
26where
27 C: HyperelasticViscoplastic<Y>,
28 F: HyperelasticViscoplasticVirtualElement<C, Y>,
29 Self: ElasticViscoplasticElements<ViscoplasticStateVariables<1, Y>, 3>,
30 Y: Differentiable + Tensor,
31{
32 fn helmholtz_free_energy(
33 &self,
34 nodal_coordinates: &NodalCoordinates,
35 state_variables: &ViscoplasticStateVariables<1, Y>,
36 ) -> Result<Quantity<Energy>, ElementModelError> {
37 self.elements()
38 .iter()
39 .zip(self.elements_nodes())
40 .zip(state_variables)
41 .map(|((element, nodes), state_variables_element)| {
42 element.helmholtz_free_energy(
43 self.constitutive_model(),
44 &Self::element_coordinates(nodal_coordinates, nodes),
45 state_variables_element,
46 )
47 })
48 .sum::<Result<_, VirtualElementError>>()
49 .map_err(|error| ElementModelError::upstream(error, self))
50 }
51}