use crate::{SQRT_2, StrError, Tensor2, Tensor4};
pub fn internal_stability_tensor(hh: &mut Tensor4<6>, sigma: &Tensor2<6>) -> Result<(), StrError> {
let sig = sigma.as_data();
hh.set(0, 0, sig[0]);
hh.set(0, 1, (-sig[0] - sig[1]) / 2.0);
hh.set(0, 2, (-sig[0] - sig[2]) / 2.0);
hh.set(0, 3, sig[3] / 2.0);
hh.set(0, 4, -sig[4] / 2.0);
hh.set(0, 5, sig[5] / 2.0);
hh.set(1, 0, (-sig[0] - sig[1]) / 2.0);
hh.set(1, 1, sig[1]);
hh.set(1, 2, (-sig[1] - sig[2]) / 2.0);
hh.set(1, 3, sig[3] / 2.0);
hh.set(1, 4, sig[4] / 2.0);
hh.set(1, 5, -sig[5] / 2.0);
hh.set(2, 0, (-sig[0] - sig[2]) / 2.0);
hh.set(2, 1, (-sig[1] - sig[2]) / 2.0);
hh.set(2, 2, sig[2]);
hh.set(2, 3, -sig[3] / 2.0);
hh.set(2, 4, sig[4] / 2.0);
hh.set(2, 5, sig[5] / 2.0);
hh.set(3, 0, sig[3] / 2.0);
hh.set(3, 1, sig[3] / 2.0);
hh.set(3, 2, -sig[3] / 2.0);
hh.set(3, 3, sig[0] + sig[1]);
hh.set(3, 4, sig[5] / SQRT_2);
hh.set(3, 5, sig[4] / SQRT_2);
hh.set(4, 0, -sig[4] / 2.0);
hh.set(4, 1, sig[4] / 2.0);
hh.set(4, 2, sig[4] / 2.0);
hh.set(4, 3, sig[5] / SQRT_2);
hh.set(4, 4, sig[1] + sig[2]);
hh.set(4, 5, sig[3] / SQRT_2);
hh.set(5, 0, sig[5] / 2.0);
hh.set(5, 1, -sig[5] / 2.0);
hh.set(5, 2, sig[5] / 2.0);
hh.set(5, 3, sig[4] / SQRT_2);
hh.set(5, 4, sig[3] / SQRT_2);
hh.set(5, 5, sig[0] + sig[2]);
Ok(())
}
#[cfg(test)]
mod tests {
use super::internal_stability_tensor;
use crate::{Tensor2, Tensor4};
use russell_lab::approx_eq;
#[test]
fn internal_stability_tensor_works() {
let sigma = Tensor2::<6>::from_std_matrix(&[
[27.06, 0.0, 0.0], [0.0, 27.06, 0.0], [0.0, 0.0, 20.585], ])
.unwrap();
let mut hh = Tensor4::<6>::new();
internal_stability_tensor(&mut hh, &sigma).unwrap();
#[rustfmt::skip]
let correct = [
[27.06, -27.06, -23.8225, 0.0, 0.0, 0.0],
[-27.06, 27.06, -23.8225, 0.0, 0.0, 0.0],
[-23.8225, -23.8225, 20.585, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 54.12, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 47.645, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 47.645],
];
for m in 0..6 {
for n in 0..6 {
approx_eq(hh.get(m, n), correct[m][n], 1e-12);
}
}
}
}