use diffsol::error::DiffsolError;
use diffsol::{FaerScalar, NalgebraScalar};
use crate::{
error::DiffsolRtError, linear_solver_type::LinearSolverType, matrix_type::MatrixKind,
matrix_type::MatrixType,
};
pub(crate) fn validate_linear_solver<
M: diffsol::Matrix + LuValidator<M> + KluValidator<M> + MatrixKind,
>(
linear_solver: LinearSolverType,
) -> Result<(), DiffsolRtError> {
match linear_solver {
LinearSolverType::Default => Ok(()),
LinearSolverType::Lu => {
if !<M as LuValidator<M>>::valid() {
return Err(DiffsolError::Other(format!(
"Lu solver not supported for {}",
MatrixType::from_diffsol::<M>().get_name()
))
.into());
}
Ok(())
}
LinearSolverType::Klu => {
if !<M as KluValidator<M>>::valid() {
return Err(DiffsolError::Other(format!(
"Klu solver not supported for {}",
MatrixType::from_diffsol::<M>().get_name()
))
.into());
}
Ok(())
}
}
}
pub(crate) trait KluValidator<M: diffsol::Matrix> {
type LS: diffsol::LinearSolver<M>;
fn valid() -> bool {
false
}
}
#[cfg(feature = "suitesparse")]
impl KluValidator<diffsol::FaerSparseMat<f64>> for diffsol::FaerSparseMat<f64> {
type LS = diffsol::KLU<diffsol::FaerSparseMat<f64>>;
fn valid() -> bool {
true
}
}
#[cfg(feature = "suitesparse")]
impl KluValidator<diffsol::FaerSparseMat<f32>> for diffsol::FaerSparseMat<f32> {
type LS = diffsol::FaerSparseLU<f32>;
fn valid() -> bool {
false
}
}
#[cfg(not(feature = "suitesparse"))]
impl<T: FaerScalar> KluValidator<diffsol::FaerSparseMat<T>> for diffsol::FaerSparseMat<T> {
type LS = diffsol::FaerSparseLU<T>;
fn valid() -> bool {
false
}
}
impl<T: NalgebraScalar> KluValidator<diffsol::NalgebraMat<T>> for diffsol::NalgebraMat<T> {
type LS = diffsol::NalgebraLU<T>;
fn valid() -> bool {
false
}
}
impl<T: FaerScalar> KluValidator<diffsol::FaerMat<T>> for diffsol::FaerMat<T> {
type LS = diffsol::FaerLU<T>;
fn valid() -> bool {
false
}
}
pub(crate) trait LuValidator<M: diffsol::Matrix> {
type LS: diffsol::LinearSolver<M>;
fn valid() -> bool {
false
}
}
impl<T: NalgebraScalar> LuValidator<diffsol::NalgebraMat<T>> for diffsol::NalgebraMat<T> {
type LS = diffsol::NalgebraLU<T>;
fn valid() -> bool {
true
}
}
impl<T: FaerScalar> LuValidator<diffsol::FaerMat<T>> for diffsol::FaerMat<T> {
type LS = diffsol::FaerLU<T>;
fn valid() -> bool {
true
}
}
impl<T: FaerScalar> LuValidator<diffsol::FaerSparseMat<T>> for diffsol::FaerSparseMat<T> {
type LS = diffsol::FaerSparseLU<T>;
fn valid() -> bool {
true
}
}