Skip to main content

conspire/math/tensor/quantity/vec/
mod.rs

1use super::Quantity;
2use crate::math::{
3    Jacobian, Solution, Tensor, TensorRank0, Vector, assert::FiniteDifference,
4    tensor::vec::TensorVector,
5};
6use crate::units::{Dimensionless, UnitDiv};
7use std::ops::{Div, Sub};
8
9use super::sparse_vec_2d::QuantitySparseVec2D;
10
11/// A vector of quantities.
12pub type QuantityVector<U = Dimensionless> = TensorVector<Quantity<U>>;
13
14impl<U> QuantityVector<U> {
15    pub fn zero(len: usize) -> Self {
16        (0..len).map(|_| Quantity::new(0.0)).collect()
17    }
18}
19
20impl<U> From<Vector> for QuantityVector<U> {
21    fn from(vector: Vector) -> Self {
22        vector.iter().map(|&entry| Quantity::new(entry)).collect()
23    }
24}
25
26impl<U> Jacobian for QuantityVector<U> {
27    fn fill_into(&self, vector: &mut Vector) {
28        self.iter()
29            .zip(vector.iter_mut())
30            .for_each(|(self_a, vector_a)| *vector_a = self_a.value())
31    }
32    fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
33        self.into_iter()
34            .map(|entry| entry.value())
35            .chain(other)
36            .zip(vector.iter_mut())
37            .for_each(|(self_a, vector_a)| *vector_a = self_a)
38    }
39    fn retain_from(self, retained: &[bool]) -> Vector {
40        self.into_iter()
41            .zip(retained.iter())
42            .filter(|(_, retained)| **retained)
43            .map(|(entry, _)| entry.value())
44            .collect()
45    }
46    fn zero_out(&mut self, indices: &[usize]) {
47        indices
48            .iter()
49            .for_each(|&index| self[index] = Quantity::new(0.0))
50    }
51}
52
53impl<U> Solution for QuantityVector<U> {
54    fn decrement_from(&mut self, other: &Vector) {
55        self.iter_mut()
56            .zip(other.iter())
57            .for_each(|(self_a, vector_a)| *self_a -= Quantity::new(*vector_a))
58    }
59    fn decrement_from_chained(&mut self, other: &mut Vector, vector: &Vector) {
60        self.iter_mut()
61            .zip(vector.iter())
62            .for_each(|(self_a, vector_a)| *self_a -= Quantity::new(*vector_a));
63        other
64            .iter_mut()
65            .zip(vector.iter().skip(self.len()))
66            .for_each(|(other_a, vector_a)| *other_a -= vector_a)
67    }
68    fn decrement_from_retained(&mut self, retained: &[bool], other: &Vector) {
69        self.iter_mut()
70            .zip(retained.iter())
71            .filter(|(_, retained_a)| **retained_a)
72            .zip(other.iter())
73            .for_each(|((self_a, _), vector_a)| *self_a -= Quantity::new(*vector_a))
74    }
75}
76
77impl<U> Sub<Vector> for QuantityVector<U> {
78    type Output = Self;
79    fn sub(mut self, vector: Vector) -> Self::Output {
80        self.iter_mut()
81            .zip(vector.iter())
82            .for_each(|(self_a, vector_a)| *self_a -= Quantity::new(*vector_a));
83        self
84    }
85}
86
87impl<U> Sub<&Vector> for QuantityVector<U> {
88    type Output = Self;
89    fn sub(mut self, vector: &Vector) -> Self::Output {
90        self.iter_mut()
91            .zip(vector.iter())
92            .for_each(|(self_a, vector_a)| *self_a -= Quantity::new(*vector_a));
93        self
94    }
95}
96
97impl<U, V> Div<QuantitySparseVec2D<V>> for &QuantityVector<U>
98where
99    U: UnitDiv<V>,
100{
101    type Output = QuantityVector<<U as UnitDiv<V>>::Output>;
102    fn div(self, _quantity_sparse_vec_2d: QuantitySparseVec2D<V>) -> Self::Output {
103        unimplemented!(
104            "A mesh-scale step wants the sparse solver the caller supplies, which a division has nowhere to hold."
105        )
106    }
107}
108
109impl<U> FiniteDifference for QuantityVector<U> {
110    fn error_fd(&self, comparator: &Self, epsilon: TensorRank0) -> Option<(bool, usize)> {
111        let error_count = self
112            .iter()
113            .zip(comparator.iter())
114            .filter(|(entry, comparator_entry)| entry.differs(**comparator_entry, epsilon))
115            .count();
116        if error_count > 0 {
117            let auxiliary = self
118                .iter()
119                .zip(comparator.iter())
120                .filter(|(entry, comparator_entry)| {
121                    entry.differs_severely(**comparator_entry, epsilon)
122                })
123                .count()
124                > 0;
125            Some((auxiliary, error_count))
126        } else {
127            None
128        }
129    }
130}