pardiso_wrapper/panua/
interface.rs

1use super::loader::*;
2use crate::enums::{MatrixType, SolverType};
3use crate::{PanuaPardisoError, PardisoData, PardisoError, PardisoInterface};
4use std::ffi::c_void;
5
6pub struct PanuaPardisoSolver {
7    _data: PardisoData,
8    _dparm: [f64; 64],
9}
10
11impl PanuaPardisoSolver {
12    pub(crate) fn pardisoinit_impl(
13        data: &mut PardisoData,
14        dparm: &mut [f64; 64],
15        mtype: MatrixType,
16        solver: SolverType,
17    ) -> Result<(), PanuaPardisoError> {
18        let ptrs = panua_ptrs()?;
19
20        let mut error: i32 = 0;
21        let pt = data.pt.as_mut_ptr() as *mut c_void;
22        let mtype = mtype as i32;
23        let solver = solver as i32;
24        let iparm = data.iparm.as_mut_ptr();
25        let dparm = dparm.as_mut_ptr();
26
27        (ptrs.pardisoinit)(pt, &mtype, &solver, iparm, dparm, &mut error);
28
29        if error != 0 {
30            return Err(PanuaPardisoError::from(error));
31        }
32        Ok(())
33    }
34}
35
36impl PanuaPardisoSolver {
37    pub fn get_dparm(&self, i: usize) -> f64 {
38        self._dparm[i]
39    }
40    pub fn get_dparms(&self) -> &[f64; 64] {
41        &self._dparm
42    }
43    pub fn set_dparm(&mut self, i: usize, value: f64) {
44        self._dparm[i] = value;
45    }
46}
47
48impl PardisoInterface for PanuaPardisoSolver {
49    fn data(&self) -> &PardisoData {
50        &self._data
51    }
52    fn data_mut(&mut self) -> &mut PardisoData {
53        &mut self._data
54    }
55
56    fn new() -> Result<Self, PardisoError> {
57        if !PanuaPardisoSolver::is_loaded() {
58            return Err(PanuaPardisoError::LibraryLoadFailure)?;
59        }
60        if !PanuaPardisoSolver::is_licensed() {
61            return Err(PanuaPardisoError::LibraryLicenseFailure)?;
62        }
63
64        let data = PardisoData::default();
65        let dparm = [0.0; 64];
66        Ok(Self {
67            _data: data,
68            _dparm: dparm,
69        })
70    }
71
72    fn pardisoinit(&mut self) -> Result<(), PardisoError> {
73        let mtype = self.get_matrix_type();
74        let solver = self.get_solver();
75        let data = &mut self._data;
76        let dparm = &mut self._dparm;
77
78        Ok(PanuaPardisoSolver::pardisoinit_impl(
79            data, dparm, mtype, solver,
80        )?)
81    }
82
83    fn pardiso(
84        &mut self,
85        a: &[f64],
86        ia: &[i32],
87        ja: &[i32],
88        b: &mut [f64],
89        x: &mut [f64],
90        n: i32,
91        nrhs: i32,
92    ) -> Result<(), PardisoError> {
93        let ptrs = panua_ptrs()?;
94
95        let mut error = 0;
96        let pt = self.data_mut().pt.as_mut_ptr() as *mut c_void;
97        let maxfct = self.data().maxfct;
98        let mnum = self.data().mnum;
99        let mtype = self.get_matrix_type() as i32;
100        let phase = self.data().phase as i32;
101        let a = a.as_ptr();
102        let ia = ia.as_ptr();
103        let ja = ja.as_ptr();
104        let b = b.as_mut_ptr();
105        let x = x.as_mut_ptr();
106        let perm = self.data_mut().perm.as_mut_ptr();
107        let iparm = self.data_mut().iparm.as_mut_ptr();
108        let msglvl = self.data().msglvl as i32;
109        let dparm = self._dparm.as_mut_ptr();
110
111        (ptrs.pardiso)(
112            pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x,
113            &mut error, dparm,
114        );
115
116        if error != 0 {
117            let error = PanuaPardisoError::from(error);
118            return Err(PardisoError::from(error));
119        }
120        Ok(())
121    }
122
123    fn name(&self) -> &'static str {
124        "panua"
125    }
126
127    fn is_licensed() -> bool {
128        crate::panua::interface::panua_is_licensed()
129    }
130
131    fn is_loaded() -> bool {
132        panua_ptrs().is_ok()
133    }
134
135    fn get_num_threads(&self) -> Result<i32, PardisoError> {
136        Ok(self.data().iparm[2])
137    }
138}
139
140// additional Panua specific functions
141impl PanuaPardisoSolver {
142    pub fn pardiso_chkmatrix(
143        &self,
144        mtype: MatrixType,
145        n: i32,
146        a: &[f64],
147        ia: &[i32],
148        ja: &[i32],
149    ) -> Result<(), PanuaPardisoError> {
150        let ptrs = panua_ptrs()?;
151
152        let mut error = 0;
153        let mtype = mtype as i32;
154        let a = a.as_ptr();
155        let ia = ia.as_ptr();
156        let ja = ja.as_ptr();
157
158        (ptrs.pardiso_chkmatrix)(&mtype, &n, a, ia, ja, &mut error);
159
160        if error != 0 {
161            return Err(PanuaPardisoError::from(error));
162        }
163        Ok(())
164    }
165
166    pub fn pardiso_chkvec(&self, n: i32, nrhs: i32, b: &[f64]) -> Result<(), PanuaPardisoError> {
167        let ptrs = panua_ptrs()?;
168
169        let mut error = 0;
170        let b = b.as_ptr();
171
172        (ptrs.pardiso_chkvec)(&n, &nrhs, b, &mut error);
173
174        if error != 0 {
175            return Err(PanuaPardisoError::from(error));
176        }
177        Ok(())
178    }
179
180    #[allow(clippy::too_many_arguments)]
181    pub fn pardiso_printstats(
182        &self,
183        mtype: MatrixType,
184        n: i32,
185        a: &[f64],
186        ia: &[i32],
187        ja: &[i32],
188        nrhs: i32,
189        b: &[f64],
190    ) -> Result<(), PanuaPardisoError> {
191        let ptrs = panua_ptrs()?;
192
193        let mut error = 0;
194        let mtype = mtype as i32;
195        let a = a.as_ptr();
196        let ia = ia.as_ptr();
197        let ja = ja.as_ptr();
198        let b = b.as_ptr();
199
200        (ptrs.pardiso_printstats)(&mtype, &n, a, ia, ja, &nrhs, b, &mut error);
201
202        if error != 0 {
203            return Err(PanuaPardisoError::from(error));
204        }
205        Ok(())
206    }
207}
208
209impl Drop for PanuaPardisoSolver {
210    fn drop(&mut self) {
211        self.release();
212    }
213}