Skip to content
Snippets Groups Projects
tnlMeshSuperentityStorageInitializer.h 10.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • /***************************************************************************
    
                              tnlMeshSuperentityStorageInitializer.h  -  description
    
                                 -------------------
        begin                : Feb 27, 2014
        copyright            : (C) 2014 by Tomas Oberhuber
        email                : tomas.oberhuber@fjfi.cvut.cz
     ***************************************************************************/
    
    /***************************************************************************
     *                                                                         *
     *   This program is free software; you can redistribute it and/or modify  *
     *   it under the terms of the GNU General Public License as published by  *
     *   the Free Software Foundation; either version 2 of the License, or     *
     *   (at your option) any later version.                                   *
     *                                                                         *
     ***************************************************************************/
    
    
    #ifndef TNLMESHSUPERENTITYSTORAGEINITIALIZER_H_
    #define TNLMESHSUPERENTITYSTORAGEINITIALIZER_H_
    
    #include <mesh/tnlDimensionsTag.h>
    
    #include <algorithm>
    
    template< typename MeshConfig >
    
    class tnlMeshInitializer;
    
    template< typename MeshConfig,
    
              typename EntityTopology,
    
              typename DimensionsTag,
    
              bool SuperentityStorage = tnlMeshSuperentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >::storageEnabled >
    
    class tnlMeshSuperentityStorageInitializerLayer;
    
    
    template< typename MeshConfig,
    
              typename EntityTopology >
    
    class tnlMeshSuperentityStorageInitializer :
    
       public tnlMeshSuperentityStorageInitializerLayer< MeshConfig, EntityTopology, tnlDimensionsTag< tnlMeshTraits< MeshConfig >::meshDimensions > >
    
    template< typename MeshConfig,
    
              typename EntityTopology,
    
              typename DimensionsTag >
    
    class tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                              EntityTopology,
    
                                              DimensionsTag,
    
                                              true >
    
       : public tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                                    EntityTopology,
    
                                                    typename DimensionsTag::Decrement >
    
       typedef tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                                          EntityTopology,
    
                                                          typename DimensionsTag::Decrement >      BaseType;
    
       static const int Dimensions = DimensionsTag::value;
    
       typedef tnlDimensionsTag< EntityTopology::dimensions >                                    EntityDimensions;
    
       typedef tnlMeshTraits< MeshConfig >                                                      MeshTraits;
       typedef typename MeshTraits::GlobalIdArrayType                                           GlobalIdArrayType;
    
       typedef typename MeshTraits::GlobalIndexType                                             GlobalIndexType;
       typedef typename MeshTraits::LocalIndexType                                              LocalIndexType;
       typedef tnlMeshInitializer< MeshConfig >                                                 MeshInitializer;
       typedef typename MeshTraits::template SuperentityTraits< EntityTopology, Dimensions >    SuperentityTraits;
       typedef typename SuperentityTraits::StorageNetworkType                                   SuperentityStorageNetwork;
    
    
       public:      
          using BaseType::addSuperentity;
    	   
          void addSuperentity( DimensionsTag, GlobalIndexType entityIndex, GlobalIndexType superentityIndex)
          {
    
             //cout << "Adding superentity with " << DimensionsTag::value << " dimensions of enity with " << EntityDimensions::value << " ... " << endl;
             indexPairs.push_back( IndexPair{ entityIndex, superentityIndex } );
    
    Tomáš Oberhuber's avatar
    Tomáš Oberhuber committed
          using BaseType::initSuperentities;
    
          void initSuperentities( MeshInitializer& meshInitializer )
          {
             std::sort( indexPairs.begin(),
                        indexPairs.end(),
                        []( IndexPair pair0, IndexPair pair1 ){ return ( pair0.entityIndex < pair1.entityIndex ); } );
    
    
             GlobalIdArrayType &superentityIdsArray = meshInitializer.template meshSuperentityIdsArray< EntityDimensions, DimensionsTag >();         
    
             superentityIdsArray.setSize( static_cast< GlobalIndexType >( indexPairs.size() )  );
             GlobalIndexType currentBegin = 0;
             GlobalIndexType lastEntityIndex = 0;
    
             cout << "There are " << superentityIdsArray.getSize() << " superentities with " << DimensionsTag::value << " dimensions of enities with " << EntityDimensions::value << " ... " << endl;
    
             for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
             {
                superentityIdsArray[ i ] = indexPairs[i].superentityIndex;
    
                //cout << "Adding superentity " << indexPairs[i].superentityIndex << " to entity " << lastEntityIndex << endl;
    
                if( indexPairs[ i ].entityIndex != lastEntityIndex )
                {
                   meshInitializer.template superentityIdsArray< DimensionsTag >( meshInitializer.template meshEntitiesArray< EntityDimensions >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, i - currentBegin );
                   currentBegin = i;
                   lastEntityIndex = indexPairs[ i ].entityIndex;
                }
             }
    
             meshInitializer.template superentityIdsArray< DimensionsTag >( meshInitializer.template meshEntitiesArray< EntityDimensions >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, superentityIdsArray.getSize() - currentBegin );
             indexPairs.clear();
    
             SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< EntityTopology, DimensionsTag >();
             //GlobalIndexType lastEntityIndex( 0 );
    
             superentityStorageNetwork.setRanges(
    
                meshInitializer.template meshEntitiesArray< EntityDimensions >().getSize(),
                meshInitializer.template meshEntitiesArray< DimensionsTag >().getSize() );
             lastEntityIndex = 0;
    
             typename SuperentityStorageNetwork::ValuesAllocationVectorType storageNetworkAllocationVector;
    
             storageNetworkAllocationVector.setSize( meshInitializer.template meshEntitiesArray< EntityDimensions >().getSize() );
             storageNetworkAllocationVector.setValue( 0 );
             for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
             {
                if( indexPairs[ i ].entityIndex == lastEntityIndex )
                   storageNetworkAllocationVector[ lastEntityIndex ]++;
                else
                   lastEntityIndex++;                           
             }
    
             superentityStorageNetwork.allocate( storageNetworkAllocationVector );
    
             lastEntityIndex = 0;
             LocalIndexType superentitiesCount( 0 );
    
             typename SuperentityStorageNetwork::ValuesAccessorType superentitiesIndecis = 
                superentityStorageNetwork.getValues( lastEntityIndex );
    
             for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
             {
                if( indexPairs[ i ].entityIndex != lastEntityIndex )
                {
    
                   superentitiesIndecis = superentityStorageNetwork.getValues( ++lastEntityIndex );
    
                   superentitiesCount = 0;
                }
                superentitiesIndecis[ superentitiesCount++ ] =  indexPairs[ i ].superentityIndex;
             }
    
             BaseType::initSuperentities( meshInitializer );
          }
    
          struct IndexPair
          {
             GlobalIndexType entityIndex;
             GlobalIndexType superentityIndex;
          };
    
          std::vector< IndexPair > indexPairs;
       
    
    template< typename MeshConfig,
    
              typename EntityTopology,
    
              typename DimensionsTag >
    
    class tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                              EntityTopology,
    
                                              DimensionsTag,
    
                                              false >
    
       : public tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                                    EntityTopology,
    
                                                    typename DimensionsTag::Decrement >
    
       typedef tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                                    EntityTopology,
    
    Tomáš Oberhuber's avatar
    Tomáš Oberhuber committed
                                                    typename DimensionsTag::Decrement > BaseType;
    
       typedef tnlMeshInitializer< MeshConfig >                                      MeshInitializerType;
    
    Tomáš Oberhuber's avatar
    Tomáš Oberhuber committed
       
       public:
       void addSuperentity()                           {} // This method is due to 'using BaseType::...;' in the derived classes.
       using BaseType::initSuperentities;
       void initSuperentities( MeshInitializerType& ) {cerr << "***" << endl;} 
    
    template< typename MeshConfig,
    
              typename EntityTopology >
    
    class tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                              EntityTopology,
                                              tnlDimensionsTag< EntityTopology::dimensions >,
    
                                              true >
    
       typedef tnlMeshInitializer< MeshConfig >                                      MeshInitializerType;
    
       void addSuperentity()                           {} // This method is due to 'using BaseType::...;' in the derived classes.
    
       void initSuperentities( MeshInitializerType& ) {}
    
    template< typename MeshConfig,
    
              typename EntityTopology >
    
    class tnlMeshSuperentityStorageInitializerLayer< MeshConfig,
    
                                              EntityTopology,
                                              tnlDimensionsTag< EntityTopology::dimensions >,
    
                                              false >
    
       typedef tnlMeshInitializer< MeshConfig >                                      MeshInitializerType;
    
       void addSuperentity()                           {} // This method is due to 'using BaseType::...;' in the derived classes.
    
       void initSuperentities( MeshInitializerType& ) {}
    
    #endif /* TNLMESHSUPERENTITYSTORAGEINITIALIZER_H_ */