From aabace24fb1da36ac4db2a17b5750b492bc1773e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkovsky@mmg.fjfi.cvut.cz> Date: Tue, 28 Jan 2020 16:49:31 +0100 Subject: [PATCH] Refactoring getLinearSolver and getPreconditioner --- src/TNL/Solvers/LinearSolverTypeResolver.h | 79 ++++++++++++++----- .../PDE/SemiImplicitTimeStepper_impl.h | 6 +- src/TNL/Solvers/SolverConfig_impl.h | 31 ++------ 3 files changed, 67 insertions(+), 49 deletions(-) diff --git a/src/TNL/Solvers/LinearSolverTypeResolver.h b/src/TNL/Solvers/LinearSolverTypeResolver.h index 18bf080399..5615ea7077 100644 --- a/src/TNL/Solvers/LinearSolverTypeResolver.h +++ b/src/TNL/Solvers/LinearSolverTypeResolver.h @@ -12,6 +12,8 @@ #pragma once +#include <vector> +#include <string> #include <memory> #include <TNL/Solvers/Linear/SOR.h> @@ -28,54 +30,89 @@ namespace TNL { namespace Solvers { +inline std::vector<std::string> +getLinearSolverOptions() +{ + return { + "sor", + "cg", + "bicgstab", + "bicgstabl", + "gmres", + "tfqmr" +#ifdef HAVE_UMFPACK + , "umfpack" +#endif + }; +} + +inline std::vector<std::string> +getPreconditionerOptions() +{ + return { + "none", + "diagonal", + "ilu0", + "ilut" + }; +} + template< typename MatrixType > std::shared_ptr< Linear::LinearSolver< MatrixType > > -getLinearSolver( const Config::ParameterContainer& parameters ) +getLinearSolver( std::string name ) { - const String& discreteSolver = parameters.getParameter< String >( "discrete-solver" ); - - if( discreteSolver == "sor" ) + if( name == "sor" ) return std::make_shared< Linear::SOR< MatrixType > >(); - if( discreteSolver == "cg" ) + if( name == "cg" ) return std::make_shared< Linear::CG< MatrixType > >(); - if( discreteSolver == "bicgstab" ) + if( name == "bicgstab" ) return std::make_shared< Linear::BICGStab< MatrixType > >(); - if( discreteSolver == "bicgstabl" ) + if( name == "bicgstabl" ) return std::make_shared< Linear::BICGStabL< MatrixType > >(); - if( discreteSolver == "gmres" ) + if( name == "gmres" ) return std::make_shared< Linear::GMRES< MatrixType > >(); - if( discreteSolver == "tfqmr" ) + if( name == "tfqmr" ) return std::make_shared< Linear::TFQMR< MatrixType > >(); #ifdef HAVE_UMFPACK if( discreteSolver == "umfpack" ) return std::make_shared< Linear::UmfpackWrapper< MatrixType > >(); #endif - std::cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, bicgstabl, gmres, tfqmr"; -#ifdef HAVE_UMFPACK - std::cerr << ", umfpack" -#endif - std::cerr << "." << std::endl; + std::string options; + for( auto o : getLinearSolverOptions() ) + if( options.empty() ) + options += o; + else + options += ", " + o; + + std::cerr << "Unknown semi-implicit discrete solver " << name << ". It can be only: " << options << "." << std::endl; return nullptr; } template< typename MatrixType > std::shared_ptr< Linear::Preconditioners::Preconditioner< MatrixType > > -getPreconditioner( const Config::ParameterContainer& parameters ) +getPreconditioner( std::string name ) { - const String& preconditioner = parameters.getParameter< String >( "preconditioner" ); - if( preconditioner == "none" ) + if( name == "none" ) return nullptr; - if( preconditioner == "diagonal" ) + if( name == "diagonal" ) return std::make_shared< Linear::Preconditioners::Diagonal< MatrixType > >(); - if( preconditioner == "ilu0" ) + if( name == "ilu0" ) return std::make_shared< Linear::Preconditioners::ILU0< MatrixType > >(); - if( preconditioner == "ilut" ) + if( name == "ilut" ) return std::make_shared< Linear::Preconditioners::ILUT< MatrixType > >(); - std::cerr << "Unknown preconditioner " << preconditioner << ". It can be only: none, diagonal, ilu0, ilut." << std::endl; + std::string options; + for( auto o : getPreconditionerOptions() ) + if( options.empty() ) + options += o; + else + options += ", " + o; + + std::cerr << "Unknown preconditioner " << name << ". It can be only: " << options << "." << std::endl; + return nullptr; } diff --git a/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h b/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h index 5faa7902e1..3e8d106b27 100644 --- a/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h +++ b/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h @@ -33,14 +33,16 @@ setup( const Config::ParameterContainer& parameters, const String& prefix ) { // set up the linear solver - linearSystemSolver = getLinearSolver< MatrixType >( parameters ); + const String& discreteSolver = parameters.getParameter< String >( prefix + "discrete-solver" ); + linearSystemSolver = getLinearSolver< MatrixType >( discreteSolver ); if( ! linearSystemSolver ) return false; if( ! linearSystemSolver->setup( parameters ) ) return false; // set up the preconditioner - preconditioner = getPreconditioner< MatrixType >( parameters ); + const String& preconditionerName = parameters.getParameter< String >( prefix + "preconditioner" ); + preconditioner = getPreconditioner< MatrixType >( preconditionerName ); if( preconditioner ) { linearSystemSolver->setPreconditioner( preconditioner ); if( ! preconditioner->setup( parameters ) ) diff --git a/src/TNL/Solvers/SolverConfig_impl.h b/src/TNL/Solvers/SolverConfig_impl.h index e5673d5c1e..9d3515157f 100644 --- a/src/TNL/Solvers/SolverConfig_impl.h +++ b/src/TNL/Solvers/SolverConfig_impl.h @@ -15,16 +15,7 @@ #include <TNL/Solvers/DummyProblem.h> #include <TNL/Solvers/PDE/ExplicitTimeStepper.h> #include <TNL/Solvers/PDE/TimeDependentPDESolver.h> -#include <TNL/Solvers/Linear/SOR.h> -#include <TNL/Solvers/Linear/CG.h> -#include <TNL/Solvers/Linear/BICGStab.h> -#include <TNL/Solvers/Linear/BICGStabL.h> -#include <TNL/Solvers/Linear/GMRES.h> -#include <TNL/Solvers/Linear/TFQMR.h> -#include <TNL/Solvers/Linear/UmfpackWrapper.h> -#include <TNL/Solvers/Linear/Preconditioners/Diagonal.h> -#include <TNL/Solvers/Linear/Preconditioners/ILU0.h> -#include <TNL/Solvers/Linear/Preconditioners/ILUT.h> +#include <TNL/Solvers/LinearSolverTypeResolver.h> #include <TNL/Matrices/CSR.h> #include <TNL/Meshes/DistributedMeshes/DistributedGrid.h> @@ -124,23 +115,11 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri } if( ConfigTagTimeDiscretisation< ConfigTag, SemiImplicitTimeDiscretisationTag >::enabled ) { - config.addEntryEnum( "cg" ); - config.addEntryEnum( "bicgstab" ); - config.addEntryEnum( "bicgstabl" ); - config.addEntryEnum( "gmres" ); - config.addEntryEnum( "tfqmr" ); - config.addEntryEnum( "sor" ); -#ifdef HAVE_UMFPACK - config.addEntryEnum( "umfpack" ); -#endif + for( auto o : getLinearSolverOptions() ) + config.addEntryEnum( String( o ) ); config.addEntry< String >( "preconditioner", "The preconditioner for the discrete solver:", "none" ); - config.addEntryEnum( "none" ); - config.addEntryEnum( "diagonal" ); - // TODO: implement parallel ILU or device-dependent build config tags for preconditioners -#ifndef HAVE_CUDA - config.addEntryEnum( "ilu0" ); - config.addEntryEnum( "ilut" ); -#endif + for( auto o : getPreconditionerOptions() ) + config.addEntryEnum( String( o ) ); } if( ConfigTagTimeDiscretisation< ConfigTag, ExplicitTimeDiscretisationTag >::enabled || ConfigTagTimeDiscretisation< ConfigTag, SemiImplicitTimeDiscretisationTag >::enabled ) -- GitLab