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

Next iteration of MeshTypeResolver generalization

parent ae7a48c5
Loading
Loading
Loading
Loading
+42 −21
Original line number Diff line number Diff line
@@ -10,54 +10,75 @@

#pragma once

#include <TNL/Config/ParameterContainer.h>
#include <TNL/Solvers/BuildConfigTags.h>
#include <TNL/Meshes/Readers/TNL.h>

/*
 * TODO:
 * The variadic template parameter pack ProblemSetterArgs will not be necessary
 * in C++14 as it will be possible to use generic lambda functions to pass
 * parameters to the ProblemSetter:
 *
 *    // wrapper for MeshTypeResolver
 *    template< typename MeshType >
 *    using ProblemSetterWrapper = ProblemSetter< Real, Device, Index, MeshType, ConfigTag, SolverStarter< ConfigTag > >;
 *
 *    bool run( const Config::ParameterContainer& parameters )
 *    {
 *       const String& meshFileName = parameters.getParameter< String >( "mesh" );
 *       auto wrapper = []( auto&& mesh ) {
 *           return ProblemSetterWrapper< decltype(mesh) >::run( parameters );
 *       };
 *       return MeshTypeResolver< ConfigTag, Device, wrapper >::run( meshFileName );
 *    }
 */

namespace TNL {
namespace Solvers {

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
class MeshTypeResolver
{
   public:

   static bool run( const Config::ParameterContainer& parameters );
   static bool run( const String& fileName,
                    ProblemSetterArgs&&... problemSetterArgs );

   protected:

   static bool resolveMeshDimension( const Config::ParameterContainer& parameters,
                                      Meshes::Readers::TNL& reader );
   static bool resolveMeshDimension( Meshes::Readers::TNL& reader,
                                     ProblemSetterArgs&&... problemSetterArgs );

   // Overload for disabled dimensions
   template< int MeshDimension,
             typename = typename std::enable_if< ! ConfigTagDimensions< ConfigTag,MeshDimension>::enabled >::type,
             typename = void >
   static bool resolveMeshRealType( const Config::ParameterContainer& parameters,
                                    Meshes::Readers::TNL& reader );
   static bool resolveMeshRealType( Meshes::Readers::TNL& reader,
                                    ProblemSetterArgs&&... problemSetterArgs );

   // Overload for enabled dimensions
   template< int MeshDimension,
             typename = typename std::enable_if< ConfigTagDimensions< ConfigTag,MeshDimension>::enabled >::type >
   static bool resolveMeshRealType( const Config::ParameterContainer& parameters,
                                    Meshes::Readers::TNL& reader );
   static bool resolveMeshRealType( Meshes::Readers::TNL& reader,
                                    ProblemSetterArgs&&... problemSetterArgs );

   // Overload for disabled real types
   template< int MeshDimension,
             typename MeshRealType,
             typename = typename std::enable_if< ! ConfigTagReal< ConfigTag, MeshRealType>::enabled >::type,
             typename = void >
   static bool resolveMeshIndexType( const Config::ParameterContainer& parameters,
                                     Meshes::Readers::TNL& reader );
   static bool resolveMeshIndexType( Meshes::Readers::TNL& reader,
                                     ProblemSetterArgs&&... problemSetterArgs );

   // Overload for enabled real types
   template< int MeshDimension,
             typename MeshRealType,
             typename = typename std::enable_if< ConfigTagReal< ConfigTag, MeshRealType>::enabled >::type >
   static bool resolveMeshIndexType( const Config::ParameterContainer& parameters,
                                     Meshes::Readers::TNL& reader );
   static bool resolveMeshIndexType( Meshes::Readers::TNL& reader,
                                     ProblemSetterArgs&&... problemSetterArgs );

   // Overload for disabled index types
   template< int MeshDimension,
@@ -65,29 +86,29 @@ class MeshTypeResolver
             typename MeshIndexType,
             typename = typename std::enable_if< ! ConfigTagIndex< ConfigTag, MeshIndexType >::enabled >::type,
             typename = void >
   static bool resolveMeshType( const Config::ParameterContainer& parameters,
                                Meshes::Readers::TNL& reader );
   static bool resolveMeshType( Meshes::Readers::TNL& reader,
                                ProblemSetterArgs&&... problemSetterArgs );

   // Overload for enabled index types
   template< int MeshDimension,
             typename MeshRealType,
             typename MeshIndexType,
             typename = typename std::enable_if< ConfigTagIndex< ConfigTag, MeshIndexType >::enabled >::type >
   static bool resolveMeshType( const Config::ParameterContainer& parameters,
                                Meshes::Readers::TNL& reader );
   static bool resolveMeshType( Meshes::Readers::TNL& reader,
                                ProblemSetterArgs&&... problemSetterArgs );

   // Overload for disabled mesh types
   template< typename MeshType,
             typename = typename std::enable_if< ! ConfigTagMesh< ConfigTag, MeshType >::enabled >::type,
             typename = void >
   static bool resolveTerminate( const Config::ParameterContainer& parameters,
                                 Meshes::Readers::TNL& reader );
   static bool resolveTerminate( Meshes::Readers::TNL& reader,
                                 ProblemSetterArgs&&... problemSetterArgs );

   // Overload for enabled mesh types
   template< typename MeshType,
             typename = typename std::enable_if< ConfigTagMesh< ConfigTag, MeshType >::enabled >::type >
   static bool resolveTerminate( const Config::ParameterContainer& parameters,
                                 Meshes::Readers::TNL& reader );
   static bool resolveTerminate( Meshes::Readers::TNL& reader,
                                 ProblemSetterArgs&&... problemSetterArgs );
};

} // namespace Solvers
+65 −53
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@

#pragma once

#include <utility>

#include <TNL/String.h>
#include <TNL/Meshes/Grid.h>
#include <TNL/Solvers/MeshTypeResolver.h>
@@ -19,44 +21,47 @@ namespace Solvers {

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
run( const Config::ParameterContainer& parameters )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
run( const String& fileName,
     ProblemSetterArgs&&... problemSetterArgs )
{
   const String& meshFileName = parameters.getParameter< String >( "mesh" );
   Meshes::Readers::TNL reader;
   if( ! reader.readFile( meshFileName ) )
   if( ! reader.readFile( fileName ) )
      return false;
   return resolveMeshDimension( parameters, reader );
   return resolveMeshDimension( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
}

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshDimension( const Config::ParameterContainer& parameters,
                       Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshDimension( Meshes::Readers::TNL& reader,
                      ProblemSetterArgs&&... problemSetterArgs )
{
   if( reader.getMeshDimension() == 1 )
      return resolveMeshRealType< 1 >( parameters, reader );
      return resolveMeshRealType< 1 >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   if( reader.getMeshDimension() == 2 )
      return resolveMeshRealType< 2 >( parameters, reader );
      return resolveMeshRealType< 2 >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   if( reader.getMeshDimension() == 3 )
      return resolveMeshRealType< 3 >( parameters, reader );
      return resolveMeshRealType< 3 >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   std::cerr << "Unsupported mesh dimension: " << reader.getMeshDimension() << std::endl;
   return false;
}

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< int MeshDimension, typename, typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshRealType( const Config::ParameterContainer& parameters,
                     Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshRealType( Meshes::Readers::TNL& reader,
    ProblemSetterArgs&&... problemSetterArgs )
{
   std::cerr << "Mesh dimension " << MeshDimension << " is not supported." << std::endl;
   return false;
@@ -64,33 +69,35 @@ resolveMeshRealType( const Config::ParameterContainer& parameters,

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< int MeshDimension, typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshRealType( const Config::ParameterContainer& parameters,
                     Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshRealType( Meshes::Readers::TNL& reader,
                     ProblemSetterArgs&&... problemSetterArgs )
{
   if( reader.getRealType() == "float" )
      return resolveMeshIndexType< MeshDimension, float >( parameters, reader );
      return resolveMeshIndexType< MeshDimension, float >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   if( reader.getRealType() == "double" )
      return resolveMeshIndexType< MeshDimension, double >( parameters, reader );
      return resolveMeshIndexType< MeshDimension, double >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   if( reader.getRealType() == "long-double" )
      return resolveMeshIndexType< MeshDimension, long double >( parameters, reader );
      return resolveMeshIndexType< MeshDimension, long double >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   std::cerr << "The type '" << reader.getRealType() << "' is not allowed for real type." << std::endl;
   return false;
}

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< int MeshDimension,
             typename MeshRealType,
             typename, typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshIndexType( const Config::ParameterContainer& parameters,
                      Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshIndexType( Meshes::Readers::TNL& reader,
                      ProblemSetterArgs&&... problemSetterArgs )
{
   std::cerr << "The type '" << reader.getRealType() << "' is not allowed for real type." << std::endl;
   return false;
@@ -98,36 +105,38 @@ resolveMeshIndexType( const Config::ParameterContainer& parameters,

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< int MeshDimension,
             typename MeshRealType,
             typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshIndexType( const Config::ParameterContainer& parameters,
                      Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshIndexType( Meshes::Readers::TNL& reader,
                      ProblemSetterArgs&&... problemSetterArgs )
{
   if( reader.getIndexType() == "short int" )
      return resolveMeshType< MeshDimension, MeshRealType, short int >( parameters, reader );
      return resolveMeshType< MeshDimension, MeshRealType, short int >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   if( reader.getIndexType() == "int" )
      return resolveMeshType< MeshDimension, MeshRealType, int >( parameters, reader );
      return resolveMeshType< MeshDimension, MeshRealType, int >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   if( reader.getIndexType() == "long int" )
      return resolveMeshType< MeshDimension, MeshRealType, long int >( parameters, reader );
      return resolveMeshType< MeshDimension, MeshRealType, long int >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   std::cerr << "The type '" << reader.getIndexType() << "' is not allowed for indexing type." << std::endl;
   return false;
}

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< int MeshDimension,
             typename MeshRealType,
             typename MeshIndexType,
             typename, typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshType( const Config::ParameterContainer& parameters,
                 Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshType( Meshes::Readers::TNL& reader,
                 ProblemSetterArgs&&... problemSetterArgs )
{
   std::cerr << "The type '" << reader.getIndexType() << "' is not allowed for indexing type." << std::endl;
   return false;
@@ -135,20 +144,21 @@ resolveMeshType( const Config::ParameterContainer& parameters,

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< int MeshDimension,
             typename MeshRealType,
             typename MeshIndexType,
             typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveMeshType( const Config::ParameterContainer& parameters,
                 Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveMeshType( Meshes::Readers::TNL& reader,
                 ProblemSetterArgs&&... problemSetterArgs )
{
   if( reader.getMeshType() == "Meshes::Grid" )
   {
      using MeshType = Meshes::Grid< MeshDimension, MeshRealType, Device, MeshIndexType >;
      return resolveTerminate< MeshType >( parameters, reader );
      return resolveTerminate< MeshType >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
   }
   std::cerr << "Unknown mesh type " << reader.getMeshType() << "." << std::endl;
   return false;
@@ -156,13 +166,14 @@ resolveMeshType( const Config::ParameterContainer& parameters,

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< typename MeshType,
             typename, typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveTerminate( const Config::ParameterContainer& parameters,
                  Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveTerminate( Meshes::Readers::TNL& reader,
                  ProblemSetterArgs&&... problemSetterArgs )
{
   std::cerr << "The mesh type " << TNL::getType< MeshType >() << " is not supported." << std::endl;
   return false;
@@ -170,16 +181,17 @@ resolveTerminate( const Config::ParameterContainer& parameters,

template< typename ConfigTag,
          typename Device,
          template< typename MeshType > class ProblemSetter >
          template< typename MeshType > class ProblemSetter,
          typename... ProblemSetterArgs >
   template< typename MeshType,
             typename >
bool
MeshTypeResolver< ConfigTag, Device, ProblemSetter >::
resolveTerminate( const Config::ParameterContainer& parameters,
                  Meshes::Readers::TNL& reader )
MeshTypeResolver< ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
resolveTerminate( Meshes::Readers::TNL& reader,
                  ProblemSetterArgs&&... problemSetterArgs )
{
   // TODO: the mesh can be loaded here (this will be probably necessary for unstructured meshes anyway)
   return ProblemSetter< MeshType >::run( parameters );
   return ProblemSetter< MeshType >::run( std::forward<ProblemSetterArgs>(problemSetterArgs)... );
};

} // namespace Solvers
+2 −1
Original line number Diff line number Diff line
@@ -212,7 +212,8 @@ class SolverInitiatorMeshResolver< ProblemSetter, Real, Device, Index, ConfigTag
   public:
      static bool run( const Config::ParameterContainer& parameters )
      {
         return MeshTypeResolver< ConfigTag, Device, ProblemSetterWrapper >::run( parameters );
         const String& meshFileName = parameters.getParameter< String >( "mesh" );
         return MeshTypeResolver< ConfigTag, Device, ProblemSetterWrapper, decltype(parameters) >::run( meshFileName, parameters );
      }
};