Loading src/Tools/tnl-init.cpp +32 −24 Original line number Diff line number Diff line Loading @@ -13,18 +13,39 @@ #include <TNL/File.h> #include <TNL/Config/parseCommandLine.h> #include <TNL/Functions/TestFunction.h> #include <TNL/Meshes/Grid.h> #include <TNL/Meshes/TypeResolver/resolveMeshType.h> #include <TNL/MPI/ScopedInitializer.h> #include <TNL/MPI/Config.h> using namespace TNL; struct TnlInitConfigTag {}; namespace TNL { namespace Meshes { namespace BuildConfigTags { // Configure real types template<> struct GridRealTag< TnlInitConfigTag, float > { enum { enabled = true }; }; template<> struct GridRealTag< TnlInitConfigTag, double > { enum { enabled = true }; }; template<> struct GridRealTag< TnlInitConfigTag, long double > { enum { enabled = false }; }; // Configure index types template<> struct GridIndexTag< TnlInitConfigTag, short int >{ enum { enabled = false }; }; template<> struct GridIndexTag< TnlInitConfigTag, int >{ enum { enabled = true }; }; template<> struct GridIndexTag< TnlInitConfigTag, long int >{ enum { enabled = true }; }; // Unstructured meshes are disabled, only grids can be on input. } // namespace BuildConfigTags } // namespace Meshes } // namespace TNL void setupConfig( Config::ConfigDescription& config ) { config.addDelimiter( "General settings:" ); config.addEntry< String >( "mesh", "Mesh file. If none is given, a regular rectangular mesh is assumed.", "mesh.vti" ); config.addEntry< String >( "mesh", "Input mesh file.", "mesh.vti" ); config.addEntry< String >( "mesh-function-name", "Name of the mesh function in the VTI files.", "f" ); config.addEntry< String >( "real-type", "Precision of the function evaluation.", "mesh-real-type" ); config.addEntryEnum< String >( "mesh-real-type" ); Loading Loading @@ -59,26 +80,13 @@ int main( int argc, char* argv[] ) if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) return EXIT_FAILURE; String meshFile = parameters.getParameter< String >( "mesh" ); String meshType; try { meshType = getObjectType( meshFile ); } catch(...) { std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl; return EXIT_FAILURE; } std::cout << meshType << " detected in " << meshFile << " file." << std::endl; std::vector< String > parsedMeshType = parseObjectType( meshType ); if( ! parsedMeshType.size() ) { std::cerr << "Unable to parse the mesh type " << meshType << "." << std::endl; return EXIT_FAILURE; } if( ! resolveMeshType( parsedMeshType, parameters ) ) return EXIT_FAILURE; const String meshFileName = parameters.getParameter< String >( "mesh" ); const String meshFileFormat = "auto"; return EXIT_SUCCESS; auto wrapper = [&] ( auto& reader, auto&& mesh ) -> bool { using MeshType = std::decay_t< decltype(mesh) >; return resolveRealType< MeshType >( parameters ); }; return ! Meshes::resolveMeshType< TnlInitConfigTag, Devices::Host >( wrapper, meshFileName, meshFileFormat ); } src/Tools/tnl-init.h +60 −95 Original line number Diff line number Diff line Loading @@ -13,17 +13,16 @@ #include <TNL/MPI/Wrappers.h> #include <TNL/Config/ParameterContainer.h> #include <TNL/Meshes/Grid.h> #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h> #include <TNL/Meshes/Readers/VTIReader.h> #include <TNL/Meshes/Readers/PVTIReader.h> #include <TNL/Meshes/Writers/VTIWriter.h> #include <TNL/Meshes/Writers/PVTIWriter.h> #include <TNL/Functions/TestFunction.h> #include <TNL/Operators/FiniteDifferences.h> #include <TNL/FileName.h> #include <TNL/Functions/MeshFunction.h> #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h> #include <TNL/Meshes/DistributedMeshes/DistributedGridIO.h> #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h> using namespace TNL; template< typename MeshType, Loading @@ -37,27 +36,18 @@ bool renderFunction( const Config::ParameterContainer& parameters ) using DistributedGridType = Meshes::DistributedMeshes::DistributedMesh<MeshType>; DistributedGridType distributedMesh; Pointers::SharedPointer< MeshType > meshPointer; MeshType globalMesh; // TODO: PVTI reader is not implemented yet // if(TNL::MPI::GetSize() > 1) // { // //suppose global mesh loaded from single file // String meshFile = parameters.getParameter< String >( "mesh" ); // std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl; // globalMesh.load( meshFile ); // // // TODO: This should work with no overlaps // distributedMesh.setGlobalGrid(globalMesh); // typename DistributedGridType::SubdomainOverlapsType lowerOverlap, upperOverlap; // SubdomainOverlapsGetter< MeshType >::getOverlaps( &distributedMesh, lowerOverlap, upperOverlap, 1 ); // distributedMesh.setOverlaps( lowerOverlap, upperOverlap ); // distributedMesh.setupGrid(*meshPointer); // } // else { String meshFile = parameters.getParameter< String >( "mesh" ); const String meshFile = parameters.getParameter< String >( "mesh" ); std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl; if( TNL::MPI::GetSize() > 1 ) { Meshes::Readers::PVTIReader reader( meshFile ); reader.loadMesh( distributedMesh ); *meshPointer = distributedMesh.getLocalMesh(); } else { Meshes::Readers::VTIReader reader( meshFile ); reader.loadMesh( *meshPointer ); } Loading Loading @@ -117,13 +107,49 @@ bool renderFunction( const Config::ParameterContainer& parameters ) const std::string meshFunctionName = parameters.getParameter< std::string >( "mesh-function-name" ); // TODO: PVTI writer is not implemented yet // if(TNL::MPI::GetSize() > 1) // { // if( ! Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType> ::save(outputFile, *meshFunction ) ) // return false; if( TNL::MPI::GetSize() > 1 ) { std::ofstream file; if( TNL::MPI::GetRank() == 0 ) file.open( outputFile ); using PVTI = Meshes::Writers::PVTIWriter< typename DistributedGridType::GridType >; PVTI pvti( file ); // TODO: write metadata: step and time pvti.writeImageData( distributedMesh ); // TODO //if( distributedMesh.getGhostLevels() > 0 ) { // pvti.template writePPointData< std::uint8_t >( Meshes::VTK::ghostArrayName() ); // pvti.template writePCellData< std::uint8_t >( Meshes::VTK::ghostArrayName() ); //} if( meshFunction->getEntitiesDimension() == 0 ) pvti.template writePPointData< typename MeshFunctionType::RealType >( meshFunctionName ); else pvti.template writePCellData< typename MeshFunctionType::RealType >( meshFunctionName ); const std::string subfilePath = pvti.addPiece( outputFile, distributedMesh ); // create a .vti file for local data // TODO: write metadata: step and time using Writer = Meshes::Writers::VTIWriter< typename DistributedGridType::GridType >; std::ofstream subfile( subfilePath ); Writer writer( subfile ); // NOTE: passing the local mesh to writeImageData does not work correctly, just like meshFunction->write(...) // (it does not write the correct extent of the subdomain - globalBegin is only in the distributed grid) // NOTE: globalBegin and globalEnd here are without overlaps writer.writeImageData( distributedMesh.getGlobalGrid().getOrigin(), distributedMesh.getGlobalBegin(), distributedMesh.getGlobalBegin() + distributedMesh.getLocalSize(), distributedMesh.getGlobalGrid().getSpaceSteps() ); if( meshFunction->getEntitiesDimension() == 0 ) writer.writePointData( meshFunction->getData(), meshFunctionName ); else writer.writeCellData( meshFunction->getData(), meshFunctionName ); // TODO //if( mesh.getGhostLevels() > 0 ) { // writer.writePointData( mesh.vtkPointGhostTypes(), Meshes::VTK::ghostArrayName() ); // writer.writeCellData( mesh.vtkCellGhostTypes(), Meshes::VTK::ghostArrayName() ); //} // else } else { // TODO: write metadata: step and time meshFunction->write( meshFunctionName, outputFile, "auto" ); Loading Loading @@ -238,64 +264,3 @@ bool resolveRealType( const Config::ParameterContainer& parameters ) // return resolveDerivatives< MeshType, long double >( parameters ); return false; } template< int Dimension, typename RealType, typename IndexType > bool resolveMesh( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting mesh type to " << parsedMeshType[ 0 ] << " ... " << std::endl; if( parsedMeshType[ 0 ] == "Meshes::Grid" ) { typedef Meshes::Grid< Dimension, RealType, Devices::Host, IndexType > MeshType; return resolveRealType< MeshType >( parameters ); } std::cerr << "Unknown mesh type." << std::endl; return false; } template< int Dimension, typename RealType > bool resolveIndexType( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting index type to " << parsedMeshType[ 4 ] << " ... " << std::endl; if( parsedMeshType[ 4 ] == "int" ) return resolveMesh< Dimension, RealType, int >( parsedMeshType, parameters ); if( parsedMeshType[ 4 ] == "long int" ) return resolveMesh< Dimension, RealType, long int >( parsedMeshType, parameters ); return false; } template< int Dimension > bool resolveRealType( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting real type to " << parsedMeshType[ 2 ] << " ... " << std::endl; if( parsedMeshType[ 2 ] == "float" ) return resolveIndexType< Dimension, float >( parsedMeshType, parameters ); if( parsedMeshType[ 2 ] == "double" ) return resolveIndexType< Dimension, double >( parsedMeshType, parameters ); // if( parsedMeshType[ 2 ] == "long double" ) // return resolveIndexType< Dimension, long double >( parsedMeshType, parameters ); return false; } bool resolveMeshType( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting dimensions to " << parsedMeshType[ 1 ] << " ... " << std::endl; int dimensions = atoi( parsedMeshType[ 1 ].getString() ); if( dimensions == 1 ) return resolveRealType< 1 >( parsedMeshType, parameters ); if( dimensions == 2 ) return resolveRealType< 2 >( parsedMeshType, parameters ); if( dimensions == 3 ) return resolveRealType< 3 >( parsedMeshType, parameters ); return false; } Loading
src/Tools/tnl-init.cpp +32 −24 Original line number Diff line number Diff line Loading @@ -13,18 +13,39 @@ #include <TNL/File.h> #include <TNL/Config/parseCommandLine.h> #include <TNL/Functions/TestFunction.h> #include <TNL/Meshes/Grid.h> #include <TNL/Meshes/TypeResolver/resolveMeshType.h> #include <TNL/MPI/ScopedInitializer.h> #include <TNL/MPI/Config.h> using namespace TNL; struct TnlInitConfigTag {}; namespace TNL { namespace Meshes { namespace BuildConfigTags { // Configure real types template<> struct GridRealTag< TnlInitConfigTag, float > { enum { enabled = true }; }; template<> struct GridRealTag< TnlInitConfigTag, double > { enum { enabled = true }; }; template<> struct GridRealTag< TnlInitConfigTag, long double > { enum { enabled = false }; }; // Configure index types template<> struct GridIndexTag< TnlInitConfigTag, short int >{ enum { enabled = false }; }; template<> struct GridIndexTag< TnlInitConfigTag, int >{ enum { enabled = true }; }; template<> struct GridIndexTag< TnlInitConfigTag, long int >{ enum { enabled = true }; }; // Unstructured meshes are disabled, only grids can be on input. } // namespace BuildConfigTags } // namespace Meshes } // namespace TNL void setupConfig( Config::ConfigDescription& config ) { config.addDelimiter( "General settings:" ); config.addEntry< String >( "mesh", "Mesh file. If none is given, a regular rectangular mesh is assumed.", "mesh.vti" ); config.addEntry< String >( "mesh", "Input mesh file.", "mesh.vti" ); config.addEntry< String >( "mesh-function-name", "Name of the mesh function in the VTI files.", "f" ); config.addEntry< String >( "real-type", "Precision of the function evaluation.", "mesh-real-type" ); config.addEntryEnum< String >( "mesh-real-type" ); Loading Loading @@ -59,26 +80,13 @@ int main( int argc, char* argv[] ) if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) return EXIT_FAILURE; String meshFile = parameters.getParameter< String >( "mesh" ); String meshType; try { meshType = getObjectType( meshFile ); } catch(...) { std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl; return EXIT_FAILURE; } std::cout << meshType << " detected in " << meshFile << " file." << std::endl; std::vector< String > parsedMeshType = parseObjectType( meshType ); if( ! parsedMeshType.size() ) { std::cerr << "Unable to parse the mesh type " << meshType << "." << std::endl; return EXIT_FAILURE; } if( ! resolveMeshType( parsedMeshType, parameters ) ) return EXIT_FAILURE; const String meshFileName = parameters.getParameter< String >( "mesh" ); const String meshFileFormat = "auto"; return EXIT_SUCCESS; auto wrapper = [&] ( auto& reader, auto&& mesh ) -> bool { using MeshType = std::decay_t< decltype(mesh) >; return resolveRealType< MeshType >( parameters ); }; return ! Meshes::resolveMeshType< TnlInitConfigTag, Devices::Host >( wrapper, meshFileName, meshFileFormat ); }
src/Tools/tnl-init.h +60 −95 Original line number Diff line number Diff line Loading @@ -13,17 +13,16 @@ #include <TNL/MPI/Wrappers.h> #include <TNL/Config/ParameterContainer.h> #include <TNL/Meshes/Grid.h> #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h> #include <TNL/Meshes/Readers/VTIReader.h> #include <TNL/Meshes/Readers/PVTIReader.h> #include <TNL/Meshes/Writers/VTIWriter.h> #include <TNL/Meshes/Writers/PVTIWriter.h> #include <TNL/Functions/TestFunction.h> #include <TNL/Operators/FiniteDifferences.h> #include <TNL/FileName.h> #include <TNL/Functions/MeshFunction.h> #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h> #include <TNL/Meshes/DistributedMeshes/DistributedGridIO.h> #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h> using namespace TNL; template< typename MeshType, Loading @@ -37,27 +36,18 @@ bool renderFunction( const Config::ParameterContainer& parameters ) using DistributedGridType = Meshes::DistributedMeshes::DistributedMesh<MeshType>; DistributedGridType distributedMesh; Pointers::SharedPointer< MeshType > meshPointer; MeshType globalMesh; // TODO: PVTI reader is not implemented yet // if(TNL::MPI::GetSize() > 1) // { // //suppose global mesh loaded from single file // String meshFile = parameters.getParameter< String >( "mesh" ); // std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl; // globalMesh.load( meshFile ); // // // TODO: This should work with no overlaps // distributedMesh.setGlobalGrid(globalMesh); // typename DistributedGridType::SubdomainOverlapsType lowerOverlap, upperOverlap; // SubdomainOverlapsGetter< MeshType >::getOverlaps( &distributedMesh, lowerOverlap, upperOverlap, 1 ); // distributedMesh.setOverlaps( lowerOverlap, upperOverlap ); // distributedMesh.setupGrid(*meshPointer); // } // else { String meshFile = parameters.getParameter< String >( "mesh" ); const String meshFile = parameters.getParameter< String >( "mesh" ); std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl; if( TNL::MPI::GetSize() > 1 ) { Meshes::Readers::PVTIReader reader( meshFile ); reader.loadMesh( distributedMesh ); *meshPointer = distributedMesh.getLocalMesh(); } else { Meshes::Readers::VTIReader reader( meshFile ); reader.loadMesh( *meshPointer ); } Loading Loading @@ -117,13 +107,49 @@ bool renderFunction( const Config::ParameterContainer& parameters ) const std::string meshFunctionName = parameters.getParameter< std::string >( "mesh-function-name" ); // TODO: PVTI writer is not implemented yet // if(TNL::MPI::GetSize() > 1) // { // if( ! Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType> ::save(outputFile, *meshFunction ) ) // return false; if( TNL::MPI::GetSize() > 1 ) { std::ofstream file; if( TNL::MPI::GetRank() == 0 ) file.open( outputFile ); using PVTI = Meshes::Writers::PVTIWriter< typename DistributedGridType::GridType >; PVTI pvti( file ); // TODO: write metadata: step and time pvti.writeImageData( distributedMesh ); // TODO //if( distributedMesh.getGhostLevels() > 0 ) { // pvti.template writePPointData< std::uint8_t >( Meshes::VTK::ghostArrayName() ); // pvti.template writePCellData< std::uint8_t >( Meshes::VTK::ghostArrayName() ); //} if( meshFunction->getEntitiesDimension() == 0 ) pvti.template writePPointData< typename MeshFunctionType::RealType >( meshFunctionName ); else pvti.template writePCellData< typename MeshFunctionType::RealType >( meshFunctionName ); const std::string subfilePath = pvti.addPiece( outputFile, distributedMesh ); // create a .vti file for local data // TODO: write metadata: step and time using Writer = Meshes::Writers::VTIWriter< typename DistributedGridType::GridType >; std::ofstream subfile( subfilePath ); Writer writer( subfile ); // NOTE: passing the local mesh to writeImageData does not work correctly, just like meshFunction->write(...) // (it does not write the correct extent of the subdomain - globalBegin is only in the distributed grid) // NOTE: globalBegin and globalEnd here are without overlaps writer.writeImageData( distributedMesh.getGlobalGrid().getOrigin(), distributedMesh.getGlobalBegin(), distributedMesh.getGlobalBegin() + distributedMesh.getLocalSize(), distributedMesh.getGlobalGrid().getSpaceSteps() ); if( meshFunction->getEntitiesDimension() == 0 ) writer.writePointData( meshFunction->getData(), meshFunctionName ); else writer.writeCellData( meshFunction->getData(), meshFunctionName ); // TODO //if( mesh.getGhostLevels() > 0 ) { // writer.writePointData( mesh.vtkPointGhostTypes(), Meshes::VTK::ghostArrayName() ); // writer.writeCellData( mesh.vtkCellGhostTypes(), Meshes::VTK::ghostArrayName() ); //} // else } else { // TODO: write metadata: step and time meshFunction->write( meshFunctionName, outputFile, "auto" ); Loading Loading @@ -238,64 +264,3 @@ bool resolveRealType( const Config::ParameterContainer& parameters ) // return resolveDerivatives< MeshType, long double >( parameters ); return false; } template< int Dimension, typename RealType, typename IndexType > bool resolveMesh( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting mesh type to " << parsedMeshType[ 0 ] << " ... " << std::endl; if( parsedMeshType[ 0 ] == "Meshes::Grid" ) { typedef Meshes::Grid< Dimension, RealType, Devices::Host, IndexType > MeshType; return resolveRealType< MeshType >( parameters ); } std::cerr << "Unknown mesh type." << std::endl; return false; } template< int Dimension, typename RealType > bool resolveIndexType( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting index type to " << parsedMeshType[ 4 ] << " ... " << std::endl; if( parsedMeshType[ 4 ] == "int" ) return resolveMesh< Dimension, RealType, int >( parsedMeshType, parameters ); if( parsedMeshType[ 4 ] == "long int" ) return resolveMesh< Dimension, RealType, long int >( parsedMeshType, parameters ); return false; } template< int Dimension > bool resolveRealType( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting real type to " << parsedMeshType[ 2 ] << " ... " << std::endl; if( parsedMeshType[ 2 ] == "float" ) return resolveIndexType< Dimension, float >( parsedMeshType, parameters ); if( parsedMeshType[ 2 ] == "double" ) return resolveIndexType< Dimension, double >( parsedMeshType, parameters ); // if( parsedMeshType[ 2 ] == "long double" ) // return resolveIndexType< Dimension, long double >( parsedMeshType, parameters ); return false; } bool resolveMeshType( const std::vector< String >& parsedMeshType, const Config::ParameterContainer& parameters ) { std::cout << "+ -> Setting dimensions to " << parsedMeshType[ 1 ] << " ... " << std::endl; int dimensions = atoi( parsedMeshType[ 1 ].getString() ); if( dimensions == 1 ) return resolveRealType< 1 >( parsedMeshType, parameters ); if( dimensions == 2 ) return resolveRealType< 2 >( parsedMeshType, parameters ); if( dimensions == 3 ) return resolveRealType< 3 >( parsedMeshType, parameters ); return false; }