Skip to content
Snippets Groups Projects
MeshEntityStorageRebinder.h 6.55 KiB
Newer Older
  • Learn to ignore specific revisions
  • /***************************************************************************
    
                              MeshEntityStorageRebinder.h  -  description
    
                                 -------------------
        begin                : Oct 22, 2016
        copyright            : (C) 2014 by Tomas Oberhuber et al.
        email                : tomas.oberhuber@fjfi.cvut.cz
     ***************************************************************************/
    
    /* See Copyright Notice in tnl/Copyright */
    
    #pragma once
    
    /*
     * Everything in this file is basically just a templatized version of the
     * following pseudo-code (which does not work because normal variables are not
     * usable in template arguments):
     *
     *   for( int dimensions = 0; dimensions < MeshTraitsType::meshDimensions; dimensions++ )
     *      for( int superdimensions = dimensions + 1; superdimensions <= MeshTraitsType::meshDimensions; superdimensions++ )
     *         if( EntityTraits< dimensions >::SuperentityTraits< superdimensions >::storageEnabled )
     *            for( GlobalIndexType i = 0; i < mesh.template getNumberOfEntities< dimensions >(); i++ )
     *            {
     *               auto& entity = mesh.template getEntity< dimensions >( i );
     *               entity.template bindSuperentitiesStorageNetwork< superdimensions >( mesh.template getSuperentityStorageNetwork< superdimensions >().getValues( i ) );
     *            }
     */
    
    #include <TNL/Meshes/MeshDimensionsTag.h>
    
    namespace TNL {
    namespace Meshes {
    
    
    template< typename Mesh,
              typename DimensionsTag,
              typename SuperdimensionsTag,
              bool Enabled =
                 Mesh::MeshTraitsType::template SuperentityTraits< typename Mesh::template EntityType< DimensionsTag::value >::EntityTopology,
                                                                   SuperdimensionsTag::value >::storageEnabled
              >
    struct MeshEntityStorageRebinderSuperentityWorker
    {
       template< typename Worker >
       static void exec( Mesh& mesh )
       {
          // If the reader is wondering why the code is in the Worker and not here:
          // that's because we're accessing protected method bindSuperentitiesStorageNetwork
          // and friend templates in GCC 6.1 apparently don't play nice with partial
          // template specializations.
          Worker::bindSuperentities( mesh );
       }
    };
    
    template< typename Mesh,
              typename DimensionsTag,
              typename SuperdimensionsTag >
    struct MeshEntityStorageRebinderSuperentityWorker< Mesh, DimensionsTag, SuperdimensionsTag, false >
    {
       template< typename Worker >
       static void exec( Mesh& mesh ) {}
    };
    
    
    template< typename Mesh,
              typename DimensionsTag,
              typename SuperdimensionsTag,
              bool Enabled =
                 Mesh::MeshTraitsType::template SubentityTraits< typename Mesh::template EntityType< SuperdimensionsTag::value >::EntityTopology,
                                                                 DimensionsTag::value >::storageEnabled
              >
    struct MeshEntityStorageRebinderSubentityWorker
    {
       template< typename Worker >
       static void exec( Mesh& mesh )
       {
          // If the reader is wondering why the code is in the Worker and not here:
          // that's because we're accessing protected method bindSubentitiesStorageNetwork
          // and friend templates in GCC 6.1 apparently don't play nice with partial
          // template specializations.
          Worker::bindSubentities( mesh );
       }
    };
    
    template< typename Mesh,
              typename DimensionsTag,
              typename SuperdimensionsTag >
    struct MeshEntityStorageRebinderSubentityWorker< Mesh, DimensionsTag, SuperdimensionsTag, false >
    {
       template< typename Worker >
       static void exec( Mesh& mesh ) {}
    };
    
    
    
    template< typename Mesh, typename DimensionsTag, typename SuperdimensionsTag >
    
    struct MeshEntityStorageRebinderWorker
    
          MeshEntityStorageRebinderSuperentityWorker< Mesh, DimensionsTag, SuperdimensionsTag >::
             template exec< MeshEntityStorageRebinderWorker >( mesh );
          MeshEntityStorageRebinderSubentityWorker< Mesh, DimensionsTag, SuperdimensionsTag >::
             template exec< MeshEntityStorageRebinderWorker >( mesh );
       }
    
          for( typename Mesh::GlobalIndexType i = 0; i < mesh.template getNumberOfEntities< DimensionsTag::value >(); i++ )
          {
    
             auto& subentity = mesh.template getEntity< DimensionsTag::value >( i );
             auto& superentitiesStorage = mesh.template getSuperentityStorageNetwork< DimensionsTag::value, SuperdimensionsTag::value >();
             subentity.template bindSuperentitiesStorageNetwork< SuperdimensionsTag::value >( superentitiesStorage.getValues( i ) );
    
    
       static void bindSubentities( Mesh& mesh )
       {
          for( typename Mesh::GlobalIndexType i = 0; i < mesh.template getNumberOfEntities< SuperdimensionsTag::value >(); i++ )
          {
             auto& superentity = mesh.template getEntity< SuperdimensionsTag::value >( i );
             auto& subentitiesStorage = mesh.template getSubentityStorageNetwork< SuperdimensionsTag::value, DimensionsTag::value >();
             superentity.template bindSubentitiesStorageNetwork< DimensionsTag::value >( subentitiesStorage.getValues( i ) );
          }
       }
    
    };
    
    
    template< typename Mesh, typename DimensionsTag, typename SuperdimensionsTag >
    
    struct MeshEntityStorageRebinderInner
    
          MeshEntityStorageRebinderWorker< Mesh, DimensionsTag, SuperdimensionsTag >::exec( mesh );
          MeshEntityStorageRebinderInner< Mesh, DimensionsTag, typename SuperdimensionsTag::Decrement >::exec( mesh );
    
       }
    };
    
    template< typename Mesh, typename SuperdimensionsTag >
    
    struct MeshEntityStorageRebinderInner< Mesh, typename SuperdimensionsTag::Decrement, SuperdimensionsTag >
    
          MeshEntityStorageRebinderWorker< Mesh, typename SuperdimensionsTag::Decrement, SuperdimensionsTag >::exec( mesh );
    
       }
    };
    
    
    template< typename Mesh, typename DimensionsTag = typename MeshDimensionsTag< Mesh::MeshTraitsType::meshDimensions >::Decrement >
    
          MeshEntityStorageRebinderInner< Mesh, DimensionsTag, MeshDimensionsTag< Mesh::MeshTraitsType::meshDimensions > >::exec( mesh );
          MeshEntityStorageRebinder< Mesh, typename DimensionsTag::Decrement >::exec( mesh );
    
    struct MeshEntityStorageRebinder< Mesh, MeshDimensionsTag< 0 > >
    
          MeshEntityStorageRebinderInner< Mesh, MeshDimensionsTag< 0 >, MeshDimensionsTag< Mesh::MeshTraitsType::meshDimensions > >::exec( mesh );