Newer
Older

Vít Hanousek
committed
/***************************************************************************
DistributedGridTest.cpp - description
-------------------
begin : Sep 6, 2017
copyright : (C) 2017 by Tomas Oberhuber et al.
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
#ifdef HAVE_GTEST
#include <gtest/gtest.h>

Vít Hanousek
committed
#ifdef HAVE_MPI

Vít Hanousek
committed
#include <TNL/Communicators/MpiCommunicator.h>

Vít Hanousek
committed
#include <TNL/Functions/MeshFunction.h>
Tomáš Oberhuber
committed
#include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
#include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>

Vít Hanousek
committed
Tomáš Oberhuber
committed
#include "../../Functions/Functions.h"

Vít Hanousek
committed
using namespace TNL;
using namespace TNL::Containers;
using namespace TNL::Meshes;
using namespace TNL::Meshes::DistributedMeshes;

Vít Hanousek
committed
using namespace TNL::Functions;
using namespace TNL::Devices;
using namespace TNL::Communicators;

Vít Hanousek
committed
template<typename DofType>
void setDof_1D(DofType &dof, typename DofType::RealType value)
{

Vít Hanousek
committed
for(int i=0;i<dof.getSize();i++)
dof[i]=value;

Vít Hanousek
committed
}
template<typename DofType>
void check_Boundary_1D(int rank, int nproc, DofType dof, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
if(rank==0)//Left
{
EXPECT_EQ( dof[0], expectedValue) << "Left boundary test failed";
return;
}
if(rank==(nproc-1))//Right
{
EXPECT_EQ( dof[dof.getSize()-1], expectedValue) << "Right boundary test failed";
return;
}

Vít Hanousek
committed
};
template<typename DofType>
void check_Overlap_1D(int rank, int nproc, DofType dof, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
if(rank==0)//Left
{
EXPECT_EQ( dof[dof.getSize()-1], expectedValue) << "Left boundary node overlap test failed";
return;
}
if(rank==(nproc-1))
{
EXPECT_EQ( dof[0], expectedValue) << "Right boundary node overlap test failed";
return;
}
EXPECT_EQ( dof[0], expectedValue) << "left overlap test failed";
EXPECT_EQ( dof[dof.getSize()-1], expectedValue)<< "right overlap test failed";

Vít Hanousek
committed
};
template<typename DofType>
void check_Inner_1D(int rank, int nproc, DofType dof, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
for(int i=1;i<(dof.getSize()-2);i++) //buď je vlevo hranice, nebo overlap
EXPECT_EQ( dof[i], expectedValue) << " "<< i;

Vít Hanousek
committed
};
/*
* Light check of 1D distriover grid and its synchronization.
* Number of process is not limitated.
* Overlap is limitated to 1
* Only double is tested as dof Real type -- it may be changed, extend test
* Global size is hardcoded as 10 -- it can be changed, extend test
*/
typedef MpiCommunicator CommunicatorType;
Tomáš Oberhuber
committed
typedef Grid<1,double,Host,int> GridType;
typedef MeshFunction<GridType> MeshFunctionType;

Vít Hanousek
committed
typedef Vector<double,Host,int> DofType;
Tomáš Oberhuber
committed
typedef typename GridType::Cell Cell;
typedef typename GridType::IndexType IndexType;
typedef typename GridType::PointType PointType;
typedef DistributedMesh<GridType> DistributedGridType;

Vít Hanousek
committed
class DistributedGridTest_1D : public ::testing::Test
Tomáš Oberhuber
committed
{
protected:

Vít Hanousek
committed
static DistributedMesh< GridType > *distributedGrid;
Tomáš Oberhuber
committed
static DofType *dof;

Vít Hanousek
committed
Tomáš Oberhuber
committed
static SharedPointer< GridType > gridptr;
static SharedPointer< MeshFunctionType > meshFunctionptr;

Vít Hanousek
committed
Tomáš Oberhuber
committed
static MeshFunctionEvaluator< MeshFunctionType, ConstFunction< double, 1 > > constFunctionEvaluator;
static SharedPointer< ConstFunction< double, 1 >, Host > constFunctionPtr;

Vít Hanousek
committed
Tomáš Oberhuber
committed
static MeshFunctionEvaluator< MeshFunctionType, LinearFunction< double, 1 > > linearFunctionEvaluator;
static SharedPointer< LinearFunction< double, 1 >, Host > linearFunctionPtr;

Vít Hanousek
committed
Tomáš Oberhuber
committed
static int rank;
static int nproc;

Vít Hanousek
committed
Tomáš Oberhuber
committed
// Per-test-case set-up.
// Called before the first test in this test case.
// Can be omitted if not needed.
static void SetUpTestCase()
{
int size=10;
rank=CommunicatorType::GetRank(CommunicatorType::AllGroup);
nproc=CommunicatorType::GetSize(CommunicatorType::AllGroup);
PointType globalOrigin;
PointType globalProportions;
GridType globalGrid;
globalOrigin.x()=-0.5;
globalProportions.x()=size;
globalGrid.setDimensions(size);
globalGrid.setDomain(globalOrigin,globalProportions);
typename DistributedGridType::CoordinatesType overlap;
overlap.setValue(1);
distributedGrid=new DistributedGridType();
Tomáš Oberhuber
committed
typename DistributedGridType::SubdomainOverlapsType lowerOverlap, upperOverlap;
distributedGrid->template setGlobalGrid<CommunicatorType>( globalGrid );
distributedGrid->setupGrid(*gridptr);
SubdomainOverlapsGetter< GridType, CommunicatorType >::getOverlaps( distributedGrid, lowerOverlap, upperOverlap, 1 );
distributedGrid->setOverlaps( lowerOverlap, upperOverlap );
Tomáš Oberhuber
committed
//distributedGrid->template setGlobalGrid<CommunicatorType>(globalGrid,overlap,overlap); // TODO: fix this
Tomáš Oberhuber
committed
distributedGrid->setupGrid(*gridptr);
Tomáš Oberhuber
committed
dof=new DofType(gridptr->template getEntitiesCount< Cell >());
meshFunctionptr->bind(gridptr,*dof);
constFunctionPtr->Number=rank;
}

Vít Hanousek
committed
// Per-test-case tear-down.
// Called after the last test in this test case.
// Can be omitted if not needed.
static void TearDownTestCase() {

Vít Hanousek
committed
delete dof;
delete distributedGrid;

Vít Hanousek
committed
}
};
DistributedMesh<GridType> *DistributedGridTest_1D::distributedGrid=NULL;
DofType *DistributedGridTest_1D::dof=NULL;
SharedPointer<GridType> DistributedGridTest_1D::gridptr;
SharedPointer<MeshFunctionType> DistributedGridTest_1D::meshFunctionptr;
MeshFunctionEvaluator< MeshFunctionType, ConstFunction<double,1> > DistributedGridTest_1D::constFunctionEvaluator;
SharedPointer< ConstFunction<double,1>, Host > DistributedGridTest_1D::constFunctionPtr;
MeshFunctionEvaluator< MeshFunctionType, LinearFunction<double,1> > DistributedGridTest_1D::linearFunctionEvaluator;
SharedPointer< LinearFunction<double,1>, Host > DistributedGridTest_1D::linearFunctionPtr;
int DistributedGridTest_1D::rank;
int DistributedGridTest_1D::nproc;
TEST_F(DistributedGridTest_1D, evaluateAllEntities)

Vít Hanousek
committed
{

Vít Hanousek
committed
//Check Traversars
//All entities, witout overlap
setDof_1D(*dof,-1);
constFunctionEvaluator.evaluateAllEntities( meshFunctionptr , constFunctionPtr );
Tomáš Oberhuber
committed
//Printer<GridType,DofType>::print_dof(rank,*gridptr,*dof);

Vít Hanousek
committed
check_Boundary_1D(rank, nproc, *dof, rank);
check_Overlap_1D(rank, nproc, *dof, -1);
check_Inner_1D(rank, nproc, *dof, rank);

Vít Hanousek
committed
}
TEST_F(DistributedGridTest_1D, evaluateBoundaryEntities)

Vít Hanousek
committed
{

Vít Hanousek
committed
//Boundary entities, witout overlap
setDof_1D(*dof,-1);
constFunctionEvaluator.evaluateBoundaryEntities( meshFunctionptr , constFunctionPtr );
check_Boundary_1D(rank, nproc, *dof, rank);
check_Overlap_1D(rank, nproc, *dof, -1);
check_Inner_1D(rank, nproc, *dof, -1);

Vít Hanousek
committed
}
TEST_F(DistributedGridTest_1D, evaluateInteriorEntities)

Vít Hanousek
committed
{

Vít Hanousek
committed
//Inner entities, witout overlap
setDof_1D(*dof,-1);
constFunctionEvaluator.evaluateInteriorEntities( meshFunctionptr , constFunctionPtr );
check_Boundary_1D(rank, nproc, *dof, -1);
check_Overlap_1D(rank, nproc, *dof, -1);
check_Inner_1D(rank, nproc, *dof, rank);
}

Vít Hanousek
committed
TEST_F(DistributedGridTest_1D, LinearFunctionTest)

Vít Hanousek
committed
{

Vít Hanousek
committed
//fill meshfunction with linear function (physical center of cell corresponds with its coordinates in grid)
setDof_1D(*dof,-1);
linearFunctionEvaluator.evaluateAllEntities(meshFunctionptr, linearFunctionPtr);
meshFunctionptr->template synchronize<CommunicatorType>();

Vít Hanousek
committed

Vít Hanousek
committed
auto entite= gridptr->template getEntity< Cell >(0);
entite.refresh();
EXPECT_EQ(meshFunctionptr->getValue(entite), (*linearFunctionPtr)(entite)) << "Linear function Overlap error on left Edge.";
auto entite2= gridptr->template getEntity< Cell >((*dof).getSize()-1);
entite2.refresh();
EXPECT_EQ(meshFunctionptr->getValue(entite), (*linearFunctionPtr)(entite)) << "Linear function Overlap error on right Edge.";

Vít Hanousek
committed
}
TEST_F(DistributedGridTest_1D, SynchronizerNeighborTest)

Vít Hanousek
committed
{

Vít Hanousek
committed
setDof_1D(*dof,-1);
constFunctionEvaluator.evaluateAllEntities( meshFunctionptr , constFunctionPtr );
meshFunctionptr->template synchronize<CommunicatorType>();

Vít Hanousek
committed

Vít Hanousek
committed
if(rank!=0)
EXPECT_EQ((*dof)[0],rank-1)<< "Left Overlap was filled by wrong process.";
if(rank!=nproc-1)
EXPECT_EQ((*dof)[dof->getSize()-1],rank+1)<< "Right Overlap was filled by wrong process.";

Vít Hanousek
committed
}
TEST_F(DistributedGridTest_1D, SynchronizePeriodicBoundariesTest)
{
setDof_1D(*dof,-1);
constFunctionEvaluator.evaluateAllEntities( meshFunctionptr , constFunctionPtr );
meshFunctionptr->template synchronize<CommunicatorType>();
if(rank!=0)
EXPECT_EQ((*dof)[0],rank-1)<< "Left Overlap was filled by wrong process.";
if(rank!=nproc-1)
EXPECT_EQ((*dof)[dof->getSize()-1],rank+1)<< "Right Overlap was filled by wrong process.";
}

Vít Hanousek
committed

Vít Hanousek
committed
#else
TEST(NoMPI, NoTest)
{

Vít Hanousek
committed
ASSERT_TRUE(true) << ":-(";

Vít Hanousek
committed
}
#endif
#endif
#if (defined(HAVE_GTEST) && defined(HAVE_MPI))
#include <sstream>
Tomáš Oberhuber
committed
class MinimalistBufferedPrinter : public ::testing::EmptyTestEventListener {

Vít Hanousek
committed

Vít Hanousek
committed
private:

Vít Hanousek
committed
std::stringstream sout;

Vít Hanousek
committed
public:

Vít Hanousek
committed

Vít Hanousek
committed
// Called before a test starts.
virtual void OnTestStart(const ::testing::TestInfo& test_info) {
sout<< test_info.test_case_name() <<"." << test_info.name() << " Start." <<std::endl;
}
// Called after a failed assertion or a SUCCEED() invocation.
virtual void OnTestPartResult(
const ::testing::TestPartResult& test_part_result) {
sout << (test_part_result.failed() ? "====Failure=== " : "===Success=== ")

Vít Hanousek
committed
<< test_part_result.file_name() << " "

Vít Hanousek
committed
<< test_part_result.line_number() <<std::endl
<< test_part_result.summary() <<std::endl;
}
// Called after a test ends.
virtual void OnTestEnd(const ::testing::TestInfo& test_info)

Vít Hanousek
committed
{
int rank=CommunicatorType::GetRank(CommunicatorType::AllGroup);

Vít Hanousek
committed
sout<< test_info.test_case_name() <<"." << test_info.name() << " End." <<std::endl;

Vít Hanousek
committed
std::cout << rank << ":" << std::endl << sout.str()<< std::endl;
sout.str( std::string() );
sout.clear();

Vít Hanousek
committed
}
};
#endif
#include "../../src/UnitTests/GtestMissingError.h"
int main( int argc, char* argv[] )
{
#ifdef HAVE_GTEST
::testing::InitGoogleTest( &argc, argv );

Vít Hanousek
committed
#ifdef HAVE_MPI
::testing::TestEventListeners& listeners =
::testing::UnitTest::GetInstance()->listeners();

Vít Hanousek
committed

Vít Hanousek
committed
delete listeners.Release(listeners.default_result_printer());
Tomáš Oberhuber
committed
listeners.Append(new MinimalistBufferedPrinter);

Vít Hanousek
committed

Vít Hanousek
committed
#endif
int result= RUN_ALL_TESTS();

Vít Hanousek
committed

Vít Hanousek
committed
#ifdef HAVE_MPI

Vít Hanousek
committed
#endif
return result;

Vít Hanousek
committed
#else
throw GtestMissingError();
#endif
}