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>
29 template<
class Gr
idView>
30 struct ParMetisGridPartitioner {
31 #if PARMETIS_MAJOR_VERSION < 4
32 typedef idxtype idx_t;
36 typedef typename GridView::template Codim<0>::Iterator ElementIterator;
37 typedef typename GridView::template Codim<0>::template Partition<Interior_Partition>::Iterator InteriorElementIterator;
55 static std::vector<unsigned> partition(
const GridView& gv,
const Dune::MPIHelper& mpihelper) {
56 const unsigned numElements = gv.size(0);
58 std::vector<unsigned> part(numElements);
64 idx_t ncommonnodes = 2;
65 idx_t options[4] = {0, 0, 0, 0};
67 idx_t nparts = mpihelper.size();
68 std::vector<real_t> tpwgts(ncon*nparts, 1./nparts);
69 std::vector<real_t> ubvec(ncon, 1.05);
72 std::vector<idx_t> elmdist(nparts+1);
74 std::fill(elmdist.begin()+1, elmdist.end(), gv.size(0));
78 std::vector<idx_t> eptr, eind;
80 eptr.push_back(numVertices);
82 for (InteriorElementIterator eIt = gv.template begin<0, Interior_Partition>(); eIt != gv.template end<0, Interior_Partition>(); ++eIt) {
83 const int curNumVertices = ReferenceElements<double, dimension>::general(eIt->type()).size(dimension);
85 numVertices += curNumVertices;
86 eptr.push_back(numVertices);
88 for (
size_t k = 0; k < curNumVertices; ++k)
89 eind.push_back(gv.indexSet().subIndex(*eIt, k, dimension));
93 if (0 == mpihelper.rank()) {
94 MPI_Comm comm = Dune::MPIHelper::getLocalCommunicator();
96 #if PARMETIS_MAJOR_VERSION >= 4
99 ParMETIS_V3_PartMeshKway(elmdist.data(), eptr.data(), eind.data(), NULL, &wgtflag, &numflag,
100 &ncon, &ncommonnodes, &nparts, tpwgts.data(), ubvec.data(),
101 options, &edgecut,
reinterpret_cast<idx_t*
>(part.data()), &comm);
103 #if PARMETIS_MAJOR_VERSION >= 4
105 DUNE_THROW(Dune::Exception,
"ParMETIS returned an error code.");
123 static std::vector<unsigned> repartition(
const GridView& gv,
const Dune::MPIHelper& mpihelper, real_t& itr = 1000) {
126 GlobalIndexSet<GridView> globalIndex(gv,0);
128 int numElements = std::distance(gv.template begin<0, Interior_Partition>(),
129 gv.template end<0, Interior_Partition>());
131 std::vector<unsigned> interiorPart(numElements);
137 idx_t options[4] = {0, 0, 0, 0};
139 idx_t nparts = mpihelper.size();
140 std::vector<real_t> tpwgts(ncon*nparts, 1./nparts);
141 std::vector<real_t> ubvec(ncon, 1.05);
143 MPI_Comm comm = Dune::MPIHelper::getCommunicator();
146 std::vector<int> offset(gv.comm().size());
147 std::fill(offset.begin(), offset.end(), 0);
149 gv.comm().template allgather<int>(&numElements, 1, offset.data());
152 std::vector<idx_t> vtxdist(gv.comm().size()+1);
155 for (
unsigned int i=1; i<vtxdist.size(); ++i)
156 vtxdist[i] = vtxdist[i-1] + offset[i-1];
159 std::vector<idx_t> xadj, adjncy;
162 for (InteriorElementIterator eIt = gv.template begin<0, Interior_Partition>(); eIt != gv.template end<0, Interior_Partition>(); ++eIt)
164 size_t numNeighbors = 0;
166 for (IntersectionIterator iIt = gv.template ibegin(*eIt); iIt != gv.template iend(*eIt); ++iIt) {
167 if (iIt->neighbor()) {
168 adjncy.push_back(globalIndex.index(*iIt->outside()));
174 xadj.push_back(xadj.back() + numNeighbors);
177 #if PARMETIS_MAJOR_VERSION >= 4
180 ParMETIS_V3_AdaptiveRepart(vtxdist.data(), xadj.data(), adjncy.data(), NULL, NULL, NULL,
181 &wgtflag, &numflag, &ncon, &nparts, tpwgts.data(), ubvec.data(),
182 &itr, options, &edgecut,
reinterpret_cast<idx_t*
>(interiorPart.data()), &comm);
184 #if PARMETIS_MAJOR_VERSION >= 4
186 DUNE_THROW(Dune::Exception,
"ParMETIS returned error code " << OK);
195 typedef MultipleCodimMultipleGeomTypeMapper<GridView, MCMGElementLayout> ElementMapper;
196 ElementMapper elementMapper(gv);
198 std::vector<unsigned int> part(gv.size(0));
199 std::fill(part.begin(), part.end(), 0);
201 for (InteriorElementIterator eIt = gv.template begin<0, Interior_Partition>();
202 eIt != gv.template end<0, Interior_Partition>();
205 part[elementMapper.index(*eIt)] = interiorPart[c++];
213 #else // HAVE_PARMETIS
214 #warning "PARMETIS was not found, please check your configuration"
217 #endif // DUNE_GRID_UTILITY_PARMETISGRIDPARTITIONER_HH
The dimension of the grid.
Definition: common/gridview.hh:130
Include standard header files.
Definition: agrid.hh:59
Mapper for multiple codim and multiple geometry types.
Traits::IntersectionIterator IntersectionIterator
type of the intersection iterator
Definition: common/gridview.hh:86
Provides a globally unique index for all entities of a distributed Dune grid.