From f554fd8f1ea6738d43390b90c072f033a00a9e27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz>
Date: Fri, 21 Oct 2016 11:03:04 +0200
Subject: [PATCH] Fixed MeshSuperentityStorageInitializer

---
 .../MeshDetails/initializer/MeshInitializer.h |   7 +
 .../MeshSuperentityStorageInitializer.h       | 211 +++++++++---------
 .../layers/MeshSuperentityAccess.h            |  12 +-
 src/UnitTests/Meshes/MeshEntityTest.h         |   1 +
 src/UnitTests/Meshes/MeshTest.h               |  85 ++++++-
 5 files changed, 194 insertions(+), 122 deletions(-)

diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h
index 33b6b7700c..f6f4f10d25 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h
@@ -137,6 +137,13 @@ class MeshInitializer
          return mesh->template getSuperentityStorageNetwork< EntityTopology, SuperdimensionsTag >();
       }
 
+      template< int Superdimensions, typename MeshEntity, typename Storage >
+      static void
+      bindSuperentitiesStorageNetwork( MeshEntity& entity, const Storage& storage )
+      {
+         entity.template bindSuperentitiesStorageNetwork< Superdimensions >( storage );
+      }
+
       static void
       setVertexPoint( typename MeshType::VertexType& vertex, const typename MeshType::PointType& point )
       {
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h
index f3bd3b9bb0..7bc2fa8a38 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h
@@ -17,7 +17,8 @@
 #pragma once
 
 #include <algorithm>
-#include <vector>
+#include <set>
+#include <map>
 
 #include <TNL/Meshes/MeshDimensionsTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h>
@@ -44,130 +45,128 @@ template< typename MeshConfig,
           typename EntityTopology,
           typename DimensionTag >
 class MeshSuperentityStorageInitializerLayer< MeshConfig,
-                                          EntityTopology,
-                                          DimensionTag,
-                                          true >
+                                              EntityTopology,
+                                              DimensionsTag,
+                                              true >
    : public MeshSuperentityStorageInitializerLayer< MeshConfig,
-                                                EntityTopology,
-                                                typename DimensionTag::Decrement >
+                                                    EntityTopology,
+                                                    typename DimensionsTag::Decrement >
 {
-   typedef MeshSuperentityStorageInitializerLayer< MeshConfig,
-                                                      EntityTopology,
-                                                      typename DimensionTag::Decrement >      BaseType;
-
-   static const int Dimension = DimensionTag::value;
-   typedef MeshDimensionTag< EntityTopology::dimensions >                                       EntityDimension;
-	
-   typedef MeshTraits< MeshConfig >                                                             MeshTraitsType;
-   typedef typename MeshTraitsType::GlobalIdArrayType                                           GlobalIdArrayType; 
-   typedef typename MeshTraitsType::GlobalIndexType                                             GlobalIndexType;
-   typedef typename MeshTraitsType::LocalIndexType                                              LocalIndexType;
-   typedef MeshInitializer< MeshConfig >                                                        MeshInitializerType;
-   typedef typename MeshTraitsType::template SuperentityTraits< EntityTopology, Dimension >    SuperentityTraitsType;
-   typedef typename SuperentityTraitsType::StorageNetworkType                                   SuperentityStorageNetwork;
+   using BaseType = MeshSuperentityStorageInitializerLayer< MeshConfig,
+                                                            EntityTopology,
+                                                            typename DimensionsTag::Decrement >;
+
+   static const int Dimensions = DimensionsTag::value;
+   using EntityDimensions          = MeshDimensionsTag< EntityTopology::dimensions >;
+   using EntityType                = MeshEntity< MeshConfig, EntityTopology >;
+
+   using MeshTraitsType            = MeshTraits< MeshConfig >;
+   using GlobalIdArrayType         = typename MeshTraitsType::GlobalIdArrayType;
+   using GlobalIndexType           = typename MeshTraitsType::GlobalIndexType;
+   using LocalIndexType            = typename MeshTraitsType::LocalIndexType;
+   using MeshInitializerType       = MeshInitializer< MeshConfig >;
+   using SuperentityTraitsType     = typename MeshTraitsType::template SuperentityTraits< EntityTopology, Dimensions >;
+   using SuperentityStorageNetwork = typename SuperentityTraitsType::StorageNetworkType;
 
    public:
       using BaseType::addSuperentity;
-	
-      void addSuperentity( DimensionTag, GlobalIndexType entityIndex, GlobalIndexType superentityIndex)
+
+      void addSuperentity( DimensionsTag, GlobalIndexType entityIndex, GlobalIndexType superentityIndex)
       {
-         //cout << "Adding superentity with " << DimensionTag::value << " dimensions of enity with " << EntityDimension::value << " ... " << std::endl;
-         indexPairs.push_back( IndexPair{ entityIndex, superentityIndex } );
+         //std::cout << "Adding superentity with " << DimensionsTag::value << " dimensions of entity with " << EntityDimensions::value << " dimensions ... " << std::endl;
+         auto& indexSet = this->dynamicStorageNetwork[ entityIndex ];
+         Assert( indexSet.count( superentityIndex ) == 0,
+                    std::cerr << "Superentity " << superentityIndex << " with dimensions " << DimensionsTag::value
+                              << " of entity " << entityIndex << " with dimensions " << EntityDimensions::value
+                              << " has been already added. This is probably a bug in the mesh initializer." << std::endl; );
+         indexSet.insert( superentityIndex );
       }
 
       using BaseType::initSuperentities;
       void initSuperentities( MeshInitializerType& meshInitializer )
       {
-         throw( 0 ); // TODO: fix this - or it may work with newer version of gcc
-         /*std::sort( indexPairs.begin(),
-                    indexPairs.end(),
-                    []( IndexPair pair0, IndexPair pair1 ){ return ( pair0.entityIndex < pair1.entityIndex ); } );*/
-
-         GlobalIdArrayType &superentityIdsArray = meshInitializer.template meshSuperentityIdsArray< EntityDimension, DimensionTag >();
-         superentityIdsArray.setSize( static_cast< GlobalIndexType >( indexPairs.size() )  );
-         GlobalIndexType currentBegin = 0;
-         GlobalIndexType lastEntityIndex = 0;
-        std::cout << "There are " << superentityIdsArray.getSize() << " superentities with " << DimensionTag::value << " dimensions of enities with " << EntityDimension::value << " ... " << std::endl;
-         for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
-         {
-            superentityIdsArray[ i ] = indexPairs[i].superentityIndex;
- 
-            //cout << "Adding superentity " << indexPairs[i].superentityIndex << " to entity " << lastEntityIndex << std::endl;
-            if( indexPairs[ i ].entityIndex != lastEntityIndex )
-            {
-               meshInitializer.template superentityIdsArray< DimensionTag >( meshInitializer.template meshEntitiesArray< EntityDimension >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, i - currentBegin );
-               currentBegin = i;
-               lastEntityIndex = indexPairs[ i ].entityIndex;
+         if( ! dynamicStorageNetwork.empty() ) {
+            GlobalIndexType maxEntityIndex = 0;
+            for( auto it = dynamicStorageNetwork.cbegin(); it != dynamicStorageNetwork.cend(); it++ ) {
+               if( it->first > maxEntityIndex )
+                  maxEntityIndex = it->first;
             }
-         }
 
-         meshInitializer.template superentityIdsArray< DimensionTag >( meshInitializer.template meshEntitiesArray< EntityDimension >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, superentityIdsArray.getSize() - currentBegin );
-         indexPairs.clear();
- 
-         /****
-          * Network initializer
-          */
-         SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< EntityTopology, DimensionTag >();
-         //GlobalIndexType lastEntityIndex( 0 );
-         superentityStorageNetwork.setRanges(
-            meshInitializer.template meshEntitiesArray< EntityDimension >().getSize(),
-            meshInitializer.template meshEntitiesArray< DimensionTag >().getSize() );
-         lastEntityIndex = 0;
-         typename SuperentityStorageNetwork::ValuesAllocationVectorType storageNetworkAllocationVector;
-         storageNetworkAllocationVector.setSize( meshInitializer.template meshEntitiesArray< EntityDimension >().getSize() );
-         storageNetworkAllocationVector.setValue( 0 );
-         for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
-         {
-            if( indexPairs[ i ].entityIndex == lastEntityIndex )
-               storageNetworkAllocationVector[ lastEntityIndex ]++;
-            else
-               lastEntityIndex++;
-         }
-         superentityStorageNetwork.allocate( storageNetworkAllocationVector );
-         lastEntityIndex = 0;
-         LocalIndexType superentitiesCount( 0 );
-         typename SuperentityStorageNetwork::ValuesAccessorType superentitiesIndecis =
-            superentityStorageNetwork.getValues( lastEntityIndex );
-         for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
-         {
-            if( indexPairs[ i ].entityIndex != lastEntityIndex )
-            {
-               superentitiesIndecis = superentityStorageNetwork.getValues( ++lastEntityIndex );
-               superentitiesCount = 0;
+            Assert( (size_t) maxEntityIndex == dynamicStorageNetwork.size() - 1,
+                       std::cerr << "Superentities for some entities are missing." << std::endl; );
+
+            // TODO: what's this supposed to do?
+//            std::cout << "There are " << superentityIdsArray.getSize() << " superentities with " << DimensionsTag::value << " dimensions of enities with dimension " << EntityDimensions::value << " ... " << std::endl;
+//            GlobalIdArrayType &superentityIdsArray = meshInitializer.template meshSuperentityIdsArray< EntityDimensions, DimensionsTag >();
+//            superentityIdsArray.setSize( dynamicStorageNetwork.size() );
+//            GlobalIndexType currentBegin = 0;
+//            GlobalIndexType lastEntityIndex = 0;
+//            for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
+//            {
+//               superentityIdsArray[ i ] = indexPairs[i].superentityIndex;
+//
+//               //cout << "Adding superentity " << indexPairs[i].superentityIndex << " to entity " << lastEntityIndex << std::endl;
+//               if( indexPairs[ i ].entityIndex != lastEntityIndex )
+//               {
+//                  meshInitializer.template superentityIdsArray< DimensionsTag >( meshInitializer.template meshEntitiesArray< EntityDimensions >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, i - currentBegin );
+//                  currentBegin = i;
+//                  lastEntityIndex = indexPairs[ i ].entityIndex;
+//               }
+//            }
+//
+//            meshInitializer.template superentityIdsArray< DimensionsTag >( meshInitializer.template meshEntitiesArray< EntityDimensions >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, superentityIdsArray.getSize() - currentBegin );
+//            indexPairs.clear();
+
+            /****
+             * Network initializer
+             */
+            SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< EntityTopology, DimensionsTag >();
+            superentityStorageNetwork.setKeysRange( maxEntityIndex + 1 );
+            typename SuperentityStorageNetwork::ValuesAllocationVectorType storageNetworkAllocationVector;
+            storageNetworkAllocationVector.setSize( maxEntityIndex + 1 );
+            for( auto it = dynamicStorageNetwork.cbegin(); it != dynamicStorageNetwork.cend(); it++ )
+               storageNetworkAllocationVector[ it->first ] = it->second.size();
+            superentityStorageNetwork.allocate( storageNetworkAllocationVector );
+
+            GlobalIndexType entityIndex = 0;
+            for( auto it = dynamicStorageNetwork.cbegin(); it != dynamicStorageNetwork.cend(); it++ ) {
+               auto superentitiesIndices = superentityStorageNetwork.getValues( it->first );
+               LocalIndexType i = 0;
+               for( auto v_it = it->second.cbegin(); v_it != it->second.cend(); v_it++ )
+                  superentitiesIndices[ i++ ] = *v_it;
+
+               EntityType& entity = meshInitializer.template meshEntitiesArray< EntityDimensions >()[ entityIndex ];
+               meshInitializer.template bindSuperentitiesStorageNetwork< DimensionsTag::value >( entity, superentityStorageNetwork.getValues( entityIndex++ ) );
             }
-            superentitiesIndecis[ superentitiesCount++ ] =  indexPairs[ i ].superentityIndex;
+
+            dynamicStorageNetwork.clear();
          }
+
          BaseType::initSuperentities( meshInitializer );
       }
 
    private:
-      struct IndexPair
-      {
-         GlobalIndexType entityIndex;
-         GlobalIndexType superentityIndex;
-      };
-
-      std::vector< IndexPair > indexPairs;
- 
+      using DynamicIndexSet = std::set< GlobalIndexType >;
+      std::map< GlobalIndexType, DynamicIndexSet > dynamicStorageNetwork;
 };
 
 template< typename MeshConfig,
           typename EntityTopology,
           typename DimensionTag >
 class MeshSuperentityStorageInitializerLayer< MeshConfig,
-                                          EntityTopology,
-                                          DimensionTag,
-                                          false >
+                                              EntityTopology,
+                                              DimensionsTag,
+                                              false >
    : public MeshSuperentityStorageInitializerLayer< MeshConfig,
-                                                EntityTopology,
-                                                typename DimensionTag::Decrement >
+                                                    EntityTopology,
+                                                    typename DimensionsTag::Decrement >
 {
-   typedef MeshSuperentityStorageInitializerLayer< MeshConfig,
-                                                EntityTopology,
-                                                typename DimensionTag::Decrement > BaseType;
-   typedef MeshInitializer< MeshConfig >                                      MeshInitializerType;
- 
-   public:
+   using BaseType = MeshSuperentityStorageInitializerLayer< MeshConfig,
+                                                            EntityTopology,
+                                                            typename DimensionsTag::Decrement >;
+   using MeshInitializerType = MeshInitializer< MeshConfig >;
+
+public:
    void addSuperentity()                           {} // This method is due to 'using BaseType::...;' in the derived classes.
    using BaseType::initSuperentities;
    void initSuperentities( MeshInitializerType& ) { std::cerr << "***" << std::endl;}
@@ -180,10 +179,11 @@ class MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           MeshDimensionTag< EntityTopology::dimensions >,
                                           true >
 {
-   typedef MeshInitializer< MeshConfig >                                      MeshInitializerType;
- 
-   public:
-   void addSuperentity()                           {} // This method is due to 'using BaseType::...;' in the derived classes.
+   using MeshInitializerType = MeshInitializer< MeshConfig >;
+
+public:
+   // Necessary due to 'using BaseType::...;' in the derived classes.
+   void addSuperentity() {}
    void initSuperentities( MeshInitializerType& ) {}
 };
 
@@ -194,10 +194,11 @@ class MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           MeshDimensionTag< EntityTopology::dimensions >,
                                           false >
 {
-   typedef MeshInitializer< MeshConfig >                                      MeshInitializerType;
+   using MeshInitializerType = MeshInitializer< MeshConfig >;
 
-   public:
-   void addSuperentity()                           {} // This method is due to 'using BaseType::...;' in the derived classes.
+public:
+   // Necessary due to 'using BaseType::...;' in the derived classes.
+   void addSuperentity() {}
    void initSuperentities( MeshInitializerType& ) {}
 };
 
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
index feee656e3c..c7fd57b657 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
@@ -230,9 +230,9 @@ protected:
                                          const SuperentityAccessorType& storage ) {}
    void setNumberOfSuperentities( DimensionsTag,
                                   const LocalIndexType size ) {}
-   LocalIndexType getNumberOfSuperentities( DimensionsTag ) const {}
-   GlobalIndexType getSuperentityIndex( DimensionsTag,
-                                        const LocalIndexType localIndex ) {}
+   void getNumberOfSuperentities( DimensionsTag ) const {}
+   void getSuperentityIndex( DimensionsTag,
+                             const LocalIndexType localIndex ) const {}
    void setSuperentityIndex( DimensionsTag,
                              const LocalIndexType& localIndex,
                              const GlobalIndexType& globalIndex ) {}
@@ -269,9 +269,9 @@ protected:
                                          const SuperentityAccessorType& storage ) {}
    void setNumberOfSuperentities( DimensionsTag,
                                   const LocalIndexType size ) {}
-   LocalIndexType getNumberOfSuperentities( DimensionsTag ) const {}
-   GlobalIndexType getSuperentityIndex( DimensionsTag,
-                                        const LocalIndexType localIndex ) {}
+   void getNumberOfSuperentities( DimensionsTag ) const {}
+   void getSuperentityIndex( DimensionsTag,
+                             const LocalIndexType localIndex ) const {}
    void setSuperentityIndex( DimensionsTag,
                              const LocalIndexType& localIndex,
                              const GlobalIndexType& globalIndex ) {}
diff --git a/src/UnitTests/Meshes/MeshEntityTest.h b/src/UnitTests/Meshes/MeshEntityTest.h
index 1f95950edc..191a5a6f0f 100644
--- a/src/UnitTests/Meshes/MeshEntityTest.h
+++ b/src/UnitTests/Meshes/MeshEntityTest.h
@@ -499,6 +499,7 @@ TEST( MeshEntityTest, TwoTrianglesMeshEntityTest )
 
    ASSERT_EQ( edgeEntities[ 0 ].template getNumberOfSuperentities< 2 >(),  2 );
    ASSERT_EQ( edgeEntities[ 0 ].template getSuperentityIndex< 2 >( 0 ),    0 );
+   ASSERT_EQ( edgeEntities[ 0 ].template getSuperentityIndex< 2 >( 1 ),    1 );
 }
 
 #endif
diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h
index 9e9e9f95f2..2c34e694d6 100644
--- a/src/UnitTests/Meshes/MeshTest.h
+++ b/src/UnitTests/Meshes/MeshTest.h
@@ -58,10 +58,18 @@ public:
 
 TEST( MeshTest, TwoTrianglesTest )
 {
-   typedef MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology > TriangleMeshEntityType;
-   typedef MeshEntity< TestTriangleMeshConfig, MeshEdgeTopology > EdgeMeshEntityType;
-   typedef MeshEntity< TestTriangleMeshConfig, MeshVertexTopology > VertexMeshEntityType;
-   typedef typename VertexMeshEntityType::PointType PointType;
+   using TriangleMeshEntityType = MeshEntity< TestTriangleMeshConfig, MeshTriangleTopology >;
+   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;
    ASSERT_TRUE( PointType::getType() == ( Containers::StaticVector< 2, RealType >::getType() ) );
 
    /****
@@ -83,14 +91,19 @@ TEST( MeshTest, TwoTrianglesTest )
             point0   edge2        point1
     */
 
+   PointType point0( 0.0, 0.0 ),
+             point1( 1.0, 0.0 ),
+             point2( 0.0, 1.0 ),
+             point3( 1.0, 1.0 );
+
    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.setPoint( 0, point0 );
+   meshBuilder.setPoint( 1, point1 );
+   meshBuilder.setPoint( 2, point2 );
+   meshBuilder.setPoint( 3, point3 );
 
    meshBuilder.setCellsCount( 2 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
@@ -101,9 +114,59 @@ TEST( MeshTest, TwoTrianglesTest )
    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 );
+   EXPECT_EQ( mesh.getNumberOfEntities< 2 >(),  2 );
+   EXPECT_EQ( mesh.getNumberOfEntities< 1 >(),  5 );
+   EXPECT_EQ( mesh.getNumberOfEntities< 0 >(),  4 );
+
+   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 );
+   EXPECT_EQ( mesh.template getEntity< 0 >( 3 ).getPoint(),  point3 );
+
+   EXPECT_EQ( mesh.template getEntity< 1 >( 0 ).getVertexIndex( 0 ),  1 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 0 ).getVertexIndex( 1 ),  2 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 1 ).getVertexIndex( 0 ),  2 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 1 ).getVertexIndex( 1 ),  0 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 2 ).getVertexIndex( 0 ),  0 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 2 ).getVertexIndex( 1 ),  1 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 3 ).getVertexIndex( 0 ),  2 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 3 ).getVertexIndex( 1 ),  3 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 4 ).getVertexIndex( 0 ),  3 );
+   EXPECT_EQ( mesh.template getEntity< 1 >( 4 ).getVertexIndex( 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 getNumberOfSuperentities< 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 getNumberOfSuperentities< 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 getNumberOfSuperentities< 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 getNumberOfSuperentities< 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 );
+
 
    //ASSERT_TRUE( mesh.save( "mesh.tnl" ) );
    //ASSERT_TRUE( mesh2.load( "mesh.tnl" ) );
-- 
GitLab