/*************************************************************************** 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 { static void exec( Mesh& mesh ) { MeshEntityStorageRebinderSuperentityWorker< Mesh, DimensionsTag, SuperdimensionsTag >:: template exec< MeshEntityStorageRebinderWorker >( mesh ); MeshEntityStorageRebinderSubentityWorker< Mesh, DimensionsTag, SuperdimensionsTag >:: template exec< MeshEntityStorageRebinderWorker >( mesh ); } static void bindSuperentities( Mesh& 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 { static void exec( Mesh& mesh ) { 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 > { static void exec( Mesh& mesh ) { MeshEntityStorageRebinderWorker< Mesh, typename SuperdimensionsTag::Decrement, SuperdimensionsTag >::exec( mesh ); } }; template< typename Mesh, typename DimensionsTag = typename MeshDimensionsTag< Mesh::MeshTraitsType::meshDimensions >::Decrement > struct MeshEntityStorageRebinder { static void exec( Mesh& mesh ) { MeshEntityStorageRebinderInner< Mesh, DimensionsTag, MeshDimensionsTag< Mesh::MeshTraitsType::meshDimensions > >::exec( mesh ); MeshEntityStorageRebinder< Mesh, typename DimensionsTag::Decrement >::exec( mesh ); } }; template< typename Mesh > struct MeshEntityStorageRebinder< Mesh, MeshDimensionsTag< 0 > > { static void exec( Mesh& mesh ) { MeshEntityStorageRebinderInner< Mesh, MeshDimensionsTag< 0 >, MeshDimensionsTag< Mesh::MeshTraitsType::meshDimensions > >::exec( mesh ); } }; } // namespace Meshes } // namespace TNL