From cfce0c1206c12b3f48bc0b978e3b4b7f8fb6d679 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz>
Date: Tue, 31 Oct 2017 20:14:00 +0100
Subject: [PATCH] Refactoring mesh storage layers

---
 .../MeshDetails/layers/MeshStorageLayer.h     | 176 +++++-------------
 .../MeshDetails/layers/MeshSubentityAccess.h  |   6 +-
 .../layers/MeshSubentityStorageLayer.h        |   5 +-
 .../layers/MeshSuperentityAccess.h            |  21 +--
 .../layers/MeshSuperentityStorageLayer.h      |  18 +-
 .../Meshes/MeshDetails/traits/CMakeLists.txt  |   3 +-
 .../traits/MeshSuperentityTraits.h            |   3 +-
 .../MeshDetails/traits/WeakStorageTraits.h    |  83 +++++++++
 8 files changed, 143 insertions(+), 172 deletions(-)
 create mode 100644 src/TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h

diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h b/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h
index bead5dcfd8..36203a56e2 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include <TNL/File.h>
-#include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
+#include <TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h>
 #include <TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h>
 #include <TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h>
 #include <TNL/Meshes/MeshDetails/layers/MeshBoundaryTagsLayer.h>
@@ -28,16 +28,16 @@ namespace Meshes {
 template< typename MeshConfig,
           typename Device,
           typename DimensionTag,
-          bool EntityStorage = MeshTraits< MeshConfig, Device >::template EntityTraits< DimensionTag::value >::storageEnabled >
+          bool EntityStorage = WeakEntityStorageTrait< MeshConfig, Device, DimensionTag >::storageEnabled >
 class MeshStorageLayer;
 
 
 template< typename MeshConfig, typename Device >
 class MeshStorageLayers
-   : public MeshStorageLayer< MeshConfig, Device, typename MeshTraits< MeshConfig, Device >::DimensionTag >
+   : public MeshStorageLayer< MeshConfig, Device, DimensionTag< 0 > >
 {
    using MeshTraitsType = MeshTraits< MeshConfig, Device >;
-   using BaseType       = MeshStorageLayer< MeshConfig, Device, typename MeshTraitsType::DimensionTag >;
+   using BaseType       = MeshStorageLayer< MeshConfig, Device, DimensionTag< 0 > >;
    template< int Dimension >
    using EntityTraits = typename MeshTraitsType::template EntityTraits< Dimension >;
 
@@ -152,17 +152,17 @@ class MeshStorageLayer< MeshConfig,
                         Device,
                         DimensionTag,
                         true >
-   : public MeshStorageLayer< MeshConfig, Device, typename DimensionTag::Decrement >,
-     public MeshSubentityStorageLayers< MeshConfig,
+   : public MeshSubentityStorageLayers< MeshConfig,
                                         Device,
                                         typename MeshTraits< MeshConfig, Device >::template EntityTraits< DimensionTag::value >::EntityTopology >,
      public MeshSuperentityStorageLayers< MeshConfig,
                                           Device,
                                           typename MeshTraits< MeshConfig, Device >::template EntityTraits< DimensionTag::value >::EntityTopology >,
-     public MeshBoundaryTagsLayer< MeshConfig, Device, DimensionTag >
+     public MeshBoundaryTagsLayer< MeshConfig, Device, DimensionTag >,
+     public MeshStorageLayer< MeshConfig, Device, typename DimensionTag::Increment >
 {
 public:
-   using BaseType = MeshStorageLayer< MeshConfig, Device, typename DimensionTag::Decrement >;
+   using BaseType = MeshStorageLayer< MeshConfig, Device, typename DimensionTag::Increment >;
    using MeshTraitsType   = MeshTraits< MeshConfig, Device >;
    using EntityTraitsType = typename MeshTraitsType::template EntityTraits< DimensionTag::value >;
    using StorageArrayType = typename EntityTraitsType::StorageArrayType;
@@ -213,26 +213,24 @@ public:
 
    MeshStorageLayer& operator=( const MeshStorageLayer& other )
    {
-      BaseType::operator=( other );
+      entities.setLike( other.entities);
+      entities = other.entities;
       SubentityStorageBaseType::operator=( other );
       SuperentityStorageBaseType::operator=( other );
       BoundaryTagsBaseType::operator=( other );
-      // TODO: throw exception if allocation fails
-      entities.setLike( other.entities);
-      entities = other.entities;
+      BaseType::operator=( other );
       return *this;
    }
 
    template< typename Device_ >
    MeshStorageLayer& operator=( const MeshStorageLayer< MeshConfig, Device_, DimensionTag >& other )
    {
-      BaseType::operator=( other );
+      entities.setLike( other.entities);
+      entities = other.entities;
       SubentityStorageBaseType::operator=( other );
       SuperentityStorageBaseType::operator=( other );
       BoundaryTagsBaseType::operator=( other );
-      // TODO: throw exception if allocation fails
-      entities.setLike( other.entities);
-      entities = other.entities;
+      BaseType::operator=( other );
       return *this;
    }
 
@@ -267,11 +265,11 @@ public:
 
    bool save( File& file ) const
    {
-      if( ! BaseType::save( file ) ||
-          ! SubentityStorageBaseType::save( file ) ||
+      if( ! SubentityStorageBaseType::save( file ) ||
           ! SuperentityStorageBaseType::save( file ) ||
           ! BoundaryTagsBaseType::save( file ) ||
-          ! this->entities.save( file ) )
+          ! this->entities.save( file ) ||
+          ! BaseType::save( file ) )
       {
          std::cerr << "Saving of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl;
          return false;
@@ -281,11 +279,11 @@ public:
 
    bool load( File& file )
    {
-      if( ! BaseType::load( file ) ||
-          ! SubentityStorageBaseType::load( file ) ||
+      if( ! SubentityStorageBaseType::load( file ) ||
           ! SuperentityStorageBaseType::load( file ) ||
           ! BoundaryTagsBaseType::load( file ) ||
-          ! this->entities.load( file ) )
+          ! this->entities.load( file ) ||
+          ! BaseType::load( file ) )
       {
          std::cerr << "Loading of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl;
          return false;
@@ -295,7 +293,6 @@ public:
 
    void print( std::ostream& str ) const
    {
-      BaseType::print( str );
       str << "The entities with dimension " << DimensionTag::value << " are: " << std::endl;
       for( GlobalIndexType i = 0; i < entities.getSize(); i++ )
          str << i << " " << entities[ i ] << std::endl;
@@ -303,15 +300,16 @@ public:
       SuperentityStorageBaseType::print( str );
       BoundaryTagsBaseType::print( str );
       str << std::endl;
+      BaseType::print( str );
    }
 
    bool operator==( const MeshStorageLayer& meshLayer ) const
    {
-      return ( BaseType::operator==( meshLayer ) &&
+      return ( entities == meshLayer.entities &&
                SubentityStorageBaseType::operator==( meshLayer ) &&
                SuperentityStorageBaseType::operator==( meshLayer ) &&
                BoundaryTagsBaseType::operator==( meshLayer ) &&
-               entities == meshLayer.entities );
+               BaseType::operator==( meshLayer ) );
    }
 
 protected:
@@ -337,154 +335,64 @@ public:
    {}
 };
 
+// termination of recursive inheritance (everything is reduced to EntityStorage == false thanks to the WeakEntityStorageTrait)
 template< typename MeshConfig,
           typename Device >
-class MeshStorageLayer< MeshConfig, Device, Meshes::DimensionTag< 0 >, true >
-   : public MeshSuperentityStorageLayers< MeshConfig, Device, MeshVertexTopology >,
-     public MeshBoundaryTagsLayer< MeshConfig, Device, Meshes::DimensionTag< 0 > >
+class MeshStorageLayer< MeshConfig, Device, DimensionTag< MeshConfig::meshDimension + 1 >, false >
 {
 public:
-   using DimensionTag               = Meshes::DimensionTag< 0 >;
-   using SuperentityStorageBaseType = MeshSuperentityStorageLayers< MeshConfig, Device, MeshVertexTopology >;
-   using BoundaryTagsBaseType       = MeshBoundaryTagsLayer< MeshConfig, Device, Meshes::DimensionTag< 0 > >;
-
-   using MeshTraitsType             = MeshTraits< MeshConfig, Device >;
-   using EntityTraitsType           = typename MeshTraitsType::template EntityTraits< 0 >;
-   using StorageArrayType           = typename EntityTraitsType::StorageArrayType;
-   using GlobalIndexType            = typename EntityTraitsType::GlobalIndexType;
-   using VertexType                 = typename EntityTraitsType::EntityType;
-   using PointType                  = typename VertexType::PointType;
-   using EntityTopology             = MeshVertexTopology;
-
-   using BoundaryTagsBaseType::resetBoundaryTags;
-   using BoundaryTagsBaseType::isBoundaryEntity;
-   using BoundaryTagsBaseType::setIsBoundaryEntity;
-   using BoundaryTagsBaseType::updateBoundaryIndices;
-   using BoundaryTagsBaseType::getBoundaryEntitiesCount;
-   using BoundaryTagsBaseType::getBoundaryEntityIndex;
-   using BoundaryTagsBaseType::getInteriorEntitiesCount;
-   using BoundaryTagsBaseType::getInteriorEntityIndex;
+   using DimensionTag     = DimensionTag< MeshConfig::meshDimension >;
+   using GlobalIndexType  = typename MeshConfig::GlobalIndexType;
 
    MeshStorageLayer() = default;
 
-   explicit MeshStorageLayer( const MeshStorageLayer& other )
-   {
-      operator=( other );
-   }
+   explicit MeshStorageLayer( const MeshStorageLayer& other ) {}
 
    template< typename Device_ >
-   MeshStorageLayer( const MeshStorageLayer< MeshConfig, Device_, DimensionTag >& other )
-   {
-      operator=( other );
-   }
+   MeshStorageLayer( const MeshStorageLayer< MeshConfig, Device_, DimensionTag >& other ) {}
 
    MeshStorageLayer& operator=( const MeshStorageLayer& other )
    {
-      SuperentityStorageBaseType::operator=( other );
-      BoundaryTagsBaseType::operator=( other );
-      // TODO: throw exception if allocation fails
-      vertices.setLike( other.vertices);
-      vertices = other.vertices;
       return *this;
    }
 
    template< typename Device_ >
    MeshStorageLayer& operator=( const MeshStorageLayer< MeshConfig, Device_, DimensionTag >& other )
    {
-      SuperentityStorageBaseType::operator=( other );
-      BoundaryTagsBaseType::operator=( other );
-      // TODO: throw exception if allocation fails
-      vertices.setLike( other.vertices);
-      vertices = other.vertices;
       return *this;
    }
 
 
-   void setNumberOfEntities( DimensionTag, const GlobalIndexType& entitiesCount )
-   {
-      this->vertices.setSize( entitiesCount );
-      SuperentityStorageBaseType::setNumberOfEntities( entitiesCount );
-      BoundaryTagsBaseType::setNumberOfEntities( entitiesCount );
-   }
-
-   __cuda_callable__
-   GlobalIndexType getEntitiesCount( DimensionTag ) const
-   {
-      return this->vertices.getSize();
-   }
-
-   __cuda_callable__
-   VertexType& getEntity( DimensionTag,
-                          const GlobalIndexType entityIndex )
-   {
-      return this->vertices[ entityIndex ];
-   }
-
-   __cuda_callable__
-   const VertexType& getEntity( DimensionTag,
-                                const GlobalIndexType entityIndex ) const
-   {
-      return this->vertices[ entityIndex ];
-   }
+   void setNumberOfEntities() {}
+   void getEntitiesCount() const {}
+   void getEntity() const {}
 
    bool save( File& file ) const
    {
-      if( ! SuperentityStorageBaseType::save( file ) ||
-          ! BoundaryTagsBaseType::save( file ) ||
-          ! this->vertices.save( file ) )
-      {
-         std::cerr << "Saving of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl;
-         return false;
-      }
       return true;
    }
 
    bool load( File& file )
    {
-      if( ! SuperentityStorageBaseType::load( file ) ||
-          ! BoundaryTagsBaseType::load( file ) ||
-          ! this->vertices.load( file ) )
-      {
-         std::cerr << "Loading of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl;
-         return false;
-      }
       return true;
    }
 
-   void print( std::ostream& str ) const
-   {
-      str << "The mesh vertices are: " << std::endl;
-      for( GlobalIndexType i = 0; i < vertices.getSize(); i++ )
-         str << i << " " << vertices[ i ] << std::endl;
-      SuperentityStorageBaseType::print( str );
-      BoundaryTagsBaseType::print( str );
-      str << std::endl;
-   }
+   void print( std::ostream& str ) const {}
 
    bool operator==( const MeshStorageLayer& meshLayer ) const
    {
-      return ( SuperentityStorageBaseType::operator==( meshLayer ) &&
-               BoundaryTagsBaseType::operator==( meshLayer ) &&
-               vertices == meshLayer.vertices );
+      return true;
    }
 
-protected:
-   StorageArrayType vertices;
 
-   // friend class is needed for templated assignment operators
-   template< typename MeshConfig_, typename Device_, typename DimensionTag_, bool Storage_ >
-   friend class MeshStorageLayer;
-};
-
-/****
- * Forces termination of recursive inheritance (prevents compiler from generating huge error logs)
- */
-template< typename MeshConfig,
-          typename Device >
-class MeshStorageLayer< MeshConfig, Device, DimensionTag< 0 >, false >
-{
-   MeshStorageLayer() = default;
-   explicit MeshStorageLayer( const MeshStorageLayer& other ) {}
+   void resetBoundaryTags() {}
+   void isBoundaryEntity() {}
+   void setIsBoundaryEntity() {}
+   void updateBoundaryIndices() {}
+   void getBoundaryEntitiesCount() {}
+   void getBoundaryEntityIndex() {}
+   void getInteriorEntitiesCount() {}
+   void getInteriorEntityIndex() {}
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSubentityAccess.h b/src/TNL/Meshes/MeshDetails/layers/MeshSubentityAccess.h
index 75fe060dac..2c169a1ca6 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSubentityAccess.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSubentityAccess.h
@@ -13,7 +13,7 @@
 #include <TNL/File.h>
 #include <TNL/Meshes/DimensionTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
-#include <TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h>
+#include <TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h>
 #include <TNL/Meshes/MeshDetails/MeshEntityOrientation.h>
 
 namespace TNL {
@@ -24,7 +24,7 @@ template< typename MeshConfig,
           typename EntityTopology,
           typename DimensionTag,
           bool SubentityStorage =
-               MeshConfig::subentityStorage( EntityTopology(), DimensionTag::value ),
+               WeakSubentityStorageTrait< MeshConfig, Device, EntityTopology, DimensionTag >::storageEnabled,
           bool SubentityOrientationStorage =
                MeshConfig::subentityOrientationStorage( EntityTopology(), DimensionTag::value ) >
 class MeshSubentityAccessLayer;
@@ -141,7 +141,6 @@ class MeshSubentityAccessLayer< MeshConfig,
 protected:
    using GlobalIndexType        = typename SubentityTraitsType::GlobalIndexType;
    using LocalIndexType         = typename SubentityTraitsType::LocalIndexType;
-   using StorageNetworkType     = typename SubentityTraitsType::StorageNetworkType;
    using SubentityAccessorType  = typename SubentityTraitsType::SubentityAccessorType;
    using OrientationArrayType   = typename SubentityTraitsType::OrientationArrayType;
    using IdPermutationArrayType = typename SubentityTraitsType::IdPermutationArrayType;
@@ -286,7 +285,6 @@ class MeshSubentityAccessLayer< MeshConfig,
 protected:
    using GlobalIndexType       = typename SubentityTraitsType::GlobalIndexType;
    using LocalIndexType        = typename SubentityTraitsType::LocalIndexType;
-   using StorageNetworkType    = typename SubentityTraitsType::StorageNetworkType;
    using SubentityAccessorType = typename SubentityTraitsType::SubentityAccessorType;
 
    MeshSubentityAccessLayer() = default;
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h
index 908b1fc9d1..1c4b74731d 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h
@@ -19,7 +19,7 @@
 #include <TNL/File.h>
 #include <TNL/Meshes/DimensionTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
-#include <TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h>
+#include <TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h>
 
 namespace TNL {
 namespace Meshes {
@@ -28,8 +28,7 @@ template< typename MeshConfig,
           typename Device,
           typename EntityTopology,
           typename SubdimensionTag,
-          bool SubentityStorage =
-               MeshConfig::subentityStorage( EntityTopology(), SubdimensionTag::value ) >
+          bool SubentityStorage = WeakSubentityStorageTrait< MeshConfig, Device, EntityTopology, SubdimensionTag >::storageEnabled >
 class MeshSubentityStorageLayer;
 
 template< typename MeshConfig,
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
index a1c101b8d5..f06c23a349 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
@@ -26,8 +26,7 @@ template< typename MeshConfig,
           typename Device,
           typename EntityTopology,
           typename DimensionTag,
-          bool SuperentityStorage =
-             MeshTraits< MeshConfig, Device >::template SuperentityTraits< EntityTopology, DimensionTag::value >::storageEnabled >
+          bool SuperentityStorage = WeakSuperentityStorageTrait< MeshConfig, Device, EntityTopology, DimensionTag >::storageEnabled >
 class MeshSuperentityAccessLayer;
 
 
@@ -130,7 +129,6 @@ class MeshSuperentityAccessLayer< MeshConfig,
 public:
    using GlobalIndexType         = typename SuperentityTraitsType::GlobalIndexType;
    using LocalIndexType          = typename SuperentityTraitsType::LocalIndexType;
-   using StorageNetworkType      = typename SuperentityTraitsType::StorageNetworkType;
    using SuperentityAccessorType = typename SuperentityTraitsType::SuperentityAccessorType;
 
    /****
@@ -248,17 +246,15 @@ class MeshSuperentityAccessLayer< MeshConfig,
                                   false >
 {
    using DimensionTag = Meshes::DimensionTag< EntityTopology::dimension >;
-   using MeshTraitsType = MeshTraits< MeshConfig, Device >;
-   using SuperentityTraitsType = typename MeshTraitsType::template SuperentityTraits< EntityTopology, DimensionTag::value >;
 
 protected:
-   using GlobalIndexType         = typename SuperentityTraitsType::GlobalIndexType;
-   using LocalIndexType          = typename SuperentityTraitsType::LocalIndexType;
-   using SuperentityAccessorType = typename SuperentityTraitsType::SuperentityAccessorType;
+   using GlobalIndexType         = typename MeshConfig::GlobalIndexType;
+   using LocalIndexType          = typename MeshConfig::LocalIndexType;
 
    /***
     * Necessary because of 'using BaseType::...;' in the derived classes
     */
+   template< typename SuperentityAccessorType >
    __cuda_callable__
    void bindSuperentitiesStorageNetwork( DimensionTag,
                                          const SuperentityAccessorType& storage ) {}
@@ -296,17 +292,15 @@ class MeshSuperentityAccessLayer< MeshConfig,
                                   true >
 {
    using DimensionTag = Meshes::DimensionTag< EntityTopology::dimension >;
-   using MeshTraitsType = MeshTraits< MeshConfig, Device >;
-   using SuperentityTraitsType = typename MeshTraitsType::template SuperentityTraits< EntityTopology, DimensionTag::value >;
 
 protected:
-   using GlobalIndexType         = typename SuperentityTraitsType::GlobalIndexType;
-   using LocalIndexType          = typename SuperentityTraitsType::LocalIndexType;
-   using SuperentityAccessorType = typename SuperentityTraitsType::SuperentityAccessorType;
+   using GlobalIndexType         = typename MeshConfig::GlobalIndexType;
+   using LocalIndexType          = typename MeshConfig::LocalIndexType;
 
    /***
     * Necessary because of 'using BaseType::...;' in the derived classes
     */
+   template< typename SuperentityAccessorType >
    __cuda_callable__
    void bindSuperentitiesStorageNetwork( DimensionTag,
                                          const SuperentityAccessorType& storage ) {}
@@ -336,4 +330,3 @@ protected:
 
 } // namespace Meshes
 } // namespace TNL
-
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h
index 6b12a7f41b..8bbae013a2 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h
@@ -19,7 +19,7 @@
 #include <TNL/File.h>
 #include <TNL/Meshes/DimensionTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
-#include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h>
+#include <TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h>
 
 namespace TNL {
 namespace Meshes {
@@ -28,8 +28,7 @@ template< typename MeshConfig,
           typename Device,
           typename EntityTopology,
           typename SuperdimensionTag,
-          bool SuperentityStorage =
-               MeshTraits< MeshConfig, Device >::template SuperentityTraits< EntityTopology, SuperdimensionTag::value >::storageEnabled >
+          bool SuperentityStorage = WeakSuperentityStorageTrait< MeshConfig, Device, EntityTopology, SuperdimensionTag >::storageEnabled >
 class MeshSuperentityStorageLayer;
 
 template< typename MeshConfig,
@@ -79,7 +78,6 @@ class MeshSuperentityStorageLayer< MeshConfig, Device, EntityTopology, Superdime
 
 protected:
    using GlobalIndexType    = typename SuperentityTraitsType::GlobalIndexType;
-   using LocalIndexType     = typename SuperentityTraitsType::LocalIndexType;
    using StorageNetworkType = typename SuperentityTraitsType::StorageNetworkType;
  
    MeshSuperentityStorageLayer() = default;
@@ -199,13 +197,9 @@ template< typename MeshConfig,
 class MeshSuperentityStorageLayer< MeshConfig, Device, EntityTopology, DimensionTag< EntityTopology::dimension >, false >
 {
    using SuperdimensionTag = DimensionTag< EntityTopology::dimension >;
-   using MeshTraitsType = MeshTraits< MeshConfig, Device >;
-   using SuperentityTraitsType = typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionTag::value >;
 
 protected:
-   using GlobalIndexType    = typename SuperentityTraitsType::GlobalIndexType;
-   using LocalIndexType     = typename SuperentityTraitsType::LocalIndexType;
-   using StorageNetworkType = typename SuperentityTraitsType::StorageNetworkType;
+   using GlobalIndexType = typename MeshConfig::GlobalIndexType;
  
    MeshSuperentityStorageLayer() = default;
    explicit MeshSuperentityStorageLayer( const MeshSuperentityStorageLayer& other ) {}
@@ -249,13 +243,9 @@ class MeshSuperentityStorageLayer< MeshConfig,
                                    true >
 {
    using SuperdimensionTag = DimensionTag< EntityTopology::dimension >;
-   using MeshTraitsType = MeshTraits< MeshConfig, Device >;
-   using SuperentityTraitsType = typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionTag::value >;
 
 protected:
-   using GlobalIndexType    = typename SuperentityTraitsType::GlobalIndexType;
-   using LocalIndexType     = typename SuperentityTraitsType::LocalIndexType;
-   using StorageNetworkType = typename SuperentityTraitsType::StorageNetworkType;
+   using GlobalIndexType = typename MeshConfig::GlobalIndexType;
  
    MeshSuperentityStorageLayer() = default;
    explicit MeshSuperentityStorageLayer( const MeshSuperentityStorageLayer& other ) {}
diff --git a/src/TNL/Meshes/MeshDetails/traits/CMakeLists.txt b/src/TNL/Meshes/MeshDetails/traits/CMakeLists.txt
index b82bb335ac..90b0fafc1c 100644
--- a/src/TNL/Meshes/MeshDetails/traits/CMakeLists.txt
+++ b/src/TNL/Meshes/MeshDetails/traits/CMakeLists.txt
@@ -2,6 +2,7 @@ SET( headers MeshTraits.h
              MeshEntityTraits.h
              MeshSubentityTraits.h
              MeshSuperentityTraits.h
+             WeakStorageTraits.h
                )
 
-INSTALL( FILES ${headers} DESTINATION ${TNL_TARGET_INCLUDE_DIRECTORY}/Meshes/MeshDetails/traits )
\ No newline at end of file
+INSTALL( FILES ${headers} DESTINATION ${TNL_TARGET_INCLUDE_DIRECTORY}/Meshes/MeshDetails/traits )
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h
index 33715d0821..a26761b33e 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h
@@ -31,8 +31,7 @@ class MeshSuperentityTraits
 {
 public:
    static_assert( 0 <= Dimension && Dimension <= MeshConfig::meshDimension, "invalid dimension" );
-   // FIXME: this would break MeshSuperentityAccess, but it should be possible to implement it similarly to MeshSubentityAccess
-   //static_assert( EntityTopology::dimension < Dimension, "Superentity dimension must be higher than the entity dimension." );
+   static_assert( EntityTopology::dimension < Dimension, "Superentity dimension must be higher than the entity dimension." );
 
    static constexpr bool storageEnabled = MeshConfig::template superentityStorage< EntityTopology >( EntityTopology(), Dimension );
 
diff --git a/src/TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h b/src/TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h
new file mode 100644
index 0000000000..154681fdd5
--- /dev/null
+++ b/src/TNL/Meshes/MeshDetails/traits/WeakStorageTraits.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+                          MeshSuperentityStorageLayer.h  -  description
+                             -------------------
+    begin                : Feb 13, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
+#pragma once
+
+#include <TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h>
+#include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h>
+
+namespace TNL {
+namespace Meshes {
+
+template< typename MeshConfig,
+          typename Device,
+          typename DimensionTag,
+          bool sensible = (DimensionTag::value <= MeshConfig::meshDimension) >
+struct WeakEntityStorageTrait
+{
+   static constexpr bool storageEnabled = MeshTraits< MeshConfig, Device >::template EntityTraits< DimensionTag::value >::storageEnabled;
+};
+
+template< typename MeshConfig,
+          typename Device,
+          typename DimensionTag >
+struct WeakEntityStorageTrait< MeshConfig, Device, DimensionTag, false >
+{
+   static constexpr bool storageEnabled = false;
+};
+
+
+template< typename MeshConfig,
+          typename Device,
+          typename EntityTopology,
+          typename SubdimensionTag,
+          bool sensible = (SubdimensionTag::value < EntityTopology::dimension) >
+struct WeakSubentityStorageTrait
+{
+   static constexpr bool storageEnabled = MeshTraits< MeshConfig, Device >::template SubentityTraits< EntityTopology, SubdimensionTag::value >::storageEnabled;
+};
+
+template< typename MeshConfig,
+          typename Device,
+          typename EntityTopology,
+          typename SubdimensionTag >
+struct WeakSubentityStorageTrait< MeshConfig, Device, EntityTopology, SubdimensionTag, false >
+{
+   static constexpr bool storageEnabled = false;
+};
+
+
+template< typename MeshConfig,
+          typename Device,
+          typename EntityTopology,
+          typename SuperdimensionTag,
+          bool sensible = (SuperdimensionTag::value > EntityTopology::dimension) >
+struct WeakSuperentityStorageTrait
+{
+   static constexpr bool storageEnabled = MeshTraits< MeshConfig, Device >::template SuperentityTraits< EntityTopology, SuperdimensionTag::value >::storageEnabled;
+};
+
+template< typename MeshConfig,
+          typename Device,
+          typename EntityTopology,
+          typename SuperdimensionTag >
+struct WeakSuperentityStorageTrait< MeshConfig, Device, EntityTopology, SuperdimensionTag, false >
+{
+   static constexpr bool storageEnabled = false;
+};
+
+} // namespace Meshes
+} // namespace TNL
-- 
GitLab