use crate::integ::Gauss;
use crate::shapes::Scratchpad;
use russell_lab::Matrix;
pub fn get_interp_matrix(pad: &mut Scratchpad, gauss: &Gauss) -> Matrix {
let nnode = pad.interp.dim();
let ngauss = gauss.npoint();
let mut pp = Matrix::new(ngauss, nnode);
for p in 0..ngauss {
pad.calc_interp(gauss.coords(p));
for j in 0..nnode {
pp.set(p, j, pad.interp[j]);
}
}
pp
}
#[cfg(test)]
mod tests {
use super::get_interp_matrix;
use crate::integ::Gauss;
use crate::shapes::{GeoKind, Scratchpad};
use russell_lab::{approx_eq, Matrix};
#[test]
pub fn get_shape_matrix_works() {
let (w, h) = (20.0, 10.0);
let space_ndim = 2;
let mut pad = Scratchpad::new(space_ndim, GeoKind::Qua4).unwrap();
pad.set_xx(0, 0, 0.0);
pad.set_xx(0, 1, 0.0);
pad.set_xx(1, 0, w);
pad.set_xx(1, 1, 0.0);
pad.set_xx(2, 0, w);
pad.set_xx(2, 1, h);
pad.set_xx(3, 0, 0.0);
pad.set_xx(3, 1, h);
let gauss = Gauss::new_sized(pad.kind.class(), 4).unwrap();
let pp = get_interp_matrix(&mut pad, &gauss);
assert_eq!(pp.dims(), (4, 4));
let ngauss = gauss.npoint();
let (ndim, nnode) = pad.xxt.dims();
let mut xx_ips = Matrix::new(ngauss, ndim);
for p in 0..ngauss {
for j in 0..ndim {
for k in 0..nnode {
xx_ips.add(p, j, pp.get(p, k) * pad.xxt.get(j, k));
}
}
}
approx_eq(xx_ips.get(0, 0), w * (1.0 - f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(0, 1), h * (1.0 - f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(1, 0), w * (1.0 + f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(1, 1), h * (1.0 - f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(2, 0), w * (1.0 - f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(2, 1), h * (1.0 + f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(3, 0), w * (1.0 + f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
approx_eq(xx_ips.get(3, 1), h * (1.0 + f64::sqrt(3.0) / 3.0) / 2.0, 1e-15);
}
}