1use crate::algebra::prelude::*;
2use crate::context::ksp_context::Workspace;
3use crate::error::KError;
4use crate::matrix::op::LinOp;
5use crate::ops::klinop::KLinOp;
6use crate::ops::kpc::KPreconditioner;
7use crate::parallel::UniverseComm;
8use crate::preconditioner::{PcSide, Preconditioner};
9use crate::solver::{CgnrSolver, LinearSolver, MonitorCallback};
10use crate::utils::convergence::SolveStats;
11use std::any::Any;
12
13pub struct CrSolver {
15 inner: CgnrSolver,
16}
17
18impl CrSolver {
19 pub fn new(rtol: f64, maxits: usize) -> Self {
20 Self {
21 inner: CgnrSolver::new(rtol, maxits),
22 }
23 }
24
25 #[allow(clippy::too_many_arguments)]
26 pub fn solve_k<A>(
27 &mut self,
28 a: &A,
29 pc: Option<&dyn KPreconditioner<Scalar = S>>,
30 b: &[S],
31 x: &mut [S],
32 pc_side: PcSide,
33 comm: &UniverseComm,
34 monitors: Option<&[Box<MonitorCallback<R>>]>,
35 work: Option<&mut Workspace>,
36 ) -> Result<SolveStats<R>, KError>
37 where
38 A: KLinOp<Scalar = S> + ?Sized,
39 {
40 self.inner
41 .solve_k(a, pc, b, x, pc_side, comm, monitors, work)
42 }
43}
44
45impl LinearSolver for CrSolver {
46 type Error = KError;
47
48 fn as_any_mut(&mut self) -> &mut dyn Any {
49 self
50 }
51
52 fn setup_workspace(&mut self, work: &mut Workspace) {
53 self.inner.setup_workspace(work);
54 }
55
56 fn solve(
57 &mut self,
58 a: &dyn LinOp<S = f64>,
59 pc: Option<&mut dyn Preconditioner>,
60 b: &[f64],
61 x: &mut [f64],
62 pc_side: PcSide,
63 comm: &UniverseComm,
64 monitors: Option<&[Box<MonitorCallback<f64>>]>,
65 work: Option<&mut Workspace>,
66 ) -> Result<SolveStats<f64>, Self::Error> {
67 self.inner
68 .solve(a, pc.as_deref(), b, x, pc_side, comm, monitors, work)
69 }
70}