Commit ab90e5bd authored by Andreas Wagner's avatar Andreas Wagner
Browse files

fixes FaceDoFFunction::getMinValue, FaceDoFFunction::getMaxValue, FaceDoFFunction::getMaxMagnitude

parent 694b1c95
Pipeline #33820 passed with stages
in 115 minutes and 12 seconds
......@@ -335,6 +335,26 @@ ValueType FaceDoFFunction< ValueType >::getMaxValue( const uint_t level, DoFType
{
ValueType localMax = -std::numeric_limits< ValueType >::max();
for ( auto& it : this->getStorage()->getVertices() )
{
Vertex& vertex = *it.second;
const DoFType vertexBC = this->getBoundaryCondition().getBoundaryType( vertex.getMeshBoundaryFlag() );
if ( testFlag( vertexBC, flag ) )
{
localMax = std::max( localMax, facedof::macrovertex::getMaxValue< ValueType >( level, vertex, vertexDataID_ ) );
}
}
for ( auto& it : this->getStorage()->getEdges() )
{
Edge& edge = *it.second;
const DoFType edgeBC = this->getBoundaryCondition().getBoundaryType( edge.getMeshBoundaryFlag() );
if ( testFlag( edgeBC, flag ) )
{
localMax = std::max( localMax, facedof::macroedge::getMaxValue< ValueType >( level, edge, edgeDataID_ ) );
}
}
for ( auto& it : this->getStorage()->getFaces() )
{
Face& face = *it.second;
......@@ -354,6 +374,26 @@ ValueType FaceDoFFunction< ValueType >::getMinValue( const uint_t level, DoFType
{
ValueType localMin = std::numeric_limits< ValueType >::max();
for ( auto& it : this->getStorage()->getVertices() )
{
Vertex& vertex = *it.second;
const DoFType vertexBC = this->getBoundaryCondition().getBoundaryType( vertex.getMeshBoundaryFlag() );
if ( testFlag( vertexBC, flag ) )
{
localMin = std::min( localMin, facedof::macrovertex::getMinValue< ValueType >( level, vertex, vertexDataID_ ) );
}
}
for ( auto& it : this->getStorage()->getEdges() )
{
Edge& edge = *it.second;
const DoFType edgeBC = this->getBoundaryCondition().getBoundaryType( edge.getMeshBoundaryFlag() );
if ( testFlag( edgeBC, flag ) )
{
localMin = std::min( localMin, facedof::macroedge::getMinValue< ValueType >( level, edge, edgeDataID_ ) );
}
}
for ( auto& it : this->getStorage()->getFaces() )
{
Face& face = *it.second;
......@@ -373,6 +413,26 @@ ValueType FaceDoFFunction< ValueType >::getMaxMagnitude( const uint_t level, DoF
{
ValueType localMax = -std::numeric_limits< ValueType >::max();
for ( auto& it : this->getStorage()->getVertices() )
{
Vertex& vertex = *it.second;
const DoFType vertexBC = this->getBoundaryCondition().getBoundaryType( vertex.getMeshBoundaryFlag() );
if ( testFlag( vertexBC, flag ) )
{
localMax = std::max( localMax, facedof::macrovertex::getMaxMagnitude< ValueType >( level, vertex, vertexDataID_ ) );
}
}
for ( auto& it : this->getStorage()->getEdges() )
{
Edge& edge = *it.second;
const DoFType edgeBC = this->getBoundaryCondition().getBoundaryType( edge.getMeshBoundaryFlag() );
if ( testFlag( edgeBC, flag ) )
{
localMax = std::max( localMax, facedof::macroedge::getMaxMagnitude< ValueType >( level, edge, edgeDataID_ ) );
}
}
for ( auto& it : this->getStorage()->getFaces() )
{
Face& face = *it.second;
......
......@@ -192,6 +192,94 @@ inline void add( const uint_t&
}
}
template < typename ValueType >
inline ValueType getMinValue( const uint_t& Level, Edge& edge, const PrimitiveDataID< FunctionMemory< ValueType >, Edge >& srcId )
{
size_t rowsize = levelinfo::num_microvertices_per_edge( Level );
auto srcPtr = edge.getData( srcId )->getPointer( Level );
ValueType localMin = +std::numeric_limits< ValueType >::max();
// gray south cells
for ( size_t i = 1; i < rowsize - 2; ++i )
{
uint_t cellIndex = facedof::macroedge::indexFaceFromVertex( Level, i, stencilDirection::CELL_GRAY_SE );
localMin = std::min( localMin, srcPtr[cellIndex] );
}
if ( edge.getNumNeighborFaces() == 2 )
{
// gray north cells
for ( size_t i = 1; i < rowsize - 2; ++i )
{
uint_t cellIndex = facedof::macroedge::indexFaceFromVertex( Level, i, stencilDirection::CELL_GRAY_NE );
localMin = std::min( localMin, srcPtr[cellIndex] );
}
}
return localMin;
}
template < typename ValueType >
inline ValueType getMaxValue( const uint_t& Level, Edge& edge, const PrimitiveDataID< FunctionMemory< ValueType >, Edge >& srcId )
{
size_t rowsize = levelinfo::num_microvertices_per_edge( Level );
auto srcPtr = edge.getData( srcId )->getPointer( Level );
ValueType localMax = -std::numeric_limits< ValueType >::max();
// gray south cells
for ( size_t i = 1; i < rowsize - 2; ++i )
{
uint_t cellIndex = facedof::macroedge::indexFaceFromVertex( Level, i, stencilDirection::CELL_GRAY_SE );
localMax = std::max( localMax, srcPtr[cellIndex] );
}
if ( edge.getNumNeighborFaces() == 2 )
{
// gray north cells
for ( size_t i = 1; i < rowsize - 2; ++i )
{
uint_t cellIndex = facedof::macroedge::indexFaceFromVertex( Level, i, stencilDirection::CELL_GRAY_NE );
localMax = std::max( localMax, srcPtr[cellIndex] );
}
}
return localMax;
}
template < typename ValueType >
inline ValueType
getMaxMagnitude( const uint_t& Level, Edge& edge, const PrimitiveDataID< FunctionMemory< ValueType >, Edge >& srcId )
{
size_t rowsize = levelinfo::num_microvertices_per_edge( Level );
auto srcPtr = edge.getData( srcId )->getPointer( Level );
ValueType localMax = ValueType( 0. );
// gray south cells
for ( size_t i = 1; i < rowsize - 2; ++i )
{
uint_t cellIndex = facedof::macroedge::indexFaceFromVertex( Level, i, stencilDirection::CELL_GRAY_SE );
localMax = std::max( localMax, std::abs( srcPtr[cellIndex] ) );
}
if ( edge.getNumNeighborFaces() == 2 )
{
// gray north cells
for ( size_t i = 1; i < rowsize - 2; ++i )
{
uint_t cellIndex = facedof::macroedge::indexFaceFromVertex( Level, i, stencilDirection::CELL_GRAY_NE );
localMax = std::max( localMax, std::abs( srcPtr[cellIndex] ) );
}
}
return localMax;
}
template < typename ValueType >
inline void multElementwise( const uint_t& level,
Edge& edge,
......
......@@ -160,6 +160,45 @@ inline void add( const uint_t& l
dstPtr[i * 2] += scalar;
}
template < typename ValueType >
inline ValueType
getMaxValue( const uint_t& level, Vertex& vertex, const PrimitiveDataID< FunctionMemory< ValueType >, Vertex >& srcId )
{
ValueType localMax = -std::numeric_limits< ValueType >::max();
ValueType* srcPtr = vertex.getData( srcId )->getPointer( level );
for ( uint_t i = 0; i < vertex.getNumNeighborFaces(); ++i )
localMax = std::max( localMax, srcPtr[i * 2] );
return localMax;
}
template < typename ValueType >
inline ValueType
getMinValue( const uint_t& level, Vertex& vertex, const PrimitiveDataID< FunctionMemory< ValueType >, Vertex >& srcId )
{
ValueType localMin = +std::numeric_limits< ValueType >::max();
ValueType* srcPtr = vertex.getData( srcId )->getPointer( level );
for ( uint_t i = 0; i < vertex.getNumNeighborFaces(); ++i )
localMin = std::min( localMin, srcPtr[i * 2] );
return localMin;
}
template < typename ValueType >
inline ValueType
getMaxMagnitude( const uint_t& level, Vertex& vertex, const PrimitiveDataID< FunctionMemory< ValueType >, Vertex >& srcId )
{
ValueType localMax = ValueType( 0.0 );
ValueType* srcPtr = vertex.getData( srcId )->getPointer( level );
for ( uint_t i = 0; i < vertex.getNumNeighborFaces(); ++i )
localMax = std::max( localMax, std::abs( srcPtr[i * 2] ) );
return localMax;
}
template < typename ValueType >
inline ValueType dot( const uint_t& level,
Vertex& vertex,
......
......@@ -520,6 +520,9 @@ waLBerla_execute_test(NAME DGDotTest)
waLBerla_compile_test(FILES DGCopyFromTest.cpp DEPENDS hyteg core)
waLBerla_execute_test(NAME DGCopyFromTest)
waLBerla_compile_test(FILES DGMinMaxTest.cpp DEPENDS hyteg core)
waLBerla_execute_test(NAME DGMinMaxTest)
waLBerla_compile_test(FILES vCycleTest.cpp DEPENDS hyteg core)
waLBerla_execute_test(NAME vCycleTest1 COMMAND $<TARGET_FILE:vCycleTest> )
......
/*
* Copyright (c) 2021 Andreas Wagner.
*
* This file is part of HyTeG
* (see https://i10git.cs.fau.de/hyteg/hyteg).
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "core/debug/all.h"
#include "core/mpi/all.h"
#include "hyteg/dataexport/VTKOutput.hpp"
#include "hyteg/facedofspace/FaceDoFFunction.hpp"
#include "hyteg/mesh/MeshInfo.hpp"
#include "hyteg/primitivestorage/PrimitiveStorage.hpp"
#include "hyteg/primitivestorage/SetupPrimitiveStorage.hpp"
#include "hyteg/primitivestorage/loadbalancing/SimpleBalancer.hpp"
using namespace hyteg;
using walberla::real_t;
int main( int argc, char** argv )
{
walberla::mpi::Environment MPIenv( argc, argv );
walberla::MPIManager::instance()->useWorldComm();
walberla::debug::enterTestMode();
MeshInfo meshInfo = MeshInfo::meshRectangle( Point2D( { 0, 0 } ), Point2D( { 1, 1 } ), MeshInfo::CRISS, 1, 1 );
SetupPrimitiveStorage setupStorage( meshInfo, uint_c( walberla::mpi::MPIManager::instance()->numProcesses() ) );
std::shared_ptr< PrimitiveStorage > storage = std::make_shared< PrimitiveStorage >( setupStorage );
const uint_t minLevel = 2;
const uint_t maxLevel = 4;
hyteg::FaceDoFFunction< real_t > x( "x", storage, minLevel, maxLevel );
x.interpolate( -1, maxLevel, DirichletBoundary );
x.interpolate( 2, maxLevel, Inner );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMinValue( maxLevel, DirichletBoundary ), -1. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxValue( maxLevel, DirichletBoundary ), -1. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxMagnitude( maxLevel, DirichletBoundary ), 1. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMinValue( maxLevel, Inner ), 2. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxValue( maxLevel, Inner ), 2. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxMagnitude( maxLevel, Inner ), 2. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMinValue( maxLevel, All ), -1. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxValue( maxLevel, All ), 2. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxMagnitude( maxLevel, All ), 2. );
const double h = 1. / levelinfo::num_microedges_per_edge( maxLevel );
x.interpolate( []( const auto& p ) { return p[0] - 0.5; }, maxLevel, All );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMinValue( maxLevel, All ), -0.5 + h / 3. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxValue( maxLevel, All ), 0.5 - h / 3. );
WALBERLA_CHECK_FLOAT_EQUAL( x.getMaxMagnitude( maxLevel, All ), 0.5 - h / 3. );
return 0;
}
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