1 #ifndef DUNE_GRID_UTILITY_PARMETISGRIDPARTITIONER_HH 2 #define DUNE_GRID_UTILITY_PARMETISGRIDPARTITIONER_HH 11 #include <dune/common/parallel/mpihelper.hh> 12 #include <dune/common/exceptions.hh> 14 #include <dune/geometry/referenceelements.hh> 23 #ifdef PARMETIS_MAJOR_VERSION 35 template<
class Gr
idView>
36 struct ParMetisGridPartitioner {
39 #if PARMETIS_MAJOR_VERSION > 3 40 typedef idx_t idx_type;
41 typedef real_t real_type;
44 typedef float real_type;
45 #endif // PARMETIS_MAJOR_VERSION > 3 47 typedef typename GridView::template Codim<0>::Iterator ElementIterator;
48 typedef typename GridView::template Codim<0>::template Partition<Interior_Partition>::Iterator InteriorElementIterator;
66 static std::vector<unsigned> partition(
const GridView& gv,
const Dune::MPIHelper& mpihelper) {
67 const unsigned numElements = gv.size(0);
69 std::vector<unsigned> part(numElements);
75 idx_type ncommonnodes = 2;
76 idx_type options[4] = {0, 0, 0, 0};
78 idx_type nparts = mpihelper.size();
79 std::vector<real_type> tpwgts(ncon*nparts, 1./nparts);
80 std::vector<real_type> ubvec(ncon, 1.05);
83 std::vector<idx_type> elmdist(nparts+1);
85 std::fill(elmdist.begin()+1, elmdist.end(), gv.size(0));
89 std::vector<idx_type> eptr, eind;
91 eptr.push_back(numVertices);
93 for (InteriorElementIterator eIt = gv.template begin<0, Interior_Partition>(); eIt != gv.template end<0, Interior_Partition>(); ++eIt) {
94 const int curNumVertices = ReferenceElements<double, dimension>::general(eIt->type()).size(dimension);
96 numVertices += curNumVertices;
97 eptr.push_back(numVertices);
99 for (
size_t k = 0; k < curNumVertices; ++k)
100 eind.push_back(gv.indexSet().subIndex(*eIt, k, dimension));
104 if (0 == mpihelper.rank()) {
105 MPI_Comm comm = Dune::MPIHelper::getLocalCommunicator();
107 #if PARMETIS_MAJOR_VERSION >= 4 110 ParMETIS_V3_PartMeshKway(elmdist.data(), eptr.data(), eind.data(), NULL, &wgtflag, &numflag,
111 &ncon, &ncommonnodes, &nparts, tpwgts.data(), ubvec.data(),
112 options, &edgecut,
reinterpret_cast<idx_type*
>(part.data()), &comm);
114 #if PARMETIS_MAJOR_VERSION >= 4 116 DUNE_THROW(Dune::Exception,
"ParMETIS returned an error code.");
134 static std::vector<unsigned> repartition(
const GridView& gv,
const Dune::MPIHelper& mpihelper, real_type& itr = 1000) {
137 GlobalIndexSet<GridView> globalIndex(gv,0);
139 int numElements = std::distance(gv.template begin<0, Interior_Partition>(),
140 gv.template end<0, Interior_Partition>());
142 std::vector<unsigned> interiorPart(numElements);
145 idx_type wgtflag = 0;
146 idx_type numflag = 0;
148 idx_type options[4] = {0, 0, 0, 0};
150 idx_type nparts = mpihelper.size();
151 std::vector<real_type> tpwgts(ncon*nparts, 1./nparts);
152 std::vector<real_type> ubvec(ncon, 1.05);
154 MPI_Comm comm = Dune::MPIHelper::getCommunicator();
157 std::vector<int> offset(gv.comm().size());
158 std::fill(offset.begin(), offset.end(), 0);
160 gv.comm().template allgather<int>(&numElements, 1, offset.data());
163 std::vector<idx_type> vtxdist(gv.comm().size()+1);
166 for (
unsigned int i=1; i<vtxdist.size(); ++i)
167 vtxdist[i] = vtxdist[i-1] + offset[i-1];
170 std::vector<idx_type> xadj, adjncy;
173 for (InteriorElementIterator eIt = gv.template begin<0, Interior_Partition>(); eIt != gv.template end<0, Interior_Partition>(); ++eIt)
175 size_t numNeighbors = 0;
177 for (IntersectionIterator iIt = gv.template ibegin(*eIt); iIt != gv.template iend(*eIt); ++iIt) {
178 if (iIt->neighbor()) {
179 adjncy.push_back(globalIndex.index(*iIt->outside()));
185 xadj.push_back(xadj.back() + numNeighbors);
188 #if PARMETIS_MAJOR_VERSION >= 4 191 ParMETIS_V3_AdaptiveRepart(vtxdist.data(), xadj.data(), adjncy.data(), NULL, NULL, NULL,
192 &wgtflag, &numflag, &ncon, &nparts, tpwgts.data(), ubvec.data(),
193 &itr, options, &edgecut,
reinterpret_cast<idx_type*
>(interiorPart.data()), &comm);
195 #if PARMETIS_MAJOR_VERSION >= 4 197 DUNE_THROW(Dune::Exception,
"ParMETIS returned error code " << OK);
206 typedef MultipleCodimMultipleGeomTypeMapper<GridView, MCMGElementLayout> ElementMapper;
207 ElementMapper elementMapper(gv);
209 std::vector<unsigned int> part(gv.size(0));
210 std::fill(part.begin(), part.end(), 0);
212 for (InteriorElementIterator eIt = gv.template begin<0, Interior_Partition>();
213 eIt != gv.template end<0, Interior_Partition>();
216 part[elementMapper.index(*eIt)] = interiorPart[c++];
224 #else // PARMETIS_MAJOR_VERSION 225 #warning "You seem to be using the ParMETIS emulation layer of scotch, which does not work with this file." 228 #else // HAVE_PARMETIS 229 #warning "PARMETIS was not found, please check your configuration" 232 #endif // DUNE_GRID_UTILITY_PARMETISGRIDPARTITIONER_HH Provides a globally unique index for all entities of a distributed Dune grid.
Traits::IntersectionIterator IntersectionIterator
type of the intersection iterator
Definition: common/gridview.hh:86
Include standard header files.
Definition: agrid.hh:59
Mapper for multiple codim and multiple geometry types.
The dimension of the grid.
Definition: common/gridview.hh:130