diff --git a/src/TNL/Functions/MeshFunction.h b/src/TNL/Functions/MeshFunction.h index 1bce0d13c9a5bd4f6796aaf04f7bef62999e1d69..7eee9aa42cc5d77f6608168ba31abef56883d518 100644 --- a/src/TNL/Functions/MeshFunction.h +++ b/src/TNL/Functions/MeshFunction.h @@ -13,6 +13,8 @@ #include <TNL/Functions/MeshFunctionGnuplotWriter.h> #include <TNL/Functions/MeshFunctionVTKWriter.h> #include <TNL/SharedPointer.h> +#include <TNL/Meshes/DistributedGrid.h> +#include <TNL/Meshes/DistributedGridSynchronizer.h> #pragma once @@ -156,13 +158,26 @@ class MeshFunction : using Object::boundLoad; +#ifdef USE_MPI + void synchronize(void); +#endif + protected: - + +#ifdef USE_MPI + Meshes::DistributedGridSynchronizer<Meshes::DistributedGrid<MeshType>,ThisType> synchronizer; +#endif + MeshPointer meshPointer; VectorType data; template< typename, typename > friend class MeshFunctionEvaluator; + +#ifdef USE_MPI + private: + void SetupSynchronizer(Meshes::DistributedGrid<Mesh> *distrgrid); +#endif }; } // namespace Functions diff --git a/src/TNL/Functions/MeshFunction_impl.h b/src/TNL/Functions/MeshFunction_impl.h index 096f0ecf4df60bf951625bb6a2cef215690e3a61..71bd45399d7736381d8e00e1f4b718e6ac62141a 100644 --- a/src/TNL/Functions/MeshFunction_impl.h +++ b/src/TNL/Functions/MeshFunction_impl.h @@ -34,8 +34,11 @@ template< typename Mesh, typename Real > MeshFunction< Mesh, MeshEntityDimension, Real >:: MeshFunction( const MeshPointer& meshPointer ) -: meshPointer( meshPointer ) { +#ifdef USE_MPI + SetupSynchronizer(meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshPointer; this->data.setSize( getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() ); TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl @@ -47,8 +50,11 @@ template< typename Mesh, typename Real > MeshFunction< Mesh, MeshEntityDimension, Real >:: MeshFunction( const ThisType& meshFunction ) -: meshPointer( meshFunction.meshPointer ) { +#ifdef USE_MPI + SetupSynchronizer(meshFunction.meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshFunction.meshPointer; this->data.bind( meshFunction.getData() ); } @@ -60,8 +66,12 @@ MeshFunction< Mesh, MeshEntityDimension, Real >:: MeshFunction( const MeshPointer& meshPointer, Vector& data, const IndexType& offset ) -: meshPointer( meshPointer ) +//: meshPointer( meshPointer ) { +#ifdef USE_MPI + SetupSynchronizer(meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshPointer; this->data.bind( data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() ); TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl @@ -77,8 +87,12 @@ MeshFunction< Mesh, MeshEntityDimension, Real >:: MeshFunction( const MeshPointer& meshPointer, SharedPointer< Vector >& data, const IndexType& offset ) -: meshPointer( meshPointer ) +//: meshPointer( meshPointer ) { +#ifdef USE_MPI + SetupSynchronizer(meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshPointer; this->data.bind( *data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() ); TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl @@ -176,7 +190,10 @@ void MeshFunction< Mesh, MeshEntityDimension, Real >:: bind( ThisType& meshFunction ) { - this->meshPointer = meshFunction.getMeshPointer(); +#ifdef USE_MPI + SetupSynchronizer(meshFunction.meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshFunction.meshPointer; this->data.bind( meshFunction.getData() ); } @@ -190,7 +207,10 @@ bind( const MeshPointer& meshPointer, const Vector& data, const IndexType& offset ) { - this->meshPointer = meshPointer; +#ifdef USE_MPI + SetupSynchronizer(meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshPointer; this->data.bind( data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() ); TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl @@ -207,7 +227,10 @@ bind( const MeshPointer& meshPointer, const SharedPointer< Vector >& data, const IndexType& offset ) { - this->meshPointer = meshPointer; +#ifdef USE_MPI + SetupSynchronizer(meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshPointer; this->data.bind( *data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() ); TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl @@ -222,7 +245,10 @@ void MeshFunction< Mesh, MeshEntityDimension, Real >:: setMesh( const MeshPointer& meshPointer ) { - this->meshPointer = meshPointer; +#ifdef USE_MPI + SetupSynchronizer(meshPointer->GetDistGrid()); +#endif + this->meshPointer=meshPointer; this->data.setSize( getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() ); TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl @@ -513,6 +539,39 @@ write( const String& fileName, } return true; } + +#ifdef USE_MPI +template< typename Mesh, + int MeshEntityDimension, + typename Real > +void +MeshFunction< Mesh, MeshEntityDimension, Real >:: +synchronize(void) +{ + //kdyĹľ je synchronizer korektnÄ› natavenĂ˝ + auto distrgrid = this->getMesh().GetDistGrid(); + if(distrgrid != NULL && distrgrid->isMPIUsed()) + { + this->synchronizer.Synchronize(*this); + } +} + +template< typename Mesh, + int MeshEntityDimension, + typename Real > +void +MeshFunction< Mesh, MeshEntityDimension, Real >:: +SetupSynchronizer(Meshes::DistributedGrid<Mesh> *distrgrid) +{ + if(distrgrid)//pokud sĂĹĄ kterou se snažà uĹľivatel nastavit je distruibuovaná + { + if(this->getMesh().GetDistGrid()!=distrgrid)//pokud má nová sĂĹĄ jinou distribuovanou sĂĹĄ neĹľ pĹ™edchozĂ + { + this->synchronizer.SetDistributedGrid(distrgrid); + } + } +} +#endif } // namespace Functions } // namespace TNL diff --git a/src/TNL/Meshes/DistributedGrid.h b/src/TNL/Meshes/DistributedGrid.h index 19fd47fe4bf1f813b849505bec72f3460d2a5ec4..8f163bb1e82122249929c864d65c812c0f0b4a7d 100644 --- a/src/TNL/Meshes/DistributedGrid.h +++ b/src/TNL/Meshes/DistributedGrid.h @@ -78,12 +78,12 @@ class DistributedGrid <GridType,1> private : - GridType GlobalGrid; PointType localorigin; CoordinatesType localbegin; CoordinatesType localsize; CoordinatesType localgridsize; CoordinatesType overlap; + PointType spaceSteps; IndexType Dimensions; @@ -96,19 +96,33 @@ class DistributedGrid <GridType,1> int left; int right; + + bool isSet; public: + DistributedGrid() + { + isSet=false; + }; + //compute everithing DistributedGrid(GridType globalGrid, CoordinatesType overlap, int *distribution=NULL) { + SetGlobalGrid(globalGrid,overlap,distribution); + }; + + void SetGlobalGrid(GridType globalGrid, CoordinatesType overlap, int *distribution=NULL) + { + isSet=true; + this->overlap=overlap; left=-1; right=-1; Dimensions= GridType::getMeshDimension(); - GlobalGrid=globalGrid; + spaceSteps=globalGrid.getSpaceSteps(); //Detect MPI and number of process mpiInUse=false; if(MPI::Is_initialized()) @@ -126,18 +140,18 @@ class DistributedGrid <GridType,1> { //Without MPI - std::cout <<"MEZ MPI"<<std::endl; + std::cout <<"BEZ MPI"<<std::endl; rank=0; - localorigin=GlobalGrid.getOrigin(); - localsize=GlobalGrid.getDimensions(); - localgridsize=GlobalGrid.getDimensions(); + localorigin=globalGrid.getOrigin(); + localsize=globalGrid.getDimensions(); + localgridsize=globalGrid.getDimensions(); + localbegin=CoordinatesType(0); return; } else { //With MPI - //nearnodes if(rank!=0) left=rank-1; @@ -145,26 +159,26 @@ class DistributedGrid <GridType,1> right=rank+1; //compute local mesh size - numberoflarger=GlobalGrid.getDimensions().x()%nproc; + numberoflarger=globalGrid.getDimensions().x()%nproc; - localsize.x()=(GlobalGrid.getDimensions().x()/nproc); + localsize.x()=(globalGrid.getDimensions().x()/nproc); if(numberoflarger>rank) localsize.x()+=1; if(numberoflarger>rank) - localorigin.x()=GlobalGrid.getOrigin().x() - +(rank*localsize.x()-overlap.x())*GlobalGrid.getSpaceSteps().x(); + localorigin.x()=globalGrid.getOrigin().x() + +(rank*localsize.x()-overlap.x())*globalGrid.getSpaceSteps().x(); else - localorigin.x()=GlobalGrid.getOrigin().x() + localorigin.x()=globalGrid.getOrigin().x() +(numberoflarger*(localsize.x()+1)+(rank-numberoflarger)*localsize.x()-overlap.x()) - *GlobalGrid.getSpaceSteps().x(); + *globalGrid.getSpaceSteps().x(); localbegin=overlap; //vlevo neni prekryv if(left==-1) { - localorigin.x()+=overlap.x()*GlobalGrid.getSpaceSteps().x(); + localorigin.x()+=overlap.x()*globalGrid.getSpaceSteps().x(); localbegin.x()=0; } @@ -175,15 +189,16 @@ class DistributedGrid <GridType,1> else localgridsize.x()+=2*overlap.x(); - } - }; + } + }; void SetupGrid( GridType& grid) { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by SetupGrid"); grid.setOrigin(localorigin); grid.setDimensions(localgridsize); //compute local proporions by sideefect - grid.setSpaceSteps(GlobalGrid.getSpaceSteps()); + grid.setSpaceSteps(spaceSteps); grid.SetDistGrid(this); }; @@ -204,11 +219,13 @@ class DistributedGrid <GridType,1> int getLeft() { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by getLeft"); return this->left; }; int getRight() { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by getRight"); return this->right; }; @@ -251,7 +268,7 @@ class DistributedGrid <GridType,2> private : - GridType GlobalGrid; + PointType spaceSteps; PointType localorigin; CoordinatesType localsize;//velikost gridu zpracovavane danym uzlem bez prekryvu CoordinatesType localbegin;//souradnice zacatku zpracovavane vypoctove oblasi @@ -270,18 +287,32 @@ class DistributedGrid <GridType,2> int numberoflarger[2]; int neighbors[8]; + + bool isSet; public: + DistributedGrid() + { + isSet=false; + }; + //compute everithing - DistributedGrid(GridType globalGrid,CoordinatesType overlap,int *distribution=NULL) + DistributedGrid(GridType &globalGrid, CoordinatesType overlap, int *distribution=NULL) + { + SetGlobalGrid(globalGrid,overlap,distribution); + }; + + void SetGlobalGrid(GridType &globalGrid, CoordinatesType overlap, int *distribution=NULL) { + isSet=true; + this->overlap=overlap; for (int i=0;i<8;i++) neighbors[i]=-1; Dimensions= GridType::getMeshDimension(); - GlobalGrid=globalGrid; + spaceSteps=globalGrid.getSpaceSteps(); //Detect MPI and number of process mpiInUse=false; @@ -305,9 +336,9 @@ class DistributedGrid <GridType,2> myproccoord[1]=0; procsdistr[0]=1; procsdistr[1]=1; - localorigin=GlobalGrid.getOrigin(); - localgridsize=GlobalGrid.getDimensions(); - localsize=GlobalGrid.getDimensions(); + localorigin=globalGrid.getOrigin(); + localgridsize=globalGrid.getDimensions(); + localsize=globalGrid.getDimensions(); localbegin.x()=0; localbegin.y()=0; @@ -332,11 +363,11 @@ class DistributedGrid <GridType,2> myproccoord[1]=rank/procsdistr[0]; //compute local mesh size - numberoflarger[0]=GlobalGrid.getDimensions().x()%procsdistr[0]; - numberoflarger[1]=GlobalGrid.getDimensions().y()%procsdistr[1]; + numberoflarger[0]=globalGrid.getDimensions().x()%procsdistr[0]; + numberoflarger[1]=globalGrid.getDimensions().y()%procsdistr[1]; - localsize.x()=(GlobalGrid.getDimensions().x()/procsdistr[0]); - localsize.y()=(GlobalGrid.getDimensions().y()/procsdistr[1]); + localsize.x()=(globalGrid.getDimensions().x()/procsdistr[0]); + localsize.y()=(globalGrid.getDimensions().y()/procsdistr[1]); if(numberoflarger[0]>myproccoord[0]) localsize.x()+=1; @@ -344,20 +375,20 @@ class DistributedGrid <GridType,2> localsize.y()+=1; if(numberoflarger[0]>myproccoord[0]) - localorigin.x()=GlobalGrid.getOrigin().x() - +(myproccoord[0]*localsize.x()-overlap.x())*GlobalGrid.getSpaceSteps().x(); + localorigin.x()=globalGrid.getOrigin().x() + +(myproccoord[0]*localsize.x()-overlap.x())*globalGrid.getSpaceSteps().x(); else - localorigin.x()=GlobalGrid.getOrigin().x() + localorigin.x()=globalGrid.getOrigin().x() +(numberoflarger[0]*(localsize.x()+1)+(myproccoord[0]-numberoflarger[0])*localsize.x()-overlap.x()) - *GlobalGrid.getSpaceSteps().x(); + *globalGrid.getSpaceSteps().x(); if(numberoflarger[1]>myproccoord[1]) - localorigin.y()=GlobalGrid.getOrigin().y() - +(myproccoord[1]*localsize.y()-overlap.y())*GlobalGrid.getSpaceSteps().y(); + localorigin.y()=globalGrid.getOrigin().y() + +(myproccoord[1]*localsize.y()-overlap.y())*globalGrid.getSpaceSteps().y(); else - localorigin.y()=GlobalGrid.getOrigin().y() + localorigin.y()=globalGrid.getOrigin().y() +(numberoflarger[1]*(localsize.y()+1)+(myproccoord[1]-numberoflarger[1])*localsize.y()-overlap.y()) - *GlobalGrid.getSpaceSteps().y(); + *globalGrid.getSpaceSteps().y(); //nearnodes if(myproccoord[0]>0) @@ -381,13 +412,13 @@ class DistributedGrid <GridType,2> if(neighbors[Left]==-1) { - localorigin.x()+=overlap.x()*GlobalGrid.getSpaceSteps().x(); + localorigin.x()+=overlap.x()*globalGrid.getSpaceSteps().x(); localbegin.x()=0; } if(neighbors[Up]==-1) { - localorigin.y()+=overlap.y()*GlobalGrid.getSpaceSteps().y(); + localorigin.y()+=overlap.y()*globalGrid.getSpaceSteps().y(); localbegin.y()=0; } @@ -410,10 +441,11 @@ class DistributedGrid <GridType,2> void SetupGrid( GridType& grid) { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by SetupGrid"); grid.setOrigin(localorigin); grid.setDimensions(localgridsize); //compute local proporions by sideefect - grid.setSpaceSteps(GlobalGrid.getSpaceSteps()); + grid.setSpaceSteps(spaceSteps); grid.SetDistGrid(this); }; @@ -439,6 +471,7 @@ class DistributedGrid <GridType,2> int * getNeighbors() { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by getNeighbors"); return this->neighbors; } @@ -488,7 +521,7 @@ class DistributedGrid <GridType,3> private : - GridType GlobalGrid; + PointType spaceSteps; PointType localorigin; CoordinatesType localsize; CoordinatesType localgridsize; @@ -507,19 +540,33 @@ class DistributedGrid <GridType,3> int numberoflarger[3]; int neighbors[26]; + + bool isSet; public: + DistributedGrid() + { + isSet=false; + }; + //compute everithing - DistributedGrid(GridType globalGrid,CoordinatesType overlap,int *distribution=NULL) + DistributedGrid(GridType &globalGrid, CoordinatesType overlap, int *distribution=NULL) + { + SetGlobalGrid(globalGrid,overlap,distribution); + }; + + void SetGlobalGrid(GridType &globalGrid, CoordinatesType overlap, int *distribution=NULL) { - + + isSet=true; + this->overlap=overlap; for (int i=0;i<26;i++) neighbors[i]=-1; Dimensions= GridType::getMeshDimension(); - GlobalGrid=globalGrid; + spaceSteps=globalGrid.getSpaceSteps(); //Detect MPI and number of process mpiInUse=false; @@ -547,8 +594,8 @@ class DistributedGrid <GridType,3> procsdistr[1]=1; procsdistr[2]=1; - localorigin=GlobalGrid.getOrigin(); - localsize=GlobalGrid.getDimensions(); + localorigin=globalGrid.getOrigin(); + localsize=globalGrid.getDimensions(); localgridsize=localsize; return; } @@ -574,13 +621,13 @@ class DistributedGrid <GridType,3> myproccoord[0]=(rank%(procsdistr[0]*procsdistr[1]))%procsdistr[0]; //compute local mesh size - numberoflarger[0]=GlobalGrid.getDimensions().x()%procsdistr[0]; - numberoflarger[1]=GlobalGrid.getDimensions().y()%procsdistr[1]; - numberoflarger[2]=GlobalGrid.getDimensions().z()%procsdistr[2]; + numberoflarger[0]=globalGrid.getDimensions().x()%procsdistr[0]; + numberoflarger[1]=globalGrid.getDimensions().y()%procsdistr[1]; + numberoflarger[2]=globalGrid.getDimensions().z()%procsdistr[2]; - localsize.x()=(GlobalGrid.getDimensions().x()/procsdistr[0]); - localsize.y()=(GlobalGrid.getDimensions().y()/procsdistr[1]); - localsize.z()=(GlobalGrid.getDimensions().z()/procsdistr[2]); + localsize.x()=(globalGrid.getDimensions().x()/procsdistr[0]); + localsize.y()=(globalGrid.getDimensions().y()/procsdistr[1]); + localsize.z()=(globalGrid.getDimensions().z()/procsdistr[2]); if(numberoflarger[0]>myproccoord[0]) localsize.x()+=1; @@ -590,28 +637,28 @@ class DistributedGrid <GridType,3> localsize.z()+=1; if(numberoflarger[0]>myproccoord[0]) - localorigin.x()=GlobalGrid.getOrigin().x() - +(myproccoord[0]*localsize.x()-overlap.x())*GlobalGrid.getSpaceSteps().x(); + localorigin.x()=globalGrid.getOrigin().x() + +(myproccoord[0]*localsize.x()-overlap.x())*globalGrid.getSpaceSteps().x(); else - localorigin.x()=GlobalGrid.getOrigin().x() + localorigin.x()=globalGrid.getOrigin().x() +(numberoflarger[0]*(localsize.x()+1)+(myproccoord[0]-numberoflarger[0])*localsize.x()-overlap.x()) - *GlobalGrid.getSpaceSteps().x(); + *globalGrid.getSpaceSteps().x(); if(numberoflarger[1]>myproccoord[1]) - localorigin.y()=GlobalGrid.getOrigin().y() - +(myproccoord[1]*localsize.y()-overlap.y())*GlobalGrid.getSpaceSteps().y(); + localorigin.y()=globalGrid.getOrigin().y() + +(myproccoord[1]*localsize.y()-overlap.y())*globalGrid.getSpaceSteps().y(); else - localorigin.y()=GlobalGrid.getOrigin().y() + localorigin.y()=globalGrid.getOrigin().y() +(numberoflarger[1]*(localsize.y()+1)+(myproccoord[1]-numberoflarger[1])*localsize.y()-overlap.y()) - *GlobalGrid.getSpaceSteps().y(); + *globalGrid.getSpaceSteps().y(); if(numberoflarger[2]>myproccoord[2]) - localorigin.z()=GlobalGrid.getOrigin().z() - +(myproccoord[2]*localsize.z()-overlap.z())*GlobalGrid.getSpaceSteps().z(); + localorigin.z()=globalGrid.getOrigin().z() + +(myproccoord[2]*localsize.z()-overlap.z())*globalGrid.getSpaceSteps().z(); else - localorigin.z()=GlobalGrid.getOrigin().z() + localorigin.z()=globalGrid.getOrigin().z() +(numberoflarger[2]*(localsize.z()+1)+(myproccoord[2]-numberoflarger[2])*localsize.z()-overlap.z()) - *GlobalGrid.getSpaceSteps().z(); + *globalGrid.getSpaceSteps().z(); //nearnodes //X Y Z @@ -678,17 +725,17 @@ class DistributedGrid <GridType,3> if(neighbors[West]==-1) { - localorigin.x()+=overlap.x()*GlobalGrid.getSpaceSteps().x(); + localorigin.x()+=overlap.x()*globalGrid.getSpaceSteps().x(); localbegin.x()=0; } if(neighbors[Nord]==-1) { - localorigin.y()+=overlap.y()*GlobalGrid.getSpaceSteps().y(); + localorigin.y()+=overlap.y()*globalGrid.getSpaceSteps().y(); localbegin.y()=0; } if(neighbors[Bottom]==-1) { - localorigin.z()+=overlap.z()*GlobalGrid.getSpaceSteps().z(); + localorigin.z()+=overlap.z()*globalGrid.getSpaceSteps().z(); localbegin.z()=0; } @@ -714,10 +761,11 @@ class DistributedGrid <GridType,3> void SetupGrid( GridType& grid) { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by SetupGrid"); grid.setOrigin(localorigin); grid.setDimensions(localgridsize); //compute local proporions by sideefect - grid.setSpaceSteps(GlobalGrid.getSpaceSteps()); + grid.setSpaceSteps(spaceSteps); grid.SetDistGrid(this); }; @@ -743,6 +791,7 @@ class DistributedGrid <GridType,3> int * getNeighbors() { + TNL_ASSERT_TRUE(isSet,"DistributedGrid is not set, but used by getNeighbors"); return this->neighbors; } diff --git a/src/TNL/Meshes/DistributedGridSynchronizer.h b/src/TNL/Meshes/DistributedGridSynchronizer.h index a08dc84019a5ae2f459011a5b077763bb6eee28f..af9f207705e54b32a20ad0583d9fa48e7fcf9fe9 100644 --- a/src/TNL/Meshes/DistributedGridSynchronizer.h +++ b/src/TNL/Meshes/DistributedGridSynchronizer.h @@ -12,7 +12,7 @@ #include <TNL/Meshes/DistributedGrid.h> -#include <TNL/Functions/MeshFunction.h> +//#include <TNL/Functions/MeshFunction.h> #include <TNL/mpi-supp.h> namespace TNL { @@ -47,36 +47,54 @@ private: int size; DistributedGridType *distributedgrid; -#endif + + bool isSet; public: + DistributedGridSynchronizer() + { + isSet=false; + }; + DistributedGridSynchronizer(DistributedGridType *distrgrid) { + isSet=false; + SetDistributedGrid(distrgrid); + }; + + void SetDistributedGrid(DistributedGridType *distrgrid) + { + if(isSet) + { + DeleteBuffers(); + } + isSet=true; + this->distributedgrid=distrgrid; -#ifdef USE_MPI + size = distributedgrid->getOverlap().x(); leftsendbuf=new Real[size]; rightsendbuf=new Real[size]; leftrcvbuf=new Real[size]; rightrcvbuf=new Real[size]; -#endif - } + }; ~DistributedGridSynchronizer() { - delete [] leftrcvbuf; - delete [] rightrcvbuf; - delete [] leftsendbuf; - delete [] rightsendbuf; - } + if(isSet) + { + DeleteBuffers(); + }; + }; void Synchronize(MeshFunctionType &meshfunction) { + TNL_ASSERT_TRUE(isSet,"Synchronizer is not set, but used to Synchronize"); + if(!distributedgrid->isMPIUsed()) return; -#ifdef USE_MPI Cell leftentity(meshfunction.getMesh()); Cell rightentity(meshfunction.getMesh()); @@ -151,8 +169,18 @@ private: meshfunction.getData()[rightentity.getIndex()]=rightrcvbuf[i]; } } -#endif }; + + private: + void DeleteBuffers(void) + { + delete [] leftrcvbuf; + delete [] rightrcvbuf; + delete [] leftsendbuf; + delete [] rightsendbuf; + }; +#endif + }; //=========================2D================================================= @@ -186,14 +214,30 @@ class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,2> CoordinatesType overlap; CoordinatesType localsize; -#endif + + bool isSet; public: - DistributedGridSynchronizer(DistributedGridType *distgrid) + DistributedGridSynchronizer() + { + isSet=false; + }; + + DistributedGridSynchronizer(DistributedGridType *distrgrid) { + isSet=false; + SetDistributedGrid(distrgrid); + }; + + void SetDistributedGrid(DistributedGridType *distrgrid) + { + if(isSet) + { + DeleteBuffers(); + } + isSet=true; -#ifdef USE_MPI - this->distributedgrid=distgrid; + this->distributedgrid=distrgrid; overlap = distributedgrid->getOverlap(); localsize = distributedgrid->getLocalSize(); @@ -232,28 +276,25 @@ class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,2> rightDst=localgridsize.x()-overlap.x(); upDst=0; downDst=localgridsize.y()-overlap.y(); -#endif - } ~DistributedGridSynchronizer() { - for(int i=0;i<8;i++) - { - delete [] sendbuffs[i]; - delete [] rcvbuffs[i]; - } + if(isSet) + DeleteBuffers(); } void Synchronize(MeshFunctionType &meshfunction) { - if(!distributedgrid->isMPIUsed()) + + TNL_ASSERT_TRUE(isSet,"Synchronizer is not set, but used to Synchronize"); + + if(!distributedgrid->isMPIUsed()) return; -#ifdef USE_MPI - int *neighbor=distributedgrid->getNeighbors(); + int *neighbor=distributedgrid->getNeighbors(); - CopyBuffers(meshfunction, sendbuffs, true, + CopyBuffers(meshfunction, sendbuffs, true, leftSrc, rightSrc, upSrc, downSrc, xcenter, ycenter, overlap,localsize, @@ -330,8 +371,19 @@ class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,2> meshfunction.getData()[entity.getIndex()]=buffer[i*sizex+j]; } } -#endif }; + + void DeleteBuffers(void) + { + for(int i=0;i<8;i++) + { + delete [] sendbuffs[i]; + delete [] rcvbuffs[i]; + } + }; + +#endif + }; //=========================3D================================================= @@ -339,6 +391,8 @@ template <typename DistributedGridType, typename MeshFunctionType> class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,3> { + +#ifdef USE_MPI typedef typename MeshFunctionType::RealType Real; typedef typename DistributedGridType::CoordinatesType CoordinatesType; @@ -366,13 +420,31 @@ class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,3> CoordinatesType overlap; CoordinatesType localsize; + + bool isSet; public: - DistributedGridSynchronizer(DistributedGridType *distgrid) + DistributedGridSynchronizer() { -#ifdef USE_MPI - this->distributedgrid=distgrid; + isSet=false; + }; + + DistributedGridSynchronizer(DistributedGridType *distrgrid) + { + isSet=false; + SetDistributedGrid(distrgrid); + }; + + void SetDistributedGrid(DistributedGridType *distrgrid) + { + if(isSet) + { + DeleteBuffers(); + } + isSet=true; + + this->distributedgrid=distrgrid; overlap = this->distributedgrid->getOverlap(); localsize = this->distributedgrid->getLocalSize(); @@ -415,27 +487,23 @@ class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,3> bottomDst=0; topDst=localgridsize.z()-overlap.z(); -#endif } ~DistributedGridSynchronizer() { -#ifdef USE_MPI - //free buffers - for(int i=0;i<26;i++) + if(isSet) { - delete [] sendbuffs[i]; - delete [] rcvbuffs[i]; + DeleteBuffers(); } -#endif - } void Synchronize(MeshFunctionType &meshfunction) { - if(!distributedgrid->isMPIUsed()) + + TNL_ASSERT_TRUE(isSet,"Synchronizer is not set, but used to Synchronize"); + + if(!distributedgrid->isMPIUsed()) return; -#ifdef USE_MPI int *neighbor=distributedgrid->getNeighbors(); @@ -565,8 +633,18 @@ class DistributedGridSynchronizer<DistributedGridType,MeshFunctionType,3> if(neighbor[TopSouthEast]!=-1) BufferEntities(meshfunction,buffers[TopSouthEast],east,south,top,shortDim.x(),shortDim.y(),shortDim.z(),toBuffer); -#endif }; + + void DeleteBuffers(void) + { + //free buffers + for(int i=0;i<26;i++) + { + delete [] sendbuffs[i]; + delete [] rcvbuffs[i]; + } + }; +#endif }; } // namespace Meshes diff --git a/src/UnitTests/Mpi/DistributedGridIOTest.cpp b/src/UnitTests/Mpi/DistributedGridIOTest.cpp index 19aec746dca99cf845178987bca544c4a5e9aa19..2fd9764ba49f2cfb67e3b4d4971a9640b43695bb 100644 --- a/src/UnitTests/Mpi/DistributedGridIOTest.cpp +++ b/src/UnitTests/Mpi/DistributedGridIOTest.cpp @@ -330,7 +330,7 @@ class TestDistributedGridIO{ CoordinatesType overlap; overlap.setValue(1); DistributedGridType distrgrid(globalGrid,overlap, distr); - DistributedGridSynchronizer<DistributedGridType,MeshFunctionType> synchronizer(&distrgrid); + //DistributedGridSynchronizer<DistributedGridType,MeshFunctionType> synchronizer(&distrgrid); //Crete "distributedgrid driven" grid filed by load SharedPointer<MeshType> loadGridptr; @@ -346,7 +346,7 @@ class TestDistributedGridIO{ DistributedGridIO<MeshFunctionType> ::load(file, *loadMeshFunctionptr ); file.close(); - synchronizer.Synchronize(*loadMeshFunctionptr);//need synchronization for overlaps to be filled corectly in loadDof + loadMeshFunctionptr->synchronize();//need synchronization for overlaps to be filled corectly in loadDof //Crete "distributedgrid driven" grid filed by evaluated linear function @@ -359,7 +359,8 @@ class TestDistributedGridIO{ meshFunctionptr->bind(gridptr,dof); linearFunctionEvaluator.evaluateAllEntities(meshFunctionptr , linearFunctionPtr); - synchronizer.Synchronize(*meshFunctionptr);//need synchronization for overlaps to be filled corectly in dof + //synchronizer.Synchronize(*meshFunctionptr);//need synchronization for overlaps to be filled corectly in dof + meshFunctionptr->synchronize(); for(int i=0;i<localDof.getSize();i++) { diff --git a/src/UnitTests/Mpi/DistributedGridTest_1D.cpp b/src/UnitTests/Mpi/DistributedGridTest_1D.cpp index e54c496f004141e43bcf38b2664cb64aee828db3..d4f70c076731f770954cb92b47cf5e15b6e436ab 100644 --- a/src/UnitTests/Mpi/DistributedGridTest_1D.cpp +++ b/src/UnitTests/Mpi/DistributedGridTest_1D.cpp @@ -97,7 +97,7 @@ class DistributedGirdTest_1D : public ::testing::Test { protected: static DistributedGrid<MeshType> *distrgrid; - static DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,1> *synchronizer; + //static DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,1> *synchronizer; static DofType *dof; static SharedPointer<MeshType> gridptr; @@ -141,7 +141,7 @@ class DistributedGirdTest_1D : public ::testing::Test { meshFunctionptr->bind(gridptr,*dof); - synchronizer=new DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,1>(distrgrid); + //synchronizer=new DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,1>(distrgrid); constFunctionPtr->Number=rank; } @@ -151,13 +151,13 @@ class DistributedGirdTest_1D : public ::testing::Test { // Can be omitted if not needed. static void TearDownTestCase() { delete dof; - delete synchronizer; + //delete synchronizer; delete distrgrid; } }; DistributedGrid<MeshType> *DistributedGirdTest_1D::distrgrid=NULL; -DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,1> *DistributedGirdTest_1D::synchronizer=NULL; +//DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,1> *DistributedGirdTest_1D::synchronizer=NULL; DofType *DistributedGirdTest_1D::dof=NULL; SharedPointer<MeshType> DistributedGirdTest_1D::gridptr; SharedPointer<MeshFunctionType> DistributedGirdTest_1D::meshFunctionptr; @@ -206,8 +206,9 @@ TEST_F(DistributedGirdTest_1D, LinearFunctionTest) //fill meshfunction with linear function (physical center of cell corresponds with its coordinates in grid) setDof_1D(*dof,-1); linearFunctionEvaluator.evaluateAllEntities(meshFunctionptr, linearFunctionPtr); - synchronizer->Synchronize(*meshFunctionptr); - + //synchronizer->Synchronize(*meshFunctionptr); + meshFunctionptr->synchronize(); + auto entite= gridptr->template getEntity< Cell >(0); entite.refresh(); EXPECT_EQ(meshFunctionptr->getValue(entite), (*linearFunctionPtr)(entite)) << "Linear function Overlap error on left Edge."; @@ -221,7 +222,9 @@ TEST_F(DistributedGirdTest_1D, SynchronizerNeighborTest) { setDof_1D(*dof,-1); constFunctionEvaluator.evaluateAllEntities( meshFunctionptr , constFunctionPtr ); - synchronizer->Synchronize(*meshFunctionptr); + //synchronizer->Synchronize(*meshFunctionptr); + meshFunctionptr->synchronize(); + if(rank!=0) EXPECT_EQ((*dof)[0],rank-1)<< "Left Overlap was filled by wrong process."; if(rank!=nproc-1) diff --git a/src/UnitTests/Mpi/DistributedGridTest_2D.cpp b/src/UnitTests/Mpi/DistributedGridTest_2D.cpp index 834d2c0d4f25730523427d7289401cef4bb30863..8f466fc6f0ad2743a3f4556f0c992c0e2c2f3c7c 100644 --- a/src/UnitTests/Mpi/DistributedGridTest_2D.cpp +++ b/src/UnitTests/Mpi/DistributedGridTest_2D.cpp @@ -361,7 +361,7 @@ class DistributedGirdTest_2D : public ::testing::Test { protected: static DistributedGrid<MeshType> *distrgrid; - static DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,2> *synchronizer; + //static DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,2> *synchronizer; static DofType *dof; static SharedPointer<MeshType> gridptr; @@ -406,7 +406,7 @@ class DistributedGirdTest_2D : public ::testing::Test { meshFunctionptr->bind(gridptr,*dof); - synchronizer=new DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,2>(distrgrid); + //synchronizer=new DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,2>(distrgrid); constFunctionPtr->Number=rank; @@ -417,7 +417,7 @@ class DistributedGirdTest_2D : public ::testing::Test { // Can be omitted if not needed. static void TearDownTestCase() { delete dof; - delete synchronizer; + //delete synchronizer; delete distrgrid; } @@ -425,7 +425,7 @@ class DistributedGirdTest_2D : public ::testing::Test { }; DistributedGrid<MeshType> *DistributedGirdTest_2D::distrgrid=NULL; -DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,2> *DistributedGirdTest_2D::synchronizer=NULL; +//DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType,2> *DistributedGirdTest_2D::synchronizer=NULL; DofType *DistributedGirdTest_2D::dof=NULL; SharedPointer<MeshType> DistributedGirdTest_2D::gridptr; SharedPointer<MeshFunctionType> DistributedGirdTest_2D::meshFunctionptr; @@ -475,7 +475,8 @@ TEST_F(DistributedGirdTest_2D, LinearFunctionTest) //fill meshfunction with linear function (physical center of cell corresponds with its coordinates in grid) setDof_2D(*dof,-1); linearFunctionEvaluator.evaluateAllEntities(meshFunctionptr, linearFunctionPtr); - synchronizer->Synchronize(*meshFunctionptr); + //synchronizer->Synchronize(*meshFunctionptr); + meshFunctionptr->synchronize(); int count =gridptr->template getEntitiesCount< Cell >(); for(int i=0;i<count;i++) @@ -490,7 +491,8 @@ TEST_F(DistributedGirdTest_2D, SynchronizerNeighborTest) { setDof_2D(*dof,-1); constFunctionEvaluator.evaluateAllEntities( meshFunctionptr , constFunctionPtr ); - synchronizer->Synchronize(*meshFunctionptr); + //synchronizer->Synchronize(*meshFunctionptr); + meshFunctionptr->synchronize(); checkNeighbor_2D(rank, *gridptr, *dof); } diff --git a/src/UnitTests/Mpi/DistributedGridTest_3D.cpp b/src/UnitTests/Mpi/DistributedGridTest_3D.cpp index 2bd48a67a142b8b892e1c35f0fa41111bbf8acc1..9f71fcda6d65af37d4de9008f80541b79c66f978 100644 --- a/src/UnitTests/Mpi/DistributedGridTest_3D.cpp +++ b/src/UnitTests/Mpi/DistributedGridTest_3D.cpp @@ -605,7 +605,7 @@ class DistributedGirdTest_3D : public ::testing::Test { protected: static DistributedGrid<MeshType> *distrgrid; - static DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType> *synchronizer; + //static DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType> *synchronizer; static DofType *dof; static SharedPointer<MeshType> gridptr; @@ -652,7 +652,7 @@ class DistributedGirdTest_3D : public ::testing::Test { meshFunctionptr->bind(gridptr,*dof); - synchronizer=new DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType>(distrgrid); + //synchronizer=new DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType>(distrgrid); constFunctionPtr->Number=rank; @@ -663,7 +663,7 @@ class DistributedGirdTest_3D : public ::testing::Test { // Can be omitted if not needed. static void TearDownTestCase() { delete dof; - delete synchronizer; + //delete synchronizer; delete distrgrid; } @@ -671,7 +671,7 @@ class DistributedGirdTest_3D : public ::testing::Test { }; DistributedGrid<MeshType> *DistributedGirdTest_3D::distrgrid=NULL; -DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType> *DistributedGirdTest_3D::synchronizer=NULL; +//DistributedGridSynchronizer<DistributedGrid<MeshType>,MeshFunctionType> *DistributedGirdTest_3D::synchronizer=NULL; DofType *DistributedGirdTest_3D::dof=NULL; SharedPointer<MeshType> DistributedGirdTest_3D::gridptr; SharedPointer<MeshFunctionType> DistributedGirdTest_3D::meshFunctionptr; @@ -720,7 +720,8 @@ TEST_F(DistributedGirdTest_3D, LinearFunctionTest) //fill meshfunction with linear function (physical center of cell corresponds with its coordinates in grid) setDof_3D(*dof,-1); linearFunctionEvaluator.evaluateAllEntities(meshFunctionptr, linearFunctionPtr); - synchronizer->Synchronize(*meshFunctionptr); + //synchronizer->Synchronize(*meshFunctionptr); + meshFunctionptr->synchronize(); int count =gridptr->template getEntitiesCount< Cell >(); for(int i=0;i<count;i++) @@ -731,7 +732,7 @@ TEST_F(DistributedGirdTest_3D, LinearFunctionTest) } } -/* +/* not implemented TEST_F(DistributedGirdTest_3D, SynchronizerNeighborTest) { setDof_2D(*dof,-1);