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

Added support for manual override of the automatically detected mesh file format

parent cd1e5102
Loading
Loading
Loading
Loading
+52 −18
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@

#pragma once

#include <experimental/filesystem>

#include <TNL/Meshes/Mesh.h>
#include <TNL/Meshes/TypeResolver/MeshTypeResolver.h>
#include <TNL/Meshes/Readers/PVTUReader.h>
@@ -22,17 +24,29 @@ template< typename ConfigTag,
          typename Device,
          typename Functor >
bool
resolveDistributedMeshType( const String& fileName,
                            Functor&& functor )
resolveDistributedMeshType( Functor&& functor,
                            const std::string& fileName,
                            const std::string& fileFormat = "auto" )
{
   std::cout << "Detecting distributed mesh from file " << fileName << " ..." << std::endl;

   auto wrapper = [&functor] ( Readers::MeshReader& reader, auto&& localMesh )
   {
      using LocalMesh = std::decay_t< decltype(localMesh) >;
      using DistributedMesh = DistributedMeshes::DistributedMesh< LocalMesh >;
      return std::forward<Functor>(functor)( reader, DistributedMesh{ std::move(localMesh) } );
   };
   std::cout << "Detecting distributed mesh from file " << fileName << " ..." << std::endl;
   if( fileName.endsWith( ".pvtu" ) ) {

   namespace fs = std::experimental::filesystem;
   std::string format = fileFormat;
   if( format == "auto" ) {
      format = fs::path(fileName).extension();
      if( format.length() > 0 )
         // remove dot from the extension
         format = format.substr(1);
   }

   if( format == "pvtu" ) {
      // FIXME: The XML VTK files don't store the local index type.
      // The reader has some defaults, but they might be disabled by the BuildConfigTags - in
      // this case we should use the first enabled type.
@@ -47,7 +61,11 @@ resolveDistributedMeshType( const String& fileName,
      }
   }
   else {
      std::cerr << "File '" << fileName << "' has unknown extension. Supported extensions are '.pvtu'." << std::endl;
      if( fileFormat == "auto" )
         std::cerr << "File '" << fileName << "' has unsupported format (based on the file extension): " << format << ".";
      else
         std::cerr << "Unsupported fileFormat parameter: " << fileFormat << ".";
      std::cerr << " Supported formats are 'pvtu'." << std::endl;
      return false;
   }
}
@@ -56,8 +74,9 @@ template< typename ConfigTag,
          typename Device,
          typename Functor >
bool
resolveAndLoadDistributedMesh( const String& fileName,
                               Functor&& functor )
resolveAndLoadDistributedMesh( Functor&& functor,
                               const std::string& fileName,
                               const std::string& fileFormat = "auto" )
{
   auto wrapper = [&]( Readers::MeshReader& reader, auto&& mesh ) -> bool
   {
@@ -72,27 +91,41 @@ resolveAndLoadDistributedMesh( const String& fileName,
      }
      return functor( reader, std::forward<MeshType>(mesh) );
   };
   return resolveDistributedMeshType< ConfigTag, Device >( fileName, wrapper );
   return resolveDistributedMeshType< ConfigTag, Device >( wrapper, fileName, fileFormat );
}

template< typename CommunicatorType,
          typename MeshConfig,
          typename Device >
bool
loadDistributedMesh( const String& fileName,
                     Mesh< MeshConfig, Device >& mesh,
                     DistributedMeshes::DistributedMesh< Mesh< MeshConfig, Device > >& distributedMesh )
loadDistributedMesh( Mesh< MeshConfig, Device >& mesh,
                     DistributedMeshes::DistributedMesh< Mesh< MeshConfig, Device > >& distributedMesh,
                     const std::string& fileName,
                     const std::string& fileFormat = "auto" )
{
   // TODO: simplify interface, pass only the distributed mesh
   TNL_ASSERT_EQ( &mesh, &distributedMesh.getLocalMesh(), "mesh is not local mesh of the distributed mesh" );

   if( fileName.endsWith( ".pvtu" ) ) {
   namespace fs = std::experimental::filesystem;
   std::string format = fileFormat;
   if( format == "auto" ) {
      format = fs::path(fileName).extension();
      if( format.length() > 0 )
         // remove dot from the extension
         format = format.substr(1);
   }

   if( format == "pvtu" ) {
      Readers::PVTUReader reader( fileName );
      reader.loadMesh( distributedMesh );
      return true;
   }
   else {
      std::cerr << "The file has an unsupported extension: " << fileName << ". Only .pvtu files can be loaded into the distributed mesh." << std::endl;
      if( fileFormat == "auto" )
         std::cerr << "File '" << fileName << "' has unsupported format (based on the file extension): " << format << ".";
      else
         std::cerr << "Unsupported fileFormat parameter: " << fileFormat << ".";
      std::cerr << " Supported formats are 'pvtu'." << std::endl;
      return false;
   }
}
@@ -102,7 +135,7 @@ template< typename Problem,
          typename Device >
bool
decomposeMesh( const Config::ParameterContainer& parameters,
               const String& prefix,
               const std::string& prefix,
               Mesh< MeshConfig, Device >& mesh,
               DistributedMeshes::DistributedMesh< Mesh< MeshConfig, Device > >& distributedMesh,
               Problem& problem )
@@ -118,9 +151,10 @@ template< typename CommunicatorType,
          typename Device,
          typename Index >
bool
loadDistributedMesh( const String& fileName,
                     Grid< Dimension, Real, Device, Index >& mesh,
                     DistributedMeshes::DistributedMesh< Grid< Dimension, Real, Device, Index > > &distributedMesh )
loadDistributedMesh( Grid< Dimension, Real, Device, Index >& mesh,
                     DistributedMeshes::DistributedMesh< Grid< Dimension, Real, Device, Index > > &distributedMesh,
                     const std::string& fileName,
                     const std::string& fileFormat = "auto" )
{
   std::cout << "Loading a global mesh from the file " << fileName << "...";
   Grid< Dimension, Real, Device, Index > globalGrid;
@@ -149,7 +183,7 @@ template< typename Problem,
          typename Index >
bool
decomposeMesh( const Config::ParameterContainer& parameters,
               const String& prefix,
               const std::string& prefix,
               Grid< Dimension, Real, Device, Index >& mesh,
               DistributedMeshes::DistributedMesh< Grid< Dimension, Real, Device, Index > > &distributedMesh,
               Problem& problem )
+17 −8
Original line number Diff line number Diff line
@@ -33,7 +33,10 @@ namespace Meshes {
template< typename ConfigTag,
          typename Device,
          typename Functor >
bool resolveMeshType( const String& fileName, Functor&& functor );
bool
resolveMeshType( Functor&& functor,
                 const std::string& fileName,
                 const std::string& fileFormat = "auto" );

/*
 * This function dues the same as `resolveMeshType`, but also reuses the mesh
@@ -51,7 +54,10 @@ bool resolveMeshType( const String& fileName, Functor&& functor );
template< typename ConfigTag,
          typename Device,
          typename Functor >
bool resolveAndLoadMesh( const String& fileName, Functor&& functor );
bool
resolveAndLoadMesh( Functor&& functor,
                    const std::string& fileName,
                    const std::string& fileFormat = "auto" );

/*
 * This function takes a file name and a mesh instance and attempts to load the
@@ -64,21 +70,24 @@ bool resolveAndLoadMesh( const String& fileName, Functor&& functor );
template< typename MeshConfig,
          typename Device >
bool
loadMesh( const String& fileName,
          Mesh< MeshConfig, Device >& mesh );
loadMesh( Mesh< MeshConfig, Device >& mesh,
          const std::string& fileName,
          const std::string& fileFormat = "auto" );

template< typename MeshConfig >
bool
loadMesh( const String& fileName,
          Mesh< MeshConfig, Devices::Cuda >& mesh );
loadMesh( Mesh< MeshConfig, Devices::Cuda >& mesh,
          const std::string& fileName,
          const std::string& fileFormat = "auto" );

template< int Dimension,
          typename Real,
          typename Device,
          typename Index >
bool
loadMesh( const String& fileName,
          Grid< Dimension, Real, Device, Index >& grid );
loadMesh( Grid< Dimension, Real, Device, Index >& grid,
          const std::string& fileName,
          const std::string& fileFormat = "auto" );

} // namespace Meshes
} // namespace TNL
+58 −20
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@

#pragma once

#include <experimental/filesystem>

#include <TNL/Meshes/TypeResolver/TypeResolver.h>
#include <TNL/Meshes/TypeResolver/GridTypeResolver.h>
#include <TNL/Meshes/TypeResolver/MeshTypeResolver.h>
@@ -24,11 +26,24 @@ namespace Meshes {
template< typename ConfigTag,
          typename Device,
          typename Functor >
bool resolveMeshType( const String& fileName, Functor&& functor )
bool
resolveMeshType( Functor&& functor,
                 const std::string& fileName,
                 const std::string& fileFormat )
{
   std::cout << "Detecting mesh from file " << fileName << " ..." << std::endl;

   namespace fs = std::experimental::filesystem;
   std::string format = fileFormat;
   if( format == "auto" ) {
      format = fs::path(fileName).extension();
      if( format.length() > 0 )
         // remove dot from the extension
         format = format.substr(1);
   }

   // TODO: when TNLReader is gone, use the MeshReader type instead of a template parameter in the mesh type resolver (and remove static_casts in this function)
   if( fileName.endsWith( ".tnl" ) ) {
   if( format == "tnl" ) {
      Readers::TNLReader reader( fileName );
      if( ! reader.detectMesh() )
         return false;
@@ -41,7 +56,7 @@ bool resolveMeshType( const String& fileName, Functor&& functor )
         return false;
      }
   }
   else if( fileName.endsWith( ".ng" ) ) {
   else if( format == "ng" ) {
      // FIXME: The Netgen files don't store the real, global index and local index types.
      // The reader has some defaults, but they might be disabled by the BuildConfigTags - in
      // this case we should use the first enabled type.
@@ -54,7 +69,7 @@ bool resolveMeshType( const String& fileName, Functor&& functor )
         return false;
      }
   }
   else if( fileName.endsWith( ".vtk" ) ) {
   else if( format == "vtk" ) {
      // FIXME: The VTK files don't store the global and local index types.
      // The reader has some defaults, but they might be disabled by the BuildConfigTags - in
      // this case we should use the first enabled type.
@@ -67,7 +82,7 @@ bool resolveMeshType( const String& fileName, Functor&& functor )
         return false;
      }
   }
   else if( fileName.endsWith( ".vtu" ) ) {
   else if( format == "vtu" ) {
      // FIXME: The XML VTK files don't store the local index type.
      // The reader has some defaults, but they might be disabled by the BuildConfigTags - in
      // this case we should use the first enabled type.
@@ -81,7 +96,11 @@ bool resolveMeshType( const String& fileName, Functor&& functor )
      }
   }
   else {
      std::cerr << "File '" << fileName << "' has unknown extension. Supported extensions are '.tnl', '.vtk', '.vtu' and '.ng'." << std::endl;
      if( fileFormat == "auto" )
         std::cerr << "File '" << fileName << "' has unsupported format (based on the file extension): " << format << ".";
      else
         std::cerr << "Unsupported fileFormat parameter: " << fileFormat << ".";
      std::cerr << " Supported formats are 'tnl', 'vtk', 'vtu' and 'ng'." << std::endl;
      return false;
   }
}
@@ -89,7 +108,10 @@ bool resolveMeshType( const String& fileName, Functor&& functor )
template< typename ConfigTag,
          typename Device,
          typename Functor >
bool resolveAndLoadMesh( const String& fileName, Functor&& functor )
bool
resolveAndLoadMesh( Functor&& functor,
                    const std::string& fileName,
                    const std::string& fileFormat )
{
   auto wrapper = [&]( auto& reader, auto&& mesh ) -> bool
   {
@@ -104,34 +126,48 @@ bool resolveAndLoadMesh( const String& fileName, Functor&& functor )
      }
      return functor( reader, std::forward<MeshType>(mesh) );
   };
   return resolveMeshType< ConfigTag, Device >( fileName, wrapper );
   return resolveMeshType< ConfigTag, Device >( wrapper, fileName, fileFormat );
}

template< typename MeshConfig,
          typename Device >
bool
loadMesh( const String& fileName,
          Mesh< MeshConfig, Device >& mesh )
loadMesh( Mesh< MeshConfig, Device >& mesh,
          const std::string& fileName,
          const std::string& fileFormat )
{
   std::cout << "Loading a mesh from the file " << fileName << " ..." << std::endl;

   namespace fs = std::experimental::filesystem;
   std::string format = fileFormat;
   if( format == "auto" ) {
      format = fs::path(fileName).extension();
      if( format.length() > 0 )
         // remove dot from the extension
         format = format.substr(1);
   }

   try {
      if( fileName.endsWith( ".tnl" ) )
      if( format == "tnl" )
         mesh.load( fileName );
      else if( fileName.endsWith( ".ng" ) ) {
      else if( format == "ng" ) {
         Readers::NetgenReader reader( fileName );
         reader.loadMesh( mesh );
      }
      else if( fileName.endsWith( ".vtk" ) ) {
      else if( format == "vtk" ) {
         Readers::VTKReader reader( fileName );
         reader.loadMesh( mesh );
      }
      else if( fileName.endsWith( ".vtu" ) ) {
      else if( format == "vtu" ) {
         Readers::VTUReader reader( fileName );
         reader.loadMesh( mesh );
      }
      else {
         std::cerr << "File '" << fileName << "' has unknown extension. Supported extensions are '.tnl', '.vtk', '.vtu' and '.ng'." << std::endl;
         if( fileFormat == "auto" )
            std::cerr << "File '" << fileName << "' has unsupported format (based on the file extension): " << format << ".";
         else
            std::cerr << "Unsupported fileFormat parameter: " << fileFormat << ".";
         std::cerr << " Supported formats are 'tnl', 'vtk', 'vtu' and 'ng'." << std::endl;
         return false;
      }
   }
@@ -145,11 +181,12 @@ loadMesh( const String& fileName,

template< typename MeshConfig >
bool
loadMesh( const String& fileName,
          Mesh< MeshConfig, Devices::Cuda >& mesh )
loadMesh( Mesh< MeshConfig, Devices::Cuda >& mesh,
          const std::string& fileName,
          const std::string& fileFormat )
{
   Mesh< MeshConfig, Devices::Host > hostMesh;
   if( ! loadMesh( fileName, hostMesh ) )
   if( ! loadMesh( hostMesh, fileName, fileFormat ) )
      return false;
   mesh = hostMesh;
   return true;
@@ -161,8 +198,9 @@ template< int Dimension,
          typename Device,
          typename Index >
bool
loadMesh( const String& fileName,
          Grid< Dimension, Real, Device, Index >& grid )
loadMesh( Grid< Dimension, Real, Device, Index >& grid,
          const std::string& fileName,
          const std::string& fileFormat )
{
   std::cout << "Loading a grid from the file " << fileName << "..." << std::endl;
   try {
+3 −2
Original line number Diff line number Diff line
@@ -60,15 +60,16 @@ setup( const Config::ParameterContainer& parameters,
   // Load the mesh from the mesh file
   //
   const String& meshFile = parameters.getParameter< String >( "mesh" );
   const String& meshFileFormat = parameters.getParameter< String >( "mesh-format" );
   this->distributedMesh.setup( parameters, prefix );
   if( Problem::CommunicatorType::isDistributed() ) {
      if( ! Meshes::loadDistributedMesh< typename Problem::CommunicatorType >( meshFile, *this->meshPointer, distributedMesh ) )
      if( ! Meshes::loadDistributedMesh< typename Problem::CommunicatorType >( *this->meshPointer, distributedMesh, meshFile, meshFileFormat ) )
         return false;
      if( ! Meshes::decomposeMesh< Problem >( parameters, prefix, *this->meshPointer, distributedMesh, *problem ) )
         return false;
   }
   else {
      if( ! Meshes::loadMesh( meshFile, *this->meshPointer ) )
      if( ! Meshes::loadMesh( *this->meshPointer, meshFile, meshFileFormat ) )
         return false;
   }

+3 −2
Original line number Diff line number Diff line
@@ -51,15 +51,16 @@ setup( const Config::ParameterContainer& parameters,
   // Load the mesh from the mesh file
   //
   const String& meshFile = parameters.getParameter< String >( "mesh" );
   const String& meshFileFormat = parameters.getParameter< String >( "mesh-format" );
   this->distributedMesh.setup( parameters, prefix );
   if( Problem::CommunicatorType::isDistributed() ) {
      if( ! Meshes::loadDistributedMesh< typename Problem::CommunicatorType >( meshFile, *this->meshPointer, distributedMesh ) )
      if( ! Meshes::loadDistributedMesh< typename Problem::CommunicatorType >( *this->meshPointer, distributedMesh, meshFile, meshFileFormat ) )
         return false;
      if( ! Meshes::decomposeMesh< Problem >( parameters, prefix, *this->meshPointer, distributedMesh, *problem ) )
         return false;
   }
   else {
      if( ! Meshes::loadMesh( meshFile, *this->meshPointer ) )
      if( ! Meshes::loadMesh( *this->meshPointer, meshFile, meshFileFormat ) )
         return false;
   }

Loading