/*************************************************************************** tnlMeshInitializer.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 TNLMESHINITIALIZER_H_ #define TNLMESHINITIALIZER_H_ #include <mesh/tnlDimensionsTag.h> #include <mesh/traits/tnlMeshEntityTraits.h> #include <mesh/traits/tnlMeshSubentityTraits.h> #include <mesh/traits/tnlMeshSuperentityTraits.h> #include <mesh/initializer/tnlMeshEntityInitializer.h> #include <mesh/tnlMesh.h> #include <mesh/initializer/tnlMeshSubentitySeedCreator.h> #include <mesh/initializer/tnlMeshSuperentityStorageInitializer.h> #include <mesh/tnlMeshEntityReferenceOrientation.h> #include <mesh/initializer/tnlMeshEntitySeed.h> #include <mesh/initializer/tnlMeshEntitySeedKey.h> template< typename MeshConfig > class tnlMesh; template< typename MeshConfig, typename DimensionsTag, bool EntityStorage = tnlMeshEntityTraits< MeshConfig, DimensionsTag::value >::storageEnabled, bool EntityReferenceOrientationStorage = tnlMeshTraits< MeshConfig >::template EntityTraits< DimensionsTag::value >::orientationNeeded > class tnlMeshInitializerLayer; template< typename MeshConfig, typename EntityTopology> class tnlMeshEntityInitializer; template< typename MeshConfig > class tnlMeshInitializer : public tnlMeshInitializerLayer< MeshConfig, typename tnlMeshTraits< MeshConfig >::DimensionsTag > { public: typedef tnlMesh< MeshConfig > MeshType; typedef tnlMeshTraits< MeshConfig > MeshTraits; static const int Dimensions = MeshTraits::meshDimensions; typedef tnlDimensionsTag< Dimensions > DimensionsTag; typedef tnlMeshInitializerLayer< MeshConfig, DimensionsTag > BaseType; typedef typename MeshTraits::PointArrayType PointArrayType; typedef typename MeshTraits::CellSeedArrayType CellSeedArrayType; typedef typename MeshTraits::GlobalIndexType GlobalIndexType; tnlMeshInitializer() : verbose( false ), mesh( 0 ) {} void setVerbose( bool verbose ) { this->verbose = verbose; } bool createMesh( const PointArrayType& points, const CellSeedArrayType& cellSeeds, MeshType& mesh ) { cout << "======= Starting mesh initiation ========" << endl; this->mesh = &mesh; cout << "========= Creating entity seeds =============" << endl; BaseType::createEntitySeedsFromCellSeeds( cellSeeds ); cout << "========= Creating entity reference orientations =============" << endl; BaseType::createEntityReferenceOrientations(); cout << "====== Initiating entities ==============" << endl; BaseType::initEntities( *this, points, cellSeeds ); return true; } template<typename SubDimensionsTag, typename EntityType > static typename MeshTraits::template SubentityTraits< typename EntityType::EntityTopology, SubDimensionsTag::value >::IdArrayType& subentityIdsArray( EntityType& entity ) { return entity.template subentityIdsArray< SubDimensionsTag::value >(); } template< typename SuperDimensionsTag, typename MeshEntity> static typename MeshTraits::IdArrayAccessorType& superentityIdsArray( MeshEntity& entity ) { return entity.template superentityIdsArray< SuperDimensionsTag::value >(); } template<typename SubDimensionsTag, typename MeshEntity > static typename MeshTraits::template SubentityTraits< typename MeshEntity::EntityTopology, SubDimensionsTag::value >::OrientationArrayType& subentityOrientationsArray( MeshEntity &entity ) { return entity.template subentityOrientationsArray< SubDimensionsTag::value >(); } template< typename DimensionsTag > typename MeshTraits::template EntityTraits< DimensionsTag::value >::StorageArrayType& meshEntitiesArray() { return mesh->template entitiesArray< DimensionsTag >(); } template< typename DimensionsTag, typename SuperDimensionsTag > typename MeshTraits::GlobalIdArrayType& meshSuperentityIdsArray() { return mesh->template superentityIdsArray< DimensionsTag, SuperDimensionsTag >(); } static void setVertexPoint( typename MeshType::VertexType& vertex, const typename MeshType::PointType& point ) { vertex.setPoint( point ); } template< typename DimensionsTag > tnlMeshSuperentityStorageInitializer< MeshConfig, typename MeshTraits::template EntityTraits< DimensionsTag::value >::EntityTopology >& getSuperentityInitializer() { return BaseType::getSuperentityInitializer( DimensionsTag() ); } template< typename DimensionsTag > const tnlMeshEntityReferenceOrientation< MeshConfig, typename MeshTraits::template EntityTraits< DimensionsTag::value >::EntityTopology >& getReferenceOrientation( GlobalIndexType index) const { return BaseType::getReferenceOrientation( DimensionsTag(), index); } protected: bool verbose; MeshType* mesh; }; /**** * Mesh initializer layer for cells * - entities storage must turned on (cells must always be stored ) * - entities orientation does not make sense for cells => it is turned off */ template< typename MeshConfig > class tnlMeshInitializerLayer< MeshConfig, typename tnlMeshTraits< MeshConfig >::DimensionsTag, true, false > : public tnlMeshInitializerLayer< MeshConfig, typename tnlMeshTraits< MeshConfig >::DimensionsTag::Decrement > { typedef tnlMeshTraits< MeshConfig > MeshTraits; static const int Dimensions = MeshTraits::meshDimensions; typedef tnlDimensionsTag< Dimensions > DimensionsTag; typedef tnlMeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > BaseType; typedef tnlMesh< MeshConfig > MeshType; typedef typename MeshTraits::template EntityTraits< Dimensions > EntityTraits; typedef typename EntityTraits::EntityTopology EntityTopology; typedef typename MeshTraits::GlobalIndexType GlobalIndexType; typedef typename MeshTraits::CellTopology CellTopology; typedef typename EntityTraits::StorageArrayType StorageArrayType; typedef tnlMeshInitializer< MeshConfig > InitializerType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > EntityInitializerType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > CellInitializerType; typedef tnlArray< CellInitializerType, tnlHost, GlobalIndexType > CellInitializerContainerType; typedef typename MeshTraits::CellSeedArrayType CellSeedArrayType; typedef typename MeshTraits::LocalIndexType LocalIndexType; typedef typename MeshTraits::PointArrayType PointArrayType; typedef tnlMeshEntitySeed< MeshConfig, CellTopology > SeedType; typedef tnlMeshSuperentityStorageInitializer< MeshConfig, EntityTopology > SuperentityInitializerType; public: void createEntitySeedsFromCellSeeds( const CellSeedArrayType& cellSeeds ) { BaseType::createEntitySeedsFromCellSeeds( cellSeeds ); } void initEntities( InitializerType &initializer, const PointArrayType &points, const CellSeedArrayType &cellSeeds) { StorageArrayType &entityArray = initializer.template meshEntitiesArray< DimensionsTag >(); //cout << " Initiating entities with " << DimensionsTag::value << " dimensions ... " << endl; entityArray.setSize( cellSeeds.getSize() ); for( GlobalIndexType i = 0; i < entityArray.getSize(); i++ ) { //cout << " Initiating entity " << i << endl; EntityInitializerType::initEntity( entityArray[i], i, cellSeeds[i], initializer ); } /*** * There are no superentities in this layer storing mesh cells. */ BaseType::initEntities( initializer, points ); } using BaseType::findEntitySeedIndex; GlobalIndexType findEntitySeedIndex( const SeedType& seed ) const { return this->seedsIndexedSet.find( seed ); } using BaseType::getSuperentityInitializer; SuperentityInitializerType& getSuperentityInitializer( DimensionsTag ) { return this->superentityInitializer; } bool checkCells() { typedef typename tnlMeshEntity< MeshConfig, EntityTopology >::template SubentitiesTraits< 0 >::LocalIndexType LocalIndexType; const GlobalIndexType numberOfVertices( this->getMesh().getNumberOfVertices() ); for( GlobalIndexType cell = 0; cell < this->getMesh().getNumberOfCells(); cell++ ) for( LocalIndexType i = 0; i < this->getMesh().getCell( cell ).getNumberOfVertices(); i++ ) { if( this->getMesh().getCell( cell ).getVerticesIndices()[ i ] == - 1 ) { cerr << "The cell number " << cell << " does not have properly set vertex index number " << i << "." << endl; return false; } if( this->getMesh().getCell( cell ).getVerticesIndices()[ i ] >= numberOfVertices ) { cerr << "The cell number " << cell << " does not have properly set vertex index number " << i << ". The index " << this->getMesh().getCell( cell ).getVerticesIndices()[ i ] << "is higher than the number of all vertices ( " << numberOfVertices << " )." << endl; return false; } } return true; } private: typedef typename tnlMeshEntityTraits< MeshConfig, DimensionsTag::value >::SeedIndexedSetType SeedIndexedSet; SeedIndexedSet seedsIndexedSet; SuperentityInitializerType superentityInitializer; }; /**** * Mesh initializer layer for other mesh entities than cells * - entities storage is turned on * - entities orientation storage is turned off */ template< typename MeshConfig, typename DimensionsTag > class tnlMeshInitializerLayer< MeshConfig, DimensionsTag, true, false > : public tnlMeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > { typedef tnlMeshTraits< MeshConfig > MeshTraits; static const int Dimensions = DimensionsTag::value; typedef tnlMeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > BaseType; typedef tnlMesh< MeshConfig > MeshType; typedef typename MeshTraits::template EntityTraits< Dimensions > EntityTraits; typedef typename EntityTraits::EntityTopology EntityTopology; typedef typename MeshTraits::GlobalIndexType GlobalIndexType; typedef typename MeshTraits::CellTopology CellTopology; typedef typename EntityTraits::StorageArrayType StorageArrayType; typedef tnlMeshInitializer< MeshConfig > InitializerType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > EntityInitializerType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > CellInitializerType; typedef tnlArray< CellInitializerType, tnlHost, GlobalIndexType > CellInitializerContainerType; typedef typename EntityTraits::SeedArrayType EntitySeedArrayType; typedef typename MeshTraits::CellSeedArrayType CellSeedArrayType; typedef typename MeshTraits::LocalIndexType LocalIndexType; typedef typename MeshTraits::PointArrayType PointArrayType; typedef tnlMeshEntitySeed< MeshConfig, EntityTopology > SeedType; typedef tnlMeshSuperentityStorageInitializer< MeshConfig, EntityTopology > SuperentityInitializerType; typedef typename tnlMeshSubentityTraits< MeshConfig, typename MeshConfig::CellTopology, DimensionsTag::value >::SubentityContainerType SubentitiesContainerType; public: using BaseType::getEntityInitializer; EntityInitializerType& getEntityInitializer( DimensionsTag, GlobalIndexType index ) { //return entityInitializerContainer[ index ]; } void createEntitySeedsFromCellSeeds( const CellSeedArrayType& cellSeeds ) { typedef tnlMeshSubentitySeedsCreator< MeshConfig, CellTopology, DimensionsTag > SubentitySeedsCreator; //cout << " Creating mesh entities with " << DimensionsTag::value << " dimensions ... " << endl; for( GlobalIndexType i = 0; i < cellSeeds.getSize(); i++ ) { //cout << " Creating mesh entities from cell number " << i << " : " << cellSeeds[ i ] << endl; typedef typename SubentitySeedsCreator::SubentitySeedArray SubentitySeedArray; SubentitySeedArray subentytiSeeds( SubentitySeedsCreator::create( cellSeeds[ i ] ) ); for( LocalIndexType j = 0; j < subentytiSeeds.getSize(); j++ ) { //cout << "Creating subentity seed no. " << j << " : " << subentytiSeeds[ j ] << endl; //tnlMeshEntitySeed< tnlMeshConfigBase< CellTopology >, EntityTopology >& entitySeed = subentytiSeeds[ j ]; this->seedsIndexedSet.insert( subentytiSeeds[ j ] ); } } BaseType::createEntitySeedsFromCellSeeds( cellSeeds ); } using BaseType::findEntitySeedIndex; GlobalIndexType findEntitySeedIndex( const SeedType& seed ) const { GlobalIndexType index; this->seedsIndexedSet.find( seed, index ); return index; } using BaseType::getSuperentityInitializer; SuperentityInitializerType& getSuperentityInitializer( DimensionsTag ) { return this->superentityInitializer; } void initEntities( InitializerType& initializer, const PointArrayType& points ) { StorageArrayType &entityArray = initializer.template meshEntitiesArray< DimensionsTag >(); //cout << " Initiating entities with " << DimensionsTag::value << " dimensions ... " << endl; entityArray.setSize( this->seedsIndexedSet.getSize() ); EntitySeedArrayType seedsArray; seedsArray.setSize( this->seedsIndexedSet.getSize() ); this->seedsIndexedSet.toArray( seedsArray ); for( GlobalIndexType i = 0; i < this->seedsIndexedSet.getSize(); i++ ) { //cout << " Initiating entity " << i << endl; EntityInitializerType::initEntity( entityArray[ i ], i, seedsArray[ i ], initializer ); } this->seedsIndexedSet.reset(); this->superentityInitializer.initSuperentities( initializer ); BaseType::initEntities(initializer, points); } void createEntityReferenceOrientations() const {} private: typedef typename tnlMeshEntityTraits< MeshConfig, DimensionsTag::value >::SeedIndexedSetType SeedIndexedSet; SeedIndexedSet seedsIndexedSet; SuperentityInitializerType superentityInitializer; }; /**** * Mesh initializer layer for other mesh entities than cells * - entities storage is turned on * - entities orientation storage is turned on */ template< typename MeshConfig, typename DimensionsTag > class tnlMeshInitializerLayer< MeshConfig, DimensionsTag, true, true > : public tnlMeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > { typedef tnlMeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > BaseType; typedef tnlMesh< MeshConfig > MeshType; typedef typename MeshType::MeshTraits MeshTraits; typedef typename MeshType::template EntityTraits< DimensionsTag::value > EntityTraits; typedef typename EntityTraits::EntityTopology EntityTopology; typedef typename EntityTraits::EntityType EntityType; typedef typename EntityTraits::StorageArrayType ContainerType; typedef typename EntityTraits::UniqueContainerType UniqueContainerType; typedef typename ContainerType::IndexType GlobalIndexType; typedef typename MeshTraits::CellTopology CellTopology; typedef tnlMeshInitializer< MeshConfig > InitializerType; typedef tnlMeshEntityInitializer< MeshConfig, CellTopology > CellInitializerType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > EntityInitializerType; typedef tnlArray< EntityInitializerType, tnlHost, GlobalIndexType > EntityInitializerContainerType; typedef typename MeshTraits::CellSeedArrayType CellSeedArrayType; typedef typename MeshTraits::LocalIndexType LocalIndexType; typedef typename MeshTraits::PointArrayType PointArrayType; typedef typename EntityTraits::StorageArrayType EntityArrayType; typedef typename EntityTraits::SeedArrayType SeedArrayType; typedef tnlMeshEntitySeed< MeshConfig, EntityTopology > SeedType; typedef tnlMeshSuperentityStorageInitializer< MeshConfig, EntityTopology > SuperentityInitializerType; typedef typename EntityTraits::ReferenceOrientationType ReferenceOrientationType; typedef typename EntityTraits::ReferenceOrientationArrayType ReferenceOrientationArrayType; typedef typename tnlMeshSubentityTraits< MeshConfig, typename MeshConfig::CellTopology, DimensionsTag::value >::SubentityContainerType SubentitiesContainerType; public: using BaseType::getEntityInitializer; EntityInitializerType& getEntityInitializer( DimensionsTag, GlobalIndexType index ) { //return entityInitializerContainer[ index ]; } void createEntitySeedsFromCellSeeds( const CellSeedArrayType& cellSeeds ) { typedef tnlMeshSubentitySeedsCreator< MeshConfig, CellTopology, DimensionsTag > SubentitySeedsCreator; //cout << " Creating mesh entities with " << DimensionsTag::value << " dimensions ... " << endl; for( GlobalIndexType i = 0; i < cellSeeds.getSize(); i++ ) { //cout << " Creating mesh entities from cell number " << i << " : " << cellSeeds[ i ] << endl; typedef typename SubentitySeedsCreator::SubentitySeedArray SubentitySeedArray; SubentitySeedArray subentytiSeeds( SubentitySeedsCreator::create( cellSeeds[ i ] ) ); for( LocalIndexType j = 0; j < subentytiSeeds.getSize(); j++ ) { //cout << "Creating subentity seed no. " << j << " : " << subentytiSeeds[ j ] << endl; //tnlMeshEntitySeed< tnlMeshConfigBase< CellTopology >, EntityTopology >& entitySeed = subentytiSeeds[ j ]; this->seedsIndexedSet.insert( subentytiSeeds[ j ] ); } } BaseType::createEntitySeedsFromCellSeeds( cellSeeds ); } using BaseType::findEntitySeedIndex; GlobalIndexType findEntitySeedIndex( const SeedType& seed ) const { GlobalIndexType index; this->seedsIndexedSet.find( seed, index ); return index; } using BaseType::getSuperentityInitializer; SuperentityInitializerType& getSuperentityInitializer( DimensionsTag ) { return this->superentityInitializer; } void initEntities( InitializerType& initializer, const PointArrayType& points ) { EntityArrayType &entityArray = initializer.template meshEntitiesArray< DimensionsTag >(); //cout << " Initiating entities with " << DimensionsTag::value << " dimensions ... " << endl; entityArray.setSize( this->seedsIndexedSet.getSize() ); SeedArrayType seedsArray; seedsArray.setSize( this->seedsIndexedSet.getSize() ); this->seedsIndexedSet.toArray( seedsArray ); for( GlobalIndexType i = 0; i < this->seedsIndexedSet.getSize(); i++ ) { //cout << " Initiating entity " << i << endl; EntityInitializerType::initEntity( entityArray[ i ], i, seedsArray[ i ], initializer ); } this->seedsIndexedSet.reset(); this->superentityInitializer.initSuperentities( initializer ); BaseType::initEntities(initializer, points); } using BaseType::getReferenceOrientation; const ReferenceOrientationType& getReferenceOrientation( DimensionsTag, GlobalIndexType index) const { return this->referenceOrientations[ index ]; } void createEntityReferenceOrientations() { //cout << " Creating entity reference orientations with " << DimensionsTag::value << " dimensions ... " << endl; SeedArrayType seedsArray; seedsArray.setSize( this->seedsIndexedSet.getSize() ); this->seedsIndexedSet.toArray( seedsArray ); this->referenceOrientations.setSize( seedsArray.getSize() ); for( GlobalIndexType i = 0; i < seedsArray.getSize(); i++ ) { //cout << " Creating reference orientation for entity " << i << endl; this->referenceOrientations[ i ] = ReferenceOrientationType( seedsArray[ i ] ); } BaseType::createEntityReferenceOrientations(); } private: typedef typename tnlMeshEntityTraits< MeshConfig, DimensionsTag::value >::SeedIndexedSetType SeedIndexedSet; SeedIndexedSet seedsIndexedSet; SuperentityInitializerType superentityInitializer; ReferenceOrientationArrayType referenceOrientations; }; /**** * Mesh initializer layer for entities not being stored */ template< typename MeshConfig, typename DimensionsTag > class tnlMeshInitializerLayer< MeshConfig, DimensionsTag, false, false > : public tnlMeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > {}; /**** * Mesh initializer layer for vertices * - vertices must always be stored * - their orientation does not make sense */ template< typename MeshConfig > class tnlMeshInitializerLayer< MeshConfig, tnlDimensionsTag< 0 >, true, false > { typedef tnlMesh< MeshConfig > MeshType; typedef typename MeshType::MeshTraits MeshTraits; typedef tnlDimensionsTag< 0 > DimensionsTag; typedef typename MeshType::template EntityTraits< DimensionsTag::value > EntityTraits; typedef typename EntityTraits::EntityTopology EntityTopology; typedef typename EntityTraits::StorageArrayType ContainerType; typedef typename EntityTraits::AccessArrayType SharedContainerType; typedef typename ContainerType::IndexType GlobalIndexType; typedef typename MeshTraits::CellTopology CellTopology; typedef tnlMeshInitializer< MeshConfig > InitializerType; typedef tnlMeshEntityInitializer< MeshConfig, CellTopology > CellInitializerType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > VertexInitializerType; typedef tnlArray< VertexInitializerType, tnlHost, GlobalIndexType > VertexInitializerContainerType; typedef typename tnlMeshTraits< MeshConfig >::CellSeedArrayType CellSeedArrayType; typedef typename tnlMeshTraits< MeshConfig >::LocalIndexType LocalIndexType; typedef typename tnlMeshTraits< MeshConfig >::PointArrayType PointArrayType; typedef typename EntityTraits::StorageArrayType EntityArrayType; typedef tnlMeshEntityInitializer< MeshConfig, EntityTopology > EntityInitializerType; typedef tnlMeshSuperentityStorageInitializer< MeshConfig, EntityTopology > SuperentityInitializerType; public: void setMesh( MeshType& mesh ) { this->mesh = &mesh; } MeshType& getMesh() { tnlAssert( this->mesh, ); return *( this->mesh ); } VertexInitializerType& getEntityInitializer( DimensionsTag, GlobalIndexType index ) { tnlAssert( index >= 0 && index < vertexInitializerContainer.getSize(), cerr << " index = " << index << " vertexInitializerContainer.getSize() = " << vertexInitializerContainer.getSize() << endl; ); return vertexInitializerContainer[ index ]; } void createEntitySeedsFromCellSeeds( const CellSeedArrayType& cellSeeds ){}; void initEntities( InitializerType& initializer, const PointArrayType& points ) { EntityArrayType &vertexArray = initializer.template meshEntitiesArray< DimensionsTag >(); vertexArray.setSize( points.getSize() ); for( GlobalIndexType i = 0; i < vertexArray.getSize(); i++ ) EntityInitializerType::setVertexPoint( vertexArray[i], points[i], initializer ); superentityInitializer.initSuperentities( initializer ); } void findEntitySeedIndex() const {} // This method is due to 'using BaseType::findEntityIndex;' in the derived class. void createEntityInitializers() { vertexInitializerContainer.setSize( this->getMesh().template getNumberOfEntities< DimensionsTag::value >() ); } SuperentityInitializerType& getSuperentityInitializer( DimensionsTag ) { return this->superentityInitializer; } void createEntityReferenceOrientations() const {} void getReferenceOrientation() const {} private: SuperentityInitializerType superentityInitializer; VertexInitializerContainerType vertexInitializerContainer; MeshType* mesh; }; #endif /* TNLMESHINITIALIZER_H_ */