Commit aabace24 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Refactoring getLinearSolver and getPreconditioner

parent 2497889f
Loading
Loading
Loading
Loading
+58 −21
Original line number Diff line number Diff line
@@ -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;
}

+4 −2
Original line number Diff line number Diff line
@@ -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 ) )
+5 −26
Original line number Diff line number Diff line
@@ -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 )