sundials 0.3.2

Suite of nonlinear and differential/algebraic equation solvers
Documentation
use crate::check::check_is_success;
use crate::nvector::NVector;
use crate::sunmatrix::SparseMatrix;

use anyhow::Result;
use sundials_sys::{
    sunrealtype, SUNLinSolFree, SUNLinSolInitialize, SUNLinSolSetup, SUNLinSolSolve,
    SUNLinearSolver,
};

pub struct LinearSolver {
    pub(crate) sunlinsol: SUNLinearSolver,
}

impl LinearSolver {
    #[cfg(feature = "klu")]
    pub fn new_klu(y: &NVector, a_mat: &SparseMatrix, sunctx: &crate::context::Context) -> Self {
        Self {
            sunlinsol: unsafe {
                sundials_sys::SUNLinSol_KLU(y.n_vector, a_mat.sunmatrix, sunctx.sunctx)
            },
        }
    }

    pub fn initialize(&self) -> Result<()> {
        let rv = unsafe { SUNLinSolInitialize(self.sunlinsol) };
        check_is_success(rv, "SUNLinSolInitialize")
    }

    pub fn setup(&self, a_mat: &SparseMatrix) -> Result<()> {
        let rv = unsafe { SUNLinSolSetup(self.sunlinsol, a_mat.sunmatrix) };
        check_is_success(rv, "SUNLinSolSetup")
    }

    pub fn solve(
        &self,
        a_mat: &SparseMatrix,
        x: &mut NVector,
        b: &NVector,
        tol: sunrealtype,
    ) -> Result<()> {
        let rv =
            unsafe { SUNLinSolSolve(self.sunlinsol, a_mat.sunmatrix, x.n_vector, b.n_vector, tol) };
        check_is_success(rv, "SUNLinSolSolve")
    }
}

impl Drop for LinearSolver {
    fn drop(&mut self) {
        unsafe { SUNLinSolFree(self.sunlinsol) };
    }
}