conspire/domain/fem/block/thermal/conduction/
mod.rs1#[cfg(test)]
2pub mod test;
3
4use crate::{
5 constitutive::thermal::conduction::ThermalConduction,
6 fem::{
7 ElementModelError,
8 block::{
9 Block,
10 element::{FiniteElementError, thermal::conduction::ThermalConductionFiniteElement},
11 thermal::{NodalTemperatures, ThermalElements},
12 },
13 thermal::conduction::ThermalConductionElements,
14 },
15 math::{Quantity, QuantitySparseVec2D, QuantityVector},
16 units::{Power, PowerPerTemperature, PowerTemperature},
17};
18
19pub type NodalForcesThermal = QuantityVector<Power>;
20pub type NodalStiffnessesThermal = QuantitySparseVec2D<PowerPerTemperature>;
21
22impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize> ThermalConductionElements
23 for Block<C, F, G, M, N, P>
24where
25 C: ThermalConduction,
26 F: ThermalConductionFiniteElement<C, G, M, N, P>,
27{
28 fn potential(
29 &self,
30 nodal_temperatures: &NodalTemperatures,
31 ) -> Result<Quantity<PowerTemperature>, ElementModelError> {
32 self.elements()
33 .iter()
34 .zip(self.connectivity())
35 .map(|(element, element_connectivity)| {
36 element.potential(
37 self.constitutive_model(),
38 &self.nodal_temperatures_element(element_connectivity, nodal_temperatures),
39 )
40 })
41 .sum::<Result<Quantity<PowerTemperature>, FiniteElementError>>()
42 .map_err(|error| ElementModelError::upstream(error, self))
43 }
44 fn nodal_forces_into(
45 &self,
46 nodal_temperatures: &NodalTemperatures,
47 nodal_forces: &mut NodalForcesThermal,
48 ) -> Result<(), ElementModelError> {
49 self.elements()
50 .iter()
51 .zip(self.connectivity())
52 .try_for_each(|(element, element_connectivity)| {
53 element
54 .nodal_forces(
55 self.constitutive_model(),
56 &self.nodal_temperatures_element(element_connectivity, nodal_temperatures),
57 )?
58 .into_iter()
59 .zip(element_connectivity)
60 .for_each(|(nodal_force, &node)| nodal_forces[node] += nodal_force);
61 Ok::<(), FiniteElementError>(())
62 })
63 .map_err(|error| ElementModelError::upstream(error, self))
64 }
65 fn nodal_stiffnesses_into(
66 &self,
67 nodal_temperatures: &NodalTemperatures,
68 nodal_stiffnesses: &mut NodalStiffnessesThermal,
69 ) -> Result<(), ElementModelError> {
70 self.elements()
71 .iter()
72 .zip(self.connectivity())
73 .try_for_each(|(element, element_connectivity)| {
74 element
75 .nodal_stiffnesses(
76 self.constitutive_model(),
77 &self.nodal_temperatures_element(element_connectivity, nodal_temperatures),
78 )?
79 .into_iter()
80 .zip(element_connectivity)
81 .for_each(|(object, &node_a)| {
82 object.into_iter().zip(element_connectivity).for_each(
83 |(nodal_stiffness, &node_b)| {
84 nodal_stiffnesses[node_a][node_b] += nodal_stiffness
85 },
86 )
87 });
88 Ok::<(), FiniteElementError>(())
89 })
90 .map_err(|error| ElementModelError::upstream(error, self))
91 }
92}