34 #define OMPI_SKIP_MPICXX
40 #if defined(METIS_NEW_API) || (defined(METIS_API) && defined(METIS_NOPTIONS))
43 #define DEFINE_METIS_COMPAT_FUNC(BASE_NAME) \
44 void FOAM_W ## BASE_NAME(int *nvtxs_p, int *xadj_p, int *adjncy_p, \
45 int *vwgt_p, int *adjwgt_p, int *wgtflag_p, \
46 int *numflag_p, int *nparts_p, \
47 float *tpwgts_p, int *options_p, \
48 int *edgecut_p, int *part_p) \
50 using namespace Foam; \
53 idx_t nvtxs = *nvtxs_p; \
55 idx_t madjncy = xadj_p[nvtxs]; \
56 List<idx_t> xadj(nvtxs+1); \
57 std::copy(xadj_p, xadj_p+nvtxs+1, xadj.begin()); \
58 List<idx_t> adjncy(madjncy); \
59 std::copy(adjncy_p, adjncy_p+madjncy, adjncy.begin()); \
63 vwgt.setSize(nvtxs); \
64 std::copy(vwgt_p, vwgt_p+nvtxs, vwgt.begin()); \
69 adjwgt.setSize(madjncy); \
70 std::copy(adjwgt_p, adjwgt_p+madjncy, adjwgt.begin()); \
72 idx_t nparts = *nparts_p; \
73 List<real_t> tpwgts; \
76 tpwgts.setSize(nparts); \
77 std::copy(tpwgts_p, tpwgts_p+nparts, tpwgts.begin()); \
79 List<idx_t> opts(METIS_NOPTIONS); \
80 METIS_SetDefaultOptions(opts.begin()); \
81 if (options_p && options_p[0]) \
85 switch (options_p[1]) \
87 case 1: opts[METIS_OPTION_CTYPE] = METIS_CTYPE_RM; break; \
89 case 3: opts[METIS_OPTION_CTYPE] = METIS_CTYPE_SHEM; break; \
92 opts[METIS_OPTION_NUMBERING] = *numflag_p; \
94 List<idx_t> part(nvtxs); \
103 vwgt_p ? vwgt.begin() : NULL, \
105 adjwgt_p ? adjwgt.begin() : NULL, \
107 tpwgts_p ? tpwgts.begin() : NULL, \
115 *edgecut_p = edgecut; \
116 forAll(part, partI) \
118 part_p[partI] = part[partI]; \
124 void FOAM_ ## BASE_NAME(int *nvtxs_p, int *xadj_p, int *adjncy_p, int *vwgt_p,\
125 int *adjwgt_p, int *wgtflag_p, int *numflag_p, \
126 int *nparts_p, int *options_p, int *edgecut_p, \
129 FOAM_W ## BASE_NAME(nvtxs_p, xadj_p, adjncy_p, vwgt_p, adjwgt_p, \
130 wgtflag_p, numflag_p, nparts_p, NULL , \
131 options_p, edgecut_p, part_p); \
135 DEFINE_METIS_COMPAT_FUNC(PartGraphRecursive)
136 DEFINE_METIS_COMPAT_FUNC(PartGraphKway)
141 #define FOAM_PartGraphRecursive METIS_PartGraphRecursive
142 #define FOAM_WPartGraphRecursive METIS_WPartGraphRecursive
143 #define FOAM_PartGraphKway METIS_PartGraphKway
144 #define FOAM_WPartGraphKway METIS_WPartGraphKway
166 Foam::label Foam::metisDecomp::decompose
168 const List<int>& adjncy,
169 const List<int>& xadj,
172 List<int>& finalDecomp
181 word method(
"k-way");
183 int numCells = xadj.size()-1;
186 List<int> options(5, 0);
190 Field<floatScalar> processorWeights;
193 List<int> cellWeights;
196 List<int> faceWeights;
200 scalar minWeights =
gMin(cWeights);
201 if (cWeights.size() > 0)
207 "metisDecomp::decompose"
208 "(const pointField&, const scalarField&)"
209 ) <<
"Illegal minimum weight " << minWeights
213 if (cWeights.size() != numCells)
217 "metisDecomp::decompose"
218 "(const pointField&, const scalarField&)"
219 ) <<
"Number of cell weights " << cWeights.size()
220 <<
" does not equal number of cells " << numCells
224 cellWeights.setSize(cWeights.size());
227 cellWeights[i] = int(cWeights[i]/minWeights);
233 if (decompositionDict_.found(
"metisCoeffs"))
235 const dictionary& metisCoeffs =
236 decompositionDict_.subDict(
"metisCoeffs");
239 if (metisCoeffs.readIfPresent(
"method", method))
241 if (method !=
"recursive" && method !=
"k-way")
244 <<
"Method " << method <<
" in metisCoeffs in dictionary : "
245 << decompositionDict_.name()
246 <<
" should be 'recursive' or 'k-way'"
250 Info<<
"metisDecomp : Using Metis method " << method
254 if (metisCoeffs.readIfPresent(
"options", options))
256 if (options.size() != 5)
259 <<
"Number of options in metisCoeffs in dictionary : "
260 << decompositionDict_.name()
265 Info<<
"metisDecomp : Using Metis options " << options
269 if (metisCoeffs.readIfPresent(
"processorWeights", processorWeights))
271 processorWeights /=
sum(processorWeights);
273 if (processorWeights.size() != nProcessors_)
275 FatalErrorIn(
"metisDecomp::decompose(const pointField&)")
276 <<
"Number of processor weights "
277 << processorWeights.size()
278 <<
" does not equal number of domains " << nProcessors_
283 if (metisCoeffs.readIfPresent(
"cellWeightsFile", weightsFile))
285 Info<<
"metisDecomp : Using cell-based weights." <<
endl;
287 IOList<int> cellIOWeights
292 mesh_.time().timeName(),
298 cellWeights.transfer(cellIOWeights);
300 if (cellWeights.size() != xadj.size()-1)
302 FatalErrorIn(
"metisDecomp::decompose(const pointField&)")
303 <<
"Number of cell weights " << cellWeights.size()
304 <<
" does not equal number of cells " << xadj.size()-1
310 int nProcs = nProcessors_;
313 finalDecomp.setSize(numCells);
321 int* adjwgtPtr = NULL;
323 if (cellWeights.size())
325 vwgtPtr = cellWeights.begin();
328 if (faceWeights.size())
330 adjwgtPtr = faceWeights.begin();
334 if (method ==
"recursive")
336 if (processorWeights.size())
338 FOAM_WPartGraphRecursive
341 const_cast<List<int>&
>(xadj).begin(),
342 const_cast<List<int>&
>(adjncy).begin(),
348 processorWeights.begin(),
356 FOAM_PartGraphRecursive
359 const_cast<List<int>&
>(xadj).begin(),
360 const_cast<List<int>&
>(adjncy).begin(),
374 if (processorWeights.size())
379 const_cast<List<int>&
>(xadj).begin(),
380 const_cast<List<int>&
>(adjncy).begin(),
386 processorWeights.begin(),
397 const_cast<List<int>&
>(xadj).begin(),
398 const_cast<List<int>&
>(adjncy).begin(),
417 Foam::metisDecomp::metisDecomp
419 const dictionary& decompositionDict,
423 decompositionMethod(decompositionDict),
436 if (points.size() != mesh_.nCells())
440 "metisDecomp::decompose(const pointField&,const scalarField&)"
441 ) <<
"Can use this decomposition method only for the whole mesh"
443 <<
"and supply one coordinate (cellCentre) for every cell." << endl
444 <<
"The number of coordinates " << points.size() << endl
445 <<
"The number of cells in the mesh " << mesh_.nCells()
459 List<int> finalDecomp;
460 decompose(adjncy, xadj, pointWeights, finalDecomp);
466 decomp[i] = finalDecomp[i];
479 if (agglom.size() != mesh_.nCells())
483 "metisDecomp::decompose"
484 "(const labelList&, const pointField&, const scalarField&)"
485 ) <<
"Size of cell-to-coarse map " << agglom.size()
486 <<
" differs from number of cells in mesh " << mesh_.nCells()
510 List<int> finalDecomp;
511 decompose(adjncy, xadj, agglomWeights, finalDecomp);
515 labelList fineDistribution(agglom.size());
517 forAll(fineDistribution, i)
519 fineDistribution[i] = finalDecomp[agglom[i]];
522 return fineDistribution;
533 if (cellCentres.size() != globalCellCells.size())
537 "metisDecomp::decompose"
538 "(const pointField&, const labelListList&, const scalarField&)"
539 ) <<
"Inconsistent number of cells (" << globalCellCells.size()
540 <<
") and number of cell centres (" << cellCentres.size()
555 List<int> finalDecomp;
556 decompose(adjncy, xadj, cellWeights, finalDecomp);
562 decomp[i] = finalDecomp[i];