#pragma once #include #include #include #include #include namespace AMDiS { /** * \ingroup Solver * \class AMDiS::DirectRunner * \brief \implements RunnerInterface for the (external) direct solvers */ template class DirectRunner : public RunnerInterface { protected: using Super = RunnerInterface; public: /// Constructor. DirectRunner(std::string const& prefix) : solver_{} { SolverConfig::init(prefix, solver_); Parameters::get(prefix + "->reuse pattern", reusePattern_); } /// Implementes \ref RunnerInterface::init() virtual void init(Matrix const& A) override { if (!reusePattern_ || !initialized_) { solver_.analyzePattern(A); initialized_ = true; } solver_.factorize(A); test_exit(solver_.info() == Eigen::Success, "Error in solver.compute(matrix)"); } /// Implementes \ref RunnerInterface::exit() virtual void exit() override {} /// Implementes \ref RunnerInterface::solve() virtual int solve(Matrix const& A, VectorX& x, VectorB const& b, SolverInfo& solverInfo) override { x = solver_.solve(b); auto r = VectorB(b); if (x.norm() != 0) r -= A * x; solverInfo.setAbsResidual(r.norm()); solverInfo.setError(solver_.info()); return solver_.info() == Eigen::Success ? 0 : 1; } private: LU solver_; bool reusePattern_ = false; bool initialized_ = false; }; }