From c3d45c5f99698cbdc81b8c069888095a10d90ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 15 Jan 2022 19:06:12 +0100 Subject: [PATCH 1/3] Added test relying on the Mesh copy-constructor --- src/UnitTests/Meshes/MeshTest.h | 135 +++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 19 deletions(-) diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h index b50e1f023..d27485149 100644 --- a/src/UnitTests/Meshes/MeshTest.h +++ b/src/UnitTests/Meshes/MeshTest.h @@ -152,22 +152,11 @@ void testFinishedMesh( const Mesh& mesh ) testEntities( mesh ); } -TEST( MeshTest, TwoTrianglesTest ) +Mesh< TestTriangleMeshConfig > +createMeshWithTwoTriangles() { - using TriangleMeshEntityType = MeshEntity< TestTriangleMeshConfig, Devices::Host, Topologies::Triangle >; - using EdgeMeshEntityType = typename TriangleMeshEntityType::SubentityTraits< 1 >::SubentityType; - using VertexMeshEntityType = typename TriangleMeshEntityType::SubentityTraits< 0 >::SubentityType; - - static_assert( TriangleMeshEntityType::SubentityTraits< 1 >::storageEnabled, "Testing triangle entity does not store edges as required." ); - static_assert( TriangleMeshEntityType::SubentityTraits< 0 >::storageEnabled, "Testing triangle entity does not store vertices as required." ); - static_assert( EdgeMeshEntityType::SubentityTraits< 0 >::storageEnabled, "Testing edge entity does not store vertices as required." ); - static_assert( EdgeMeshEntityType::SuperentityTraits< 2 >::storageEnabled, "Testing edge entity does not store triangles as required." ); - static_assert( VertexMeshEntityType::SuperentityTraits< 2 >::storageEnabled, "Testing vertex entity does not store triangles as required." ); - static_assert( VertexMeshEntityType::SuperentityTraits< 1 >::storageEnabled, "Testing vertex entity does not store edges as required." ); - - using PointType = typename VertexMeshEntityType::PointType; - static_assert( std::is_same< PointType, Containers::StaticVector< 2, RealType > >::value, - "unexpected PointType" ); + using MeshType = Mesh< TestTriangleMeshConfig >; + using PointType = typename MeshType::PointType; /**** * We set-up the following situation @@ -193,9 +182,8 @@ TEST( MeshTest, TwoTrianglesTest ) point2( 0.0, 1.0 ), point3( 1.0, 1.0 ); - typedef Mesh< TestTriangleMeshConfig > TriangleTestMesh; - TriangleTestMesh mesh; - MeshBuilder< TriangleTestMesh > meshBuilder; + MeshType mesh; + MeshBuilder< MeshType > meshBuilder; meshBuilder.setEntitiesCount( 4, 2 ); @@ -210,12 +198,41 @@ TEST( MeshTest, TwoTrianglesTest ) meshBuilder.getCellSeed( 1 ).setCornerId( 0, 1 ); meshBuilder.getCellSeed( 1 ).setCornerId( 1, 2 ); meshBuilder.getCellSeed( 1 ).setCornerId( 2, 3 ); - ASSERT_TRUE( meshBuilder.build( mesh ) ); + if( ! meshBuilder.build( mesh ) ) + throw std::runtime_error("mesh builder failed"); + + return mesh; +} + +TEST( MeshTest, TwoTrianglesTest ) +{ + using TriangleMeshEntityType = MeshEntity< TestTriangleMeshConfig, Devices::Host, Topologies::Triangle >; + using EdgeMeshEntityType = typename TriangleMeshEntityType::SubentityTraits< 1 >::SubentityType; + using VertexMeshEntityType = typename TriangleMeshEntityType::SubentityTraits< 0 >::SubentityType; + + static_assert( TriangleMeshEntityType::SubentityTraits< 1 >::storageEnabled, "Testing triangle entity does not store edges as required." ); + static_assert( TriangleMeshEntityType::SubentityTraits< 0 >::storageEnabled, "Testing triangle entity does not store vertices as required." ); + static_assert( EdgeMeshEntityType::SubentityTraits< 0 >::storageEnabled, "Testing edge entity does not store vertices as required." ); + static_assert( EdgeMeshEntityType::SuperentityTraits< 2 >::storageEnabled, "Testing edge entity does not store triangles as required." ); + static_assert( VertexMeshEntityType::SuperentityTraits< 2 >::storageEnabled, "Testing vertex entity does not store triangles as required." ); + static_assert( VertexMeshEntityType::SuperentityTraits< 1 >::storageEnabled, "Testing vertex entity does not store edges as required." ); + + using PointType = typename VertexMeshEntityType::PointType; + static_assert( std::is_same< PointType, Containers::StaticVector< 2, RealType > >::value, + "unexpected PointType" ); + + using MeshType = Mesh< TestTriangleMeshConfig >; + const MeshType& mesh = createMeshWithTwoTriangles(); EXPECT_EQ( mesh.getEntitiesCount< 2 >(), 2 ); EXPECT_EQ( mesh.getEntitiesCount< 1 >(), 5 ); EXPECT_EQ( mesh.getEntitiesCount< 0 >(), 4 ); + const PointType point0( 0.0, 0.0 ), + point1( 1.0, 0.0 ), + point2( 0.0, 1.0 ), + point3( 1.0, 1.0 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 0 ).getPoint(), point0 ); EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).getPoint(), point1 ); EXPECT_EQ( mesh.template getEntity< 0 >( 2 ).getPoint(), point2 ); @@ -272,6 +289,86 @@ TEST( MeshTest, TwoTrianglesTest ) testFinishedMesh( mesh ); }; +TEST( MeshTest, TwoTrianglesTest_ReturnedPair ) +{ + using TriangleTestMesh = Mesh< TestTriangleMeshConfig >; + using PointsArray = typename TriangleTestMesh::MeshTraitsType::PointArrayType; + + auto create_mesh_with_two_triangles = [] () + -> std::pair< Mesh< TestTriangleMeshConfig >, typename Mesh< TestTriangleMeshConfig >::MeshTraitsType::PointArrayType > + { + using MeshType = Mesh< TestTriangleMeshConfig >; + const MeshType mesh = createMeshWithTwoTriangles(); + return std::make_pair( mesh, mesh.getPoints() ); + }; + + std::vector< std::pair< TriangleTestMesh, PointsArray > > pairs; + // this invokes the Mesh copy-constructor which is the thing that we originally wanted to test here + pairs.emplace_back( create_mesh_with_two_triangles() ); + + const auto& mesh = pairs.front().first; + const auto& points = pairs.front().second; + + EXPECT_EQ( mesh.getEntitiesCount< 2 >(), 2 ); + EXPECT_EQ( mesh.getEntitiesCount< 1 >(), 5 ); + EXPECT_EQ( mesh.getEntitiesCount< 0 >(), 4 ); + + EXPECT_EQ( mesh.template getEntity< 0 >( 0 ).getPoint(), points[ 0 ] ); + EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).getPoint(), points[ 1 ] ); + EXPECT_EQ( mesh.template getEntity< 0 >( 2 ).getPoint(), points[ 2 ] ); + EXPECT_EQ( mesh.template getEntity< 0 >( 3 ).getPoint(), points[ 3 ] ); + + EXPECT_EQ( mesh.template getEntity< 1 >( 0 ).template getSubentityIndex< 0 >( 0 ), 1 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 0 ).template getSubentityIndex< 0 >( 1 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 1 ).template getSubentityIndex< 0 >( 0 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 1 ).template getSubentityIndex< 0 >( 1 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 2 ).template getSubentityIndex< 0 >( 0 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 2 ).template getSubentityIndex< 0 >( 1 ), 1 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 3 ).template getSubentityIndex< 0 >( 0 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 3 ).template getSubentityIndex< 0 >( 1 ), 3 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 4 ).template getSubentityIndex< 0 >( 0 ), 3 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 4 ).template getSubentityIndex< 0 >( 1 ), 1 ); + + EXPECT_EQ( mesh.template getEntity< 2 >( 0 ).template getSubentityIndex< 0 >( 0 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 0 ).template getSubentityIndex< 0 >( 1 ), 1 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 0 ).template getSubentityIndex< 0 >( 2 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 0 ).template getSubentityIndex< 1 >( 0 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 0 ).template getSubentityIndex< 1 >( 1 ), 1 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 0 ).template getSubentityIndex< 1 >( 2 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 1 ).template getSubentityIndex< 0 >( 0 ), 1 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 1 ).template getSubentityIndex< 0 >( 1 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 1 ).template getSubentityIndex< 0 >( 2 ), 3 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 1 ).template getSubentityIndex< 1 >( 0 ), 3 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 1 ).template getSubentityIndex< 1 >( 1 ), 4 ); + EXPECT_EQ( mesh.template getEntity< 2 >( 1 ).template getSubentityIndex< 1 >( 2 ), 0 ); + + // tests for the superentities layer + ASSERT_EQ( mesh.template getEntity< 0 >( 0 ).template getSuperentitiesCount< 1 >(), 2 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 0 ).template getSuperentityIndex< 1 >( 0 ), 1 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 0 ).template getSuperentityIndex< 1 >( 1 ), 2 ); + + ASSERT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentitiesCount< 1 >(), 3 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentityIndex< 1 >( 0 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentityIndex< 1 >( 1 ), 2 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentityIndex< 1 >( 2 ), 4 ); + + ASSERT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentitiesCount< 2 >(), 2 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentityIndex< 2 >( 0 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 0 >( 1 ).template getSuperentityIndex< 2 >( 1 ), 1 ); + + ASSERT_EQ( mesh.template getEntity< 1 >( 0 ).template getSuperentitiesCount< 2 >(), 2 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 0 ).template getSuperentityIndex< 2 >( 0 ), 0 ); + EXPECT_EQ( mesh.template getEntity< 1 >( 0 ).template getSuperentityIndex< 2 >( 1 ), 1 ); + + // tests for the dual graph layer + ASSERT_EQ( mesh.getCellNeighborsCount( 0 ), 1 ); + ASSERT_EQ( mesh.getCellNeighborsCount( 1 ), 1 ); + EXPECT_EQ( mesh.getCellNeighborIndex( 0, 0 ), 1 ); + EXPECT_EQ( mesh.getCellNeighborIndex( 1, 0 ), 0 ); + + testFinishedMesh( mesh ); +}; + TEST( MeshTest, TetrahedronsTest ) { using TetrahedronMeshEntityType = MeshEntity< TestTetrahedronMeshConfig, Devices::Host, Topologies::Tetrahedron >; -- GitLab From 4173b0f0538fed74c8dae4c39431a12de96dd815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 15 Jan 2022 19:09:44 +0100 Subject: [PATCH 2/3] Simplified copy-constructor of Mesh --- src/TNL/Meshes/Mesh.h | 2 +- src/TNL/Meshes/Mesh.hpp | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/TNL/Meshes/Mesh.h b/src/TNL/Meshes/Mesh.h index dfd693ac5..c8ebd5338 100644 --- a/src/TNL/Meshes/Mesh.h +++ b/src/TNL/Meshes/Mesh.h @@ -87,7 +87,7 @@ class Mesh // constructors Mesh() = default; - Mesh( const Mesh& mesh ); + Mesh( const Mesh& mesh ) = default; Mesh( Mesh&& mesh ) = default; diff --git a/src/TNL/Meshes/Mesh.hpp b/src/TNL/Meshes/Mesh.hpp index 938f9eab6..11da9ef92 100644 --- a/src/TNL/Meshes/Mesh.hpp +++ b/src/TNL/Meshes/Mesh.hpp @@ -36,15 +36,6 @@ init( typename MeshTraitsType::PointArrayType& points, } -template< typename MeshConfig, typename Device > -Mesh< MeshConfig, Device >:: -Mesh( const Mesh& mesh ) - : StorageBaseType( mesh ), - EntityTagsLayerFamily( mesh ) -{ - points = mesh.getPoints(); -} - template< typename MeshConfig, typename Device > template< typename Device_ > Mesh< MeshConfig, Device >:: -- GitLab From 89cda8c24474f2eddedc9486a0b908a49635352f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 15 Jan 2022 19:07:27 +0100 Subject: [PATCH 3/3] Fixed copy-constructor in SparseMatrix It cannot be default, because the internal view would still point to the original matrix. --- src/TNL/Matrices/SparseMatrix.h | 2 +- src/TNL/Matrices/SparseMatrix.hpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/TNL/Matrices/SparseMatrix.h b/src/TNL/Matrices/SparseMatrix.h index f4ed3244b..c8d8eff28 100644 --- a/src/TNL/Matrices/SparseMatrix.h +++ b/src/TNL/Matrices/SparseMatrix.h @@ -181,7 +181,7 @@ class SparseMatrix : public Matrix< Real, Device, Index, RealAllocator > * * \param matrix is the source matrix */ - SparseMatrix( const SparseMatrix& matrix1 ) = default; + explicit SparseMatrix( const SparseMatrix& matrix ); /** * \brief Move constructor. diff --git a/src/TNL/Matrices/SparseMatrix.hpp b/src/TNL/Matrices/SparseMatrix.hpp index 33c9296f2..48269db05 100644 --- a/src/TNL/Matrices/SparseMatrix.hpp +++ b/src/TNL/Matrices/SparseMatrix.hpp @@ -27,6 +27,24 @@ SparseMatrix( const RealAllocatorType& realAllocator, { } +template< typename Real, + typename Device, + typename Index, + typename MatrixType, + template< typename, typename, typename > class Segments, + typename ComputeReal, + typename RealAllocator, + typename IndexAllocator > +SparseMatrix< Real, Device, Index, MatrixType, Segments, ComputeReal, RealAllocator, IndexAllocator >:: +SparseMatrix( const SparseMatrix& matrix ) +: BaseType( matrix ), + columnIndexes( matrix.columnIndexes ), + segments( matrix.segments ), + indexAllocator( matrix.indexAllocator ), + view( this->getView() ) +{ +} + template< typename Real, typename Device, typename Index, -- GitLab