/*************************************************************************** tnlMeshEntityInitializer.h - description ------------------- begin : Feb 23, 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 TNLMESHENTITYINITIALIZER_H_ #define TNLMESHENTITYINITIALIZER_H_ #include <core/tnlStaticFor.h> #include <mesh/tnlMeshSuperentityInitializerLayer.h> template< typename ConfigTag > class tnlMeshInitializer; template<typename ConfigTag, typename EntityTag, typename DimensionsTag, typename SubentityStorageTag = typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag >::SubentityStorageTag, typename SuperentityStorageTag = typename tnlMeshSuperentitiesTraits< ConfigTag, typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag >::SubentityTag, tnlDimensionsTag< EntityTag::dimensions > >::SuperentityStorageTag > class tnlMeshEntityInitializerLayer; template< typename ConfigTag, typename EntityTag > class tnlMeshEntityInitializer : public tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, tnlDimensionsTag< EntityTag::dimensions - 1 > >/*, public tnlMeshSuperentityInitializerLayer< ConfigTag, EntityTag, typename tnlMeshTraits< ConfigTag >::DimensionsTag >*/ { typedef tnlDimensionsTag< EntityTag::dimensions > DimensionsTag; private: typedef tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, tnlDimensionsTag< EntityTag::dimensions - 1 > > SubentityBaseType; typedef tnlMeshSuperentityInitializerLayer< ConfigTag, EntityTag, typename tnlMeshTraits< ConfigTag >::DimensionsTag > SuperentityBaseType; typedef typename tnlMeshEntitiesTraits< ConfigTag, DimensionsTag >::Type EntityType; typedef typename tnlMeshEntitiesTraits< ConfigTag, DimensionsTag >::ContainerType::IndexType GlobalIndexType; typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, tnlDimensionsTag< 0 > > SubvertexTag; typedef typename SubvertexTag::ContainerType::ElementType VertexGlobalIndexType; typedef typename SubvertexTag::ContainerType::IndexType VertexLocalIndexType; typedef tnlMeshInitializer< ConfigTag > InitializerType; template< typename > class SubentitiesCreator; public: //using SuperentityBaseType::setNumberOfSuperentities; static tnlString getType() {}; tnlMeshEntityInitializer() : entity(0), entityIndex( -1 ) {} void initEntity( EntityType& entity, GlobalIndexType entityIndex, InitializerType &meshInitializer ) { tnlAssert( this->entity, ); this->entity->setId( entityIndex ); initSubentities( entity, entityIndex, meshInitializer ); //cout << " Entity initiation done ... " << endl; } template< typename SubentityDimensionsTag > void createSubentities( typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, SubentityDimensionsTag >::SubentityContainerType& subentities ) const { SubentitiesCreator< SubentityDimensionsTag >::createSubentities( subentities, *entity ); } GlobalIndexType getEntityIndex() const { tnlAssert( entityIndex >= 0, cerr << "entityIndex = " << entityIndex ); return this->entityIndex; } template< typename SubentityDimensionTag > typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, SubentityDimensionTag >::SharedContainerType& subentityContainer( SubentityDimensionTag ) { return this->entity->template getSubentitiesIndices< SubentityDimensionTag::value >(); } /*template< typename SuperentityDimensionTag > bool setNumberOfSuperentities( SuperentityDimensionTag, typename tnlMeshSuperentitiesTraits< ConfigTag, EntityTag, SuperentityDimensionTag >::ContainerType::IndexType size ) { return this->entity->template setNumberOfSuperentities< SuperentityDimensionTag::value >( size ); }*/ // TODO: check if we need the following two methods /*template< typename SuperentityDimensionTag > bool getSuperentityContainer( SuperentityDimensionTag, typename tnlMeshSuperentitiesTraits< ConfigTag, EntityTag, SuperentityDimensionTag >::ContainerType::IndexType size ) { return this->entity->template setNumberOfSuperentities< SuperentityDimensionTag::value >( size ); }*/ template< typename SuperentityDimensionTag > typename tnlMeshSuperentitiesTraits< ConfigTag, EntityTag, SuperentityDimensionTag >::SharedContainerType& getSuperentityContainer( SuperentityDimensionTag ) { return this->entity->template getSuperentitiesIndices< SuperentityDimensionTag::value >(); } static void setEntityVertex( EntityType& entity, VertexLocalIndexType localIndex, VertexGlobalIndexType globalIndex ) { entity.setVertexIndex( localIndex, globalIndex ); } private: EntityType *entity; GlobalIndexType entityIndex; void initSubentities( EntityType& entity, GlobalIndexType entityIndex, InitializerType& meshInitializer ) { //cout << " Initiating subentities of entity ... " << endl; SubentityBaseType::initSubentities( *this, meshInitializer ); } /*void initSuperentities() { //cout << " Initiating superentities..." << endl; //SuperentityBaseType::initSuperentities( *this) ; }*/ template< typename SubentityDimensionTag > class SubentitiesCreator { typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, SubentityDimensionTag > Tag; typedef typename Tag::SubentityTag SubentityTag; typedef typename Tag::SubentityType SubentityType; typedef typename Tag::ContainerType::IndexType LocalIndexType; typedef typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, SubentityDimensionTag >::SharedContainerType SubentitiesIndicesContainerType; typedef typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, SubentityDimensionTag>::SubentityContainerType SubentityContainerType; enum { subentitiesCount = Tag::count }; enum { subentityVerticesCount = tnlMeshSubentitiesTraits< ConfigTag, SubentityTag, tnlDimensionsTag< 0 > >::count }; public: static void createSubentities( SubentityContainerType& subentities, const EntityType &entity ) { const SubentitiesIndicesContainerType& subvertexIndices = entity.template getSubentitiesIndices< 0 >(); //cout << " entity = " << entity << endl; //cout << " subvertexIndices = " << subvertexIndices << endl; tnlStaticFor< LocalIndexType, 0, subentitiesCount, CreateSubentities >::exec( subentities, subvertexIndices ); } private: template< LocalIndexType subentityIndex > class CreateSubentities { public: static void exec( SubentityContainerType &subentities, const SubentitiesIndicesContainerType& subvertexIndices ) { SubentityType &subentity = subentities[ subentityIndex ]; tnlStaticFor< LocalIndexType, 0, subentityVerticesCount, SetSubentityVertex >::exec( subentity, subvertexIndices ); } private: template< LocalIndexType subentityVertexIndex > class SetSubentityVertex { public: static bool exec( SubentityType &subentity, const SubentitiesIndicesContainerType& subvertexIndices ) { LocalIndexType vertexIndex = Tag::template Vertex< subentityIndex, subentityVertexIndex >::index; //cout << " Setting subentity " << subentityIndex << " vertex " << subentityVertexIndex << " to " << subvertexIndices[ vertexIndex ] << endl; tnlMeshEntityInitializer< ConfigTag, SubentityTag >::setEntityVertex( subentity, subentityVertexIndex, subvertexIndices[ vertexIndex ] ); return true; } }; }; }; }; template< typename ConfigTag > class tnlMeshEntityInitializer< ConfigTag, tnlMeshVertexTag >/* : public tnlMeshSuperentityInitializerLayer< ConfigTag, tnlMeshVertexTag, typename tnlMeshTraits< ConfigTag >::DimensionsTag >*/ { typedef tnlDimensionsTag< 0 > DimensionsTag; typedef tnlMeshSuperentityInitializerLayer< ConfigTag, tnlMeshVertexTag, typename tnlMeshTraits< ConfigTag >::DimensionsTag > SuperentityBaseType; typedef typename tnlMeshEntitiesTraits< ConfigTag, DimensionsTag >::Type EntityType; typedef typename tnlMeshEntitiesTraits< ConfigTag, DimensionsTag >::ContainerType::IndexType GlobalIndexType; typedef tnlMeshInitializer< ConfigTag > InitializerType; public: tnlMeshEntityInitializer() : entity(0), entityIndex(-1) {} static tnlString getType() {}; /*void init( EntityType& entity, GlobalIndexType entityIndex ) { this->entity = &entity; this->entityIndex = entityIndex; }*/ void initEntity( EntityType& entity, GlobalIndexType entityIndex, InitializerType &meshInitializer ) { this->entity->setId( this->entityIndex ); //initSuperentities(); //cout << "Vertex initiation done ... " << endl; } template< typename SuperentityDimensionsTag > bool setNumberOfSuperentities( SuperentityDimensionsTag, const typename EntityType::template SuperentitiesTraits< SuperentityDimensionsTag::value >::ContainerType::IndexType size ) { return this->entity->template setNumberOfSuperentities< SuperentityDimensionsTag::value >( size ); } template< typename SuperentityDimensionsTag > typename tnlMeshSuperentitiesTraits< ConfigTag, tnlMeshVertexTag, SuperentityDimensionsTag >::SharedContainerType& getSuperentityContainer( SuperentityDimensionsTag ) { return this->entity->template getSuperentitiesIndices< SuperentityDimensionsTag::value >(); } private: EntityType *entity; GlobalIndexType entityIndex; /*void initSuperentities() { //cout << " Initiating superentities of vertex ..." << endl; //SuperentityBaseType::initSuperentities(*this); }*/ }; /**** * Mesh entity initializer layer */ template< typename ConfigTag, typename EntityTag, typename DimensionsTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, DimensionsTag, tnlStorageTraits< true >, tnlStorageTraits< true > > : public tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > { typedef tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > BaseType; typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag > SubentitiesTraits; typedef typename SubentitiesTraits::SubentityContainerType SubentityContainerType; typedef typename SubentitiesTraits::SharedContainerType SharedContainerType; typedef typename SharedContainerType::ElementType GlobalIndexType; typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef tnlDimensionsTag< EntityTag::dimensions > EntityDimensionsTag; typedef typename tnlMeshConfigTraits< ConfigTag >::template EntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType& entityInitializer, InitializerType& meshInitializer ) { SubentityContainerType subentities; //cout << " Initiating subentities with " << DimensionsTag::value << " dimensions..." << endl; entityInitializer.template createSubentities< DimensionsTag >( subentities ); SharedContainerType& subentityContainer = entityInitializer.subentityContainer( DimensionsTag() ); //cout << " Subentities = " << subentities << endl; for( typename SubentityContainerType::IndexType i = 0; i < subentities.getSize(); i++ ) { GlobalIndexType subentityIndex = meshInitializer.findEntityIndex( subentities[ i ] ); GlobalIndexType superentityIndex = entityInitializer.getEntityIndex(); subentityContainer[ i ] = subentityIndex; //meshInitializer.template getSuperentityInitializer< DimensionsTag >().addSuperentity( EntityDimensionsTag(), subentityIndex, entityIndex); //cout << " Setting " << i << "-th subentity to " << subentityContainer[ i ] << endl; //meshInitializer.getEntityInitializer( DimensionsTag(), subentityIndex ).addSuperentity( EntityDimensionsTag(), superentityIndex ); } BaseType::initSubentities( entityInitializer, meshInitializer ); } }; template< typename ConfigTag, typename EntityTag, typename DimensionsTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, DimensionsTag, tnlStorageTraits< true >, tnlStorageTraits< false > > : public tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > { typedef tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > BaseType; typedef typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag >::SubentityContainerType SubentityContainerType; typedef typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag >::SharedContainerType SharedContainerType; typedef typename SharedContainerType::ElementType GlobalIndexType; typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef typename tnlMeshConfigTraits< ConfigTag >::template tnlMeshEntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType& entityInitializer, InitializerType& meshInitializer ) { SubentityContainerType subentities; //cout << " Initiating subentities with " << DimensionsTag::value << " dimensions..." << endl; entityInitializer.template createSubentities< DimensionsTag >( subentities ); SharedContainerType& subentityContainer = entityInitializer.subentityContainer( DimensionsTag() ); for( typename SubentityContainerType::IndexType i = 0; i < subentityContainer.getSize(); i++ ) { subentityContainer[ i ] = meshInitializer.findEntityIndex( subentities[ i ] ); //cout << " Setting " << i << "-th subentity to " << subentityContainer[ i ] << endl; } BaseType::initSubentities( entityInitializer, meshInitializer ); } }; template< typename ConfigTag, typename EntityTag, typename DimensionsTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, DimensionsTag, tnlStorageTraits< false >, tnlStorageTraits< true > > : public tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > { typedef tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > BaseType; typedef typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag >::SubentityContainerType SubentityContainerType; typedef typename tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag >::SharedContainerType SharedContainerType; typedef typename SharedContainerType::DataType GlobalIndexType; typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef tnlDimensionsTag< EntityTag::dimensions > EntityDimensionsTag; typedef typename tnlMeshConfigTraits< ConfigTag >::template tnlMeshEntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType& entityInitializer, InitializerType& meshInitializer ) { SubentityContainerType subentities; //cout << " Initiating subentities with " << DimensionsTag::value << " dimensions..." << endl; entityInitializer.template createSubentities< DimensionsTag >( subentities ); for( typename SubentityContainerType::IndexType i = 0; i < subentities.getSize(); i++ ) { GlobalIndexType subentityIndex = meshInitializer.findEntityIndex( subentities[ i ] ); GlobalIndexType superentityIndex = entityInitializer.getEntityIndex(); //cout << " NOT setting " << i << "-th subentity to " << subentityIndex << endl; //meshInitializer.template getSuperentityInitializer< DimensionsTag >().addSuperentity( EntityDimensionsTag(), subentityIndex, entityIndex); //meshInitializer.getEntityInitializer( DimensionsTag(), subentityIndex ).addSuperentity( EntityDimensionsTag(), superentityIndex ); } BaseType::initSubentities( entityInitializer, meshInitializer ); } }; template< typename ConfigTag, typename EntityTag, typename DimensionsTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, DimensionsTag, tnlStorageTraits< false >, tnlStorageTraits< false > > : public tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, typename DimensionsTag::Decrement > {}; template< typename ConfigTag, typename EntityTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, tnlDimensionsTag< 0 >, tnlStorageTraits< true >, tnlStorageTraits< true > > { typedef tnlDimensionsTag< 0 > DimensionsTag; typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag > SubentitiesTraits; typedef typename SubentitiesTraits::SharedContainerType SharedContainerType; typedef typename SharedContainerType::ElementType GlobalIndexType; typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef tnlDimensionsTag< EntityTag::dimensions > EntityDimensionsTag; typedef typename tnlMeshConfigTraits< ConfigTag >::template EntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType &entityInitializer, InitializerType &meshInitializer ) { //cout << " Initiating subentities with " << DimensionsTag::value << " dimensions..." << endl; const SharedContainerType &subentityContainer = entityInitializer.subentityContainer( DimensionsTag() ); for (typename SharedContainerType::IndexType i = 0; i < subentityContainer.getSize(); i++) { GlobalIndexType subentityIndex = subentityContainer[ i ]; //cout << " Setting " << i << "-th subentity to " << subentityContainer[ i ] << endl; tnlAssert( subentityIndex >= 0, cerr << " subentityContainer = " << subentityContainer << endl; ); GlobalIndexType superentityIndex = entityInitializer.getEntityIndex(); tnlAssert( superentityIndex >= 0, ); //meshInitializer.getEntityInitializer( DimensionsTag(), subentityIndex).addSuperentity( EntityDimensionsTag(), superentityIndex ); } } }; template< typename ConfigTag, typename EntityTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, tnlDimensionsTag< 0 >, tnlStorageTraits< true >, tnlStorageTraits< false > > { typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef tnlDimensionsTag< 0 > DimensionsTag; typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag > SubentitiesTraits; typedef typename SubentitiesTraits::SharedContainerType SharedContainerType; typedef typename SharedContainerType::ElementType GlobalIndexType; typedef typename tnlMeshConfigTraits< ConfigTag >::template tnlMeshEntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType&, InitializerType& ) {} }; template< typename ConfigTag, typename EntityTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, tnlDimensionsTag< 0 >, tnlStorageTraits< false >, tnlStorageTraits< true > > // Forces termination of recursive inheritance (prevents compiler from generating huge error logs) { typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef tnlDimensionsTag< 0 > DimensionsTag; typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag > SubentitiesTraits; typedef typename SubentitiesTraits::SharedContainerType SharedContainerType; typedef typename SharedContainerType::ElementType GlobalIndexType; typedef typename tnlMeshConfigTraits< ConfigTag >::template tnlMeshEntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType&, InitializerType& ) {} }; template< typename ConfigTag, typename EntityTag > class tnlMeshEntityInitializerLayer< ConfigTag, EntityTag, tnlDimensionsTag< 0 >, tnlStorageTraits< false >, tnlStorageTraits< false > > // Forces termination of recursive inheritance (prevents compiler from generating huge error logs) { typedef tnlMeshInitializer< ConfigTag > InitializerType; typedef tnlMeshEntityInitializer< ConfigTag, EntityTag > EntityInitializerType; typedef tnlDimensionsTag< 0 > DimensionsTag; typedef tnlMeshSubentitiesTraits< ConfigTag, EntityTag, DimensionsTag > SubentitiesTraits; typedef typename SubentitiesTraits::SharedContainerType SharedContainerType; typedef typename SharedContainerType::ElementType GlobalIndexType; typedef typename tnlMeshConfigTraits< ConfigTag >::template tnlMeshEntityTraits< DimensionsTag >::Type EntityType; protected: void initSubentities( EntityType& entity, GlobalIndexType entityIndex, EntityInitializerType&, InitializerType& ) {} }; #endif /* TNLMESHENTITYINITIALIZER_H_ */