Foam::labelList Foam::decompositionMethod::decompose ( const labelListList& globalCellCells, const pointField& cc ) { scalarField cWeights(cc.size(), 1.0); return decompose(globalCellCells, cc, cWeights); }
Foam::labelList Foam::decompositionMethod::decompose ( const polyMesh& mesh, const labelList& fineToCoarse, const pointField& coarsePoints ) { scalarField cWeights(coarsePoints.size(), 1.0); return decompose ( mesh, fineToCoarse, coarsePoints, cWeights ); }
//- Does prevention of 0 cell domains and calls ptscotch. Foam::label Foam::ptscotchDecomp::decomposeZeroDomains ( const fileName& meshPath, const List<int>& initadjncy, const List<int>& initxadj, const scalarField& initcWeights, List<int>& finalDecomp ) const { globalIndex globalCells(initxadj.size()-1); bool hasZeroDomain = false; for (label procI = 0; procI < Pstream::nProcs(); procI++) { if (globalCells.localSize(procI) == 0) { hasZeroDomain = true; break; } } if (!hasZeroDomain) { return decompose ( meshPath, initadjncy, initxadj, initcWeights, finalDecomp ); } if (debug) { Info<< "ptscotchDecomp : have graphs with locally 0 cells." << " trickling down." << endl; } // Make sure every domain has at least one cell // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // (scotch does not like zero sized domains) // Trickle cells from processors that have them up to those that // don't. // Number of cells to send to the next processor // (is same as number of cells next processor has to receive) List<int> nSendCells(Pstream::nProcs(), 0); for (label procI = nSendCells.size()-1; procI >=1; procI--) { label nLocalCells = globalCells.localSize(procI); if (nLocalCells-nSendCells[procI] < 1) { nSendCells[procI-1] = nSendCells[procI]-nLocalCells+1; } } // First receive (so increasing the sizes of all arrays) Field<int> xadj(initxadj); Field<int> adjncy(initadjncy); scalarField cWeights(initcWeights); if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0) { // Receive cells from previous processor IPstream fromPrevProc(Pstream::blocking, Pstream::myProcNo()-1); Field<int> prevXadj(fromPrevProc); Field<int> prevAdjncy(fromPrevProc); scalarField prevCellWeights(fromPrevProc); if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1]) { FatalErrorIn("ptscotchDecomp::decompose(..)") << "Expected from processor " << Pstream::myProcNo()-1 << " connectivity for " << nSendCells[Pstream::myProcNo()-1] << " nCells but only received " << prevXadj.size() << abort(FatalError); } // Insert adjncy prepend(prevAdjncy, adjncy); // Adapt offsets and prepend xadj xadj += prevAdjncy.size(); prepend(prevXadj, xadj); // Weights prepend(prevCellWeights, cWeights); } // Send to my next processor if (nSendCells[Pstream::myProcNo()] > 0) { // Send cells to next processor OPstream toNextProc(Pstream::blocking, Pstream::myProcNo()+1); int nCells = nSendCells[Pstream::myProcNo()]; int startCell = xadj.size()-1 - nCells; int startFace = xadj[startCell]; int nFaces = adjncy.size()-startFace; // Send for all cell data: last nCells elements // Send for all face data: last nFaces elements toNextProc << Field<int>::subField(xadj, nCells, startCell)-startFace << Field<int>::subField(adjncy, nFaces, startFace) << ( cWeights.size() ? static_cast<const scalarField&> ( scalarField::subField(cWeights, nCells, startCell) ) : scalarField(0) ); // Remove data that has been sent if (cWeights.size()) { cWeights.setSize(cWeights.size()-nCells); } adjncy.setSize(adjncy.size()-nFaces); xadj.setSize(xadj.size() - nCells); } // Do decomposition as normal. Sets finalDecomp. label result = decompose(meshPath, adjncy, xadj, cWeights, finalDecomp); if (debug) { Info<< "ptscotchDecomp : have graphs with locally 0 cells." << " trickling up." << endl; } // If we sent cells across make sure we undo it // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Receive back from next processor if I sent something if (nSendCells[Pstream::myProcNo()] > 0) { IPstream fromNextProc(Pstream::blocking, Pstream::myProcNo()+1); List<int> nextFinalDecomp(fromNextProc); if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()]) { FatalErrorIn("parMetisDecomp::decompose(..)") << "Expected from processor " << Pstream::myProcNo()+1 << " decomposition for " << nSendCells[Pstream::myProcNo()] << " nCells but only received " << nextFinalDecomp.size() << abort(FatalError); } append(nextFinalDecomp, finalDecomp); } // Send back to previous processor. if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0) { OPstream toPrevProc(Pstream::blocking, Pstream::myProcNo()-1); int nToPrevious = nSendCells[Pstream::myProcNo()-1]; toPrevProc << SubList<int> ( finalDecomp, nToPrevious, finalDecomp.size()-nToPrevious ); // Remove locally what has been sent finalDecomp.setSize(finalDecomp.size()-nToPrevious); } return result; }