Commit 8708b2e0 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Optimized the initialization of mesh links from subentities to superentities

parent 56652119
Loading
Loading
Loading
Loading
+83 −18
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#include <TNL/Meshes/MeshDetails/initializer/EntitySeed.h>
#include <TNL/Meshes/MeshDetails/initializer/SubentitySeedsCreator.h>
#include <TNL/Meshes/MeshDetails/initializer/SuperentityStorageInitializer.h>

namespace TNL {
namespace Meshes {
@@ -119,32 +118,55 @@ class EntityInitializerLayer< MeshConfig,

   using GlobalIndexType            = typename MeshTraits< MeshConfig >::GlobalIndexType;
   using LocalIndexType             = typename MeshTraits< MeshConfig >::LocalIndexType;
   using SubentityTraitsType        = typename MeshTraits< MeshConfig >::template EntityTraits< SubdimensionTag::value >;
   using SubentityTopology          = typename SubentityTraitsType::EntityTopology;
   using SuperentityTraitsType      = typename MeshTraits< MeshConfig >::template EntityTraits< SuperdimensionTag::value >;
   using SuperentityTopology        = typename SuperentityTraitsType::EntityTopology;
   using SubentitySeedsCreatorType  = SubentitySeedsCreator< MeshConfig, SuperdimensionTag, SubdimensionTag >;
   using SuperentityInitializerType = SuperentityStorageInitializer< MeshConfig, SubdimensionTag, SuperdimensionTag >;
   using SuperentityStorageNetwork  = typename MeshTraits< MeshConfig >::template SuperentityTraits< SubentityTopology, SuperdimensionTag::value >::StorageNetworkType;
   using ValuesAllocationVectorType = typename SuperentityStorageNetwork::ValuesAllocationVectorType;

public:
   static void initSuperentities( InitializerType& meshInitializer, MeshType& mesh )
   {
      //std::cout << "   Initiating superentities with dimension " << SuperdimensionTag::value << " for subentities with dimension " << SubdimensionTag::value << " ... " << std::endl;
      SuperentityInitializerType superentityInitializer;

      // counter for superentities of each subentity
      const GlobalIndexType subentitiesCount = mesh.template getEntitiesCount< SubdimensionTag::value >();
      ValuesAllocationVectorType superentitiesCounts( subentitiesCount );
      superentitiesCounts.setValue( 0 );

      for( GlobalIndexType superentityIndex = 0;
           superentityIndex < mesh.template getEntitiesCount< SuperdimensionTag::value >();
           superentityIndex++ )
      {
         auto subentitySeeds = SubentitySeedsCreatorType::create( meshInitializer.template getSubvertices< SuperdimensionTag::value >( superentityIndex ) );

         for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
         {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
            meshInitializer.template setSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i, subentityIndex );
            superentityInitializer.addSuperentity( subentityIndex, superentityIndex );
            superentitiesCounts[ subentityIndex ]++;
         }
      }

      superentityInitializer.initSuperentities( meshInitializer );
      // allocate superentities storage
      SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< SubdimensionTag::value, SuperdimensionTag::value >();
      superentityStorageNetwork.allocate( superentitiesCounts );
      superentitiesCounts.setValue( 0 );

      // initialize superentities storage
      for( GlobalIndexType superentityIndex = 0;
           superentityIndex < mesh.template getEntitiesCount< SuperdimensionTag::value >();
           superentityIndex++ )
      {
         for( LocalIndexType i = 0;
              i < mesh.template getSubentitiesCount< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex );
              i++ )
         {
            const GlobalIndexType subentityIndex = mesh.template getSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i );
            superentityStorageNetwork.getValues( subentityIndex ).setValue( superentitiesCounts[ subentityIndex ]++, superentityIndex );
         }
      }

      BaseType::initSuperentities( meshInitializer, mesh );
   }
@@ -178,36 +200,57 @@ class EntityInitializerLayer< MeshConfig,

   using GlobalIndexType            = typename MeshTraits< MeshConfig >::GlobalIndexType;
   using LocalIndexType             = typename MeshTraits< MeshConfig >::LocalIndexType;
   using SubentityTraitsType        = typename MeshTraits< MeshConfig >::template EntityTraits< SubdimensionTag::value >;
   using SubentityTopology          = typename SubentityTraitsType::EntityTopology;
   using SuperentityTraitsType      = typename MeshTraits< MeshConfig >::template EntityTraits< SuperdimensionTag::value >;
   using SuperentityTopology        = typename SuperentityTraitsType::EntityTopology;
   using SubentitySeedsCreatorType  = SubentitySeedsCreator< MeshConfig, SuperdimensionTag, SubdimensionTag >;
   using SuperentityInitializerType = SuperentityStorageInitializer< MeshConfig, SubdimensionTag, SuperdimensionTag >;
   using SuperentityStorageNetwork  = typename MeshTraits< MeshConfig >::template SuperentityTraits< SubentityTopology, SuperdimensionTag::value >::StorageNetworkType;
   using ValuesAllocationVectorType = typename SuperentityStorageNetwork::ValuesAllocationVectorType;

public:
   static void initSuperentities( InitializerType& meshInitializer, MeshType& mesh )
   {
      //std::cout << "   Initiating superentities with dimension " << SuperdimensionTag::value << " for subentities with dimension " << SubdimensionTag::value << " ... " << std::endl;
      SuperentityInitializerType superentityInitializer;

      // counter for superentities of each subentity
      const GlobalIndexType subentitiesCount = mesh.template getEntitiesCount< SubdimensionTag::value >();
      ValuesAllocationVectorType superentitiesCounts( subentitiesCount );
      superentitiesCounts.setValue( 0 );

      for( GlobalIndexType superentityIndex = 0;
           superentityIndex < mesh.template getEntitiesCount< SuperdimensionTag::value >();
           superentityIndex++ )
      {
         auto subentitySeeds = SubentitySeedsCreatorType::create( meshInitializer.template getSubvertices< SuperdimensionTag::value >( superentityIndex ) );

         auto& subentityOrientationsArray = meshInitializer.template subentityOrientationsArray< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex );

         for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
         {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
            meshInitializer.template setSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i, subentityIndex );
            superentityInitializer.addSuperentity( subentityIndex, superentityIndex );

            superentitiesCounts[ subentityIndex ]++;
            subentityOrientationsArray[ i ] = meshInitializer.template getReferenceOrientation< SubdimensionTag >( subentityIndex ).createOrientation( subentitySeeds[ i ] );
         }
      }

      superentityInitializer.initSuperentities( meshInitializer );
      // allocate superentities storage
      SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< SubdimensionTag::value, SuperdimensionTag::value >();
      superentityStorageNetwork.allocate( superentitiesCounts );
      superentitiesCounts.setValue( 0 );

      // initialize superentities storage
      for( GlobalIndexType superentityIndex = 0;
           superentityIndex < mesh.template getEntitiesCount< SuperdimensionTag::value >();
           superentityIndex++ )
      {
         for( LocalIndexType i = 0;
              i < mesh.template getSubentitiesCount< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex );
              i++ )
         {
            const GlobalIndexType subentityIndex = mesh.template getSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i );
            superentityStorageNetwork.getValues( subentityIndex ).setValue( superentitiesCounts[ subentityIndex ]++, superentityIndex );
         }
      }

      BaseType::initSuperentities( meshInitializer, mesh );
   }
@@ -351,31 +394,53 @@ class EntityInitializerLayer< MeshConfig,

   using GlobalIndexType            = typename MeshTraits< MeshConfig >::GlobalIndexType;
   using LocalIndexType             = typename MeshTraits< MeshConfig >::LocalIndexType;
   using SubentityTraitsType        = typename MeshTraits< MeshConfig >::template EntityTraits< SubdimensionTag::value >;
   using SubentityTopology          = typename SubentityTraitsType::EntityTopology;
   using SuperentityTraitsType      = typename MeshTraits< MeshConfig >::template EntityTraits< SuperdimensionTag::value >;
   using SuperentityTopology        = typename SuperentityTraitsType::EntityTopology;
   using SubentitySeedsCreatorType  = SubentitySeedsCreator< MeshConfig, SuperdimensionTag, SubdimensionTag >;
   using SuperentityInitializerType = SuperentityStorageInitializer< MeshConfig, SubdimensionTag, SuperdimensionTag >;
   using SuperentityStorageNetwork  = typename MeshTraits< MeshConfig >::template SuperentityTraits< SubentityTopology, SuperdimensionTag::value >::StorageNetworkType;
   using ValuesAllocationVectorType = typename SuperentityStorageNetwork::ValuesAllocationVectorType;

public:
   static void initSuperentities( InitializerType& meshInitializer, MeshType& mesh )
   {
      //std::cout << "   Initiating superentities with dimension " << SuperdimensionTag::value << " for subentities with dimension " << SubdimensionTag::value << " ... " << std::endl;
      SuperentityInitializerType superentityInitializer;

      // counter for superentities of each subentity
      const GlobalIndexType subentitiesCount = mesh.template getEntitiesCount< SubdimensionTag::value >();
      ValuesAllocationVectorType superentitiesCounts( subentitiesCount );
      superentitiesCounts.setValue( 0 );

      for( GlobalIndexType superentityIndex = 0;
           superentityIndex < mesh.template getEntitiesCount< SuperdimensionTag::value >();
           superentityIndex++ )
      {
         auto subentitySeeds = SubentitySeedsCreatorType::create( meshInitializer.template getSubvertices< SuperdimensionTag::value >( superentityIndex ) );

         for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
         {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
            superentityInitializer.addSuperentity( subentityIndex, superentityIndex );
            superentitiesCounts[ subentityIndex ]++;
         }
      }

      superentityInitializer.initSuperentities( meshInitializer );
      // allocate superentities storage
      SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< SubdimensionTag::value, SuperdimensionTag::value >();
      superentityStorageNetwork.allocate( superentitiesCounts );
      superentitiesCounts.setValue( 0 );

      // initialize superentities storage
      for( GlobalIndexType superentityIndex = 0;
           superentityIndex < mesh.template getEntitiesCount< SuperdimensionTag::value >();
           superentityIndex++ )
      {
         auto subentitySeeds = SubentitySeedsCreatorType::create( meshInitializer.template getSubvertices< SuperdimensionTag::value >( superentityIndex ) );
         for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
         {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
            superentityStorageNetwork.getValues( subentityIndex ).setValue( superentitiesCounts[ subentityIndex ]++, superentityIndex );
         }
      }

      BaseType::initSuperentities( meshInitializer, mesh );
   }
+0 −102
Original line number Diff line number Diff line
/***************************************************************************
                          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 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< SubdimensionTag::value, 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