use russell_lab::{Matrix, Vector};
pub struct Qua17 {}
impl Qua17 {
pub const GEO_NDIM: usize = 2;
pub const NNODE: usize = 17;
pub const NEDGE: usize = 4;
pub const NFACE: usize = 0;
pub const EDGE_NNODE: usize = 5;
pub const FACE_NNODE: usize = 0;
pub const FACE_NEDGE: usize = 0;
pub const N_INTERIOR_NODE: usize = 1;
pub const TRIANGULATE_NTRIANGLE: usize = 32;
pub const TRIANGULATE_EXTRA_NNODE: usize = 8;
#[rustfmt::skip]
pub const EDGE_NODE_IDS: [[usize; Qua17::EDGE_NNODE]; Qua17::NEDGE] = [
[1, 0, 4, 10, 9],
[2, 1, 5, 12, 11],
[3, 2, 6, 14, 13],
[0, 3, 7, 16, 15]
];
#[rustfmt::skip]
pub const EDGE_NODE_IDS_INWARD: [[usize; Qua17::EDGE_NNODE]; Qua17::NEDGE] = [
[0, 1, 4, 9 , 10],
[1, 2, 5, 11, 12],
[2, 3, 6, 13, 14],
[3, 0, 7, 15, 16]
];
#[rustfmt::skip]
pub const NODE_REFERENCE_COORDS: [[f64; Qua17::GEO_NDIM]; Qua17::NNODE] = [
[-1.0, -1.0], [ 1.0, -1.0], [ 1.0, 1.0], [-1.0, 1.0], [ 0.0, -1.0], [ 1.0, 0.0], [ 0.0, 1.0], [-1.0, 0.0], [ 0.0, 0.0], [-0.5, -1.0], [ 0.5, -1.0], [ 1.0, -0.5], [ 1.0, 0.5], [ 0.5, 1.0], [-0.5, 1.0], [-1.0, 0.5], [-1.0, -0.5], ];
pub const INTERIOR_NODES: [usize; Qua17::N_INTERIOR_NODE] = [ 8];
#[rustfmt::skip]
pub const TRIANGULATE_TRIANGLES: [[usize; 3]; Qua17::TRIANGULATE_NTRIANGLE] = [
[ 0, 9, 16], [ 9, 17, 16], [ 9, 4, 17], [ 4, 21, 17], [ 4, 10, 21], [10, 18, 21], [10, 1, 18], [ 1, 11, 18], [16, 17, 7], [17, 24, 7], [17, 21, 24], [21, 8, 24], [21, 18, 8], [18, 22, 8], [18, 11, 22], [11, 5, 22], [ 7, 24, 15], [24, 20, 15], [24, 8, 20], [ 8, 23, 20], [ 8, 22, 23], [22, 19, 23], [22, 5, 19], [ 5, 12, 19], [15, 20, 3], [20, 14, 3], [20, 23, 14], [23, 6, 14], [23, 19, 6], [19, 13, 6], [19, 12, 13], [12, 2, 13], ];
#[rustfmt::skip]
pub const TRIANGULATE_EXTRA_COORDS: [[f64; Qua17::GEO_NDIM]; Qua17::TRIANGULATE_EXTRA_NNODE] = [
[-0.5, -0.5], [ 0.5, -0.5], [ 0.5, 0.5], [-0.5, 0.5], [ 0.0, -0.5], [ 0.5, 0.0], [ 0.0, 0.5], [-0.5, 0.0], ];
pub fn calc_interp(interp: &mut Vector, ksi: &[f64]) {
let (r, s) = (ksi[0], ksi[1]);
let a = 2.0 / 3.0;
let rr = r * r;
let ss = s * s;
let rs = r * s;
let rp = 1.0 + r;
let rm = 1.0 - r;
let sp = 1.0 + s;
let sm = 1.0 - s;
interp[0] = rm * sm * (-4.0 * r * (rr - 1.0) - 4.0 * s * (ss - 1.0) + 3.0 * rs) / 12.0;
interp[1] = rp * sm * (4.0 * r * (rr - 1.0) - 4.0 * s * (ss - 1.0) - 3.0 * rs) / 12.0;
interp[2] = rp * sp * (4.0 * r * (rr - 1.0) + 4.0 * s * (ss - 1.0) + 3.0 * rs) / 12.0;
interp[3] = rm * sp * (-4.0 * r * (rr - 1.0) + 4.0 * s * (ss - 1.0) - 3.0 * rs) / 12.0;
interp[4] = 0.5 * rm * rp * (-s - 4.0 * rr) * sm;
interp[5] = 0.5 * sm * sp * (r - 4.0 * ss) * rp;
interp[6] = 0.5 * rm * rp * (s - 4.0 * rr) * sp;
interp[7] = 0.5 * sm * sp * (-r - 4.0 * ss) * rm;
interp[8] = rm * rp * sm * sp;
interp[9] = -a * r * sm * rm * rp * (1.0 - 2.0 * r);
interp[10] = a * r * sm * rm * rp * (1.0 + 2.0 * r);
interp[11] = -a * s * rp * sm * sp * (1.0 - 2.0 * s);
interp[12] = a * s * rp * sm * sp * (1.0 + 2.0 * s);
interp[13] = a * r * sp * rm * rp * (1.0 + 2.0 * r);
interp[14] = -a * r * sp * rm * rp * (1.0 - 2.0 * r);
interp[15] = a * s * sm * sp * (1.0 + 2.0 * s) * rm;
interp[16] = -a * s * rm * sm * sp * (1.0 - 2.0 * s);
}
pub fn calc_deriv(deriv: &mut Matrix, ksi: &[f64]) {
let (r, s) = (ksi[0], ksi[1]);
let a = 2.0 / 3.0;
let rr = r * r;
let ss = s * s;
let rs = r * s;
let rp = 1.0 + r;
let rm = 1.0 - r;
let sp = 1.0 + s;
let sm = 1.0 - s;
let b = 1.0 / 12.0;
let r1 = r - 1.0;
let rrr = rr * r;
let sss = ss * s;
deriv.set(
0,
0,
b * sm * (16.0 * rrr - 12.0 * rr - 6.0 * rs - 8.0 * r + 4.0 * sss - s + 4.0),
);
deriv.set(
1,
0,
b * sm * (16.0 * rrr + 12.0 * rr - 6.0 * rs - 8.0 * r - 4.0 * sss + s - 4.0),
);
deriv.set(
2,
0,
b * sp * (16.0 * rrr + 12.0 * rr + 6.0 * rs - 8.0 * r + 4.0 * sss - s - 4.0),
);
deriv.set(
3,
0,
b * sp * (16.0 * rrr - 12.0 * rr + 6.0 * rs - 8.0 * r - 4.0 * sss + s + 4.0),
);
deriv.set(9, 0, -a * (1.0 - 4.0 * r - 3.0 * rr + 8.0 * rrr) * sm);
deriv.set(11, 0, a * s * sm * sp * (-1.0 + 2.0 * s));
deriv.set(13, 0, -a * (-1.0 - 4.0 * r + 3.0 * rr + 8.0 * rrr) * sp);
deriv.set(15, 0, -a * s * sm * sp * (1.0 + 2.0 * s));
deriv.set(4, 0, r * sm * (8.0 * rr + s - 4.0));
deriv.set(5, 0, 0.5 * sm * sp * (2.0 * r - 4.0 * ss + 1.0));
deriv.set(6, 0, r * sp * (8.0 * rr - s - 4.0));
deriv.set(7, 0, 0.5 * sm * sp * (2.0 * r - 1.0 + 4.0 * ss));
deriv.set(10, 0, a * (1.0 + 4.0 * r - 3.0 * rr - 8.0 * rrr) * sm);
deriv.set(12, 0, a * s * sm * sp * (1.0 + 2.0 * s));
deriv.set(14, 0, -a * (1.0 - 4.0 * r - 3.0 * rr + 8.0 * rrr) * sp);
deriv.set(16, 0, a * s * sm * sp * (1.0 - 2.0 * s));
deriv.set(8, 0, -2.0 * r * sm * sp);
deriv.set(
0,
1,
b * rm * (16.0 * sss - 12.0 * ss - 6.0 * rs - 8.0 * s + 4.0 * rrr - r + 4.0),
);
deriv.set(
1,
1,
-b * rp * (-16.0 * sss + 12.0 * ss - 6.0 * rs + 8.0 * s + 4.0 * rrr - r - 4.0),
);
deriv.set(
2,
1,
b * rp * (16.0 * sss + 12.0 * ss + 6.0 * rs - 8.0 * s + 4.0 * rrr - r - 4.0),
);
deriv.set(
3,
1,
b * r1 * (-16.0 * sss - 12.0 * ss + 6.0 * rs + 8.0 * s + 4.0 * rrr - r + 4.0),
);
deriv.set(9, 1, a * r * r1 * rp * (2.0 * r - 1.0));
deriv.set(11, 1, -a * (1.0 - 4.0 * s - 3.0 * ss + 8.0 * sss) * rp);
deriv.set(13, 1, -a * r * r1 * rp * (1.0 + 2.0 * r));
deriv.set(15, 1, a * (-1.0 - 4.0 * s + 3.0 * ss + 8.0 * sss) * r1);
deriv.set(4, 1, -0.5 * r1 * rp * (2.0 * s - 1.0 + 4.0 * rr));
deriv.set(5, 1, -s * rp * (-8.0 * ss + r + 4.0));
deriv.set(6, 1, 0.5 * r1 * rp * (-2.0 * s + 4.0 * rr - 1.0));
deriv.set(7, 1, -s * r1 * (8.0 * ss + r - 4.0));
deriv.set(10, 1, a * r * r1 * rp * (1.0 + 2.0 * r));
deriv.set(12, 1, -a * (-1.0 - 4.0 * s + 3.0 * ss + 8.0 * sss) * rp);
deriv.set(14, 1, -a * r * r1 * rp * (2.0 * r - 1.0));
deriv.set(16, 1, a * (1.0 - 4.0 * s - 3.0 * ss + 8.0 * sss) * r1);
deriv.set(8, 1, 2.0 * s * r1 * rp);
}
}