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/Meshes/DistributedMeshes/DistributedMesh.h>

Vít Hanousek
committed
#include <TNL/Functions/MeshFunction.h>
#include <TNL/Communicators/MpiCommunicator.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::Functions;
using namespace TNL::Devices;
using namespace TNL::Communicators;
using namespace TNL::Meshes::DistributedMeshes;

Vít Hanousek
committed
template<typename DofType>
void setDof_2D( 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,typename GridType>
void checkLeftEdge(GridType &grid, DofType &dof, bool with_first, bool with_last, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
int maxx=grid.getDimensions().x();
int maxy=grid.getDimensions().y();
int begin=0;
int end=maxy;
if(!with_first)
begin++;
if(!with_last)
end--;
for(int i=begin;i<end;i++) //posledni je overlap
EXPECT_EQ( dof[maxx*i], expectedValue) << "Left Edge test failed " << i<<" " << maxx << " "<< maxy;

Vít Hanousek
committed
}
template<typename DofType,typename GridType>
void checkRightEdge(GridType &grid, DofType &dof, bool with_first, bool with_last, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
int maxx=grid.getDimensions().x();
int maxy=grid.getDimensions().y();
int begin=0;
int end=maxy;
if(!with_first)
begin++;
if(!with_last)
end--;
for(int i=begin;i<end;i++)
EXPECT_EQ( dof[maxx*i+(maxx-1)], expectedValue) << "Right Edge test failed " << i <<" " << maxx << " "<< maxy;

Vít Hanousek
committed
}
template<typename DofType,typename GridType>
void checkUpEdge(GridType &grid, DofType &dof, bool with_first, bool with_last, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
int maxx=grid.getDimensions().x();
int maxy=grid.getDimensions().y();
int begin=0;
int end=maxx;
if(!with_first)
begin++;
if(!with_last)
end--;
for(int i=begin;i<end;i++) //posledni je overlap
EXPECT_EQ( dof[i], expectedValue) << "Up Edge test failed " << i<<" " << maxx << " "<< maxy;

Vít Hanousek
committed
}
template<typename DofType,typename GridType>
void checkDownEdge(GridType &grid, DofType &dof, bool with_first, bool with_last, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
int maxx=grid.getDimensions().x();
int maxy=grid.getDimensions().y();
int begin=0;
int end=maxx;
if(!with_first)
begin++;
if(!with_last)
end--;
for(int i=begin;i<end;i++) //posledni je overlap
EXPECT_EQ( dof[maxx*(maxy-1)+i], expectedValue) << "Down Edge test failed " << i<<" " << maxx << " "<< maxy;

Vít Hanousek
committed
}
template<typename DofType,typename GridType>
void checkConner(GridType &grid, DofType &dof, bool up, bool left, typename DofType::RealType expectedValue )
{

Vít Hanousek
committed
int maxx=grid.getDimensions().x();
int maxy=grid.getDimensions().y();
if(up&&left)
{
EXPECT_EQ( dof[0], expectedValue) << "Up Left Conner test failed ";
}
if(up && !left)
{
EXPECT_EQ( dof[maxx-1], expectedValue) << "Up Right Conner test failed ";
}
if(!up && left)
{
EXPECT_EQ( dof[(maxy-1)*maxx], expectedValue) << "Down Left Conner test failed ";
}
if(!up && !left)
{
EXPECT_EQ( dof[(maxy-1)*maxx+maxx-1], expectedValue) << "Down right Conner test failed ";
}

Vít Hanousek
committed
}
/*expect 9 process*/
template<typename DofType,typename GridType>
void check_Boundary_2D(int rank, GridType &grid, DofType &dof, typename DofType::RealType expectedValue)

Vít Hanousek
committed
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
{
if(rank==0)//Up Left
{
checkUpEdge(grid,dof,true,false,expectedValue);//posledni je overlap
checkLeftEdge(grid,dof,true,false, expectedValue);//posledni je overlap
}
if(rank==1)//Up Center
{
checkUpEdge(grid,dof,false,false, expectedValue);//prvni a posledni je overlap
}
if(rank==2)//Up Right
{
checkUpEdge(grid,dof,false,true,expectedValue);//prvni je overlap
checkRightEdge(grid,dof,true,false,expectedValue);//posledni je overlap
}
if(rank==3)//Center Left
{
checkLeftEdge(grid,dof,false,false,expectedValue);//prvni a posledni je overlap
}
if(rank==4)//Center Center
{
//No boundary
}
if(rank==5)//Center Right
{
checkRightEdge(grid,dof,false,false,expectedValue);
}
if(rank==6)//Down Left
{
checkDownEdge(grid,dof,true,false,expectedValue);
checkLeftEdge(grid,dof,false,true,expectedValue);
}
if(rank==7) //Down Center
{
checkDownEdge(grid,dof,false,false,expectedValue);
}
if(rank==8) //Down Right
{
checkDownEdge(grid,dof,false,true,expectedValue);
checkRightEdge(grid,dof,false,true,expectedValue);
}

Vít Hanousek
committed
};
/*expect 9 process
* Known BUG of Traversars: Process boundary is writing over overlap.
* it should be true, true, every where, but we dont chcek boundary overalp on boundary
* so boundary overlap is not checked (it is filled incorectly by boundary condition).

Vít Hanousek
committed
*/
template<typename DofType,typename GridType>
void check_Overlap_2D(int rank, GridType &grid, DofType &dof, typename DofType::RealType expectedValue)
{

Vít Hanousek
committed
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
if(rank==0)//Up Left
{
checkRightEdge(grid,dof,false,true,expectedValue);
checkDownEdge(grid,dof,false,true,expectedValue);
}
if(rank==1)//Up Center
{
checkDownEdge(grid,dof,true,true,expectedValue);
checkLeftEdge(grid,dof,false,true,expectedValue);
checkRightEdge(grid,dof,false,true,expectedValue);
}
if(rank==2)//Up Right
{
checkDownEdge(grid,dof,true,false,expectedValue);//prvni je overlap
checkLeftEdge(grid,dof,false,true,expectedValue);
}
if(rank==3)//Center Left
{
checkUpEdge(grid,dof,false,true,expectedValue);
checkDownEdge(grid,dof,false,true,expectedValue);
checkRightEdge(grid,dof,true,true,expectedValue);
}
if(rank==4)//Center Center
{
checkUpEdge(grid,dof,true,true,expectedValue);
checkDownEdge(grid,dof,true,true,expectedValue);
checkRightEdge(grid,dof,true,true,expectedValue);
checkLeftEdge(grid,dof,true,true,expectedValue);
}
if(rank==5)//Center Right
{
checkUpEdge(grid,dof,true,false,expectedValue);
checkDownEdge(grid,dof,true,false,expectedValue);
checkLeftEdge(grid,dof,true,true,expectedValue);
}
if(rank==6)//Down Left
{
checkUpEdge(grid,dof,false,true,expectedValue);
checkRightEdge(grid,dof,true,false,expectedValue);
}
if(rank==7) //Down Center
{
checkUpEdge(grid,dof,true,true,expectedValue);
checkLeftEdge(grid,dof,true,false,expectedValue);
checkRightEdge(grid,dof,true,false,expectedValue);
}
if(rank==8) //Down Right
{
checkUpEdge(grid,dof,true,false,expectedValue);
checkLeftEdge(grid,dof,true,false,expectedValue);
}

Vít Hanousek
committed
}
/*Expect 9 process
*/
template<typename DofType,typename GridType>
void checkNeighbor_2D(int rank, GridType &grid, DofType &dof)
{

Vít Hanousek
committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
if(rank==0)//Up Left
{
checkRightEdge(grid,dof,true,false,1);
checkDownEdge(grid,dof,true,false,3);
checkConner(grid,dof,false,false,4);
}
if(rank==1)//Up Center
{
checkLeftEdge(grid,dof,true,false,0);
checkRightEdge(grid,dof,true,false,2);
checkConner(grid,dof,false,true,3);
checkDownEdge(grid,dof,false,false,4);
checkConner(grid,dof,false,false,5);
}
if(rank==2)//Up Right
{
checkLeftEdge(grid,dof,true,false,1);
checkConner(grid,dof,false,true,4);
checkDownEdge(grid,dof,false,true,5);
}
if(rank==3)//Center Left
{
checkUpEdge(grid,dof,true,false,0);
checkConner(grid,dof,true,false,1);
checkRightEdge(grid,dof,false,false,4);
checkDownEdge(grid,dof,true,false,6);
checkConner(grid,dof,false,false,7);
}
if(rank==4)//Center Center
{
checkConner(grid,dof,true,true,0);
checkUpEdge(grid,dof,false,false,1);
checkConner(grid,dof,true,false,2);
checkLeftEdge(grid,dof,false,false,3);
checkRightEdge(grid,dof,false,false,5);
checkConner(grid,dof,false,true,6);
checkDownEdge(grid,dof,false,false,7);
checkConner(grid,dof,false,false,8);
}
if(rank==5)//Center Right
{
checkConner(grid,dof,true,true,1);
checkUpEdge(grid,dof,false,true,2);
checkLeftEdge(grid,dof,false,false,4);
checkConner(grid,dof,false,true,7);
checkDownEdge(grid,dof,false,true,8);
}
if(rank==6)//Down Left
{
checkUpEdge(grid,dof,true,false,3);
checkConner(grid,dof,true,false,4);
checkRightEdge(grid,dof,false,true,7);
}
if(rank==7) //Down Center
{
checkConner(grid,dof,true,true,3);
checkUpEdge(grid,dof,false,false,4);
checkConner(grid,dof,true,false,5);
checkLeftEdge(grid,dof,false,true,6);
checkRightEdge(grid,dof,false,true,8);
}
if(rank==8) //Down Right
{
checkConner(grid,dof,true,true,4);
checkUpEdge(grid,dof,false,true,5);
checkLeftEdge(grid,dof,false,true,7);
}

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

Vít Hanousek
committed
int maxx=grid.getDimensions().x();
int maxy=grid.getDimensions().y();
for(int j=1;j<maxy-1;j++)//prvni a posledni jsou buď hranice, nebo overlap
for(int i=1;i<maxx-1;i++) //buď je vlevo hranice, nebo overlap
EXPECT_EQ( dof[j*maxx+i], expectedValue) << " "<< j<<" "<<i << " " << maxx << " " << maxy;

Vít Hanousek
committed
}

Vít Hanousek
committed
/*
* Light check of 2D distributed grid and its synchronization.
* expected 9 processors
*/
typedef MpiCommunicator CommunicatorType;

Vít Hanousek
committed
typedef Grid<2,double,Host,int> MeshType;
typedef MeshFunction<MeshType> MeshFunctionType;
typedef Vector<double,Host,int> DofType;
typedef typename MeshType::Cell Cell;
typedef typename MeshType::IndexType IndexType;
typedef typename MeshType::PointType PointType;
typedef DistributedMesh<MeshType> DistributedGridType;
Tomáš Oberhuber
committed
class DistributedGirdTest_2D : public ::testing::Test
{
Tomáš Oberhuber
committed
public:

Vít Hanousek
committed
Tomáš Oberhuber
committed
static DistributedGridType *distrgrid;
static DofType *dof;

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

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

Vít Hanousek
committed
Tomáš Oberhuber
committed
static MeshFunctionEvaluator< MeshFunctionType, LinearFunction<double,2> > linearFunctionEvaluator;
static SharedPointer< LinearFunction<double,2>, 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);

Vít Hanousek
committed
Tomáš Oberhuber
committed
PointType globalOrigin;
PointType globalProportions;
MeshType globalGrid;

Vít Hanousek
committed
Tomáš Oberhuber
committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
globalOrigin.x()=-0.5;
globalOrigin.y()=-0.5;
globalProportions.x()=size;
globalProportions.y()=size;
globalGrid.setDimensions(size,size);
globalGrid.setDomain(globalOrigin,globalProportions);
//typename DistributedGridType::CoordinatesType overlap( 1 );
distrgrid=new DistributedGridType();
distrgrid->setDomainDecomposition( typename DistributedGridType::CoordinatesType( 3, 3 ) );
distrgrid->template setGlobalGrid<CommunicatorType>( globalGrid );
typename DistributedGridType::SubdomainOverlapsType lowerOverlap, upperOverlap;
SubdomainOverlapsGetter< MeshType, CommunicatorType >::getOverlaps( distrgrid, lowerOverlap, upperOverlap, 1 );
distrgrid->setOverlaps( lowerOverlap, upperOverlap );
distrgrid->setupGrid(*gridptr);
dof=new DofType(gridptr->template getEntitiesCount< Cell >());
meshFunctionptr->bind(gridptr,*dof);
constFunctionPtr->Number=rank;
}
// Per-test-case tear-down.
// Called after the last test in this test case.
// Can be omitted if not needed.
static void TearDownTestCase()
{
delete dof;
delete distrgrid;
}

Vít Hanousek
committed
};
DistributedMesh<MeshType> *DistributedGirdTest_2D::distrgrid=NULL;

Vít Hanousek
committed
DofType *DistributedGirdTest_2D::dof=NULL;
SharedPointer<MeshType> DistributedGirdTest_2D::gridptr;
SharedPointer<MeshFunctionType> DistributedGirdTest_2D::meshFunctionptr;
MeshFunctionEvaluator< MeshFunctionType, ConstFunction<double,2> > DistributedGirdTest_2D::constFunctionEvaluator;
SharedPointer< ConstFunction<double,2>, Host > DistributedGirdTest_2D::constFunctionPtr;
MeshFunctionEvaluator< MeshFunctionType, LinearFunction<double,2> > DistributedGirdTest_2D::linearFunctionEvaluator;
SharedPointer< LinearFunction<double,2>, Host > DistributedGirdTest_2D::linearFunctionPtr;
int DistributedGirdTest_2D::rank;

Vít Hanousek
committed
int DistributedGirdTest_2D::nproc;

Vít Hanousek
committed
TEST_F(DistributedGirdTest_2D, evaluateAllEntities)
{
Tomáš Oberhuber
committed
//Check Traversars
//All entities, without overlap
setDof_2D(*dof,-1);
constFunctionEvaluator.evaluateAllEntities( meshFunctionptr , constFunctionPtr );
//Printer<MeshType,DofType>::print_dof(rank,*gridptr,*dof);
check_Boundary_2D(rank, *gridptr, *dof, rank);
check_Overlap_2D(rank, *gridptr, *dof, -1);
check_Inner_2D(rank, *gridptr, *dof, rank);

Vít Hanousek
committed
}
TEST_F(DistributedGirdTest_2D, evaluateBoundaryEntities)
{
Tomáš Oberhuber
committed
//Boundary entities, without overlap

Vít Hanousek
committed
setDof_2D(*dof,-1);
constFunctionEvaluator.evaluateBoundaryEntities( meshFunctionptr , constFunctionPtr );
//print_dof_2D(rank,*gridptr,dof);
check_Boundary_2D(rank, *gridptr, *dof, rank);
check_Overlap_2D(rank, *gridptr, *dof, -1);
check_Inner_2D(rank, *gridptr, *dof, -1);

Vít Hanousek
committed
}
TEST_F(DistributedGirdTest_2D, evaluateInteriorEntities)
{
Tomáš Oberhuber
committed
//Inner entities, without overlap

Vít Hanousek
committed
setDof_2D(*dof,-1);
constFunctionEvaluator.evaluateInteriorEntities( meshFunctionptr , constFunctionPtr );
check_Boundary_2D(rank, *gridptr, *dof, -1);
check_Overlap_2D(rank, *gridptr, *dof, -1);
check_Inner_2D(rank, *gridptr, *dof, rank);
}

Vít Hanousek
committed
TEST_F(DistributedGirdTest_2D, LinearFunctionTest)
{

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

Vít Hanousek
committed
int count =gridptr->template getEntitiesCount< Cell >();
for(int i=0;i<count;i++)
{
auto entity= gridptr->template getEntity< Cell >(i);
entity.refresh();
EXPECT_EQ(meshFunctionptr->getValue(entity), (*linearFunctionPtr)(entity)) << "Linear function doesnt fit recievd data. " << entity.getCoordinates().x() << " "<<entity.getCoordinates().y() << " "<< gridptr->getDimensions().x() <<" "<<gridptr->getDimensions().y();
}

Vít Hanousek
committed
}
TEST_F(DistributedGirdTest_2D, SynchronizerNeighborTest)
{

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

Vít Hanousek
committed
checkNeighbor_2D(rank, *gridptr, *dof);

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
}