Matrix for Upwind4
This commit is contained in:
parent
45e4d51513
commit
c660354c3f
|
@ -178,6 +178,71 @@ pub(crate) mod constmatrix {
|
|||
let m3 = m1 * m2;
|
||||
assert_eq!(m3, Matrix::new([[74, 80, 86, 92], [173, 188, 203, 218]]));
|
||||
}
|
||||
#[test]
|
||||
fn iter() {
|
||||
let m = Matrix::new([[1_u8, 2, 3], [4, 5, 6]]);
|
||||
let mut iter = m.iter();
|
||||
assert_eq!(iter.next(), Some(&1));
|
||||
assert_eq!(iter.next(), Some(&2));
|
||||
assert_eq!(iter.next(), Some(&3));
|
||||
assert_eq!(iter.next(), Some(&4));
|
||||
assert_eq!(iter.next(), Some(&5));
|
||||
assert_eq!(iter.next(), Some(&6));
|
||||
assert_eq!(iter.next(), None);
|
||||
}
|
||||
}
|
||||
|
||||
mod approx {
|
||||
use super::Matrix;
|
||||
use ::approx::{AbsDiffEq, RelativeEq, UlpsEq};
|
||||
|
||||
impl<T, const M: usize, const N: usize> AbsDiffEq for Matrix<T, M, N>
|
||||
where
|
||||
T: AbsDiffEq,
|
||||
{
|
||||
type Epsilon = T::Epsilon;
|
||||
fn default_epsilon() -> Self::Epsilon {
|
||||
T::default_epsilon()
|
||||
}
|
||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||
self.iter()
|
||||
.zip(other.iter())
|
||||
.all(|(r, l)| r.abs_diff_eq(l, T::default_epsilon()))
|
||||
}
|
||||
}
|
||||
impl<T, const M: usize, const N: usize> RelativeEq for Matrix<T, M, N>
|
||||
where
|
||||
T: RelativeEq,
|
||||
Self::Epsilon: Copy,
|
||||
{
|
||||
fn default_max_relative() -> Self::Epsilon {
|
||||
T::default_max_relative()
|
||||
}
|
||||
fn relative_eq(
|
||||
&self,
|
||||
other: &Self,
|
||||
epsilon: Self::Epsilon,
|
||||
max_relative: Self::Epsilon,
|
||||
) -> bool {
|
||||
self.iter()
|
||||
.zip(other.iter())
|
||||
.all(|(r, l)| r.relative_eq(l, epsilon, max_relative))
|
||||
}
|
||||
}
|
||||
impl<T, const M: usize, const N: usize> UlpsEq for Matrix<T, M, N>
|
||||
where
|
||||
T: UlpsEq,
|
||||
Self::Epsilon: Copy,
|
||||
{
|
||||
fn default_max_ulps() -> u32 {
|
||||
T::default_max_ulps()
|
||||
}
|
||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||
self.iter()
|
||||
.zip(other.iter())
|
||||
.all(|(r, l)| r.ulps_eq(l, epsilon, max_ulps))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,6 +293,7 @@ pub(crate) fn diff_op_1d_matrix<const M: usize, const N: usize, const D: usize>(
|
|||
*f = diff * idx;
|
||||
}
|
||||
|
||||
let prev = prev.slice(ndarray::s![nx - N..]);
|
||||
for (bl, f) in blockend.iter_rows().zip(fut.iter_mut().rev().take(M).rev()) {
|
||||
let diff = bl
|
||||
.iter()
|
||||
|
|
|
@ -240,8 +240,5 @@ fn block_equality() {
|
|||
let mut flipped_inverted = SBP4::BLOCK_MATRIX.flip();
|
||||
flipped_inverted *= -1.0;
|
||||
|
||||
assert!(flipped_inverted
|
||||
.iter()
|
||||
.zip(SBP4::BLOCKEND_MATRIX.iter())
|
||||
.all(|(x, y)| (x - y).abs() < 1e-3))
|
||||
approx::assert_ulps_eq!(SBP4::BLOCKEND_MATRIX, flipped_inverted, max_ulps = 1);
|
||||
}
|
||||
|
|
|
@ -221,8 +221,5 @@ fn block_equality() {
|
|||
let mut flipped_inverted = SBP8::BLOCK_MATRIX.flip();
|
||||
flipped_inverted *= -1.0;
|
||||
|
||||
assert!(flipped_inverted
|
||||
.iter()
|
||||
.zip(SBP8::BLOCKEND_MATRIX.iter())
|
||||
.all(|(x, y)| (x - y).abs() < 1e-12))
|
||||
approx::assert_ulps_eq!(SBP8::BLOCKEND_MATRIX, flipped_inverted, max_ulps = 1);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::{
|
||||
diff_op_col, diff_op_row, SbpOperator1d, SbpOperator2d, UpwindOperator1d, UpwindOperator2d,
|
||||
diff_op_col, diff_op_row, Matrix, RowVector, SbpOperator1d, SbpOperator2d, UpwindOperator1d,
|
||||
UpwindOperator2d,
|
||||
};
|
||||
use crate::Float;
|
||||
use ndarray::{ArrayView1, ArrayView2, ArrayViewMut1, ArrayViewMut2, Axis};
|
||||
|
@ -174,12 +175,30 @@ impl Upwind4 {
|
|||
-1.0 / 24.0, 1.0 / 4.0, -7.0 / 8.0, 0.0, 7.0 / 8.0, -1.0 / 4.0, 1.0 / 24.0
|
||||
];
|
||||
#[rustfmt::skip]
|
||||
const DIAG_MATRIX : RowVector<Float, 7> = RowVector::new([
|
||||
[-1.0 / 24.0, 1.0 / 4.0, -7.0 / 8.0, 0.0, 7.0 / 8.0, -1.0 / 4.0, 1.0 / 24.0]
|
||||
]);
|
||||
#[rustfmt::skip]
|
||||
const BLOCK: &'static [&'static [Float]] = &[
|
||||
&[ -72.0 / 49.0, 187.0 / 98.0, -20.0 / 49.0, -3.0 / 98.0, 0.0, 0.0, 0.0],
|
||||
&[-187.0 / 366.0, 0.0, 69.0 / 122.0, -16.0 / 183.0, 2.0 / 61.0, 0.0, 0.0],
|
||||
&[ 20.0 / 123.0, -69.0 / 82.0, 0.0, 227.0 / 246.0, -12.0 / 41.0, 2.0 / 41.0, 0.0],
|
||||
&[ 3.0 / 298.0, 16.0 / 149.0, -227.0 / 298.0, 0.0, 126.0 / 149.0, -36.0 / 149.0, 6.0 / 149.0],
|
||||
];
|
||||
#[rustfmt::skip]
|
||||
const BLOCK_MATRIX: Matrix<Float, 4, 7> = Matrix::new([
|
||||
[ -72.0 / 49.0, 187.0 / 98.0, -20.0 / 49.0, -3.0 / 98.0, 0.0, 0.0, 0.0],
|
||||
[-187.0 / 366.0, 0.0, 69.0 / 122.0, -16.0 / 183.0, 2.0 / 61.0, 0.0, 0.0],
|
||||
[ 20.0 / 123.0, -69.0 / 82.0, 0.0, 227.0 / 246.0, -12.0 / 41.0, 2.0 / 41.0, 0.0],
|
||||
[ 3.0 / 298.0, 16.0 / 149.0, -227.0 / 298.0, 0.0, 126.0 / 149.0, -36.0 / 149.0, 6.0 / 149.0],
|
||||
]);
|
||||
#[rustfmt::skip]
|
||||
const BLOCKEND_MATRIX: Matrix<Float, 4, 7> = Matrix::new([
|
||||
[ -6.0 / 149.0, 36.0 / 149.0, -126.0 / 149.0, 0.0, 227.0 / 298.0, -16.0 / 149.0, -3.0 / 298.0],
|
||||
[ 0.0, -2.0/41.0, 12.0/41.0, -227.0/246.0, 0.0, 69.0/82.0, -20.0/123.0],
|
||||
[ 0.0, 0.0, -2.0/61.0, 16.0/183.0, -69.0/122.0, 0.0, 187.0/366.0],
|
||||
[ 0.0, 0.0, 0.0, 3.0 / 98.0, 20.0 / 49.0, -187.0 / 98.0, 72.0/49.0],
|
||||
]);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const DISS_BLOCK: &'static [&'static [Float]] = &[
|
||||
|
@ -197,10 +216,10 @@ impl Upwind4 {
|
|||
|
||||
impl SbpOperator1d for Upwind4 {
|
||||
fn diff(&self, prev: ArrayView1<Float>, fut: ArrayViewMut1<Float>) {
|
||||
super::diff_op_1d(
|
||||
Self::BLOCK,
|
||||
Self::DIAG,
|
||||
super::Symmetry::AntiSymmetric,
|
||||
super::diff_op_1d_matrix(
|
||||
&Self::BLOCK_MATRIX,
|
||||
&Self::BLOCKEND_MATRIX,
|
||||
&Self::DIAG_MATRIX,
|
||||
super::OperatorType::Normal,
|
||||
prev,
|
||||
fut,
|
||||
|
@ -229,18 +248,29 @@ impl SbpOperator1d for Upwind4 {
|
|||
}
|
||||
}
|
||||
|
||||
fn diff_op_row_local(prev: ndarray::ArrayView2<Float>, mut fut: ndarray::ArrayViewMut2<Float>) {
|
||||
for (p, mut f) in prev
|
||||
.axis_iter(ndarray::Axis(0))
|
||||
.zip(fut.axis_iter_mut(ndarray::Axis(0)))
|
||||
{
|
||||
super::diff_op_1d_slice_matrix(
|
||||
&Upwind4::BLOCK_MATRIX,
|
||||
&Upwind4::BLOCKEND_MATRIX,
|
||||
&Upwind4::DIAG_MATRIX,
|
||||
super::OperatorType::Normal,
|
||||
p.as_slice().unwrap(),
|
||||
f.as_slice_mut().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl SbpOperator2d for Upwind4 {
|
||||
fn diffxi(&self, prev: ArrayView2<Float>, mut fut: ArrayViewMut2<Float>) {
|
||||
assert_eq!(prev.shape(), fut.shape());
|
||||
assert!(prev.shape()[1] >= 2 * Upwind4::BLOCK.len());
|
||||
|
||||
match (prev.strides(), fut.strides()) {
|
||||
([_, 1], [_, 1]) => diff_op_row(
|
||||
Upwind4::BLOCK,
|
||||
Upwind4::DIAG,
|
||||
super::Symmetry::AntiSymmetric,
|
||||
super::OperatorType::Normal,
|
||||
)(prev, fut),
|
||||
([_, 1], [_, 1]) => diff_op_row_local(prev, fut),
|
||||
([1, _], [1, _]) if prev.len_of(Axis(0)) % SimdT::lanes() == 0 => {
|
||||
diff_simd_col(prev, fut)
|
||||
}
|
||||
|
@ -465,3 +495,11 @@ fn upwind4_test2() {
|
|||
1e-1,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_equality() {
|
||||
let mut flipped_inverted = Upwind4::BLOCK_MATRIX.flip();
|
||||
flipped_inverted *= -1.0;
|
||||
|
||||
approx::assert_ulps_eq!(Upwind4::BLOCKEND_MATRIX, flipped_inverted, max_ulps = 1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue