use russell_lab::{Matrix, Vector};
pub struct Qua16 {}
impl Qua16 {
pub const GEO_NDIM: usize = 2;
pub const NNODE: usize = 16;
pub const NEDGE: usize = 4;
pub const NFACE: usize = 0;
pub const EDGE_NNODE: usize = 4;
pub const FACE_NNODE: usize = 0;
pub const FACE_NEDGE: usize = 0;
pub const N_INTERIOR_NODE: usize = 4;
pub const TRIANGULATE_NTRIANGLE: usize = 18;
#[rustfmt::skip]
pub const EDGE_NODE_IDS: [[usize; Qua16::EDGE_NNODE]; Qua16::NEDGE] = [
[1, 0, 8, 4],
[2, 1, 9, 5],
[3, 2, 10, 6],
[0, 3, 11, 7]
];
#[rustfmt::skip]
pub const EDGE_NODE_IDS_INWARD: [[usize; Qua16::EDGE_NNODE]; Qua16::NEDGE] = [
[0, 1, 4, 8],
[1, 2, 5, 9],
[2, 3, 6, 10],
[3, 0, 7, 11]
];
#[rustfmt::skip]
pub const NODE_REFERENCE_COORDS: [[f64; Qua16::GEO_NDIM]; Qua16::NNODE] = [
[-1.0 , -1.0 ],
[ 1.0 , -1.0 ],
[ 1.0 , 1.0 ],
[-1.0 , 1.0 ],
[-1.0 / 3.0 , -1.0 ],
[ 1.0 , -1.0 / 3.0 ],
[ 1.0 / 3.0 , 1.0 ],
[-1.0 , 1.0 / 3.0 ],
[ 1.0 / 3.0 , -1.0 ],
[ 1.0 , 1.0 / 3.0 ],
[-1.0 / 3.0 , 1.0 ],
[-1.0 , -1.0 / 3.0 ],
[-1.0 / 3.0 , -1.0 / 3.0 ],
[ 1.0 / 3.0 , -1.0 / 3.0 ],
[ 1.0 / 3.0 , 1.0 / 3.0 ],
[-1.0 / 3.0 , 1.0 / 3.0 ],
];
pub const INTERIOR_NODES: [usize; Qua16::N_INTERIOR_NODE] = [12, 13, 14, 15];
#[rustfmt::skip]
pub const TRIANGULATE_TRIANGLES: [[usize; 3]; Qua16::TRIANGULATE_NTRIANGLE] = [
[ 0, 4, 11], [ 4, 12, 11], [ 4, 8, 12], [ 8, 13, 12], [ 8, 1, 13], [ 1, 5, 13], [11, 12, 7], [12, 15, 7], [12, 13, 15], [13, 14, 15], [13, 5, 14], [ 5, 9, 14], [ 7, 15, 3], [15, 10, 3], [15, 14, 10], [14, 6, 10], [14, 9, 6], [ 9, 2, 6], ];
pub fn calc_interp(interp: &mut Vector, ksi: &[f64]) {
let (r, s) = (ksi[0], ksi[1]);
let nn_r0 = (-9.0 * r * r * r + 9.0 * r * r + r - 1.0) / 16.0;
let nn_r1 = (9.0 * r * r * r + 9.0 * r * r - r - 1.0) / 16.0;
let nn_r2 = (27.0 * r * r * r - 9.0 * r * r - 27.0 * r + 9.0) / 16.0;
let nn_r3 = (-27.0 * r * r * r - 9.0 * r * r + 27.0 * r + 9.0) / 16.0;
let nn_s0 = (-9.0 * s * s * s + 9.0 * s * s + s - 1.0) / 16.0;
let nn_s1 = (9.0 * s * s * s + 9.0 * s * s - s - 1.0) / 16.0;
let nn_s2 = (27.0 * s * s * s - 9.0 * s * s - 27.0 * s + 9.0) / 16.0;
let nn_s3 = (-27.0 * s * s * s - 9.0 * s * s + 27.0 * s + 9.0) / 16.0;
interp[0] = nn_r0 * nn_s0;
interp[1] = nn_r1 * nn_s0;
interp[2] = nn_r1 * nn_s1;
interp[3] = nn_r0 * nn_s1;
interp[4] = nn_r2 * nn_s0;
interp[5] = nn_r1 * nn_s2;
interp[6] = nn_r3 * nn_s1;
interp[7] = nn_r0 * nn_s3;
interp[8] = nn_r3 * nn_s0;
interp[9] = nn_r1 * nn_s3;
interp[10] = nn_r2 * nn_s1;
interp[11] = nn_r0 * nn_s2;
interp[12] = nn_r2 * nn_s2;
interp[13] = nn_r3 * nn_s2;
interp[14] = nn_r3 * nn_s3;
interp[15] = nn_r2 * nn_s3;
}
pub fn calc_deriv(deriv: &mut Matrix, ksi: &[f64]) {
let (r, s) = (ksi[0], ksi[1]);
let nn_r0 = (-9.0 * r * r * r + 9.0 * r * r + r - 1.0) / 16.0;
let nn_r1 = (9.0 * r * r * r + 9.0 * r * r - r - 1.0) / 16.0;
let nn_r2 = (27.0 * r * r * r - 9.0 * r * r - 27.0 * r + 9.0) / 16.0;
let nn_r3 = (-27.0 * r * r * r - 9.0 * r * r + 27.0 * r + 9.0) / 16.0;
let nn_s0 = (-9.0 * s * s * s + 9.0 * s * s + s - 1.0) / 16.0;
let nn_s1 = (9.0 * s * s * s + 9.0 * s * s - s - 1.0) / 16.0;
let nn_s2 = (27.0 * s * s * s - 9.0 * s * s - 27.0 * s + 9.0) / 16.0;
let nn_s3 = (-27.0 * s * s * s - 9.0 * s * s + 27.0 * s + 9.0) / 16.0;
let dnn_dr0 = (-27.0 * r * r + 18.0 * r + 1.0) / 16.0;
let dnn_dr1 = (27.0 * r * r + 18.0 * r - 1.0) / 16.0;
let dnn_dr2 = (81.0 * r * r - 18.0 * r - 27.0) / 16.0;
let dnn_dr3 = (-81.0 * r * r - 18.0 * r + 27.0) / 16.0;
let dnn_ds0 = (-27.0 * s * s + 18.0 * s + 1.0) / 16.0;
let dnn_ds1 = (27.0 * s * s + 18.0 * s - 1.0) / 16.0;
let dnn_ds2 = (81.0 * s * s - 18.0 * s - 27.0) / 16.0;
let dnn_ds3 = (-81.0 * s * s - 18.0 * s + 27.0) / 16.0;
deriv.set(0, 0, dnn_dr0 * nn_s0);
deriv.set(1, 0, dnn_dr1 * nn_s0);
deriv.set(2, 0, dnn_dr1 * nn_s1);
deriv.set(3, 0, dnn_dr0 * nn_s1);
deriv.set(4, 0, dnn_dr2 * nn_s0);
deriv.set(5, 0, dnn_dr1 * nn_s2);
deriv.set(6, 0, dnn_dr3 * nn_s1);
deriv.set(7, 0, dnn_dr0 * nn_s3);
deriv.set(8, 0, dnn_dr3 * nn_s0);
deriv.set(9, 0, dnn_dr1 * nn_s3);
deriv.set(10, 0, dnn_dr2 * nn_s1);
deriv.set(11, 0, dnn_dr0 * nn_s2);
deriv.set(12, 0, dnn_dr2 * nn_s2);
deriv.set(13, 0, dnn_dr3 * nn_s2);
deriv.set(14, 0, dnn_dr3 * nn_s3);
deriv.set(15, 0, dnn_dr2 * nn_s3);
deriv.set(0, 1, nn_r0 * dnn_ds0);
deriv.set(1, 1, nn_r1 * dnn_ds0);
deriv.set(2, 1, nn_r1 * dnn_ds1);
deriv.set(3, 1, nn_r0 * dnn_ds1);
deriv.set(4, 1, nn_r2 * dnn_ds0);
deriv.set(5, 1, nn_r1 * dnn_ds2);
deriv.set(6, 1, nn_r3 * dnn_ds1);
deriv.set(7, 1, nn_r0 * dnn_ds3);
deriv.set(8, 1, nn_r3 * dnn_ds0);
deriv.set(9, 1, nn_r1 * dnn_ds3);
deriv.set(10, 1, nn_r2 * dnn_ds1);
deriv.set(11, 1, nn_r0 * dnn_ds2);
deriv.set(12, 1, nn_r2 * dnn_ds2);
deriv.set(13, 1, nn_r3 * dnn_ds2);
deriv.set(14, 1, nn_r3 * dnn_ds3);
deriv.set(15, 1, nn_r2 * dnn_ds3);
}
}