Newer
Older
/***************************************************************************
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
*/
#include <unordered_map>
#include <TNL/Meshes/DimensionTag.h>
#include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h>
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;
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;
}