diff --git a/src/TNL/Meshes/NDMetaGrid.h b/src/TNL/Meshes/NDMetaGrid.h new file mode 100644 index 0000000000000000000000000000000000000000..3cfe8ac83d7a7072a04e0dad724f076a6efcb6dc --- /dev/null +++ b/src/TNL/Meshes/NDMetaGrid.h @@ -0,0 +1,101 @@ +/*************************************************************************** + NDMetaGrid.h - description + ------------------- + begin : Dec 09, 2021 + copyright : (C) 2021 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +// Implemented by: Jakub Klinkovský + +#pragma once + +#include + +namespace TNL { +namespace Meshes { + +/** + * \brief Minimal class usable as \e Mesh in the \ref VTIWriter. + * + * It does not have a \e Device template argument, because it does not describe + * a data structure - it contains only the information describing the domain of + * the grid (i.e., the metadata of the \e ImageData tag in the VTI file + * format). Note that VTK supports only 1, 2, or 3-dimensional grids. + */ +template< int Dimension, typename Real, typename Index > +class NDMetaGrid +{ +public: + using RealType = Real; + using GlobalIndexType = Index; + using PointType = Containers::StaticVector< Dimension, Real >; + using CoordinatesType = Containers::StaticVector< Dimension, Index >; + + //! \brief Returns the spatial dimension of the grid. + static constexpr int getMeshDimension() + { + return Dimension; + } + + //! \brief Sets the grid dimensions/size. + void setDimensions( const CoordinatesType& dimensions ) + { + this->dimensions = dimensions; + } + + //! \brief Returns the grid dimensions/size. + const CoordinatesType& getDimensions() const + { + return dimensions; + } + + //! \brief Sets the origin of the grid (coordinates of the left bottom front + //! corner). + void setOrigin( const PointType& origin ) + { + this->origin = origin; + } + + //! \brief Returns the origin of the grid (coordinates of the left bottom + //! front corner). + const PointType& getOrigin() const + { + return origin; + } + + //! \brief Sets the domain of the grid (i.e., the origin and + //! proportions/length). Note that space steps are computed using the + //! current grid dimensions. + void setDomain( const PointType& origin, + const PointType& proportions ) + { + this->origin = origin; + this->spaceSteps = proportions / dimensions; + } + + //! \brief Sets the space steps of the grid, i.e. the parameters usually + //! denoted as \e hx, \e hy, \e hz. + void setSpaceSteps( const PointType& spaceSteps ) + { + this->spaceSteps = spaceSteps; + } + + //! \brief Returns the space steps of the grid. + const PointType& getSpaceSteps() const + { + return spaceSteps; + } + +protected: + CoordinatesType dimensions; + + PointType origin; + + PointType spaceSteps; +}; + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/Writers/PVTIWriter.h b/src/TNL/Meshes/Writers/PVTIWriter.h index ce2fe60572dcd84fe86deef3f09d9873d629d10b..4f391b142e972267eb67bad9415121c7e44c0e17 100644 --- a/src/TNL/Meshes/Writers/PVTIWriter.h +++ b/src/TNL/Meshes/Writers/PVTIWriter.h @@ -29,8 +29,6 @@ class PVTIWriter // LOL, VTK does not support signed header types (but the GridTypeResolver maps unsigned types to signed, so we are good) using HeaderType = std::make_unsigned_t< typename Grid::GlobalIndexType >; public: - using MeshRealType = typename Grid::RealType; - using IndexType = typename Grid::GlobalIndexType; PVTIWriter() = delete; diff --git a/src/TNL/Meshes/Writers/PVTIWriter.hpp b/src/TNL/Meshes/Writers/PVTIWriter.hpp index 3922aa2f460c09df4f8ce962d254cb848a48ca52..fd3d9bfeb0f71a5742dd97fe9cdd2b0d87c80f0e 100644 --- a/src/TNL/Meshes/Writers/PVTIWriter.hpp +++ b/src/TNL/Meshes/Writers/PVTIWriter.hpp @@ -67,24 +67,24 @@ PVTIWriter< Grid >::writeImageData( const Grid& globalGrid, std::stringstream extent, origin, spacing; auto dims = globalGrid.getDimensions(); - for( IndexType j = 0; j < dims.getSize(); j++ ) + for( int j = 0; j < dims.getSize(); j++ ) extent << "0 " << dims[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = dims.getSize(); j < 3; j++ ) + for( int j = dims.getSize(); j < 3; j++ ) extent << "0 0 "; auto o = globalGrid.getOrigin(); - for( IndexType j = 0; j < o.getSize(); j++ ) + for( int j = 0; j < o.getSize(); j++ ) origin << std::scientific << o[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = o.getSize(); j < 3; j++ ) + for( int j = o.getSize(); j < 3; j++ ) origin << 0 << " "; auto h = globalGrid.getSpaceSteps(); - for( IndexType j = 0; j < h.getSize(); j++ ) + for( int j = 0; j < h.getSize(); j++ ) spacing << std::scientific << h[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = h.getSize(); j < 3; j++ ) + for( int j = h.getSize(); j < 3; j++ ) spacing << 0 << " "; str << "::addPiece( const String& mainFileName, // prepare the extent std::stringstream extent; - for( IndexType j = 0; j < Grid::getMeshDimension(); j++ ) + for( int j = 0; j < Grid::getMeshDimension(); j++ ) extent << globalBegin[ j ] << " " << globalEnd[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = Grid::getMeshDimension(); j < 3; j++ ) + for( int j = Grid::getMeshDimension(); j < 3; j++ ) extent << "0 0 "; namespace fs = std::experimental::filesystem; diff --git a/src/TNL/Meshes/Writers/PVTUWriter.h b/src/TNL/Meshes/Writers/PVTUWriter.h index 92167c6fd3399f3d4a09f0ccc8957df72b337a6e..6d76781ff7ae68b33c05111186ae1276799b09ae 100644 --- a/src/TNL/Meshes/Writers/PVTUWriter.h +++ b/src/TNL/Meshes/Writers/PVTUWriter.h @@ -25,8 +25,6 @@ class PVTUWriter { using HeaderType = std::uint64_t; public: - using MeshRealType = typename Mesh::RealType; - using IndexType = typename Mesh::GlobalIndexType; PVTUWriter() = delete; diff --git a/src/TNL/Meshes/Writers/VTIWriter.h b/src/TNL/Meshes/Writers/VTIWriter.h index 55bba8611de41b73320c8601b28cfaf740eca76e..8772205718c859a031a16c5f73c1d88020a49888 100644 --- a/src/TNL/Meshes/Writers/VTIWriter.h +++ b/src/TNL/Meshes/Writers/VTIWriter.h @@ -14,7 +14,6 @@ #include -#include #include namespace TNL { @@ -30,8 +29,6 @@ class VTIWriter // LOL, VTK does not support signed header types (but the GridTypeResolver maps unsigned types to signed, so we are good) using HeaderType = std::make_unsigned_t< typename Mesh::GlobalIndexType >; public: - using MeshRealType = typename Mesh::RealType; - using IndexType = typename Mesh::GlobalIndexType; VTIWriter() = delete; @@ -82,10 +79,10 @@ protected: VTK::FileFormat format; // number of points written to the file - IndexType pointsCount = 0; + std::uint64_t pointsCount = 0; // number of cells (in the VTK sense) written to the file - IndexType cellsCount = 0; + std::uint64_t cellsCount = 0; // indicator if the tag is open bool vtkfileOpen = false; diff --git a/src/TNL/Meshes/Writers/VTIWriter.hpp b/src/TNL/Meshes/Writers/VTIWriter.hpp index 72824720558dea8f14e279f5f9d1b023b54fe4ed..0744850d3e1a0760410a1dfad3394ba5cc37cbd2 100644 --- a/src/TNL/Meshes/Writers/VTIWriter.hpp +++ b/src/TNL/Meshes/Writers/VTIWriter.hpp @@ -14,6 +14,7 @@ #include +#include // TNL::product #include #include #include @@ -66,22 +67,22 @@ VTIWriter< Mesh >::writeImageData( const typename Mesh::PointType& gridOrigin, std::stringstream extent, origin, spacing; - for( IndexType j = 0; j < Mesh::getMeshDimension(); j++ ) + for( int j = 0; j < Mesh::getMeshDimension(); j++ ) extent << begin[ j ] << " " << end[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = Mesh::getMeshDimension(); j < 3; j++ ) + for( int j = Mesh::getMeshDimension(); j < 3; j++ ) extent << "0 0 "; - for( IndexType j = 0; j < Mesh::getMeshDimension(); j++ ) + for( int j = 0; j < Mesh::getMeshDimension(); j++ ) origin << std::scientific << gridOrigin[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = Mesh::getMeshDimension(); j < 3; j++ ) + for( int j = Mesh::getMeshDimension(); j < 3; j++ ) origin << 0 << " "; - for( IndexType j = 0; j < Mesh::getMeshDimension(); j++ ) + for( int j = 0; j < Mesh::getMeshDimension(); j++ ) spacing << std::scientific << spaceSteps[ j ] << " "; // VTK knows only 3D grids - for( IndexType j = Mesh::getMeshDimension(); j < 3; j++ ) + for( int j = Mesh::getMeshDimension(); j < 3; j++ ) spacing << 0 << " "; str << "\n"; @@ -125,7 +126,7 @@ VTIWriter< Mesh >::writePointData( const Array& array, { if( ! pieceOpen ) throw std::logic_error("The tag has not been opened yet - call writeEntities first."); - if( array.getSize() / numberOfComponents != pointsCount ) + if( array.getSize() / numberOfComponents != typename Array::IndexType(pointsCount) ) throw std::length_error("Mismatched array size for section: " + std::to_string(array.getSize()) + " (there are " + std::to_string(pointsCount) + " points in the file)"); openPointData(); @@ -141,7 +142,7 @@ VTIWriter< Mesh >::writeCellData( const Array& array, { if( ! pieceOpen ) throw std::logic_error("The tag has not been opened yet - call writeEntities first."); - if( array.getSize() / numberOfComponents != cellsCount ) + if( array.getSize() / numberOfComponents != typename Array::IndexType(cellsCount) ) throw std::length_error("Mismatched array size for section: " + std::to_string(array.getSize()) + " (there are " + std::to_string(cellsCount) + " cells in the file)"); openCellData(); @@ -179,7 +180,7 @@ VTIWriter< Mesh >::writeDataArray( const Array& array, { case VTK::FileFormat::ascii: str.precision( std::numeric_limits< typename Array::ValueType >::digits10 ); - for( IndexType i = 0; i < array.getSize(); i++ ) + for( typename Array::IndexType i = 0; i < array.getSize(); i++ ) // If Array::ValueType is uint8_t, it might be a typedef for unsigned char, which // would be normally printed as char rather than a number. Hence, we use the trick // with unary operator+, see https://stackoverflow.com/a/28414758 diff --git a/src/TNL/Meshes/Writers/VTKWriter.h b/src/TNL/Meshes/Writers/VTKWriter.h index f5cae9efb68fc66abdcb376f4a4d3632b3656eb4..fbff5c6428c46eadce16cecce8901f1a7f003657 100644 --- a/src/TNL/Meshes/Writers/VTKWriter.h +++ b/src/TNL/Meshes/Writers/VTKWriter.h @@ -10,8 +10,6 @@ #pragma once -#include -#include #include namespace TNL { @@ -40,7 +38,6 @@ class VTKWriter using EntityTypesWriter = details::MeshEntityTypesVTKWriter< Mesh, EntityDimension >; public: - using IndexType = typename Mesh::GlobalIndexType; VTKWriter() = delete; @@ -83,10 +80,10 @@ protected: VTK::FileFormat format; // number of cells (in the VTK sense) written to the file - IndexType cellsCount = 0; + std::uint64_t cellsCount = 0; // number of points written to the file - IndexType pointsCount = 0; + std::uint64_t pointsCount = 0; // indicator if the header has been written bool headerWritten = false; diff --git a/src/TNL/Meshes/Writers/VTKWriter.hpp b/src/TNL/Meshes/Writers/VTKWriter.hpp index 06474f1e532339c0337ff862b81539d6919daf43..87b7950813cde6e7a2811962789e06c8c9faa677 100644 --- a/src/TNL/Meshes/Writers/VTKWriter.hpp +++ b/src/TNL/Meshes/Writers/VTKWriter.hpp @@ -14,6 +14,7 @@ #include #include +#include #include namespace TNL { @@ -61,11 +62,11 @@ struct MeshEntitiesVTKWriter using Index = typename Mesh::GlobalIndexType; const Index entitiesCount = mesh.template getEntitiesCount< EntityType >(); - const Index verticesPerEntity = VerticesPerEntity< EntityType >::count;; + const int verticesPerEntity = VerticesPerEntity< EntityType >::count;; for( Index i = 0; i < entitiesCount; i++ ) { const auto& entity = mesh.template getEntity< EntityType >( i ); writeInt( format, str, verticesPerEntity ); - for( Index j = 0; j < verticesPerEntity; j++ ) + for( int j = 0; j < verticesPerEntity; j++ ) writeInt( format, str, entity.template getSubentityIndex< 0 >( j ) ); if( format == VTK::FileFormat::ascii ) str << "\n"; @@ -83,7 +84,7 @@ struct MeshEntitiesVTKWriter< Mesh, 0 > using Index = typename Mesh::GlobalIndexType; const Index entitiesCount = mesh.template getEntitiesCount< EntityType >(); - const Index verticesPerEntity = 1; + const int verticesPerEntity = 1; for( Index i = 0; i < entitiesCount; i++ ) { writeInt( format, str, verticesPerEntity ); @@ -441,8 +442,8 @@ VTKWriter< Mesh >::writeEntities( const Mesh& mesh ) using EntityType = typename Mesh::template EntityType< EntityDimension >; cellsCount = mesh.template getEntitiesCount< EntityType >(); - const IndexType verticesPerEntity = VerticesPerEntity< EntityType >::count; - const IndexType cellsListSize = cellsCount * ( verticesPerEntity + 1 ); + const int verticesPerEntity = VerticesPerEntity< EntityType >::count; + const std::uint64_t cellsListSize = cellsCount * ( verticesPerEntity + 1 ); str << std::endl << "CELLS " << cellsCount << " " << cellsListSize << std::endl; EntitiesWriter< EntityDimension >::exec( mesh, str, format ); @@ -458,7 +459,7 @@ VTKWriter< Mesh >::writePointData( const Array& array, const String& name, const int numberOfComponents ) { - if( array.getSize() / numberOfComponents != pointsCount ) + if( array.getSize() / numberOfComponents != typename Array::IndexType(pointsCount) ) throw std::length_error("Mismatched array size for POINT_DATA section: " + std::to_string(array.getSize()) + " (there are " + std::to_string(pointsCount) + " points in the file)"); @@ -482,7 +483,7 @@ VTKWriter< Mesh >::writeCellData( const Array& array, const String& name, const int numberOfComponents ) { - if( array.getSize() / numberOfComponents != cellsCount ) + if( array.getSize() / numberOfComponents != typename Array::IndexType(cellsCount) ) throw std::length_error("Mismatched array size for CELL_DATA section: " + std::to_string(array.getSize()) + " (there are " + std::to_string(cellsCount) + " cells in the file)"); @@ -529,7 +530,7 @@ VTKWriter< Mesh >::writeDataArray( const Array& array, } using Meshes::Writers::details::writeReal; - for( IndexType i = 0; i < array.getSize(); i++ ) { + for( typename Array::IndexType i = 0; i < array.getSize(); i++ ) { writeReal( format, str, array[i] ); if( format == VTK::FileFormat::ascii ) str << "\n"; @@ -543,13 +544,13 @@ VTKWriter< Mesh >::writePoints( const Mesh& mesh ) using details::writeReal; pointsCount = mesh.template getEntitiesCount< typename Mesh::Vertex >(); str << "POINTS " << pointsCount << " " << getType< typename Mesh::RealType >() << std::endl; - for( IndexType i = 0; i < pointsCount; i++ ) { + for( std::uint64_t i = 0; i < pointsCount; i++ ) { const auto& vertex = mesh.template getEntity< typename Mesh::Vertex >( i ); const auto& point = vertex.getPoint(); - for( IndexType j = 0; j < point.getSize(); j++ ) + for( int j = 0; j < point.getSize(); j++ ) writeReal( format, str, point[ j ] ); // VTK needs zeros for unused dimensions - for( IndexType j = 0; j < 3 - point.getSize(); j++ ) + for( int j = point.getSize(); j < 3; j++ ) writeReal( format, str, (typename Mesh::PointType::RealType) 0 ); if( format == VTK::FileFormat::ascii ) str << "\n"; diff --git a/src/TNL/Meshes/Writers/VTUWriter.h b/src/TNL/Meshes/Writers/VTUWriter.h index 3359566ba874b53397bab88f07fae9bdc05644ad..31a1175b8dfde2225fe3460ea6859a8af8bc90b7 100644 --- a/src/TNL/Meshes/Writers/VTUWriter.h +++ b/src/TNL/Meshes/Writers/VTUWriter.h @@ -12,8 +12,6 @@ #pragma once -#include -#include #include namespace TNL { @@ -38,8 +36,6 @@ class VTUWriter using HeaderType = std::uint64_t; public: - using MeshRealType = typename Mesh::RealType; - using IndexType = typename Mesh::GlobalIndexType; VTUWriter() = delete; @@ -83,10 +79,10 @@ protected: VTK::FileFormat format; // number of points written to the file - IndexType pointsCount = 0; + std::uint64_t pointsCount = 0; // number of cells (in the VTK sense) written to the file - IndexType cellsCount = 0; + std::uint64_t cellsCount = 0; // indicator if the tag is open bool vtkfileOpen = false; diff --git a/src/TNL/Meshes/Writers/VTUWriter.hpp b/src/TNL/Meshes/Writers/VTUWriter.hpp index 058c8427176d00f0b9c67638f8df93d31b3a1e4c..e26b2942aeb44b7315d82effd43d6b48a362bb87 100644 --- a/src/TNL/Meshes/Writers/VTUWriter.hpp +++ b/src/TNL/Meshes/Writers/VTUWriter.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #ifdef HAVE_ZLIB @@ -409,14 +410,15 @@ VTUWriter< Mesh >::writeEntities( const Mesh& mesh ) writePoints( mesh ); // collect all data before writing + using IndexType = typename Mesh::GlobalIndexType; std::vector< IndexType > connectivity, offsets; std::vector< std::uint8_t > types; EntitiesCollector< EntityDimension >::exec( mesh, connectivity, offsets, types ); // create array views that can be passed to writeDataArray - Containers::ArrayView< IndexType > connectivity_v( connectivity.data(), connectivity.size() ); - Containers::ArrayView< IndexType > offsets_v( offsets.data(), offsets.size() ); - Containers::ArrayView< std::uint8_t > types_v( types.data(), types.size() ); + Containers::ArrayView< IndexType, Devices::Host, std::uint64_t > connectivity_v( connectivity.data(), connectivity.size() ); + Containers::ArrayView< IndexType, Devices::Host, std::uint64_t > offsets_v( offsets.data(), offsets.size() ); + Containers::ArrayView< std::uint8_t, Devices::Host, std::uint64_t > types_v( types.data(), types.size() ); // write cells str << "\n"; @@ -435,7 +437,7 @@ VTUWriter< Mesh >::writePointData( const Array& array, { if( ! pieceOpen ) throw std::logic_error("The tag has not been opened yet - call writeEntities first."); - if( array.getSize() / numberOfComponents != pointsCount ) + if( array.getSize() / numberOfComponents != typename Array::IndexType(pointsCount) ) throw std::length_error("Mismatched array size for section: " + std::to_string(array.getSize()) + " (there are " + std::to_string(pointsCount) + " points in the file)"); openPointData(); @@ -451,7 +453,7 @@ VTUWriter< Mesh >::writeCellData( const Array& array, { if( ! pieceOpen ) throw std::logic_error("The tag has not been opened yet - call writeEntities first."); - if( array.getSize() / numberOfComponents != cellsCount ) + if( array.getSize() / numberOfComponents != typename Array::IndexType(cellsCount) ) throw std::length_error("Mismatched array size for section: " + std::to_string(array.getSize()) + " (there are " + std::to_string(cellsCount) + " cells in the file)"); openCellData(); @@ -490,7 +492,7 @@ VTUWriter< Mesh >::writeDataArray( const Array& array, { case VTK::FileFormat::ascii: str.precision( std::numeric_limits< typename Array::ValueType >::digits10 ); - for( IndexType i = 0; i < array.getSize(); i++ ) + for( typename Array::IndexType i = 0; i < array.getSize(); i++ ) // If Array::ValueType is uint8_t, it might be a typedef for unsigned char, which // would be normally printed as char rather than a number. Hence, we use the trick // with unary operator+, see https://stackoverflow.com/a/28414758 @@ -519,16 +521,16 @@ void VTUWriter< Mesh >::writePoints( const Mesh& mesh ) { // copy all coordinates into a contiguous array - using BufferType = Containers::Array< MeshRealType, Devices::Host, IndexType >; + using BufferType = Containers::Array< typename Mesh::RealType, Devices::Host, typename Mesh::GlobalIndexType >; BufferType buffer( 3 * pointsCount ); - IndexType k = 0; - for( IndexType i = 0; i < pointsCount; i++ ) { + typename Mesh::GlobalIndexType k = 0; + for( std::uint64_t i = 0; i < pointsCount; i++ ) { const auto& vertex = mesh.template getEntity< typename Mesh::Vertex >( i ); const auto& point = vertex.getPoint(); - for( IndexType j = 0; j < point.getSize(); j++ ) + for( int j = 0; j < point.getSize(); j++ ) buffer[ k++ ] = point[ j ]; // VTK needs zeros for unused dimensions - for( IndexType j = point.getSize(); j < 3; j++ ) + for( int j = point.getSize(); j < 3; j++ ) buffer[ k++ ] = 0; }