use mathhook_core::calculus::pde::method_of_characteristics::solve_characteristic_odes;
use mathhook_core::core::Expression;
#[test]
fn test_pde_to_ode_bridge_transport_equation() {
let char_eqs = vec![
Expression::integer(1), Expression::integer(1), Expression::integer(0), ];
let initial_conditions = vec![0.0, 0.0, 1.0]; let s_end = 2.0;
let step_size = 0.1;
let result = solve_characteristic_odes(&char_eqs, &initial_conditions, s_end, step_size);
assert!(result.is_ok(), "ODE solver should succeed");
let solution = result.unwrap();
assert!(!solution.is_empty(), "Solution should not be empty");
assert_eq!(
solution[0].1.len(),
3,
"Each solution point should have 3 components"
);
let (s0, state0) = &solution[0];
assert_eq!(*s0, 0.0, "First point should be at s=0");
assert!((state0[0] - 0.0).abs() < 1e-10, "x(0) should be 0");
assert!((state0[1] - 0.0).abs() < 1e-10, "y(0) should be 0");
assert!((state0[2] - 1.0).abs() < 1e-10, "u(0) should be 1");
let (s_final, state_final) = solution.last().unwrap();
assert!(
(*s_final - s_end).abs() < 0.15,
"Final s should be near s_end"
);
assert!(
(state_final[0] - *s_final).abs() < 0.5,
"x(s) ≈ s for dx/ds = 1"
);
assert!(
(state_final[2] - 1.0).abs() < 1e-6,
"u(s) should remain constant"
);
}
#[test]
fn test_pde_to_ode_bridge_with_different_coefficients() {
let char_eqs = vec![
Expression::integer(2), Expression::integer(3), Expression::integer(0), ];
let initial_conditions = vec![1.0, 2.0, 5.0]; let s_end = 1.0;
let step_size = 0.1;
let result = solve_characteristic_odes(&char_eqs, &initial_conditions, s_end, step_size);
assert!(result.is_ok(), "ODE solver should succeed");
let solution = result.unwrap();
assert!(!solution.is_empty(), "Solution should not be empty");
for (s, state) in &solution {
assert!(state.len() == 3, "Each state should have 3 components");
assert!(
*s >= 0.0 && *s <= s_end + step_size,
"s should be in valid range"
);
}
}
#[test]
fn test_bridge_error_handling_wrong_equation_count() {
let char_eqs = vec![
Expression::integer(1),
Expression::integer(1),
];
let initial_conditions = vec![0.0, 0.0, 1.0];
let result = solve_characteristic_odes(&char_eqs, &initial_conditions, 1.0, 0.1);
assert!(result.is_err(), "Should error with wrong equation count");
}
#[test]
fn test_bridge_error_handling_wrong_ic_count() {
let char_eqs = vec![
Expression::integer(1),
Expression::integer(1),
Expression::integer(0),
];
let initial_conditions = vec![0.0, 0.0];
let result = solve_characteristic_odes(&char_eqs, &initial_conditions, 1.0, 0.1);
assert!(result.is_err(), "Should error with wrong IC count");
}