use pounce_common::timing::TimingStatistics;
use pounce_common::types::{Index, Number};
use pounce_linalg::{Matrix, SymMatrix, Vector};
use pounce_linsol::ESymSolverStatus;
use std::rc::Rc;
pub struct AugSysCoeffs<'a> {
pub w: Option<&'a dyn SymMatrix>,
pub w_factor: Number,
pub d_x: Option<&'a dyn Vector>,
pub delta_x: Number,
pub d_s: Option<&'a dyn Vector>,
pub delta_s: Number,
pub j_c: &'a dyn Matrix,
pub d_c: Option<&'a dyn Vector>,
pub delta_c: Number,
pub j_d: &'a dyn Matrix,
pub d_d: Option<&'a dyn Vector>,
pub delta_d: Number,
}
pub struct AugSysRhs<'a> {
pub rhs_x: &'a dyn Vector,
pub rhs_s: &'a dyn Vector,
pub rhs_c: &'a dyn Vector,
pub rhs_d: &'a dyn Vector,
}
pub struct AugSysSol<'a> {
pub sol_x: &'a mut dyn Vector,
pub sol_s: &'a mut dyn Vector,
pub sol_c: &'a mut dyn Vector,
pub sol_d: &'a mut dyn Vector,
}
pub trait AugSystemSolver {
fn provides_inertia(&self) -> bool;
fn number_of_neg_evals(&self) -> Index;
fn increase_quality(&mut self) -> bool;
fn last_solve_status(&self) -> ESymSolverStatus;
fn set_timing_stats(&mut self, _timing: Rc<TimingStatistics>) {}
fn set_diagnostics(&mut self, _diag: Rc<pounce_common::diagnostics::DiagnosticsState>) {}
fn solve(
&mut self,
coeffs: &AugSysCoeffs<'_>,
rhs: &AugSysRhs<'_>,
sol: &mut AugSysSol<'_>,
check_neg_evals: bool,
num_neg_evals: Index,
) -> ESymSolverStatus;
fn resolve(
&mut self,
coeffs: &AugSysCoeffs<'_>,
rhs: &AugSysRhs<'_>,
sol: &mut AugSysSol<'_>,
) -> ESymSolverStatus {
self.solve(coeffs, rhs, sol, false, 0)
}
fn multi_solve(
&mut self,
coeffs: &AugSysCoeffs<'_>,
rhs_list: &[&AugSysRhs<'_>],
sol_list: &mut [&mut AugSysSol<'_>],
check_neg_evals: bool,
num_neg_evals: Index,
) -> ESymSolverStatus {
debug_assert_eq!(rhs_list.len(), sol_list.len());
for (rhs, sol) in rhs_list.iter().zip(sol_list.iter_mut()) {
let status = self.solve(coeffs, rhs, *sol, check_neg_evals, num_neg_evals);
if status != ESymSolverStatus::Success {
return status;
}
}
ESymSolverStatus::Success
}
}