#![cfg(sidereon_repo_tests)]
use sidereon_core::tides::{ocean_tide_loading, OceanLoadingBlq};
const ZIM2_ECEF_M: [f64; 3] = [
4_331_299.584_071_246,
567_537.707_032_023_1,
4_633_133.964_520_6,
];
const ZIM2_BLQ: OceanLoadingBlq = OceanLoadingBlq {
amplitude_m: [
[
0.00693, 0.00228, 0.00148, 0.00061, 0.00220, 0.00094, 0.00070, 0.00001, 0.00047,
0.00025, 0.00019,
],
[
0.00272, 0.00076, 0.00061, 0.00020, 0.00036, 0.00025, 0.00011, 0.00005, 0.00004,
0.00001, 0.00002,
],
[
0.00061, 0.00026, 0.00010, 0.00009, 0.00025, 0.00002, 0.00008, 0.00003, 0.00002,
0.00000, 0.00001,
],
],
phase_deg: [
[
-72.3, -44.2, -90.8, -44.1, -62.9, -94.5, -64.3, 171.0, 3.4, 3.6, 1.1,
],
[
84.3, 115.4, 63.3, 113.7, 98.6, 20.7, 94.2, -44.5, -170.0, -162.7, -177.8,
],
[
-29.3, 1.7, -44.0, -4.2, 44.2, -39.1, 43.7, 170.1, -93.3, -118.3, -176.4,
],
],
};
const RTKLIB_REFERENCE: [(f64, [f64; 3]); 4] = [
(0.5, [-0.004_737_883, -0.003_185_751, -0.004_739_565]),
(6.0, [0.004_896_691, 0.003_423_851, 0.005_868_452]),
(12.5, [-0.003_182_591, -0.002_774_004, -0.003_668_216]),
(18.0, [0.003_182_610, 0.003_079_126, 0.003_326_319]),
];
const OCEAN_LOADING_ORACLE_BOUND_M: f64 = 7.0e-4;
#[test]
fn ocean_loading_matches_rtklib_tidedisp() {
let mut max_dev = 0.0_f64;
for (fhr, reference) in RTKLIB_REFERENCE {
let got = ocean_tide_loading(&ZIM2_ECEF_M, 2026, 5, 13, fhr, &ZIM2_BLQ)
.expect("valid ZIM2 ocean loading input");
let dev = ((got[0] - reference[0]).powi(2)
+ (got[1] - reference[1]).powi(2)
+ (got[2] - reference[2]).powi(2))
.sqrt();
max_dev = max_dev.max(dev);
eprintln!("ZIM2 OTL fhr={fhr}: sidereon={got:?} rtklib={reference:?} dev={dev:.3e} m");
}
eprintln!("ZIM2 ocean loading: max sidereon-vs-RTKLIB deviation = {max_dev:.3e} m");
assert!(
max_dev < OCEAN_LOADING_ORACLE_BOUND_M,
"ocean loading vs RTKLIB max dev {max_dev:.3e} m exceeds bound {OCEAN_LOADING_ORACLE_BOUND_M:.1e} m"
);
}