#pragma once #include #include #include #include #include namespace AMDiS { template class IterativeRunner : public RunnerInterface { using SolverCfg = SolverConfig; using PreconCfg = PreconConfig; using Mat = typename Traits::Mat; using Sol = typename Traits::Sol; using Rhs = typename Traits::Rhs; using Comm = typename Traits::Comm; public: IterativeRunner(std::string const& prefix) : solver_{} { SolverCfg::init(prefix, solver_); PreconCfg::init(prefix + "->precon", solver_.preconditioner()); Parameters::get(prefix + "->reuse pattern", reusePattern_); } /// Implements \ref RunnerInterface::init() void init(Mat const& A, Comm& comm) override { DUNE_UNUSED_PARAMETER(comm); if (!reusePattern_ || !initialized_) { solver_.analyzePattern(A); initialized_ = true; } solver_.factorize(A); test_exit(solver_.info() == Eigen::Success, "Error in solver.compute(matrix)"); } /// Implements \ref RunnerInterface::exit() void exit() override {} /// Implements \ref RunnerInterface::solve() int solve(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) override { DUNE_UNUSED_PARAMETER(A); solver_.setTolerance(solverInfo.relTolerance()); x = solver_.solveWithGuess(b, x); auto r = Rhs(b); if (x.norm() != 0) r -= A * x; solverInfo.setAbsResidual(r.norm()); solverInfo.setRelResidual(solver_.error()); solverInfo.setError(solver_.info()); msg("number of iteration: {}", solver_.iterations()); return solver_.info() == Eigen::Success ? 0 : int(solver_.info()); } private: IterativeSolver solver_; bool reusePattern_ = false; bool initialized_ = false; }; } // end namespace AMDiS