Commit 9d59bde8 authored by Nils Kohl's avatar Nils Kohl 🌝
Browse files

[PrimitiveStorage refinement] Fixed indirect neighborhood and added test.

parent 4b6c5c37
Pipeline #39676 failed with stages
in 15 minutes and 40 seconds
......@@ -474,6 +474,12 @@ uint_t PrimitiveStorage::getCurrentGlobalMaxRefinement() const
return walberla::mpi::allReduce( getCurrentLocalMaxRefinement(), walberla::mpi::MAX );
}
/// \brief Returns the refinement level of the corresponding primitive.
uint_t PrimitiveStorage::getRefinementLevel( const PrimitiveID& pid ) const
{
return pid.numAncestors();
}
uint_t PrimitiveStorage::getNumberOfLocalVertices() const
{
uint_t num = 0;
......@@ -2473,7 +2479,7 @@ void PrimitiveStorage::refinementAndCoarseningHanging( const std::vector< Primit
"Face to be refined must exist locally or in neighborhood now that this data should have been communicated." );
auto coarseFace = getFace( coarseVolumeID );
auto level = coarseVolumeID.numAncestors();
auto level = getRefinementLevel( coarseVolumeID );
// Creating new primitives.
//
......@@ -2705,7 +2711,7 @@ void PrimitiveStorage::refinementAndCoarseningHanging( const std::vector< Primit
edge_y->setParent( coarseVolumeID );
edge_xy->setParent( coarseVolumeID );
coarseFace->addChildEdges( {edge_x_idx, edge_y_idx, edge_xy_idx} );
coarseFace->addChildEdges( { edge_x_idx, edge_y_idx, edge_xy_idx } );
// Now the child faces.
......@@ -2860,10 +2866,13 @@ void PrimitiveStorage::refinementAndCoarseningHanging( const std::vector< Primit
auto vertex = getVertex( neighborVertexID );
for ( const auto& neighborFaceID : vertex->neighborFaces() )
{
auto nFace = getFace( neighborFaceID );
if ( neighborFaceID != fineFaceID &&
!algorithms::contains( fineFace->indirectNeighborFaceIDsOverVertices_, neighborFaceID ) )
{
fineFace->indirectNeighborFaceIDsOverVertices_.push_back( neighborFaceID );
nFace->indirectNeighborFaceIDsOverVertices_.push_back( fineFaceID );
}
}
}
......@@ -2873,9 +2882,13 @@ void PrimitiveStorage::refinementAndCoarseningHanging( const std::vector< Primit
auto edge = getEdge( neighborEdgeID );
for ( const auto& neighborFaceID : edge->neighborFaces() )
{
auto nFace = getFace( neighborFaceID );
if ( neighborFaceID != fineFaceID )
{
WALBERLA_ASSERT( algorithms::contains( nFace->neighborEdges(), neighborEdgeID ) );
fineFace->indirectNeighborFaceIDsOverEdges_[fineFace->edge_index( neighborEdgeID )] = neighborFaceID;
nFace->indirectNeighborFaceIDsOverEdges_[nFace->edge_index( neighborEdgeID )] = fineFaceID;
}
}
}
......
......@@ -158,6 +158,9 @@ class PrimitiveStorage : private walberla::NonCopyable
/// \brief Returns the currently maximum number that a primitive is refined globally (involves global reduction).
uint_t getCurrentGlobalMaxRefinement() const;
/// \brief Returns the refinement level of the corresponding primitive.
uint_t getRefinementLevel( const PrimitiveID & pid ) const;
/// @name \ref Primitive access methods
/// Various methods to obtain primitives or IDs.
///@{
......
......@@ -21,6 +21,7 @@
#include "core/Environment.h"
#include "core/logging/Logging.h"
#include "hyteg/Algorithms.hpp"
#include "hyteg/mesh/MeshInfo.hpp"
#include "hyteg/primitivestorage/PrimitiveStorage.hpp"
#include "hyteg/primitivestorage/SetupPrimitiveStorage.hpp"
......@@ -33,17 +34,18 @@ using walberla::uint_t;
namespace hyteg {
void ARHangingNodesStorageTest()
/// Just testing the most basic features.
void smokeTest()
{
MeshInfo meshInfo = MeshInfo::fromGmshFile( "../../data/meshes/quad_184el.msh" );
SetupPrimitiveStorage setupStorage( meshInfo, uint_c( walberla::mpi::MPIManager::instance()->numProcesses() ) );
auto storage = std::make_shared< PrimitiveStorage >( setupStorage );
auto storage = std::make_shared< PrimitiveStorage >( setupStorage, 1 );
const uint_t numRefinements = 3;
writeDomainPartitioningVTK( *storage, "../../output/", "ARHangingNodesStorageTest_Domain_Refinement_0" );
writeDomainPartitioningVTK( *storage, "../../output/", "ARHangingNodesStorageTest_SmokeTest_Domain_Refinement_0" );
auto refinementLevelAtPoint = []( const Point3D& x ) -> uint_t {
// refine near (0, 0)
......@@ -57,6 +59,8 @@ void ARHangingNodesStorageTest()
std::map< uint_t, uint_t > numFaces;
numFaces[0] = storage->getNumberOfGlobalFaces();
for ( uint_t i = 1; i <= numRefinements; i++ )
{
// Collect all volume primitives that shall be refined.
......@@ -85,10 +89,93 @@ void ARHangingNodesStorageTest()
storage->refinementAndCoarseningHanging( refine, coarsen, refineResult, coarsenResult );
numFaces[i] = storage->getNumberOfGlobalFaces();
WALBERLA_CHECK_GREATER( numFaces[i], numFaces[i - 1] );
writeDomainPartitioningVTK(
*storage, "../../output/", "ARHangingNodesStorageTest_Domain_Refinement_" + std::to_string( i ) );
*storage, "../../output/", "ARHangingNodesStorageTest_SmokeTest_Domain_Refinement_" + std::to_string( i ) );
}
}
/// Checks indirect (volume-)neighborhood after refinement.
void indirectNeighborhoodTest()
{
WALBERLA_CHECK_EQUAL(
walberla::mpi::MPIManager::instance()->numProcesses(), 1, "Test currently only written for serial runs." );
MeshInfo meshInfo = MeshInfo::fromGmshFile( "../../data/meshes/quad_16el.msh" );
SetupPrimitiveStorage setupStorage( meshInfo, uint_c( walberla::mpi::MPIManager::instance()->numProcesses() ) );
auto storage = std::make_shared< PrimitiveStorage >( setupStorage, 1 );
const uint_t numRefinements = 5;
WALBERLA_CHECK_LESS( numRefinements, storage->getNumberOfGlobalFaces(), "Cannot run test on this mesh." );
writeDomainPartitioningVTK(
*storage, "../../output/", "ARHangingNodesStorageTest_IndNeighTest_Domain_Refinement_" + std::to_string( 0 ) );
for ( uint_t i = 1; i <= numRefinements; i++ )
{
// Refine a single macro-face on each currently available refinement level.
const auto maxRefinementLevel = storage->getCurrentGlobalMaxRefinement();
const auto faceIDs = storage->getFaceIDs();
std::vector< PrimitiveID > refine, coarsen;
// Running over all available refinement levels.
for ( uint_t refLevel = 0; refLevel < maxRefinementLevel; refLevel++ )
{
for ( const auto faceID : faceIDs )
{
if ( storage->getRefinementLevel( faceID ) == refLevel )
{
refine.push_back( faceID );
break;
}
}
}
// Refine all selected primitives.
storage->refinementAndCoarseningHanging( refine, coarsen );
writeDomainPartitioningVTK(
*storage, "../../output/", "ARHangingNodesStorageTest_IndNeighTest_Domain_Refinement_" + std::to_string( i ) );
// Check neighborhood.
for ( const auto& faceID : storage->getFaceIDs() )
{
const auto face = storage->getFace( faceID );
std::vector< PrimitiveID > faceNeighbors;
for ( const auto& [tmp0, nFaceID] : face->getIndirectNeighborFaceIDsOverEdges() )
{
faceNeighbors.push_back( nFaceID );
const auto nface = storage->getFace( nFaceID );
std::vector< PrimitiveID > nFaceNeighbors;
for ( const auto& [tmp1, nFaceNFaceID] : nface->getIndirectNeighborFaceIDsOverEdges() )
{
nFaceNeighbors.push_back( nFaceNFaceID );
}
WALBERLA_LOG_INFO_ON_ROOT( "Face (pid = " << faceID << ") neighbors: " );
for ( const auto& f : faceNeighbors )
{
WALBERLA_LOG_INFO_ON_ROOT( " " << f );
}
WALBERLA_LOG_INFO_ON_ROOT( "nFace (pid = " << nFaceID << ") neighbors: " );
for ( const auto& f : nFaceNeighbors )
{
WALBERLA_LOG_INFO_ON_ROOT( " " << f );
}
WALBERLA_LOG_INFO_ON_ROOT( "" );
WALBERLA_CHECK( algorithms::contains( nFaceNeighbors, faceID ), "Face is not a neighbor of its neighbors." );
}
}
}
}
......@@ -100,5 +187,8 @@ int main( int argc, char* argv[] )
walberla::logging::Logging::instance()->setLogLevel( walberla::logging::Logging::PROGRESS );
walberla::MPIManager::instance()->useWorldComm();
hyteg::ARHangingNodesStorageTest();
using namespace hyteg;
smokeTest();
indirectNeighborhoodTest();
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment