#ifndef LINEAR_SOLVER_OPTIONS_HPP #define LINEAR_SOLVER_OPTIONS_HPP #include <utils/Exceptions.hpp> #include <iostream> enum class LSLibrary : int8_t { LS__begin = 0, // builtin = LS__begin, petsc, // LS__end }; enum class LSMethod : int8_t { LS__begin = 0, // cg = LS__begin, bicgstab, bicgstab2, gmres, lu, choleski, // LS__end }; enum class LSPrecond : int8_t { LS__begin = 0, // none = LS__begin, diagonal, incomplete_choleski, incomplete_LU, amg, // LS__end }; inline std::string name(const LSLibrary library) { switch (library) { case LSLibrary::builtin: { return "builtin"; } case LSLibrary::petsc: { return "PETSc"; } case LSLibrary::LS__end: { } } throw UnexpectedError("Linear system library name is not defined!"); } inline std::string name(const LSMethod method) { switch (method) { case LSMethod::cg: { return "CG"; } case LSMethod::bicgstab: { return "BICGStab"; } case LSMethod::bicgstab2: { return "BICGStab2"; } case LSMethod::gmres: { return "GMRES"; } case LSMethod::lu: { return "LU"; } case LSMethod::choleski: { return "Choleski"; } case LSMethod::LS__end: { } } throw UnexpectedError("Linear system method name is not defined!"); } inline std::string name(const LSPrecond precond) { switch (precond) { case LSPrecond::none: { return "none"; } case LSPrecond::diagonal: { return "diagonal"; } case LSPrecond::incomplete_choleski: { return "ICholeski"; } case LSPrecond::incomplete_LU: { return "ILU"; } case LSPrecond::amg: { return "AMG"; } case LSPrecond::LS__end: { } } throw UnexpectedError("Linear system preconditioner name is not defined!"); } template <typename LSEnumType> inline LSEnumType getLSEnumFromName(const std::string& enum_name) { using BaseT = std::underlying_type_t<LSEnumType>; for (BaseT enum_value = static_cast<BaseT>(LSEnumType::LS__begin); enum_value < static_cast<BaseT>(LSEnumType::LS__end); ++enum_value) { if (name(LSEnumType{enum_value}) == enum_name) { return LSEnumType{enum_value}; } } throw NormalError(std::string{"could not find '"} + enum_name + "' associate type!"); } template <typename LSEnumType> inline void printLSEnumListNames(std::ostream& os) { using BaseT = std::underlying_type_t<LSEnumType>; for (BaseT enum_value = static_cast<BaseT>(LSEnumType::LS__begin); enum_value < static_cast<BaseT>(LSEnumType::LS__end); ++enum_value) { os << " - " << name(LSEnumType{enum_value}) << '\n'; } } class LinearSolverOptions { private: LSLibrary m_library = LSLibrary::builtin; LSMethod m_method = LSMethod::bicgstab; LSPrecond m_precond = LSPrecond::none; double m_epsilon = 1E-6; size_t m_maximum_iteration = 200; bool m_verbose = false; public: static LinearSolverOptions default_options; friend std::ostream& operator<<(std::ostream& os, const LinearSolverOptions& options); LSLibrary& library() { return m_library; } LSLibrary library() const { return m_library; } LSMethod method() const { return m_method; } LSMethod& method() { return m_method; } LSPrecond precond() const { return m_precond; } LSPrecond& precond() { return m_precond; } double epsilon() const { return m_epsilon; } double& epsilon() { return m_epsilon; } size_t& maximumIteration() { return m_maximum_iteration; } size_t maximumIteration() const { return m_maximum_iteration; } bool& verbose() { return m_verbose; }; bool verbose() const { return m_verbose; }; LinearSolverOptions(const LinearSolverOptions&) = default; LinearSolverOptions(LinearSolverOptions&&) = default; LinearSolverOptions() = default; ~LinearSolverOptions() = default; }; inline LinearSolverOptions LinearSolverOptions::default_options; #endif // LINEAR_SOLVER_OPTIONS_HPP