diff --git a/src/UnitTests/CMakeLists.txt b/src/UnitTests/CMakeLists.txt index 883f2e8a32cf8509390d7fcbd5315f4624ef51c1..fb90e6ee3d41fe06dd4e0724b2356a7f046bddad 100644 --- a/src/UnitTests/CMakeLists.txt +++ b/src/UnitTests/CMakeLists.txt @@ -2,6 +2,7 @@ if( WITH_TESTS STREQUAL "yes" ) ADD_SUBDIRECTORY( Containers ) ADD_SUBDIRECTORY( Matrices ) +ADD_SUBDIRECTORY( Meshes ) ADD_EXECUTABLE( UniquePointerTest UniquePointerTest.cpp ) TARGET_COMPILE_OPTIONS( UniquePointerTest PRIVATE ${CXX_TESTS_FLAGS} ) diff --git a/src/UnitTests/Meshes/CMakeLists.txt b/src/UnitTests/Meshes/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..cdebbf56bb30fb36a969516029cda37fd06e2da8 --- /dev/null +++ b/src/UnitTests/Meshes/CMakeLists.txt @@ -0,0 +1,13 @@ +ADD_EXECUTABLE( MeshTest${mpiExt}${debugExt} ${headers} MeshTest.cpp ) +SET_TARGET_PROPERTIES( MeshTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" ) +TARGET_LINK_LIBRARIES( MeshTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES} + tnl${mpiExt}${debugExt}-${tnlVersion} ) + +ADD_EXECUTABLE( MeshEntityTest${mpiExt}${debugExt} ${headers} MeshEntityTest.cpp ) +SET_TARGET_PROPERTIES( MeshEntityTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" ) +TARGET_LINK_LIBRARIES( MeshEntityTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES} + tnl${mpiExt}${debugExt}-${tnlVersion} ) + + +ADD_TEST( MeshTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/MeshTest${mpiExt}${debugExt} ) +ADD_TEST( MeshEntityTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/MeshEntityTest${mpiExt}${debugExt} ) diff --git a/src/UnitTests/Meshes/MeshEntityTest.cpp b/src/UnitTests/Meshes/MeshEntityTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39fb5791acc7a225672f2d883c1b7cd22cbff52d --- /dev/null +++ b/src/UnitTests/Meshes/MeshEntityTest.cpp @@ -0,0 +1,15 @@ +#ifdef HAVE_GTEST +#include "gtest/gtest.h" +#endif + +#include "MeshEntityTest.h" + +int main( int argc, char* argv[] ) +{ +#ifdef HAVE_GTEST + ::testing::InitGoogleTest( &argc, argv ); + return RUN_ALL_TESTS(); +#else + return EXIT_FAILURE; +#endif +} diff --git a/src/UnitTests/Meshes/MeshEntityTest.h b/src/UnitTests/Meshes/MeshEntityTest.h new file mode 100644 index 0000000000000000000000000000000000000000..939f8037a42768ac8faaa0abf1733a2e4cbd23f4 --- /dev/null +++ b/src/UnitTests/Meshes/MeshEntityTest.h @@ -0,0 +1,449 @@ +#pragma once + +#ifdef HAVE_GTEST +#include <TNL/Meshes/MeshEntity.h> +#include <TNL/Meshes/MeshConfigBase.h> +#include <TNL/Meshes/Topologies/MeshVertexTopology.h> +#include <TNL/Meshes/Topologies/MeshEdgeTopology.h> +#include <TNL/Meshes/Topologies/MeshTriangleTopology.h> +#include <TNL/Meshes/Topologies/MeshTetrahedronTopology.h> + +using namespace TNL; +using namespace TNL::Meshes; + +//typedef MeshConfigBase< MeshTriangleTopology, 2, double, int, int, void > TestTriangleEntityTopology; +typedef MeshConfigBase< MeshEdgeTopology, 2, double, int, int, void > TestEdgeEntityTopology; +typedef MeshConfigBase< MeshVertexTopology, 2, double, int, int, void > TestVertexEntityTopology; + +class TestTriangleMeshConfig : public MeshConfigBase< MeshTriangleTopology > +{ + public: + + template< typename MeshEntity > + static constexpr bool subentityStorage( MeshEntity entity, int subentityDimensions ) + { + return true; + } + + template< typename MeshEntity > + static constexpr bool superentityStorage( MeshEntity entity, int superentityDimensions ) + { + return true; + } +}; + +class TestTetrahedronMeshConfig : public MeshConfigBase< MeshTetrahedronTopology > +{ + public: + + template< typename MeshEntity > + static constexpr bool subentityStorage( MeshEntity entity, int subentityDimensions ) + { + return true; + } + + template< typename MeshEntity > + static constexpr bool superentityStorage( MeshEntity entity, int superentityDimensions ) + { + return true; + } +}; + +using RealType = double; +using Device = Devices::Host; +using IndexType = int; + +TEST( MeshEntityTest, VertexMeshEntityTest ) +{ + typedef MeshConfigBase< MeshEdgeTopology, 2, RealType, IndexType, IndexType, void > TestEntityTopology; + typedef MeshEntity< TestEntityTopology, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + + ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 2, RealType >::getType() ) ); + VertexMeshEntityType vertexEntity; + PointType point; + + point.x() = 1.0; + point.y() = 2.0; + vertexEntity.setPoint( point ); + ASSERT_TRUE( vertexEntity.getPoint() == point ); +} + +TEST( MeshEntityTest, EdgeMeshEntityTest ) +{ + typedef MeshEntity< TestEdgeEntityTopology, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestEdgeEntityTopology, MeshVertexTopology > VertexMeshEntityType; + + typedef typename VertexMeshEntityType::PointType PointType; + ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 2, RealType >::getType() ) ); + + /**** + * + * Here we test the following simple example: + * + + point2 + |\ + | \ + | \ + | \ + + .... + edge1 edge0 + .... + + + | \ + | \ + --------------------- + point0 edge2 point1 + + */ + + PointType point0( 0.0, 0.0 ), + point1( 1.0, 0.0 ), + point2( 0.0, 1.0 ); + + Containers::StaticArray< 3, VertexMeshEntityType > vertexEntities; + vertexEntities[ 0 ].setPoint( point0 ); + vertexEntities[ 1 ].setPoint( point1 ); + vertexEntities[ 2 ].setPoint( point2 ); + + ASSERT_TRUE( vertexEntities[ 0 ].getPoint() == point0 ); + ASSERT_TRUE( vertexEntities[ 1 ].getPoint() == point1 ); + ASSERT_TRUE( vertexEntities[ 2 ].getPoint() == point2 ); + + Containers::StaticArray< 3, EdgeMeshEntityType > edgeEntities; + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 0, 0 ); + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 1, 1 ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 0, 1 ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 1, 2 ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 0, 2 ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 1, 0 ); + edgeEntities[ 0 ].setId( 0 ); + edgeEntities[ 1 ].setId( 1 ); + edgeEntities[ 2 ].setId( 2 ); + + ASSERT_TRUE( vertexEntities[ edgeEntities[ 0 ].getVertexIndex( 0 ) ].getPoint() == point0 ); + ASSERT_TRUE( vertexEntities[ edgeEntities[ 0 ].getVertexIndex( 1 ) ].getPoint() == point1 ); + ASSERT_TRUE( vertexEntities[ edgeEntities[ 1 ].getVertexIndex( 0 ) ].getPoint() == point1 ); + ASSERT_TRUE( vertexEntities[ edgeEntities[ 1 ].getVertexIndex( 1 ) ].getPoint() == point2 ); + ASSERT_TRUE( vertexEntities[ edgeEntities[ 2 ].getVertexIndex( 0 ) ].getPoint() == point2 ); + ASSERT_TRUE( vertexEntities[ edgeEntities[ 2 ].getVertexIndex( 1 ) ].getPoint() == point0 ); +} + +TEST( MeshEntityTest, TriangleMeshEntityTest ) +{ + typedef MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology > TriangleMeshEntityType; + + static_assert( TriangleMeshEntityType::SubentityTraits< 1 >::storageEnabled, "Testing triangular mesh does not store edges as required." ); + static_assert( TriangleMeshEntityType::SubentityTraits< 0 >::storageEnabled, "" ); + typedef MeshEntity< TestEdgeEntityTopology, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestVertexEntityTopology, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 2, RealType >::getType() ) ); + + /**** + * We set-up the same situation as in the test above + */ + PointType point0( 0.0, 0.0 ), + point1( 1.0, 0.0 ), + point2( 0.0, 1.0 ); + + Containers::StaticArray< 3, VertexMeshEntityType > vertexEntities; + vertexEntities[ 0 ].setPoint( point0 ); + vertexEntities[ 1 ].setPoint( point1 ); + vertexEntities[ 2 ].setPoint( point2 ); + + ASSERT_TRUE( vertexEntities[ 0 ].getPoint() == point0 ); + ASSERT_TRUE( vertexEntities[ 1 ].getPoint() == point1 ); + ASSERT_TRUE( vertexEntities[ 2 ].getPoint() == point2 ); + + Containers::StaticArray< 3, EdgeMeshEntityType > edgeEntities; + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 0, 0 >::index ); + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 0, 1 >::index ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 1, 0 >::index ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 1, 1 >::index ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 2, 0 >::index ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 2, 1 >::index ); + + ASSERT_TRUE( edgeEntities[ 0 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 0, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 0 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 0, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 1 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 1, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 1 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 1, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 2 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 2, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 2 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTriangleTopology, MeshEdgeTopology, 2, 1 >::index ) ); + + TriangleMeshEntityType triangleEntity; + + triangleEntity.template setSubentityIndex< 0 >( 0 , 0 ); + triangleEntity.template setSubentityIndex< 0 >( 1 , 1 ); + triangleEntity.template setSubentityIndex< 0 >( 2 , 2 ); + + ASSERT_TRUE( triangleEntity.template getSubentityIndex< 0 >( 0 ) == 0 ); + ASSERT_TRUE( triangleEntity.template getSubentityIndex< 0 >( 1 ) == 1 ); + ASSERT_TRUE( triangleEntity.template getSubentityIndex< 0 >( 2 ) == 2 ); + + triangleEntity.template setSubentityIndex< 1 >( 0 , 0 ); + triangleEntity.template setSubentityIndex< 1 >( 1 , 1 ); + triangleEntity.template setSubentityIndex< 1 >( 2 , 2 ); + + ASSERT_TRUE( triangleEntity.template getSubentityIndex< 1 >( 0 ) == 0 ); + ASSERT_TRUE( triangleEntity.template getSubentityIndex< 1 >( 1 ) == 1 ); + ASSERT_TRUE( triangleEntity.template getSubentityIndex< 1 >( 2 ) == 2 ); +} + +TEST( MeshEntityTest, TetragedronMeshEntityTest ) +{ + //typedef MeshConfigBase< MeshTetrahedronTopology, 3, RealType, IndexType, IndexType, void > TestTetrahedronEntityTopology; + typedef MeshConfigBase< MeshTriangleTopology, 3, RealType, IndexType, IndexType, void > TestTriangleEntityTopology; + typedef MeshConfigBase< MeshEdgeTopology, 3, RealType, IndexType, IndexType, void > TestEdgeEntityTopology; + typedef MeshConfigBase< MeshVertexTopology, 3, RealType, IndexType, IndexType, void > TestVertexEntityTopology; + + typedef MeshEntity< TestTetrahedronMeshConfig, MeshTetrahedronTopology > TetrahedronMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology > TriangleMeshEntityType; + typedef MeshEntity< TestEdgeEntityTopology, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestVertexEntityTopology, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 3, RealType >::getType() ) ); + + /**** + * We set-up similar situation as above but with + * tetrahedron. + */ + PointType point0( 0.0, 0.0, 0.0), + point1( 1.0, 0.0, 0.0 ), + point2( 0.0, 1.0, 0.0 ), + point3( 0.0, 0.0, 1.0 ); + + Containers::StaticArray< MeshSubtopology< MeshTetrahedronTopology, 0 >::count, + VertexMeshEntityType > vertexEntities; + + vertexEntities[ 0 ].setPoint( point0 ); + vertexEntities[ 1 ].setPoint( point1 ); + vertexEntities[ 2 ].setPoint( point2 ); + vertexEntities[ 3 ].setPoint( point3 ); + + ASSERT_TRUE( vertexEntities[ 0 ].getPoint() == point0 ); + ASSERT_TRUE( vertexEntities[ 1 ].getPoint() == point1 ); + ASSERT_TRUE( vertexEntities[ 2 ].getPoint() == point2 ); + ASSERT_TRUE( vertexEntities[ 3 ].getPoint() == point3 ); + + Containers::StaticArray< MeshSubtopology< MeshTetrahedronTopology, 1 >::count, + EdgeMeshEntityType > edgeEntities; + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 0, 0 >::index ); + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 0, 1 >::index ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 1, 0 >::index ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 1, 1 >::index ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 2, 0 >::index ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 2, 1 >::index ); + edgeEntities[ 3 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 3, 0 >::index ); + edgeEntities[ 3 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 3, 1 >::index ); + edgeEntities[ 4 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 4, 0 >::index ); + edgeEntities[ 4 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 4, 1 >::index ); + edgeEntities[ 5 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 5, 0 >::index ); + edgeEntities[ 5 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 5, 1 >::index ); + + ASSERT_TRUE( edgeEntities[ 0 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 0, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 0 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 0, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 1 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 1, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 1 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 1, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 2 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 2, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 2 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 2, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 3 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 3, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 3 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 3, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 4 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 4, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 4 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 4, 1 >::index ) ); + ASSERT_TRUE( edgeEntities[ 5 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 5, 0 >::index ) ); + ASSERT_TRUE( edgeEntities[ 5 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshEdgeTopology, 5, 1 >::index ) ); + + Containers::StaticArray< MeshSubtopology< MeshTetrahedronTopology, 2 >::count, + TriangleMeshEntityType > triangleEntities; + triangleEntities[ 0 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 0, 0 >::index ); + triangleEntities[ 0 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 0, 1 >::index ); + triangleEntities[ 0 ].template setSubentityIndex< 0 >( 2, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 0, 2 >::index ); + triangleEntities[ 1 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 1, 0 >::index ); + triangleEntities[ 1 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 1, 1 >::index ); + triangleEntities[ 1 ].template setSubentityIndex< 0 >( 2, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 1, 2 >::index ); + triangleEntities[ 2 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 2, 0 >::index ); + triangleEntities[ 2 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 2, 1 >::index ); + triangleEntities[ 2 ].template setSubentityIndex< 0 >( 2, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 2, 2 >::index ); + triangleEntities[ 3 ].template setSubentityIndex< 0 >( 0, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 3, 0 >::index ); + triangleEntities[ 3 ].template setSubentityIndex< 0 >( 1, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 3, 1 >::index ); + triangleEntities[ 3 ].template setSubentityIndex< 0 >( 2, tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 3, 2 >::index ); + + ASSERT_TRUE( triangleEntities[ 0 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 0, 0 >::index ) ); + ASSERT_TRUE( triangleEntities[ 0 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 0, 1 >::index ) ); + ASSERT_TRUE( triangleEntities[ 0 ].getVertexIndex( 2 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 0, 2 >::index ) ); + ASSERT_TRUE( triangleEntities[ 1 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 1, 0 >::index ) ); + ASSERT_TRUE( triangleEntities[ 1 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 1, 1 >::index ) ); + ASSERT_TRUE( triangleEntities[ 1 ].getVertexIndex( 2 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 1, 2 >::index ) ); + ASSERT_TRUE( triangleEntities[ 2 ].getVertexIndex( 0 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 2, 0 >::index ) ); + ASSERT_TRUE( triangleEntities[ 2 ].getVertexIndex( 1 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 2, 1 >::index ) ); + ASSERT_TRUE( triangleEntities[ 2 ].getVertexIndex( 2 ) == ( tnlSubentityVertex< MeshTetrahedronTopology, MeshTriangleTopology, 2, 2 >::index ) ); + + TetrahedronMeshEntityType tetrahedronEntity; + tetrahedronEntity.template setSubentityIndex< 0 >( 0, 0 ); + tetrahedronEntity.template setSubentityIndex< 0 >( 1, 1 ); + tetrahedronEntity.template setSubentityIndex< 0 >( 2, 2 ); + tetrahedronEntity.template setSubentityIndex< 0 >( 3, 3 ); + + ASSERT_TRUE( tetrahedronEntity.getVertexIndex( 0 ) == 0 ); + ASSERT_TRUE( tetrahedronEntity.getVertexIndex( 1 ) == 1 ); + ASSERT_TRUE( tetrahedronEntity.getVertexIndex( 2 ) == 2 ); + ASSERT_TRUE( tetrahedronEntity.getVertexIndex( 3 ) == 3 ); + + tetrahedronEntity.template setSubentityIndex< 2 >( 0, 0 ); + tetrahedronEntity.template setSubentityIndex< 2 >( 1, 1 ); + tetrahedronEntity.template setSubentityIndex< 2 >( 2, 2 ); + tetrahedronEntity.template setSubentityIndex< 2 >( 3, 3 ); + + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 2 >( 0 ) == 0 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 2 >( 1 ) == 1 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 2 >( 2 ) == 2 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 2 >( 3 ) == 3 ); + + tetrahedronEntity.template setSubentityIndex< 1 >( 0, 0 ); + tetrahedronEntity.template setSubentityIndex< 1 >( 1, 1 ); + tetrahedronEntity.template setSubentityIndex< 1 >( 2, 2 ); + tetrahedronEntity.template setSubentityIndex< 1 >( 3, 3 ); + tetrahedronEntity.template setSubentityIndex< 1 >( 4, 4 ); + tetrahedronEntity.template setSubentityIndex< 1 >( 5, 5 ); + + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 1 >( 0 ) == 0 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 1 >( 1 ) == 1 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 1 >( 2 ) == 2 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 1 >( 3 ) == 3 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 1 >( 4 ) == 4 ); + ASSERT_TRUE( tetrahedronEntity.template getSubentityIndex< 1 >( 5 ) == 5 ); +} + +TEST( MeshEntityTest, TwoTrianglesMeshEntityTest ) +{ + typedef MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology > TriangleMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 2, RealType >::getType() ) ); + + /**** + * We set-up the following situation + point2 edge3 point3 + |\-------------------| + | \ | + | \ triangle1 | + | \ | + + .... + edge1 edge0 edge4 + .... + + + | triangle0 \ | + | \ | + ---------------------| + point0 edge2 point1 + */ + + PointType point0( 0.0, 0.0 ), + point1( 1.0, 0.0 ), + point2( 0.0, 1.0 ), + point3( 1.0, 1.0 ); + + Containers::StaticArray< 4, VertexMeshEntityType > vertexEntities; + vertexEntities[ 0 ].setPoint( point0 ); + vertexEntities[ 1 ].setPoint( point1 ); + vertexEntities[ 2 ].setPoint( point2 ); + vertexEntities[ 3 ].setPoint( point3 ); + + ASSERT_TRUE( vertexEntities[ 0 ].getPoint() == point0 ); + ASSERT_TRUE( vertexEntities[ 1 ].getPoint() == point1 ); + ASSERT_TRUE( vertexEntities[ 2 ].getPoint() == point2 ); + ASSERT_TRUE( vertexEntities[ 3 ].getPoint() == point3 ); + + Containers::StaticArray< 5, EdgeMeshEntityType > edgeEntities; + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 0, 1 ); + edgeEntities[ 0 ].template setSubentityIndex< 0 >( 1, 2 ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 0, 2 ); + edgeEntities[ 1 ].template setSubentityIndex< 0 >( 1, 0 ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 0, 0 ); + edgeEntities[ 2 ].template setSubentityIndex< 0 >( 1, 1 ); + edgeEntities[ 3 ].template setSubentityIndex< 0 >( 0, 2 ); + edgeEntities[ 3 ].template setSubentityIndex< 0 >( 1, 3 ); + edgeEntities[ 4 ].template setSubentityIndex< 0 >( 0, 3 ); + edgeEntities[ 4 ].template setSubentityIndex< 0 >( 1, 1 ); + + ASSERT_TRUE( edgeEntities[ 0 ].getVertexIndex( 0 ) == 1 ); + ASSERT_TRUE( edgeEntities[ 0 ].getVertexIndex( 1 ) == 2 ); + ASSERT_TRUE( edgeEntities[ 1 ].getVertexIndex( 0 ) == 2 ); + ASSERT_TRUE( edgeEntities[ 1 ].getVertexIndex( 1 ) == 0 ); + ASSERT_TRUE( edgeEntities[ 2 ].getVertexIndex( 0 ) == 0 ); + ASSERT_TRUE( edgeEntities[ 2 ].getVertexIndex( 1 ) == 1 ); + ASSERT_TRUE( edgeEntities[ 3 ].getVertexIndex( 0 ) == 2 ); + ASSERT_TRUE( edgeEntities[ 3 ].getVertexIndex( 1 ) == 3 ); + ASSERT_TRUE( edgeEntities[ 4 ].getVertexIndex( 0 ) == 3 ); + ASSERT_TRUE( edgeEntities[ 4 ].getVertexIndex( 1 ) == 1 ); + + Containers::StaticArray< 2, TriangleMeshEntityType > triangleEntities; + + triangleEntities[ 0 ].template setSubentityIndex< 0 >( 0 , 0 ); + triangleEntities[ 0 ].template setSubentityIndex< 0 >( 1 , 1 ); + triangleEntities[ 0 ].template setSubentityIndex< 0 >( 2 , 2 ); + triangleEntities[ 0 ].template setSubentityIndex< 1 >( 0 , 0 ); + triangleEntities[ 0 ].template setSubentityIndex< 1 >( 1 , 1 ); + triangleEntities[ 0 ].template setSubentityIndex< 1 >( 2 , 2 ); + triangleEntities[ 1 ].template setSubentityIndex< 0 >( 0 , 0 ); + triangleEntities[ 1 ].template setSubentityIndex< 0 >( 1 , 2 ); + triangleEntities[ 1 ].template setSubentityIndex< 0 >( 2 , 3 ); + triangleEntities[ 1 ].template setSubentityIndex< 1 >( 0 , 0 ); + triangleEntities[ 1 ].template setSubentityIndex< 1 >( 1 , 3 ); + triangleEntities[ 1 ].template setSubentityIndex< 1 >( 2 , 4 ); + + ASSERT_TRUE( triangleEntities[ 0 ].template getSubentityIndex< 0 >( 0 ) == 0 ); + ASSERT_TRUE( triangleEntities[ 0 ].template getSubentityIndex< 0 >( 1 ) == 1 ); + ASSERT_TRUE( triangleEntities[ 0 ].template getSubentityIndex< 0 >( 2 ) == 2 ); + ASSERT_TRUE( triangleEntities[ 0 ].template getSubentityIndex< 1 >( 0 ) == 0 ); + ASSERT_TRUE( triangleEntities[ 0 ].template getSubentityIndex< 1 >( 1 ) == 1 ); + ASSERT_TRUE( triangleEntities[ 0 ].template getSubentityIndex< 1 >( 2 ) == 2 ); + ASSERT_TRUE( triangleEntities[ 1 ].template getSubentityIndex< 0 >( 0 ) == 0 ); + ASSERT_TRUE( triangleEntities[ 1 ].template getSubentityIndex< 0 >( 1 ) == 2 ); + ASSERT_TRUE( triangleEntities[ 1 ].template getSubentityIndex< 0 >( 2 ) == 3 ); + ASSERT_TRUE( triangleEntities[ 1 ].template getSubentityIndex< 1 >( 0 ) == 0 ); + ASSERT_TRUE( triangleEntities[ 1 ].template getSubentityIndex< 1 >( 1 ) == 3 ); + ASSERT_TRUE( triangleEntities[ 1 ].template getSubentityIndex< 1 >( 2 ) == 4 ); + + /*vertexEntities[ 0 ].template setNumberOfSuperentities< 1 >( 2 ); + vertexEntities[ 0 ].template setSuperentityIndex< 1 >( 0, 2 ); + vertexEntities[ 0 ].template setSuperentityIndex< 1 >( 1, 1 ); + + vertexEntities[ 1 ].template setNumberOfSuperentities< 1 >( 3 ); + vertexEntities[ 1 ].template setSuperentityIndex< 1 >( 0, 0 ); + vertexEntities[ 1 ].template setSuperentityIndex< 1 >( 1, 2 ); + vertexEntities[ 1 ].template setSuperentityIndex< 1 >( 2, 4 ); + + vertexEntities[ 1 ].template setNumberOfSuperentities< 2 >( 2 ); + vertexEntities[ 1 ].template setSuperentityIndex< 2 >( 0, 0 ); + vertexEntities[ 1 ].template setSuperentityIndex< 2 >( 1, 1 );*/ + +// ASSERT_TRUE( vertexEntities[ 0 ].template getNumberOfSuperentities< 1 >() == 2 ); +// ASSERT_TRUE( vertexEntities[ 0 ].template getSuperentityIndex< 1 >( 0 ) == 2 ); +// ASSERT_TRUE( vertexEntities[ 0 ].template getSuperentityIndex< 1 >( 1 ) == 1 ); + +// ASSERT_TRUE( vertexEntities[ 1 ].template getNumberOfSuperentities< 1 >() == 3 ); +// ASSERT_TRUE( vertexEntities[ 1 ].template getSuperentityIndex< 1 >( 0 ) == 0 ); +// ASSERT_TRUE( vertexEntities[ 1 ].template getSuperentityIndex< 1 >( 1 ) == 2 ); +// ASSERT_TRUE( vertexEntities[ 1 ].template getSuperentityIndex< 1 >( 2 ) == 4 ); + +// ASSERT_TRUE( vertexEntities[ 1 ].template getNumberOfSuperentities< 2 >() == 2 ); +// ASSERT_TRUE( vertexEntities[ 1 ].template getSuperentityIndex< 2 >( 0 ) == 0 ); +// ASSERT_TRUE( vertexEntities[ 1 ].template getSuperentityIndex< 2 >( 1 ) == 1 ); + + /*edgeEntities[ 0 ].template setNumberOfSuperentities< 2 >( 2 ); + edgeEntities[ 0 ].template setSuperentityIndex< 2 >( 0, 0 ); + edgeEntities[ 0 ].template setSuperentityIndex< 2 >( 1, 1 );*/ + + /*ASSERT_TRUE( edgeEntities[ 0 ].template getNumberOfSuperentities< 2 >() == 2 ); + ASSERT_TRUE( edgeEntities[ 0 ].template getSuperentityIndex< 2 >( 0 ) == 0 );*/ +} + +#endif diff --git a/src/UnitTests/Meshes/MeshTest.cpp b/src/UnitTests/Meshes/MeshTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abb034cfc5e58b3c19896aaaaa5207c060b064d5 --- /dev/null +++ b/src/UnitTests/Meshes/MeshTest.cpp @@ -0,0 +1,15 @@ +#ifdef HAVE_GTEST +#include "gtest/gtest.h" +#endif + +#include "MeshTest.h" + +int main( int argc, char* argv[] ) +{ +#ifdef HAVE_GTEST + ::testing::InitGoogleTest( &argc, argv ); + return RUN_ALL_TESTS(); +#else + return EXIT_FAILURE; +#endif +} diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1575d656e773cf85df90a48db3adacee3287b37f --- /dev/null +++ b/src/UnitTests/Meshes/MeshTest.h @@ -0,0 +1,454 @@ +#pragma once + +#ifdef HAVE_GTEST +#include <TNL/Meshes/Mesh.h> +#include <TNL/Meshes/MeshEntity.h> +#include <TNL/Meshes/MeshConfigBase.h> +#include <TNL/Meshes/Topologies/MeshVertexTopology.h> +#include <TNL/Meshes/Topologies/MeshEdgeTopology.h> +#include <TNL/Meshes/Topologies/MeshTriangleTopology.h> +#include <TNL/Meshes/Topologies/MeshQuadrilateralTopology.h> +#include <TNL/Meshes/Topologies/MeshTetrahedronTopology.h> +#include <TNL/Meshes/Topologies/MeshHexahedronTopology.h> +#include <TNL/Meshes/MeshDetails/initializer/MeshInitializer.h> +#include <TNL/Meshes/MeshBuilder.h> + +using namespace TNL; +using namespace TNL::Meshes; + +class TestTriangleMeshConfig : public MeshConfigBase< MeshTriangleTopology > +{ + public: + + static constexpr bool entityStorage( int dimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; }; + //template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; }; +}; + +class TestQuadrilateralMeshConfig : public MeshConfigBase< MeshQuadrilateralTopology > +{ + public: + + static constexpr bool entityStorage( int dimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) { return ( SubentityDimensions % 2 != 0 ); }; + template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; }; +}; + +class TestTetrahedronMeshConfig : public MeshConfigBase< MeshTetrahedronTopology > +{ + public: + + static constexpr bool entityStorage( int dimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) { return ( SubentityDimensions % 2 != 0 ); }; + template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; }; +}; + +class TestHexahedronMeshConfig : public MeshConfigBase< MeshHexahedronTopology > +{ + public: + + static constexpr bool entityStorage( int dimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; }; + template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) { return ( SubentityDimensions % 2 != 0 ); }; + template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; }; +}; + +using RealType = double; +using Device = Devices::Host; +using IndexType = int; + +TEST( MeshTest, TwoTrianglesTest ) +{ + typedef MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology > TriangleMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 2, RealType >::getType() ) ); + + /**** + * We set-up the following situation + point2 edge3 point3 + |\-------------------| + | \ | + | \ triangle1 | + | \ | + + .... + edge1 edge0 edge4 + .... + + + | triangle0 \ | + | \ | + ---------------------| + point0 edge2 point1 + */ + + typedef Mesh< TestTriangleMeshConfig > TriangleTestMesh; + TriangleTestMesh mesh, mesh2; + MeshBuilder< TriangleTestMesh > meshBuilder; + meshBuilder.setPointsCount( 4 ); + meshBuilder.setPoint( 0, PointType( 0.0, 0.0 ) ); + meshBuilder.setPoint( 1, PointType( 1.0, 0.0 ) ); + meshBuilder.setPoint( 2, PointType( 0.0, 1.0 ) ); + meshBuilder.setPoint( 3, PointType( 1.0, 1.0 ) ); + + meshBuilder.setCellsCount( 2 ); + meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 ); + meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 ); + meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 ); + meshBuilder.getCellSeed( 1 ).setCornerId( 0, 1 ); + meshBuilder.getCellSeed( 1 ).setCornerId( 1, 2 ); + meshBuilder.getCellSeed( 1 ).setCornerId( 2, 3 ); + meshBuilder.build( mesh ); + + ASSERT_TRUE( mesh.getNumberOfEntities< 2 >() == 2 ); + ASSERT_TRUE( mesh.getNumberOfEntities< 1 >() == 5 ); + ASSERT_TRUE( mesh.getNumberOfEntities< 0 >() == 4 ); + + //ASSERT_TRUE( mesh.save( "mesh.tnl" ) ); + //ASSERT_TRUE( mesh2.load( "mesh.tnl" ) ); + //ASSERT_TRUE( mesh == mesh2 ); + + //mesh.print(std::cout ); + //mesh2.print(std::cout ); +}; + +TEST( MeshTest, TetrahedronsTest ) +{ + typedef MeshEntity< TestTetrahedronMeshConfig, MeshTriangleTopology > TriangleMeshEntityType; + typedef MeshEntity< TestTetrahedronMeshConfig, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestTetrahedronMeshConfig, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + typedef Mesh< TestTetrahedronMeshConfig > TestTetrahedronMesh; + TestTetrahedronMesh mesh; + MeshBuilder< TestTetrahedronMesh > meshBuilder; + meshBuilder.setPointsCount( 13 ); + meshBuilder.setPoint( 0, PointType( 0.000000, 0.000000, 0.000000 ) ); + meshBuilder.setPoint( 1, PointType( 0.000000, 0.000000, 8.000000 ) ); + meshBuilder.setPoint( 2, PointType( 0.000000, 8.000000, 0.000000 ) ); + meshBuilder.setPoint( 3, PointType( 15.000000, 0.000000, 0.000000 ) ); + meshBuilder.setPoint( 4, PointType( 0.000000, 8.000000, 8.000000 ) ); + meshBuilder.setPoint( 5, PointType( 15.000000, 0.000000, 8.000000 ) ); + meshBuilder.setPoint( 6, PointType( 15.000000, 8.000000, 0.000000 ) ); + meshBuilder.setPoint( 7, PointType( 15.000000, 8.000000, 8.000000 ) ); + meshBuilder.setPoint( 8, PointType( 7.470740, 8.000000, 8.000000 ) ); + meshBuilder.setPoint( 9, PointType( 7.470740, 0.000000, 8.000000 ) ); + meshBuilder.setPoint( 10, PointType( 7.504125, 8.000000, 0.000000 ) ); + meshBuilder.setPoint( 11, PointType( 7.212720, 0.000000, 0.000000 ) ); + meshBuilder.setPoint( 12, PointType( 11.184629, 3.987667, 3.985835 ) ); + + /**** + * Setup the following tetrahedrons: + * ( Generated by Netgen ) + * + * 12 8 7 5 + * 12 7 8 10 + * 12 11 8 9 + * 10 11 2 8 + * 12 7 6 5 + * 9 12 5 8 + * 12 11 9 3 + * 9 4 11 8 + * 12 9 5 3 + * 1 2 0 11 + * 8 11 2 4 + * 1 2 11 4 + * 9 4 1 11 + * 10 11 8 12 + * 12 6 7 10 + * 10 11 12 3 + * 12 6 3 5 + * 12 3 6 10 + */ + + meshBuilder.setCellsCount( 18 ); + // 12 8 7 5 + meshBuilder.getCellSeed( 0 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 0 ).setCornerId( 1, 8 ); + meshBuilder.getCellSeed( 0 ).setCornerId( 2, 7 ); + meshBuilder.getCellSeed( 0 ).setCornerId( 3, 5 ); + + // 12 7 8 10 + meshBuilder.getCellSeed( 1 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 1 ).setCornerId( 1, 7 ); + meshBuilder.getCellSeed( 1 ).setCornerId( 2, 8 ); + meshBuilder.getCellSeed( 1 ).setCornerId( 3, 10 ); + + // 12 11 8 9 + meshBuilder.getCellSeed( 2 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 2 ).setCornerId( 1, 11 ); + meshBuilder.getCellSeed( 2 ).setCornerId( 2, 8 ); + meshBuilder.getCellSeed( 2 ).setCornerId( 3, 9 ); + + // 10 11 2 8 + meshBuilder.getCellSeed( 3 ).setCornerId( 0, 10 ); + meshBuilder.getCellSeed( 3 ).setCornerId( 1, 11 ); + meshBuilder.getCellSeed( 3 ).setCornerId( 2, 2 ); + meshBuilder.getCellSeed( 3 ).setCornerId( 3, 8 ); + + // 12 7 6 5 + meshBuilder.getCellSeed( 4 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 4 ).setCornerId( 1, 7 ); + meshBuilder.getCellSeed( 4 ).setCornerId( 2, 6 ); + meshBuilder.getCellSeed( 4 ).setCornerId( 3, 5 ); + + // 9 12 5 8 + meshBuilder.getCellSeed( 5 ).setCornerId( 0, 9 ); + meshBuilder.getCellSeed( 5 ).setCornerId( 1, 12 ); + meshBuilder.getCellSeed( 5 ).setCornerId( 2, 5 ); + meshBuilder.getCellSeed( 5 ).setCornerId( 3, 8 ); + + // 12 11 9 3 + meshBuilder.getCellSeed( 6 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 6 ).setCornerId( 1, 11 ); + meshBuilder.getCellSeed( 6 ).setCornerId( 2, 9 ); + meshBuilder.getCellSeed( 6 ).setCornerId( 3, 3 ); + + // 9 4 11 8 + meshBuilder.getCellSeed( 7 ).setCornerId( 0, 9 ); + meshBuilder.getCellSeed( 7 ).setCornerId( 1, 4 ); + meshBuilder.getCellSeed( 7 ).setCornerId( 2, 11 ); + meshBuilder.getCellSeed( 7 ).setCornerId( 3, 8 ); + + // 12 9 5 3 + meshBuilder.getCellSeed( 8 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 8 ).setCornerId( 1, 9 ); + meshBuilder.getCellSeed( 8 ).setCornerId( 2, 5 ); + meshBuilder.getCellSeed( 8 ).setCornerId( 3, 3 ); + + // 1 2 0 11 + meshBuilder.getCellSeed( 9 ).setCornerId( 0, 1 ); + meshBuilder.getCellSeed( 9 ).setCornerId( 1, 2 ); + meshBuilder.getCellSeed( 9 ).setCornerId( 2, 0 ); + meshBuilder.getCellSeed( 9 ).setCornerId( 3, 11 ); + + // 8 11 2 4 + meshBuilder.getCellSeed( 10 ).setCornerId( 0, 8 ); + meshBuilder.getCellSeed( 10 ).setCornerId( 1, 11 ); + meshBuilder.getCellSeed( 10 ).setCornerId( 2, 2 ); + meshBuilder.getCellSeed( 10 ).setCornerId( 3, 4 ); + + // 1 2 11 4 + meshBuilder.getCellSeed( 11 ).setCornerId( 0, 1 ); + meshBuilder.getCellSeed( 11 ).setCornerId( 1, 2 ); + meshBuilder.getCellSeed( 11 ).setCornerId( 2, 11 ); + meshBuilder.getCellSeed( 11 ).setCornerId( 3, 4 ); + + // 9 4 1 11 + meshBuilder.getCellSeed( 12 ).setCornerId( 0, 9 ); + meshBuilder.getCellSeed( 12 ).setCornerId( 1, 4 ); + meshBuilder.getCellSeed( 12 ).setCornerId( 2, 1 ); + meshBuilder.getCellSeed( 12 ).setCornerId( 3, 11 ); + + // 10 11 8 12 + meshBuilder.getCellSeed( 13 ).setCornerId( 0, 10 ); + meshBuilder.getCellSeed( 13 ).setCornerId( 1, 11 ); + meshBuilder.getCellSeed( 13 ).setCornerId( 2, 8 ); + meshBuilder.getCellSeed( 13 ).setCornerId( 3, 12 ); + + // 12 6 7 10 + meshBuilder.getCellSeed( 14 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 14 ).setCornerId( 1, 6 ); + meshBuilder.getCellSeed( 14 ).setCornerId( 2, 7 ); + meshBuilder.getCellSeed( 14 ).setCornerId( 3, 10 ); + + // 10 11 12 3 + meshBuilder.getCellSeed( 15 ).setCornerId( 0, 10 ); + meshBuilder.getCellSeed( 15 ).setCornerId( 1, 11 ); + meshBuilder.getCellSeed( 15 ).setCornerId( 2, 12 ); + meshBuilder.getCellSeed( 15 ).setCornerId( 3, 3 ); + + // 12 6 3 5 + meshBuilder.getCellSeed( 16 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 16 ).setCornerId( 1, 6 ); + meshBuilder.getCellSeed( 16 ).setCornerId( 2, 3 ); + meshBuilder.getCellSeed( 16 ).setCornerId( 3, 5 ); + + // 12 3 6 10 + meshBuilder.getCellSeed( 17 ).setCornerId( 0, 12 ); + meshBuilder.getCellSeed( 17 ).setCornerId( 1, 3 ); + meshBuilder.getCellSeed( 17 ).setCornerId( 2, 6 ); + meshBuilder.getCellSeed( 17 ).setCornerId( 3, 10 ); + + meshBuilder.build( mesh ); + + /*ASSERT_TRUE( mesh.save( "mesh.tnl" ) ); + ASSERT_TRUE( mesh2.load( "mesh.tnl" ) ); + ASSERT_TRUE( mesh == mesh2 );*/ + //mesh.print(std::cout ); +} + +TEST( MeshTest, RegularMeshOfTrianglesTest ) +{ + typedef MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology > TriangleMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestTriangleMeshConfig, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + + const IndexType xSize( 5 ), ySize( 5 ); + const RealType width( 1.0 ), height( 1.0 ); + const RealType hx( width / ( RealType ) xSize ), + hy( height / ( RealType ) ySize ); + const IndexType numberOfCells = 2*xSize * ySize; + const IndexType numberOfVertices = ( xSize + 1 ) * ( ySize + 1 ); + + typedef Mesh< TestTriangleMeshConfig > TestTriangleMesh; + Mesh< TestTriangleMeshConfig > mesh; + MeshBuilder< TestTriangleMesh > meshBuilder; + meshBuilder.setPointsCount( numberOfVertices ); + meshBuilder.setCellsCount( numberOfCells ); + + /**** + * Setup vertices + */ + for( IndexType i = 0; i <= xSize; i++ ) + for( IndexType j = 0; j <= ySize; j++ ) + meshBuilder.setPoint( j*xSize + i, PointType( i * hx, j * hy ) ); + + /**** + * Setup cells + */ + IndexType cellIdx( 0 ); + for( IndexType i = 0; i < xSize; i++ ) + for( IndexType j = 0; j < ySize; j++ ) + { + IndexType vertex0 = j * xSize + i; + IndexType vertex1 = j * xSize + i + 1; + IndexType vertex2 = ( j + 1 ) * xSize + i; + IndexType vertex3 = ( j + 1 ) * xSize + i + 1; + meshBuilder.getCellSeed( cellIdx ).setCornerId( 0, vertex0 ); + meshBuilder.getCellSeed( cellIdx ).setCornerId( 1, vertex1 ); + meshBuilder.getCellSeed( cellIdx++ ).setCornerId( 2, vertex2 ); + meshBuilder.getCellSeed( cellIdx ).setCornerId( 0, vertex1 ); + meshBuilder.getCellSeed( cellIdx ).setCornerId( 1, vertex2 ); + meshBuilder.getCellSeed( cellIdx++ ).setCornerId( 2, vertex3 ); + } + + meshBuilder.build( mesh ); + //ASSERT_TRUE( mesh.save( "mesh-test.tnl" ) ); + //ASSERT_TRUE( mesh2.load( "mesh-test.tnl" ) ); + //ASSERT_TRUE( mesh == mesh2 ); + //mesh.print(std::cout ); +} + +TEST( MeshTest, RegularMeshOfQuadrilateralsTest ) +{ +#ifdef UNDEF + typedef MeshEntity< TestQuadrilateralMeshConfig, MeshQuadrilateralTopology > QuadrilateralMeshEntityType; + typedef MeshEntity< TestQuadrilateralMeshConfig, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestQuadrilateralMeshConfig, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + + const IndexType xSize( 5 ), ySize( 5 ); + const RealType width( 1.0 ), height( 1.0 ); + const RealType hx( width / ( RealType ) xSize ), + hy( height / ( RealType ) ySize ); + const IndexType numberOfCells = xSize * ySize; + const IndexType numberOfVertices = ( xSize + 1 ) * ( ySize + 1 ); + + Mesh< TestQuadrilateralMeshConfig > mesh, mesh2; + mesh.setNumberOfCells( numberOfCells ); + mesh.setNumberOfVertices( numberOfVertices ); + + /**** + * Setup vertices + */ + for( IndexType i = 0; i <= xSize; i++ ) + for( IndexType j = 0; j <= ySize; j++ ) + mesh.setVertex( j*xSize + i, PointType( i * hx, j * hy ) ); + + /**** + * Setup cells + */ + IndexType cellIdx( 0 ); + for( IndexType i = 0; i < xSize; i++ ) + for( IndexType j = 0; j < ySize; j++ ) + { + IndexType vertex0 = j * xSize + i; + IndexType vertex1 = j * xSize + i + 1; + IndexType vertex2 = ( j + 1 ) * xSize + i; + IndexType vertex3 = ( j + 1 ) * xSize + i + 1; + mesh.getEntities< 2 >()[ cellIdx ].getVerticesIndices()[ 0 ] = vertex0; + mesh.getEntities< 2 >()[ cellIdx ].getVerticesIndices()[ 1 ] = vertex1; + mesh.getEntities< 2 >()[ cellIdx ].getVerticesIndices()[ 2 ] = vertex2; + mesh.getEntities< 2 >()[ cellIdx++ ].getVerticesIndices()[ 3 ] = vertex3; + } + + MeshInitializer< TestQuadrilateralMeshConfig > meshInitializer; + //meshInitializer.initMesh( mesh ); + ASSERT_TRUE( mesh.save( "mesh-test.tnl" ) ); + ASSERT_TRUE( mesh2.load( "mesh-test.tnl" ) ); + ASSERT_TRUE( mesh == mesh2 ); + //mesh.print(std::cout ); +#endif +} + +TEST( MeshTest, RegularMeshOfHexahedronsTest ) +{ +#ifdef UNDEF + typedef MeshEntity< TestHexahedronMeshConfig, MeshHexahedronTopology > HexahedronMeshEntityType; + typedef MeshEntity< TestHexahedronMeshConfig, MeshEdgeTopology > EdgeMeshEntityType; + typedef MeshEntity< TestHexahedronMeshConfig, MeshVertexTopology > VertexMeshEntityType; + typedef typename VertexMeshEntityType::PointType PointType; + + const IndexType xSize( 5 ), ySize( 5 ), zSize( 5 ); + const RealType width( 1.0 ), height( 1.0 ), depth( 1.0 ); + const RealType hx( width / ( RealType ) xSize ), + hy( height / ( RealType ) ySize ), + hz( depth / ( RealType ) zSize ); + const IndexType numberOfCells = xSize * ySize * zSize; + const IndexType numberOfVertices = ( xSize + 1 ) * ( ySize + 1 ) * ( zSize + 1 ); + + Mesh< TestHexahedronMeshConfig > mesh, mesh2; + mesh.setNumberOfCells( numberOfCells ); + mesh.setNumberOfVertices( numberOfVertices ); + + /**** + * Setup vertices + */ + for( IndexType i = 0; i <= xSize; i++ ) + for( IndexType j = 0; j <= ySize; j++ ) + for( IndexType k = 0; k <= zSize; k++ ) + mesh.setVertex( k * xSize * ySize + j * xSize + i, PointType( i * hx, j * hy, k * hz ) ); + + /**** + * Setup cells + */ + IndexType cellIdx( 0 ); + for( IndexType i = 0; i < xSize; i++ ) + for( IndexType j = 0; j < ySize; j++ ) + for( IndexType k = 0; k < zSize; k++ ) + { + IndexType vertex0 = k * xSize * ySize + j * xSize + i; + IndexType vertex1 = k * xSize * ySize + j * xSize + i + 1; + IndexType vertex2 = k * xSize * ySize + ( j + 1 ) * xSize + i; + IndexType vertex3 = k * xSize * ySize + ( j + 1 ) * xSize + i + 1; + IndexType vertex4 = ( k + 1 ) * xSize * ySize + j * xSize + i; + IndexType vertex5 = ( k + 1 ) * xSize * ySize + j * xSize + i + 1; + IndexType vertex6 = ( k + 1 ) * xSize * ySize + ( j + 1 ) * xSize + i; + IndexType vertex7 = ( k + 1 )* xSize * ySize + ( j + 1 ) * xSize + i + 1; + + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 0 ] = vertex0; + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 1 ] = vertex1; + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 2 ] = vertex2; + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 3 ] = vertex3; + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 4 ] = vertex4; + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 5 ] = vertex5; + mesh.getEntities< 3 >()[ cellIdx ].getVerticesIndices()[ 6 ] = vertex6; + mesh.getEntities< 3 >()[ cellIdx++ ].getVerticesIndices()[ 7 ] = vertex7; + } + + MeshInitializer< TestHexahedronMeshConfig > meshInitializer; + //meshInitializer.initMesh( mesh ); + /*ASSERT_TRUE( mesh.save( "mesh-test.tnl" ) ); + ASSERT_TRUE( mesh2.load( "mesh-test.tnl" ) ); + ASSERT_TRUE( mesh == mesh2 );*/ + //mesh.print(std::cout ); +#endif +} + +#endif