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

Improved parsing of CLI arguments in tnl-grid-to-mesh

parent b740ae77
Loading
Loading
Loading
Loading
+73 −36
Original line number Diff line number Diff line
/***************************************************************************
                          tnl-grid-to-mesh.cpp  -  description
                             -------------------
    begin                : Oct 24, 2017
    copyright            : (C) 2017 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#include <TNL/Config/parseCommandLine.h>
#include <TNL/Meshes/TypeResolver/TypeResolver.h>
#include <TNL/Meshes/Writers/VTKWriter.h>
#include <TNL/Meshes/Writers/VTUWriter.h>
#include <TNL/Meshes/Writers/NetgenWriter.h>

using namespace TNL;

struct GridToMeshConfigTag {};

@@ -26,8 +42,7 @@ template<> struct GridIndexTag< GridToMeshConfigTag, long int >{ enum { enabled
} // namespace Meshes
} // namespace TNL


// FIXME: can't be deduced from GridType
// cannot be deduced from GridType
using LocalIndexType = short int;

template< typename Mesh >
@@ -43,23 +58,23 @@ struct MeshCreator
};

template< typename Real, typename Device, typename Index >
struct MeshCreator< TNL::Meshes::Grid< 1, Real, Device, Index > >
struct MeshCreator< Meshes::Grid< 1, Real, Device, Index > >
{
   using GridType = TNL::Meshes::Grid< 1, Real, Device, Index >;
   using CellTopology = TNL::Meshes::Topologies::Edge;
   using MeshConfig = TNL::Meshes::DefaultConfig< CellTopology,
   using GridType = Meshes::Grid< 1, Real, Device, Index >;
   using CellTopology = Meshes::Topologies::Edge;
   using MeshConfig = Meshes::DefaultConfig< CellTopology,
                                                  CellTopology::dimension,
                                                  typename GridType::RealType,
                                                  typename GridType::GlobalIndexType,
                                                  LocalIndexType >;
   using MeshType = TNL::Meshes::Mesh< MeshConfig >;
   using MeshType = Meshes::Mesh< MeshConfig >;

   static bool run( const GridType& grid, MeshType& mesh )
   {
      const Index numberOfVertices = grid.template getEntitiesCount< typename GridType::Vertex >();
      const Index numberOfCells = grid.template getEntitiesCount< typename GridType::Cell >();

      TNL::Meshes::MeshBuilder< MeshType > meshBuilder;
      Meshes::MeshBuilder< MeshType > meshBuilder;
      meshBuilder.setPointsCount( numberOfVertices );
      meshBuilder.setCellsCount( numberOfCells );

@@ -80,23 +95,23 @@ struct MeshCreator< TNL::Meshes::Grid< 1, Real, Device, Index > >
};

template< typename Real, typename Device, typename Index >
struct MeshCreator< TNL::Meshes::Grid< 2, Real, Device, Index > >
struct MeshCreator< Meshes::Grid< 2, Real, Device, Index > >
{
   using GridType = TNL::Meshes::Grid< 2, Real, Device, Index >;
   using CellTopology = TNL::Meshes::Topologies::Quadrilateral;
   using MeshConfig = TNL::Meshes::DefaultConfig< CellTopology,
   using GridType = Meshes::Grid< 2, Real, Device, Index >;
   using CellTopology = Meshes::Topologies::Quadrilateral;
   using MeshConfig = Meshes::DefaultConfig< CellTopology,
                                                  CellTopology::dimension,
                                                  typename GridType::RealType,
                                                  typename GridType::GlobalIndexType,
                                                  LocalIndexType >;
   using MeshType = TNL::Meshes::Mesh< MeshConfig >;
   using MeshType = Meshes::Mesh< MeshConfig >;

   static bool run( const GridType& grid, MeshType& mesh )
   {
      const Index numberOfVertices = grid.template getEntitiesCount< typename GridType::Vertex >();
      const Index numberOfCells = grid.template getEntitiesCount< typename GridType::Cell >();

      TNL::Meshes::MeshBuilder< MeshType > meshBuilder;
      Meshes::MeshBuilder< MeshType > meshBuilder;
      meshBuilder.setPointsCount( numberOfVertices );
      meshBuilder.setCellsCount( numberOfCells );

@@ -119,23 +134,23 @@ struct MeshCreator< TNL::Meshes::Grid< 2, Real, Device, Index > >
};

template< typename Real, typename Device, typename Index >
struct MeshCreator< TNL::Meshes::Grid< 3, Real, Device, Index > >
struct MeshCreator< Meshes::Grid< 3, Real, Device, Index > >
{
   using GridType = TNL::Meshes::Grid< 3, Real, Device, Index >;
   using CellTopology = TNL::Meshes::Topologies::Hexahedron;
   using MeshConfig = TNL::Meshes::DefaultConfig< CellTopology,
   using GridType = Meshes::Grid< 3, Real, Device, Index >;
   using CellTopology = Meshes::Topologies::Hexahedron;
   using MeshConfig = Meshes::DefaultConfig< CellTopology,
                                                  CellTopology::dimension,
                                                  typename GridType::RealType,
                                                  typename GridType::GlobalIndexType,
                                                  LocalIndexType >;
   using MeshType = TNL::Meshes::Mesh< MeshConfig >;
   using MeshType = Meshes::Mesh< MeshConfig >;

   static bool run( const GridType& grid, MeshType& mesh )
   {
      const Index numberOfVertices = grid.template getEntitiesCount< typename GridType::Vertex >();
      const Index numberOfCells = grid.template getEntitiesCount< typename GridType::Cell >();

      TNL::Meshes::MeshBuilder< MeshType > meshBuilder;
      Meshes::MeshBuilder< MeshType > meshBuilder;
      meshBuilder.setPointsCount( numberOfVertices );
      meshBuilder.setCellsCount( numberOfCells );

@@ -162,7 +177,7 @@ struct MeshCreator< TNL::Meshes::Grid< 3, Real, Device, Index > >
};

template< typename Grid >
bool convertGrid( Grid& grid, const TNL::String& fileName, const TNL::String& outputFileName )
bool convertGrid( Grid& grid, const String& fileName, const String& outputFileName, const String& outputFormat )
{
   using MeshCreator = MeshCreator< Grid >;
   using Mesh = typename MeshCreator::MeshType;
@@ -175,35 +190,57 @@ bool convertGrid( Grid& grid, const TNL::String& fileName, const TNL::String& ou
      return false;
   }

   try
   {
      mesh.save( outputFileName );
   if( outputFormat == "vtk" ) {
      using VTKWriter = Meshes::Writers::VTKWriter< Mesh >;
      std::ofstream file( outputFileName.getString() );
      VTKWriter writer( file );
      writer.template writeEntities< Mesh::getMeshDimension() >( mesh );
   }
   catch(...)
   {
      std::cerr << "Failed to save the mesh to file '" << outputFileName << "'." << std::endl;
      return false;
   else if( outputFormat == "vtu" ) {
      using VTKWriter = Meshes::Writers::VTUWriter< Mesh >;
      std::ofstream file( outputFileName.getString() );
      VTKWriter writer( file );
      writer.template writeEntities< Mesh::getMeshDimension() >( mesh );
   }
   else if( outputFormat == "netgen" ) {
      using NetgenWriter = Meshes::Writers::NetgenWriter< Mesh >;
      std::fstream file( outputFileName.getString() );
      NetgenWriter::writeMesh( mesh, file );
   }

   return true;
}

void configSetup( Config::ConfigDescription& config )
{
   config.addDelimiter( "General settings:" );
   config.addRequiredEntry< String >( "input-file", "Input file with the mesh." );
   config.addRequiredEntry< String >( "output-file", "Output mesh file in TNL or VTK format." );
   config.addEntry< String >( "output-file-format", "Output mesh file format." );
   config.addEntryEnum( "tnl" );
   config.addEntryEnum( "vtk" );
   config.addEntryEnum( "vtu" );
   config.addEntryEnum( "netgen" );
}

int
main( int argc, char* argv[] )
{
   using namespace TNL;
   Config::ParameterContainer parameters;
   Config::ConfigDescription conf_desc;

   configSetup( conf_desc );

   if( argc < 3 ) {
      std::cerr << "Usage: " << argv[ 0 ] << " input-grid.tnl output-mesh.tnl" << std::endl;
   if( ! parseCommandLine( argc, argv, conf_desc, parameters ) )
      return EXIT_FAILURE;
   }

   String fileName( argv[ 1 ] );
   String outputFileName( argv[ 2 ] );
   const String inputFileName = parameters.getParameter< String >( "input-file" );
   const String outputFileName = parameters.getParameter< String >( "output-file" );
   const String outputFileFormat = parameters.getParameter< String >( "output-file-format" );

   auto wrapper = [&] ( const auto& reader, auto&& grid )
   {
      return convertGrid( grid, fileName, outputFileName );
      return convertGrid( grid, inputFileName, outputFileName, outputFileFormat );
   };
   return ! Meshes::resolveMeshType< GridToMeshConfigTag, Devices::Host >( wrapper, fileName );
   return ! Meshes::resolveMeshType< GridToMeshConfigTag, Devices::Host >( wrapper, inputFileName );
}