/*************************************************************************** SuperentityStorageInitializer.h - description ------------------- begin : Feb 27, 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 <set> #include <unordered_map> #include <TNL/Meshes/DimensionTag.h> #include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h> namespace TNL { namespace Meshes { template< typename MeshConfig > class Initializer; template< typename MeshConfig, typename SubdimensionTag, typename SuperdimensionTag > class SuperentityStorageInitializer { using MeshTraitsType = MeshTraits< MeshConfig >; using InitializerType = Initializer< MeshConfig >; using GlobalIndexType = typename MeshTraitsType::GlobalIndexType; using LocalIndexType = typename MeshTraitsType::LocalIndexType; using EntityTraitsType = typename MeshTraitsType::template EntityTraits< SubdimensionTag::value >; using EntityTopology = typename EntityTraitsType::EntityTopology; using EntityType = typename EntityTraitsType::EntityType; using SuperentityTraitsType = typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionTag::value >; using SuperentityStorageNetwork = typename SuperentityTraitsType::StorageNetworkType; public: void addSuperentity( GlobalIndexType entityIndex, GlobalIndexType superentityIndex) { //std::cout << "Adding superentity with " << SuperdimensionTag::value << " dimension of entity with " << SubdimensionTag::value << " dimension: entityIndex = " << entityIndex << ", superentityIndex = " << superentityIndex << std::endl; auto& indexSet = this->dynamicStorageNetwork[ entityIndex ]; TNL_ASSERT( indexSet.count( superentityIndex ) == 0, std::cerr << "Superentity " << superentityIndex << " with dimension " << SuperdimensionTag::value << " of entity " << entityIndex << " with dimension " << SubdimensionTag::value << " has been already added. This is probably a bug in the mesh initializer." << std::endl; ); indexSet.insert( superentityIndex ); } void initSuperentities( InitializerType& meshInitializer ) { TNL_ASSERT_GT( dynamicStorageNetwork.size(), (size_t) 0, "No superentity indices were collected. This is a bug in the mesh initializer." ); TNL_ASSERT_EQ( (size_t) getMaxSuperentityIndex(), dynamicStorageNetwork.size() - 1, "Superentities for some entities are missing. " "This is probably a bug in the mesh initializer." ); SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< EntityTopology, SuperdimensionTag::value >(); TNL_ASSERT_EQ( (size_t) superentityStorageNetwork.getKeysRange(), dynamicStorageNetwork.size(), "Sizes of the static and dynamic storage networks don't match. " "This is probably a bug in the mesh initializer." ); typename SuperentityStorageNetwork::ValuesAllocationVectorType storageNetworkAllocationVector; storageNetworkAllocationVector.setSize( superentityStorageNetwork.getKeysRange() ); for( auto it = dynamicStorageNetwork.cbegin(); it != dynamicStorageNetwork.cend(); it++ ) storageNetworkAllocationVector[ it->first ] = it->second.size(); superentityStorageNetwork.allocate( storageNetworkAllocationVector ); 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; } dynamicStorageNetwork.clear(); } private: using DynamicIndexSet = std::set< GlobalIndexType >; std::unordered_map< GlobalIndexType, DynamicIndexSet > dynamicStorageNetwork; GlobalIndexType getMaxSuperentityIndex() { GlobalIndexType max = 0; for( auto it = dynamicStorageNetwork.cbegin(); it != dynamicStorageNetwork.cend(); it++ ) { if( it->first > max ) max = it->first; } return max; } }; } // namespace Meshes } // namespace TNL