Skip to main content

diffsol_c/
valid_linear_solver.rs

1// Validation used by py_solve to determine that solver type and matrix type
2// combinations are valid.
3
4use diffsol::error::DiffsolError;
5use diffsol::{FaerScalar, NalgebraScalar};
6
7use crate::{
8    error::DiffsolRtError, linear_solver_type::LinearSolverType, matrix_type::MatrixKind,
9    matrix_type::MatrixType,
10};
11
12pub(crate) fn validate_linear_solver<
13    M: diffsol::Matrix + LuValidator<M> + KluValidator<M> + MatrixKind,
14>(
15    linear_solver: LinearSolverType,
16) -> Result<(), DiffsolRtError> {
17    match linear_solver {
18        LinearSolverType::Default => Ok(()),
19        LinearSolverType::Lu => {
20            if !<M as LuValidator<M>>::valid() {
21                return Err(DiffsolError::Other(format!(
22                    "Lu solver not supported for {}",
23                    MatrixType::from_diffsol::<M>().get_name()
24                ))
25                .into());
26            }
27            Ok(())
28        }
29        LinearSolverType::Klu => {
30            if !<M as KluValidator<M>>::valid() {
31                return Err(DiffsolError::Other(format!(
32                    "Klu solver not supported for {}",
33                    MatrixType::from_diffsol::<M>().get_name()
34                ))
35                .into());
36            }
37            Ok(())
38        }
39    }
40}
41
42pub(crate) trait KluValidator<M: diffsol::Matrix> {
43    type LS: diffsol::LinearSolver<M>;
44    fn valid() -> bool {
45        false
46    }
47}
48
49// Known issue: FaerSparseMat currently only supports KLU for f64
50#[cfg(feature = "suitesparse")]
51impl KluValidator<diffsol::FaerSparseMat<f64>> for diffsol::FaerSparseMat<f64> {
52    type LS = diffsol::KLU<diffsol::FaerSparseMat<f64>>;
53    fn valid() -> bool {
54        true
55    }
56}
57
58#[cfg(feature = "suitesparse")]
59impl KluValidator<diffsol::FaerSparseMat<f32>> for diffsol::FaerSparseMat<f32> {
60    type LS = diffsol::FaerSparseLU<f32>;
61    fn valid() -> bool {
62        false
63    }
64}
65
66#[cfg(not(feature = "suitesparse"))]
67impl<T: FaerScalar> KluValidator<diffsol::FaerSparseMat<T>> for diffsol::FaerSparseMat<T> {
68    type LS = diffsol::FaerSparseLU<T>;
69    fn valid() -> bool {
70        false
71    }
72}
73
74impl<T: NalgebraScalar> KluValidator<diffsol::NalgebraMat<T>> for diffsol::NalgebraMat<T> {
75    type LS = diffsol::NalgebraLU<T>;
76    fn valid() -> bool {
77        false
78    }
79}
80
81impl<T: FaerScalar> KluValidator<diffsol::FaerMat<T>> for diffsol::FaerMat<T> {
82    type LS = diffsol::FaerLU<T>;
83    fn valid() -> bool {
84        false
85    }
86}
87
88pub(crate) trait LuValidator<M: diffsol::Matrix> {
89    type LS: diffsol::LinearSolver<M>;
90    fn valid() -> bool {
91        false
92    }
93}
94
95impl<T: NalgebraScalar> LuValidator<diffsol::NalgebraMat<T>> for diffsol::NalgebraMat<T> {
96    type LS = diffsol::NalgebraLU<T>;
97    fn valid() -> bool {
98        true
99    }
100}
101
102impl<T: FaerScalar> LuValidator<diffsol::FaerMat<T>> for diffsol::FaerMat<T> {
103    type LS = diffsol::FaerLU<T>;
104    fn valid() -> bool {
105        true
106    }
107}
108
109impl<T: FaerScalar> LuValidator<diffsol::FaerSparseMat<T>> for diffsol::FaerSparseMat<T> {
110    type LS = diffsol::FaerSparseLU<T>;
111    fn valid() -> bool {
112        true
113    }
114}