diff --git a/Applications/CLI/Tests.cmake b/Applications/CLI/Tests.cmake index 6ecfc9f3baa866d4831b175106c2c891b78a3900..2c218b4c432b345f8c3f5e987711ba7c0ec5468e 100644 --- a/Applications/CLI/Tests.cmake +++ b/Applications/CLI/Tests.cmake @@ -142,7 +142,7 @@ if(NOT OGS_USE_MPI) EXECUTABLE_ARGS line_${mesh_size}_robin_right_picard.prj WRAPPER time TESTER vtkdiff - ABSTOL 1e-14 RELTOL 1e-14 + ABSTOL 4e-14 RELTOL 2e-14 DIFF_DATA line_1_line_${mesh_size}.vtu line_${mesh_size}_robin_right_picard_pcs_0_ts_1_t_1.000000.vtu D1_left_N1_right pressure ) diff --git a/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp b/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp index 3d05dfbdbb1eeed15657e26939d31d1c0b9b89cd..d6f45b29c494ba3424b0c637963d3e4b54d0e3d3 100644 --- a/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp +++ b/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp @@ -102,6 +102,53 @@ private: T_SOLVER _solver; }; +template <template <typename, typename> class Solver, typename Precon> +std::unique_ptr<EigenLinearSolverBase> createIterativeSolver() +{ + using Slv = EigenIterativeLinearSolver< + Solver<EigenMatrix::RawMatrixType, Precon>>; + return std::unique_ptr<Slv>(new Slv); +} + +template <template <typename, typename> class Solver> +std::unique_ptr<EigenLinearSolverBase> createIterativeSolver( + EigenOption::PreconType precon_type) +{ + switch (precon_type) { + case EigenOption::PreconType::NONE: + return createIterativeSolver<Solver, + Eigen::IdentityPreconditioner>(); + case EigenOption::PreconType::DIAGONAL: + return createIterativeSolver< + Solver, Eigen::DiagonalPreconditioner<double>>(); + case EigenOption::PreconType::ILUT: + // TODO for this preconditioner further options can be passed. + // see https://eigen.tuxfamily.org/dox/classEigen_1_1IncompleteLUT.html + return createIterativeSolver< + Solver, Eigen::IncompleteLUT<double>>(); + default: + OGS_FATAL("Invalid Eigen preconditioner type."); + } +} + +template <typename Mat, typename Precon> +using EigenCGSolver = Eigen::ConjugateGradient<Mat, Eigen::Lower, Precon>; + +std::unique_ptr<EigenLinearSolverBase> createIterativeSolver( + EigenOption::SolverType solver_type, EigenOption::PreconType precon_type) +{ + switch (solver_type) { + case EigenOption::SolverType::BiCGSTAB: { + return createIterativeSolver<Eigen::BiCGSTAB>(precon_type); + } + case EigenOption::SolverType::CG: { + return createIterativeSolver<EigenCGSolver>(precon_type); + } + default: + OGS_FATAL("Invalid Eigen iterative linear solver type. Aborting."); + } +} + } // details EigenLinearSolver::EigenLinearSolver( @@ -115,26 +162,21 @@ EigenLinearSolver::EigenLinearSolver( // TODO for my taste it is much too unobvious that the default solver type // currently is SparseLU. - switch (_option.solver_type) - { - case EigenOption::SolverType::SparseLU: { - using SolverType = Eigen::SparseLU<Matrix, Eigen::COLAMDOrdering<int>>; - _solver.reset(new details::EigenDirectLinearSolver<SolverType>); - break; - } - case EigenOption::SolverType::BiCGSTAB: { - using SolverType = Eigen::BiCGSTAB<Matrix, Eigen::DiagonalPreconditioner<double>>; - _solver.reset(new details::EigenIterativeLinearSolver<SolverType>); - break; - } - case EigenOption::SolverType::CG: { - using SolverType = Eigen::ConjugateGradient<Matrix, Eigen::Lower, Eigen::DiagonalPreconditioner<double>>; - _solver.reset(new details::EigenIterativeLinearSolver<SolverType>); - break; - } - case EigenOption::SolverType::INVALID: - OGS_FATAL("Invalid Eigen linear solver type. Aborting."); + switch (_option.solver_type) { + case EigenOption::SolverType::SparseLU: { + using SolverType = + Eigen::SparseLU<Matrix, Eigen::COLAMDOrdering<int>>; + _solver.reset(new details::EigenDirectLinearSolver<SolverType>); + return; + } + case EigenOption::SolverType::BiCGSTAB: + case EigenOption::SolverType::CG: + _solver = details::createIterativeSolver(_option.solver_type, + _option.precon_type); + return; } + + OGS_FATAL("Invalid Eigen linear solver type. Aborting."); } EigenLinearSolver::~EigenLinearSolver() = default; @@ -147,20 +189,24 @@ void EigenLinearSolver::setOption(BaseLib::ConfigTree const& option) if (!ptSolver) return; - //! \ogs_file_param{linear_solver__eigen__solver_type} - if (auto solver_type = ptSolver->getConfigParameterOptional<std::string>("solver_type")) { + if (auto solver_type = + //! \ogs_file_param{linear_solver__eigen__solver_type} + ptSolver->getConfigParameterOptional<std::string>("solver_type")) { _option.solver_type = _option.getSolverType(*solver_type); } - //! \ogs_file_param{linear_solver__eigen__precon_type} - if (auto precon_type = ptSolver->getConfigParameterOptional<std::string>("precon_type")) { + if (auto precon_type = + //! \ogs_file_param{linear_solver__eigen__precon_type} + ptSolver->getConfigParameterOptional<std::string>("precon_type")) { _option.precon_type = _option.getPreconType(*precon_type); } - //! \ogs_file_param{linear_solver__eigen__error_tolerance} - if (auto error_tolerance = ptSolver->getConfigParameterOptional<double>("error_tolerance")) { + if (auto error_tolerance = + //! \ogs_file_param{linear_solver__eigen__error_tolerance} + ptSolver->getConfigParameterOptional<double>("error_tolerance")) { _option.error_tolerance = *error_tolerance; } - //! \ogs_file_param{linear_solver__eigen__max_iteration_step} - if (auto max_iteration_step = ptSolver->getConfigParameterOptional<int>("max_iteration_step")) { + if (auto max_iteration_step = + //! \ogs_file_param{linear_solver__eigen__max_iteration_step} + ptSolver->getConfigParameterOptional<int>("max_iteration_step")) { _option.max_iterations = *max_iteration_step; } } diff --git a/MathLib/LinAlg/Eigen/EigenOption.cpp b/MathLib/LinAlg/Eigen/EigenOption.cpp index 36bc4a671ff8fbfbba51a5a3f0d6088f21c2b3cf..3c273491484a7404ccbfde4e5be205f7b3db49c1 100644 --- a/MathLib/LinAlg/Eigen/EigenOption.cpp +++ b/MathLib/LinAlg/Eigen/EigenOption.cpp @@ -8,6 +8,7 @@ */ #include "EigenOption.h" +#include "BaseLib/Error.h" namespace MathLib { @@ -22,27 +23,26 @@ EigenOption::EigenOption() EigenOption::SolverType EigenOption::getSolverType(const std::string &solver_name) { -#define RETURN_SOLVER_ENUM_IF_SAME_STRING(str, TypeName) \ - if (#TypeName==(str)) return SolverType::TypeName; - - RETURN_SOLVER_ENUM_IF_SAME_STRING(solver_name, CG); - RETURN_SOLVER_ENUM_IF_SAME_STRING(solver_name, BiCGSTAB); - RETURN_SOLVER_ENUM_IF_SAME_STRING(solver_name, SparseLU); - - return SolverType::INVALID; -#undef RETURN_SOLVER_ENUM_IF_SAME_STRING + if (solver_name == "CG") + return SolverType::CG; + if (solver_name == "BiCGSTAB") + return SolverType::BiCGSTAB; + if (solver_name == "SparseLU") + return SolverType::SparseLU; + + OGS_FATAL("Unknown Eigen solver type `%s'", solver_name.c_str()); } EigenOption::PreconType EigenOption::getPreconType(const std::string &precon_name) { -#define RETURN_PRECOM_ENUM_IF_SAME_STRING(str, TypeName) \ - if (#TypeName==(str)) return PreconType::TypeName; - - RETURN_PRECOM_ENUM_IF_SAME_STRING(precon_name, NONE); - RETURN_PRECOM_ENUM_IF_SAME_STRING(precon_name, DIAGONAL); - - return PreconType::NONE; -#undef RETURN_PRECOM_ENUM_IF_SAME_STRING + if (precon_name == "NONE") + return PreconType::NONE; + if (precon_name == "DIAGONAL") + return PreconType::DIAGONAL; + if (precon_name == "ILUT") + return PreconType::ILUT; + + OGS_FATAL("Unknown Eigen preconditioner type `%s'", precon_name.c_str()); } } //MathLib diff --git a/MathLib/LinAlg/Eigen/EigenOption.h b/MathLib/LinAlg/Eigen/EigenOption.h index b0e0f34688af2ef5d4b96570a9b802b3dd865c52..5b64fc41a7b42da5fb1ab976a975c32222cba4b1 100644 --- a/MathLib/LinAlg/Eigen/EigenOption.h +++ b/MathLib/LinAlg/Eigen/EigenOption.h @@ -21,7 +21,6 @@ struct EigenOption final /// Solver type enum class SolverType : short { - INVALID, CG, BiCGSTAB, SparseLU @@ -31,7 +30,8 @@ struct EigenOption final enum class PreconType : short { NONE, - DIAGONAL + DIAGONAL, + ILUT }; /// Linear solver type diff --git a/NumLib/NamedFunctionCaller.cpp b/NumLib/NamedFunctionCaller.cpp index b7111612e0f45bf3bee11137e8ef745d16dd414c..e7b89d90119b9177a9406a0742686e949a76afa1 100644 --- a/NumLib/NamedFunctionCaller.cpp +++ b/NumLib/NamedFunctionCaller.cpp @@ -204,8 +204,6 @@ double NamedFunctionCaller::call( assert(_deferred_plugs.empty() && "You must call applyPlugs() before this method!"); - DBUG("Preparing call of fct #%lu %s()", function_idx, - _named_functions[function_idx].getName().c_str()); auto const& sis_sos = _map_sink_source[function_idx]; assert(sis_sos.size() == _named_functions[function_idx].getArgumentNames().size()); @@ -217,17 +215,12 @@ double NamedFunctionCaller::call( if (source >= 0) { fct_args[sink] = call(source, unbound_arguments); - DBUG("setting %luth argument to %g", sink, fct_args[sink]); } else { assert(source != _uninitialized); fct_args[sink] = unbound_arguments[-source-1]; - DBUG("setting %luth argument to %g", sink, fct_args[sink]); } } - DBUG("Finished preparing call of fct #%lu %s()", function_idx, - _named_functions[function_idx].getName().c_str()); - return _named_functions[function_idx].call(fct_args); } diff --git a/Tests/Data b/Tests/Data index 2085e1093f2b2235d82a6e8091c07fb98b6d3dfb..077539a7a9cb452c0797ec3dc3a255df1e05392d 160000 --- a/Tests/Data +++ b/Tests/Data @@ -1 +1 @@ -Subproject commit 2085e1093f2b2235d82a6e8091c07fb98b6d3dfb +Subproject commit 077539a7a9cb452c0797ec3dc3a255df1e05392d