diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index 7ced14726d9a901280d58cdf90e24c84550b4668..c48abfbc3960fd724e31bbc94a9937d92e34aad9 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -334,8 +334,7 @@ int main(int argc, char *argv[]) ( decompositionMethod::New ( - decomposeDict, - mesh + decomposeDict ) ); decompositionMethod& decomposer = decomposerPtr(); diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C index 19a80bac5f0585be8b69fdde2210184f35181594..3394b928b22f3079e0f3470d1ffabdf68b89af16 100644 --- a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C +++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C @@ -489,11 +489,17 @@ int main(int argc, char *argv[]) ); autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New ( - decomposeDict, - mesh + decomposeDict ); - labelList cellToRegion(decomposePtr().decompose(mesh.cellCentres())); + labelList cellToRegion + ( + decomposePtr().decompose + ( + mesh, + mesh.cellCentres() + ) + ); // For debugging: write out region { diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C index e9c20f1afbf34e6d1c31b84f02616e63a69e7727..7e3cd14588a8e2502bb868bf31ac46922be410e6 100644 --- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C +++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C @@ -381,7 +381,8 @@ void subsetVolFields const fvMesh& mesh, const fvMesh& subMesh, const labelList& cellMap, - const labelList& faceMap + const labelList& faceMap, + const labelHashSet& addedPatches ) { const labelList patchMap(identity(mesh.boundaryMesh().size())); @@ -412,14 +413,7 @@ void subsetVolFields // get initialised. forAll(tSubFld().boundaryField(), patchI) { - const fvPatchField<typename GeoField::value_type>& pfld = - tSubFld().boundaryField()[patchI]; - - if - ( - isA<calculatedFvPatchField<typename GeoField::value_type> > - (pfld) - ) + if (addedPatches.found(patchI)) { tSubFld().boundaryField()[patchI] == pTraits<typename GeoField::value_type>::zero; @@ -440,7 +434,8 @@ void subsetSurfaceFields ( const fvMesh& mesh, const fvMesh& subMesh, - const labelList& faceMap + const labelList& faceMap, + const labelHashSet& addedPatches ) { const labelList patchMap(identity(mesh.boundaryMesh().size())); @@ -470,14 +465,7 @@ void subsetSurfaceFields // get initialised. forAll(tSubFld().boundaryField(), patchI) { - const fvsPatchField<typename GeoField::value_type>& pfld = - tSubFld().boundaryField()[patchI]; - - if - ( - isA<calculatedFvsPatchField<typename GeoField::value_type> > - (pfld) - ) + if (addedPatches.found(patchI)) { tSubFld().boundaryField()[patchI] == pTraits<typename GeoField::value_type>::zero; @@ -852,6 +840,15 @@ void createAndWriteRegion newMesh ); + + // Make map of all added patches + labelHashSet addedPatches(2*interfaceToPatch.size()); + forAllConstIter(EdgeMap<label>, interfaceToPatch, iter) + { + addedPatches.insert(iter()); + addedPatches.insert(iter()+1); + } + Info<< "Mapping fields" << endl; // Map existing fields @@ -863,66 +860,76 @@ void createAndWriteRegion mesh, newMesh(), map().cellMap(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetVolFields<volVectorField> ( mesh, newMesh(), map().cellMap(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetVolFields<volSphericalTensorField> ( mesh, newMesh(), map().cellMap(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetVolFields<volSymmTensorField> ( mesh, newMesh(), map().cellMap(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetVolFields<volTensorField> ( mesh, newMesh(), map().cellMap(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetSurfaceFields<surfaceScalarField> ( mesh, newMesh(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetSurfaceFields<surfaceVectorField> ( mesh, newMesh(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetSurfaceFields<surfaceSphericalTensorField> ( mesh, newMesh(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetSurfaceFields<surfaceSymmTensorField> ( mesh, newMesh(), - map().faceMap() + map().faceMap(), + addedPatches ); subsetSurfaceFields<surfaceTensorField> ( mesh, newMesh(), - map().faceMap() + map().faceMap(), + addedPatches ); diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict index a183ebd0cb405f1a2af5ec8ae1cbe66366cc4dc1..0f09fca3539fe7fb2bf67d934856c7fc98790ab9 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict +++ b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict @@ -19,6 +19,7 @@ FoamFile numberOfSubdomains 4; + //- Keep owner and neighbour on same processor for faces in zones: // preserveFaceZones (heater solid1 solid3); @@ -28,15 +29,40 @@ numberOfSubdomains 4; //preservePatches (cyclic_half0 cyclic_half1); -method scotch; +// method scotch; // method hierarchical; // method simple; // method metis; // method manual; +method multiLevel; + +multiLevelCoeffs +{ + level0 + { + numberOfSubdomains 2; + method simple; + simpleCoeffs + { + n (2 1 1); + delta 0.001; + } + } + level1 + { + numberOfSubdomains 2; + method scotch; + } +} + + +// Desired output + + simpleCoeffs { - n (2 2 1); + n (2 1 1); delta 0.001; } diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C index 6adf0639626bd08a62370060d192ae6e33a1de0d..877395e38d463b2b783d59038513953e7efac1f5 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C @@ -109,13 +109,12 @@ void Foam::domainDecomposition::distributeCells() autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New ( - decompositionDict_, - *this + decompositionDict_ ); if (sameProcFaces.empty()) { - cellToProc_ = decomposePtr().decompose(cellCentres()); + cellToProc_ = decomposePtr().decompose(*this, cellCentres()); } else { @@ -174,7 +173,12 @@ void Foam::domainDecomposition::distributeCells() // Do decomposition on agglomeration // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres); + cellToProc_ = decomposePtr().decompose + ( + *this, + globalRegion, + regionCentres + ); } Info<< "\nFinished decomposition in " diff --git a/applications/utilities/parallelProcessing/redistributeMeshPar/redistributeMeshPar.C b/applications/utilities/parallelProcessing/redistributeMeshPar/redistributeMeshPar.C index 5df7310f8ea3fffc7cdebf5db99747300e7c60d4..173d6314dfdd377e5dda0e3048468419b81130ab 100644 --- a/applications/utilities/parallelProcessing/redistributeMeshPar/redistributeMeshPar.C +++ b/applications/utilities/parallelProcessing/redistributeMeshPar/redistributeMeshPar.C @@ -594,8 +594,7 @@ int main(int argc, char *argv[]) ( decompositionMethod::New ( - decompositionDict, - mesh + decompositionDict ) ); @@ -612,7 +611,7 @@ int main(int argc, char *argv[]) << endl; } - finalDecomp = decomposer().decompose(mesh.cellCentres()); + finalDecomp = decomposer().decompose(mesh, mesh.cellCentres()); } // Dump decomposition to volScalarField diff --git a/src/dummyThirdParty/metisDecomp/dummyMetisDecomp.C b/src/dummyThirdParty/metisDecomp/dummyMetisDecomp.C index e7b61fd28dbf58cb596661879ce1f03c72c36239..4be4cd995b80591e38f21dfaa7484ad501b7e7f9 100644 --- a/src/dummyThirdParty/metisDecomp/dummyMetisDecomp.C +++ b/src/dummyThirdParty/metisDecomp/dummyMetisDecomp.C @@ -46,7 +46,7 @@ namespace Foam ( decompositionMethod, metisDecomp, - dictionaryMesh + dictionary ); } @@ -80,12 +80,10 @@ Foam::label Foam::metisDecomp::decompose Foam::metisDecomp::metisDecomp ( - const dictionary& decompositionDict, - const polyMesh& mesh + const dictionary& decompositionDict ) : - decompositionMethod(decompositionDict), - mesh_(mesh) + decompositionMethod(decompositionDict) {} @@ -93,6 +91,7 @@ Foam::metisDecomp::metisDecomp Foam::labelList Foam::metisDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) @@ -112,6 +111,7 @@ Foam::labelList Foam::metisDecomp::decompose Foam::labelList Foam::metisDecomp::decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& agglomPoints, const scalarField& agglomWeights diff --git a/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C b/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C index 2e877de4a9007cdb53e4c958378911e953e23f21..9e59239fd1f7000c6d7c9e01e144f9bcc75fdfd4 100644 --- a/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C +++ b/src/dummyThirdParty/ptscotchDecomp/dummyPtscotchDecomp.C @@ -48,7 +48,7 @@ namespace Foam ( decompositionMethod, ptscotchDecomp, - dictionaryMesh + dictionary ); } @@ -85,12 +85,10 @@ Foam::label Foam::ptscotchDecomp::decompose Foam::ptscotchDecomp::ptscotchDecomp ( - const dictionary& decompositionDict, - const polyMesh& mesh + const dictionary& decompositionDict ) : - decompositionMethod(decompositionDict), - mesh_(mesh) + decompositionMethod(decompositionDict) {} @@ -98,6 +96,7 @@ Foam::ptscotchDecomp::ptscotchDecomp Foam::labelList Foam::ptscotchDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) @@ -117,6 +116,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose Foam::labelList Foam::ptscotchDecomp::decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& agglomPoints, const scalarField& pointWeights diff --git a/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C b/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C index 3c846339320f1a864570de321609ddc202cca28d..007f708a5debd2700104115a664dc8d3489b5f5d 100644 --- a/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C +++ b/src/dummyThirdParty/scotchDecomp/dummyScotchDecomp.C @@ -47,7 +47,7 @@ namespace Foam ( decompositionMethod, scotchDecomp, - dictionaryMesh + dictionary ); } @@ -59,6 +59,7 @@ void Foam::scotchDecomp::check(const int retVal, const char* str) Foam::label Foam::scotchDecomp::decompose ( + const fileName& meshPath, const List<int>& adjncy, const List<int>& xadj, const scalarField& cWeights, @@ -68,13 +69,14 @@ Foam::label Foam::scotchDecomp::decompose { FatalErrorIn ( - "label scotchDecomp::decompose" - "(" - "const List<int>&, " - "const List<int>&, " - "const scalarField&, " - "List<int>&" - ")" + "label scotchDecomp::decompose\n" + "(\n" + "const fileName& meshPath,\n" + "const List<int>&,\n" + "const List<int>&,\n" + "const scalarField&,\n" + "List<int>&\n" + ")\n" ) << notImplementedMessage << exit(FatalError); return -1; @@ -85,12 +87,10 @@ Foam::label Foam::scotchDecomp::decompose Foam::scotchDecomp::scotchDecomp ( - const dictionary& decompositionDict, - const polyMesh& mesh + const dictionary& decompositionDict ) : - decompositionMethod(decompositionDict), - mesh_(mesh) + decompositionMethod(decompositionDict) {} @@ -98,6 +98,7 @@ Foam::scotchDecomp::scotchDecomp Foam::labelList Foam::scotchDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) @@ -117,6 +118,7 @@ Foam::labelList Foam::scotchDecomp::decompose Foam::labelList Foam::scotchDecomp::decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& agglomPoints, const scalarField& pointWeights diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C index 1fd66dfda8d38196bb3ac90f2c2ebf79266f68e3..b5085a465abb4a286b3b229145cac45a3f611bef 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C @@ -415,11 +415,7 @@ Foam::autoHexMeshDriver::autoHexMeshDriver { // Decomposition - decomposerPtr_ = decompositionMethod::New - ( - decomposeDict, - mesh_ - ); + decomposerPtr_ = decompositionMethod::New(decomposeDict); decompositionMethod& decomposer = decomposerPtr_(); diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C index 0622273a4ef922a6342de997919c1a1eefb82a7a..43d1c740609a0c408967a858a11e7d28192ab29b 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C @@ -1214,6 +1214,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::meshRefinement::balance // Normal decomposition distribution = decomposer.decompose ( + mesh_, mesh_.cellCentres(), cellWeights ); @@ -1224,6 +1225,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::meshRefinement::balance // Normal decomposition distribution = decomposer.decompose ( + mesh_, mesh_.cellCentres(), cellWeights ); diff --git a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C index a046f05050e1b04207bcb501c7c8fb4e3e751186..e736ec8945e754fd5c95cef2abdab9514018726e 100644 --- a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C +++ b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C @@ -34,6 +34,7 @@ License #include "IFstream.H" #include "decompositionMethod.H" +#include "geomDecomp.H" #include "vectorList.H" #include "PackedBoolList.H" @@ -855,6 +856,19 @@ Foam::distributedTriSurfaceMesh::independentlyDistributedBbs << " does not decompose in parallel." << " Please choose one that does." << exit(FatalError); } + + if (!isA<geomDecomp>(decomposer_())) + { + FatalErrorIn + ( + "distributedTriSurfaceMesh::independentlyDistributedBbs" + "(const triSurface&)" + ) << "The decomposition method " << decomposer_().typeName + << " is not a geometric decomposition method." << endl + << "Only geometric decomposition methods are currently" + << " supported." + << exit(FatalError); + } } // Do decomposition according to triangle centre @@ -864,8 +878,11 @@ Foam::distributedTriSurfaceMesh::independentlyDistributedBbs triCentres[triI] = s[triI].centre(s.points()); } + + geomDecomp& decomposer = refCast<geomDecomp>(decomposer_()); + // Do the actual decomposition - labelList distribution(decomposer_->decompose(triCentres)); + labelList distribution(decomposer.decompose(triCentres)); // Find bounding box for all triangles on new distribution. diff --git a/src/parallel/decompose/decompositionMethods/Make/files b/src/parallel/decompose/decompositionMethods/Make/files index 43bb9a25c1ddcd504bf938804ff526b7e512fb39..fccb8b7c8f602795a79b445e365285e21b2a8a91 100644 --- a/src/parallel/decompose/decompositionMethods/Make/files +++ b/src/parallel/decompose/decompositionMethods/Make/files @@ -3,5 +3,6 @@ geomDecomp/geomDecomp.C simpleGeomDecomp/simpleGeomDecomp.C hierarchGeomDecomp/hierarchGeomDecomp.C manualDecomp/manualDecomp.C +multiLevelDecomp/multiLevelDecomp.C LIB = $(FOAM_LIBBIN)/libdecompositionMethods diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C index 4e026f9e487a7b46fc034f959fe8129ea22921ca..e68e31c7b97911d2ebed46eef074a674a5c4b568 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C +++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C @@ -37,7 +37,6 @@ namespace Foam { defineTypeNameAndDebug(decompositionMethod, 0); defineRunTimeSelectionTable(decompositionMethod, dictionary); - defineRunTimeSelectionTable(decompositionMethod, dictionaryMesh); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -71,57 +70,45 @@ Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New } -Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New -( - const dictionary& decompositionDict, - const polyMesh& mesh -) -{ - const word methodType(decompositionDict.lookup("method")); - - Info<< "Selecting decompositionMethod " << methodType << endl; - - dictionaryMeshConstructorTable::iterator cstrIter = - dictionaryMeshConstructorTablePtr_->find(methodType); - - if (cstrIter == dictionaryMeshConstructorTablePtr_->end()) - { - FatalErrorIn - ( - "decompositionMethod::New" - "(const dictionary& decompositionDict, " - "const polyMesh& mesh)" - ) << "Unknown decompositionMethod " - << methodType << nl << nl - << "Valid decompositionMethods are : " << endl - << dictionaryMeshConstructorTablePtr_->sortedToc() - << exit(FatalError); - } - - return autoPtr<decompositionMethod>(cstrIter()(decompositionDict, mesh)); -} - - Foam::labelList Foam::decompositionMethod::decompose ( + const polyMesh& mesh, const pointField& points ) { - scalarField weights(0); + scalarField weights(points.size(), 1.0); - return decompose(points, weights); + return decompose(mesh, points, weights); } Foam::labelList Foam::decompositionMethod::decompose ( + const polyMesh& mesh, const labelList& fineToCoarse, const pointField& coarsePoints, const scalarField& coarseWeights ) { + CompactListList<label> coarseCellCells; + calcCellCells + ( + mesh, + fineToCoarse, + coarsePoints.size(), + coarseCellCells + ); + // Decompose based on agglomerated points - labelList coarseDistribution(decompose(coarsePoints, coarseWeights)); + labelList coarseDistribution + ( + decompose + ( + coarseCellCells(), + coarsePoints, + coarseWeights + ) + ); // Rework back into decomposition for original mesh_ labelList fineDistribution(fineToCoarse.size()); @@ -137,22 +124,20 @@ Foam::labelList Foam::decompositionMethod::decompose Foam::labelList Foam::decompositionMethod::decompose ( + const polyMesh& mesh, const labelList& fineToCoarse, const pointField& coarsePoints ) { - // Decompose based on agglomerated points - labelList coarseDistribution(decompose(coarsePoints)); - - // Rework back into decomposition for original mesh_ - labelList fineDistribution(fineToCoarse.size()); - - forAll(fineDistribution, i) - { - fineDistribution[i] = coarseDistribution[fineToCoarse[i]]; - } - - return fineDistribution; + scalarField cWeights(coarsePoints.size(), 1.0); + + return decompose + ( + mesh, + fineToCoarse, + coarsePoints, + cWeights + ); } @@ -162,57 +147,12 @@ Foam::labelList Foam::decompositionMethod::decompose const pointField& cc ) { - scalarField cWeights(0); + scalarField cWeights(cc.size(), 1.0); return decompose(globalCellCells, cc, cWeights); } -void Foam::decompositionMethod::calcCellCells -( - const polyMesh& mesh, - const labelList& fineToCoarse, - const label nCoarse, - labelListList& cellCells -) -{ - if (fineToCoarse.size() != mesh.nCells()) - { - FatalErrorIn - ( - "decompositionMethod::calcCellCells" - "(const labelList&, labelListList&) const" - ) << "Only valid for mesh agglomeration." << exit(FatalError); - } - - List<DynamicList<label> > dynCellCells(nCoarse); - - forAll(mesh.faceNeighbour(), faceI) - { - label own = fineToCoarse[mesh.faceOwner()[faceI]]; - label nei = fineToCoarse[mesh.faceNeighbour()[faceI]]; - - if (own != nei) - { - if (findIndex(dynCellCells[own], nei) == -1) - { - dynCellCells[own].append(nei); - } - if (findIndex(dynCellCells[nei], own) == -1) - { - dynCellCells[nei].append(own); - } - } - } - - cellCells.setSize(dynCellCells.size()); - forAll(dynCellCells, coarseI) - { - cellCells[coarseI].transfer(dynCellCells[coarseI]); - } -} - - // Return the minimum face between two cells. Only relevant for // cells with multiple faces inbetween. Foam::label Foam::decompositionMethod::masterFace @@ -250,208 +190,209 @@ Foam::label Foam::decompositionMethod::masterFace } -void Foam::decompositionMethod::calcCSR -( - const polyMesh& mesh, - List<int>& adjncy, - List<int>& xadj -) -{ - const polyBoundaryMesh& pbm = mesh.boundaryMesh(); - - // Make Metis CSR (Compressed Storage Format) storage - // adjncy : contains neighbours (= edges in graph) - // xadj(celli) : start of information in adjncy for celli - - - // Count unique faces between cells - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - labelList nFacesPerCell(mesh.nCells(), 0); - - // Internal faces - for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) - { - label own = mesh.faceOwner()[faceI]; - label nei = mesh.faceNeighbour()[faceI]; - - if (faceI == masterFace(mesh, own, nei)) - { - nFacesPerCell[own]++; - nFacesPerCell[nei]++; - } - } - - // Coupled faces. Only cyclics done. - HashSet<edge, Hash<edge> > cellPair(mesh.nFaces()-mesh.nInternalFaces()); - - forAll(pbm, patchI) - { - if - ( - isA<cyclicPolyPatch>(pbm[patchI]) - && refCast<const cyclicPolyPatch>(pbm[patchI]).owner() - ) - { - const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch> - ( - pbm[patchI] - ); - - const unallocLabelList& faceCells = cycPatch.faceCells(); - const unallocLabelList& nbrCells = - cycPatch.neighbPatch().faceCells(); - - forAll(faceCells, facei) - { - label own = faceCells[facei]; - label nei = nbrCells[facei]; - - if (cellPair.insert(edge(own, nei))) - { - nFacesPerCell[own]++; - nFacesPerCell[nei]++; - } - } - } - } - +//void Foam::decompositionMethod::calcCSR +//( +// const polyMesh& mesh, +// List<int>& adjncy, +// List<int>& xadj +//) +//{ +// const polyBoundaryMesh& pbm = mesh.boundaryMesh(); +// +// // Make Metis CSR (Compressed Storage Format) storage +// // adjncy : contains neighbours (= edges in graph) +// // xadj(celli) : start of information in adjncy for celli +// +// +// // Count unique faces between cells +// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// labelList nFacesPerCell(mesh.nCells(), 0); +// +// // Internal faces +// for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) +// { +// label own = mesh.faceOwner()[faceI]; +// label nei = mesh.faceNeighbour()[faceI]; +// +// if (faceI == masterFace(mesh, own, nei)) +// { +// nFacesPerCell[own]++; +// nFacesPerCell[nei]++; +// } +// } +// +// // Coupled faces. Only cyclics done. +// HashSet<edge, Hash<edge> > cellPair(mesh.nFaces()-mesh.nInternalFaces()); +// +// forAll(pbm, patchI) +// { +// if +// ( +// isA<cyclicPolyPatch>(pbm[patchI]) +// && refCast<const cyclicPolyPatch>(pbm[patchI]).owner() +// ) +// { +// const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch> +// ( +// pbm[patchI] +// ); +// +// const unallocLabelList& faceCells = cycPatch.faceCells(); +// const unallocLabelList& nbrCells = +// cycPatch.neighbPatch().faceCells(); +// +// forAll(faceCells, facei) +// { +// label own = faceCells[facei]; +// label nei = nbrCells[facei]; +// +// if (cellPair.insert(edge(own, nei))) +// { +// nFacesPerCell[own]++; +// nFacesPerCell[nei]++; +// } +// } +// } +// } +// +// +// // Size tables +// // ~~~~~~~~~~~ +// +// // Sum nFacesPerCell +// xadj.setSize(mesh.nCells()+1); +// +// label nConnections = 0; +// +// for (label cellI = 0; cellI < mesh.nCells(); cellI++) +// { +// xadj[cellI] = nConnections; +// nConnections += nFacesPerCell[cellI]; +// } +// xadj[mesh.nCells()] = nConnections; +// adjncy.setSize(nConnections); +// +// +// +// // Fill tables +// // ~~~~~~~~~~~ +// +// nFacesPerCell = 0; +// +// // Internal faces +// for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) +// { +// label own = mesh.faceOwner()[faceI]; +// label nei = mesh.faceNeighbour()[faceI]; +// +// if (faceI == masterFace(mesh, own, nei)) +// { +// adjncy[xadj[own] + nFacesPerCell[own]++] = nei; +// adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; +// } +// } +// +// // Coupled faces. Only cyclics done. +// cellPair.clear(); +// forAll(pbm, patchI) +// { +// if +// ( +// isA<cyclicPolyPatch>(pbm[patchI]) +// && refCast<const cyclicPolyPatch>(pbm[patchI]).owner() +// ) +// { +// const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch> +// ( +// pbm[patchI] +// ); +// +// const unallocLabelList& faceCells = cycPatch.faceCells(); +// const unallocLabelList& nbrCells = +// cycPatch.neighbPatch().faceCells(); +// +// forAll(faceCells, facei) +// { +// label own = faceCells[facei]; +// label nei = nbrCells[facei]; +// +// if (cellPair.insert(edge(own, nei))) +// { +// adjncy[xadj[own] + nFacesPerCell[own]++] = nei; +// adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; +// } +// } +// } +// } +//} +// +// +//// From cell-cell connections to Metis format (like CompactListList) +//void Foam::decompositionMethod::calcCSR +//( +// const labelListList& cellCells, +// List<int>& adjncy, +// List<int>& xadj +//) +//{ +// labelHashSet nbrCells; +// +// // Count number of internal faces +// label nConnections = 0; +// +// forAll(cellCells, coarseI) +// { +// nbrCells.clear(); +// +// const labelList& cCells = cellCells[coarseI]; +// +// forAll(cCells, i) +// { +// if (nbrCells.insert(cCells[i])) +// { +// nConnections++; +// } +// } +// } +// +// // Create the adjncy array as twice the size of the total number of +// // internal faces +// adjncy.setSize(nConnections); +// +// xadj.setSize(cellCells.size()+1); +// +// +// // Fill in xadj +// // ~~~~~~~~~~~~ +// label freeAdj = 0; +// +// forAll(cellCells, coarseI) +// { +// xadj[coarseI] = freeAdj; +// +// nbrCells.clear(); +// +// const labelList& cCells = cellCells[coarseI]; +// +// forAll(cCells, i) +// { +// if (nbrCells.insert(cCells[i])) +// { +// adjncy[freeAdj++] = cCells[i]; +// } +// } +// } +// xadj[cellCells.size()] = freeAdj; +//} - // Size tables - // ~~~~~~~~~~~ - // Sum nFacesPerCell - xadj.setSize(mesh.nCells()+1); - - label nConnections = 0; - - for (label cellI = 0; cellI < mesh.nCells(); cellI++) - { - xadj[cellI] = nConnections; - nConnections += nFacesPerCell[cellI]; - } - xadj[mesh.nCells()] = nConnections; - adjncy.setSize(nConnections); - - - - // Fill tables - // ~~~~~~~~~~~ - - nFacesPerCell = 0; - - // Internal faces - for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) - { - label own = mesh.faceOwner()[faceI]; - label nei = mesh.faceNeighbour()[faceI]; - - if (faceI == masterFace(mesh, own, nei)) - { - adjncy[xadj[own] + nFacesPerCell[own]++] = nei; - adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; - } - } - - // Coupled faces. Only cyclics done. - cellPair.clear(); - forAll(pbm, patchI) - { - if - ( - isA<cyclicPolyPatch>(pbm[patchI]) - && refCast<const cyclicPolyPatch>(pbm[patchI]).owner() - ) - { - const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch> - ( - pbm[patchI] - ); - - const unallocLabelList& faceCells = cycPatch.faceCells(); - const unallocLabelList& nbrCells = - cycPatch.neighbPatch().faceCells(); - - forAll(faceCells, facei) - { - label own = faceCells[facei]; - label nei = nbrCells[facei]; - - if (cellPair.insert(edge(own, nei))) - { - adjncy[xadj[own] + nFacesPerCell[own]++] = nei; - adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; - } - } - } - } -} - - -// From cell-cell connections to Metis format (like CompactListList) -void Foam::decompositionMethod::calcCSR -( - const labelListList& cellCells, - List<int>& adjncy, - List<int>& xadj -) -{ - labelHashSet nbrCells; - - // Count number of internal faces - label nConnections = 0; - - forAll(cellCells, coarseI) - { - nbrCells.clear(); - - const labelList& cCells = cellCells[coarseI]; - - forAll(cCells, i) - { - if (nbrCells.insert(cCells[i])) - { - nConnections++; - } - } - } - - // Create the adjncy array as twice the size of the total number of - // internal faces - adjncy.setSize(nConnections); - - xadj.setSize(cellCells.size()+1); - - - // Fill in xadj - // ~~~~~~~~~~~~ - label freeAdj = 0; - - forAll(cellCells, coarseI) - { - xadj[coarseI] = freeAdj; - - nbrCells.clear(); - - const labelList& cCells = cellCells[coarseI]; - - forAll(cCells, i) - { - if (nbrCells.insert(cCells[i])) - { - adjncy[freeAdj++] = cCells[i]; - } - } - } - xadj[cellCells.size()] = freeAdj; -} - - -void Foam::decompositionMethod::calcDistributedCSR +void Foam::decompositionMethod::calcCellCells ( const polyMesh& mesh, - List<int>& adjncy, - List<int>& xadj + const labelList& agglom, + const label nCoarse, + CompactListList<label>& cellCells ) { // Create global cell numbers @@ -459,14 +400,6 @@ void Foam::decompositionMethod::calcDistributedCSR globalIndex globalCells(mesh.nCells()); - - // - // Make Metis Distributed CSR (Compressed Storage Format) storage - // adjncy : contains cellCells (= edges in graph) - // xadj(celli) : start of information in adjncy for celli - // - - const labelList& faceOwner = mesh.faceOwner(); const labelList& faceNeighbour = mesh.faceNeighbour(); const polyBoundaryMesh& patches = mesh.boundaryMesh(); @@ -475,7 +408,7 @@ void Foam::decompositionMethod::calcDistributedCSR // Get renumbered owner on other side of coupled faces // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - List<int> globalNeighbour(mesh.nFaces()-mesh.nInternalFaces()); + labelList globalNeighbour(mesh.nFaces()-mesh.nInternalFaces()); forAll(patches, patchI) { @@ -504,18 +437,15 @@ void Foam::decompositionMethod::calcDistributedCSR // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Number of faces per cell - List<int> nFacesPerCell(mesh.nCells(), 0); + labelList nFacesPerCell(mesh.nCells(), 0); for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) { - label own = faceOwner[faceI]; - label nei = faceNeighbour[faceI]; + label own = agglom[faceOwner[faceI]]; + label nei = agglom[faceNeighbour[faceI]]; - if (faceI == masterFace(mesh, own, nei)) - { - nFacesPerCell[own]++; - nFacesPerCell[nei]++; - } + nFacesPerCell[own]++; + nFacesPerCell[nei]++; } // Handle coupled faces @@ -532,7 +462,7 @@ void Foam::decompositionMethod::calcDistributedCSR forAll(pp, i) { - label own = faceOwner[faceI]; + label own = agglom[faceOwner[faceI]]; label globalNei = globalNeighbour[bFaceI]; if (cellPair.insert(edge(own, globalNei))) { @@ -545,43 +475,24 @@ void Foam::decompositionMethod::calcDistributedCSR } - // Fill in xadj - // ~~~~~~~~~~~~ + // Fill in offset and data + // ~~~~~~~~~~~~~~~~~~~~~~~ - xadj.setSize(mesh.nCells()+1); - - int freeAdj = 0; - - for (label cellI = 0; cellI < mesh.nCells(); cellI++) - { - xadj[cellI] = freeAdj; - - freeAdj += nFacesPerCell[cellI]; - } - xadj[mesh.nCells()] = freeAdj; - - - - // Fill in adjncy - // ~~~~~~~~~~~~~~ - - adjncy.setSize(freeAdj); + cellCells.setSize(nFacesPerCell); nFacesPerCell = 0; + labelList& m = cellCells.m(); + const labelList& offsets = cellCells.offsets(); + // For internal faces is just offsetted owner and neighbour for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) { - label own = faceOwner[faceI]; - label nei = faceNeighbour[faceI]; + label own = agglom[faceOwner[faceI]]; + label nei = agglom[faceNeighbour[faceI]]; - if (faceI == masterFace(mesh, own, nei)) - { - adjncy[xadj[own] + nFacesPerCell[own]++] = - globalCells.toGlobal(nei); - adjncy[xadj[nei] + nFacesPerCell[nei]++] = - globalCells.toGlobal(own); - } + m[offsets[own] + nFacesPerCell[own]++] = globalCells.toGlobal(nei); + m[offsets[nei] + nFacesPerCell[nei]++] = globalCells.toGlobal(own); } // For boundary faces is offsetted coupled neighbour @@ -597,17 +508,41 @@ void Foam::decompositionMethod::calcDistributedCSR forAll(pp, i) { - label own = faceOwner[faceI]; + label own = agglom[faceOwner[faceI]]; label globalNei = globalNeighbour[bFaceI]; if (cellPair.insert(edge(own, globalNei))) { - adjncy[xadj[own] + nFacesPerCell[own]++] = globalNei; + m[offsets[own] + nFacesPerCell[own]++] = globalNei; } faceI++; bFaceI++; } } } + + + // Check for duplicates connections between cells as a postprocessing step + // (since quite rare) + label startIndex = 0; + label newIndex = 0; + labelHashSet nbrCells; + forAll(cellCells, cellI) + { + nbrCells.clear(); + + label& endIndex = cellCells.offsets()[cellI+1]; + + for (label i = startIndex; i < endIndex; i++) + { + if (nbrCells.insert(cellCells.m()[i])) + { + cellCells.m()[newIndex++] = cellCells.m()[i]; + } + } + + startIndex = endIndex; + endIndex = newIndex; + } } diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H index dabca144c88c1b6679882d528cb7407ce5da5bce..26ad6cc5e7c04aff1023c21508c86dac9a142f3b 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H +++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.H @@ -37,6 +37,7 @@ SourceFiles #include "polyMesh.H" #include "pointField.H" +#include "CompactListList.H" namespace Foam { @@ -56,43 +57,37 @@ protected: label nProcessors_; - //- Helper: determine (non-parallel) cellCells from mesh agglomeration. + //- Helper: determine (global) cellCells from mesh agglomeration. static void calcCellCells ( const polyMesh& mesh, const labelList& agglom, const label nCoarse, - labelListList& cellCells + CompactListList<label>& cellCells ); //- Calculate the minimum face between two neighbouring cells // (usually there is only one) static label masterFace(const polyMesh&, const label, const label); - // From mesh to compact row storage format - // (like CompactListList) - static void calcCSR - ( - const polyMesh& mesh, - List<int>& adjncy, - List<int>& xadj - ); +// // From mesh to compact row storage format +// // (like CompactListList) +// static void calcCSR +// ( +// const polyMesh& mesh, +// List<int>& adjncy, +// List<int>& xadj +// ); +// +// // From cell-cell connections to compact row storage format +// // (like CompactListList) +// static void calcCSR +// ( +// const labelListList& cellCells, +// List<int>& adjncy, +// List<int>& xadj +// ); - // From cell-cell connections to compact row storage format - // (like CompactListList) - static void calcCSR - ( - const labelListList& cellCells, - List<int>& adjncy, - List<int>& xadj - ); - - static void calcDistributedCSR - ( - const polyMesh& mesh, - List<int>& adjncy, - List<int>& xadj - ); private: @@ -122,18 +117,6 @@ public: (decompositionDict) ); - declareRunTimeSelectionTable - ( - autoPtr, - decompositionMethod, - dictionaryMesh, - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ), - (decompositionDict, mesh) - ); - // Selectors @@ -143,13 +126,6 @@ public: const dictionary& decompositionDict ); - //- Return a reference to the selected decomposition method - static autoPtr<decompositionMethod> New - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); - // Constructors @@ -171,63 +147,105 @@ public: // Member Functions + label nDomains() const + { + return nProcessors_; + } + //- Is method parallel aware (i.e. does it synchronize domains across // proc boundaries) virtual bool parallelAware() const = 0; - //- Return for every coordinate the wanted processor number. Use the - // mesh connectivity (if needed) - virtual labelList decompose - ( - const pointField& points, - const scalarField& pointWeights - ) = 0; - - //- Like decompose but with uniform weights on the points - virtual labelList decompose(const pointField&); - - - //- Return for every coordinate the wanted processor number. Gets - // passed agglomeration map (from fine to coarse cells) and coarse cell - // location. Can be overridden by decomposers that provide this - // functionality natively. Coarse cells are local to the processor - // (if in parallel). If you want to have coarse cells spanning - // processors use the globalCellCells instead. - virtual labelList decompose - ( - const labelList& cellToRegion, - const pointField& regionPoints, - const scalarField& regionWeights - ); - - //- Like decompose but with uniform weights on the regions - virtual labelList decompose - ( - const labelList& cellToRegion, - const pointField& regionPoints - ); + // No topology (implemented by geometric decomposers) - //- Return for every coordinate the wanted processor number. Explicitly - // provided connectivity - does not use mesh_. - // The connectivity is equal to mesh.cellCells() except for - // - in parallel the cell numbers are global cell numbers (starting - // from 0 at processor0 and then incrementing all through the - // processors) - // - the connections are across coupled patches - virtual labelList decompose - ( - const labelListList& globalCellCells, - const pointField& cc, - const scalarField& cWeights - ) = 0; + //- Return for every coordinate the wanted processor number. + virtual labelList decompose + ( + const pointField& points, + const scalarField& pointWeights + ) + { + notImplemented + ( + "decompositionMethod:decompose(const pointField&" + ", const scalarField&)" + ); + return labelList(0); + } + + //- Like decompose but with uniform weights on the points + virtual labelList decompose(const pointField&) + { + notImplemented + ( + "decompositionMethod:decompose(const pointField&)" + ); + return labelList(0); + } + + + // Topology provided by mesh + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList decompose + ( + const polyMesh& mesh, + const pointField& points, + const scalarField& pointWeights + ) = 0; + + //- Like decompose but with uniform weights on the points + virtual labelList decompose(const polyMesh&, const pointField&); + + + //- Return for every coordinate the wanted processor number. Gets + // passed agglomeration map (from fine to coarse cells) and coarse + // cell + // location. Can be overridden by decomposers that provide this + // functionality natively. Coarse cells are local to the processor + // (if in parallel). If you want to have coarse cells spanning + // processors use the globalCellCells instead. + virtual labelList decompose + ( + const polyMesh& mesh, + const labelList& cellToRegion, + const pointField& regionPoints, + const scalarField& regionWeights + ); + + //- Like decompose but with uniform weights on the regions + virtual labelList decompose + ( + const polyMesh& mesh, + const labelList& cellToRegion, + const pointField& regionPoints + ); + + + // Topology provided explicitly addressing + + //- Return for every coordinate the wanted processor number. + // The connectivity is equal to mesh.cellCells() except for + // - in parallel the cell numbers are global cell numbers + // (starting + // from 0 at processor0 and then incrementing all through the + // processors) + // - the connections are across coupled patches + virtual labelList decompose + ( + const labelListList& globalCellCells, + const pointField& cc, + const scalarField& cWeights + ) = 0; - //- Like decompose but with uniform weights on the cells - virtual labelList decompose - ( - const labelListList& globalCellCells, - const pointField& cc - ); + //- Like decompose but with uniform weights on the cells + virtual labelList decompose + ( + const labelListList& globalCellCells, + const pointField& cc + ); }; diff --git a/src/parallel/decompose/decompositionMethods/geomDecomp/geomDecomp.H b/src/parallel/decompose/decompositionMethods/geomDecomp/geomDecomp.H index 14dfc5a1c126b4aa08bdcb2720440b7f42d59ed1..f10b5f7c6e6e1e0e9f53d397987d54bba9844a88 100644 --- a/src/parallel/decompose/decompositionMethods/geomDecomp/geomDecomp.H +++ b/src/parallel/decompose/decompositionMethods/geomDecomp/geomDecomp.H @@ -71,6 +71,17 @@ public: const dictionary& decompositionDict, const word& derivedType ); + + //- Return for every coordinate the wanted processor number. + virtual labelList decompose + ( + const pointField& points, + const scalarField& pointWeights + ) = 0; + + //- Like decompose but with uniform weights on the points + virtual labelList decompose(const pointField&) = 0; + }; diff --git a/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.C b/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.C index 98f808160808942eee21db696fe018f2ff4cdcd4..3761d11b7fc286023d277b48dff45a038264cf71 100644 --- a/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.C +++ b/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.C @@ -40,13 +40,6 @@ namespace Foam hierarchGeomDecomp, dictionary ); - - addToRunTimeSelectionTable - ( - decompositionMethod, - hierarchGeomDecomp, - dictionaryMesh - ); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -685,35 +678,6 @@ void Foam::hierarchGeomDecomp::sortComponent } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::hierarchGeomDecomp::hierarchGeomDecomp -( - const dictionary& decompositionDict -) -: - geomDecomp(decompositionDict, typeName), - decompOrder_() -{ - setDecompOrder(); -} - - -Foam::hierarchGeomDecomp::hierarchGeomDecomp -( - const dictionary& decompositionDict, - const polyMesh& -) -: - geomDecomp(decompositionDict, hierarchGeomDecomp::typeName), - decompOrder_() -{ - setDecompOrder(); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - Foam::labelList Foam::hierarchGeomDecomp::decompose ( const pointField& points @@ -797,4 +761,20 @@ Foam::labelList Foam::hierarchGeomDecomp::decompose } +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::hierarchGeomDecomp::hierarchGeomDecomp +( + const dictionary& decompositionDict +) +: + geomDecomp(decompositionDict, typeName), + decompOrder_() +{ + setDecompOrder(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + // ************************************************************************* // diff --git a/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.H b/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.H index 62eef72ae3242457acc9d4cff76a2d8d2dbd8250..b82b9890da76c037bc0400f8f42222343f4445d1 100644 --- a/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.H +++ b/src/parallel/decompose/decompositionMethods/hierarchGeomDecomp/hierarchGeomDecomp.H @@ -154,7 +154,6 @@ class hierarchGeomDecomp labelList& finalDecomp // overall decomposition ); - //- Disallow default bitwise copy construct and assignment void operator=(const hierarchGeomDecomp&); hierarchGeomDecomp(const hierarchGeomDecomp&); @@ -171,13 +170,6 @@ public: //- Construct given the decomposition dictionary hierarchGeomDecomp(const dictionary& decompositionDict); - //- Construct given the decomposition dictionary and mesh - hierarchGeomDecomp - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); - //- Destructor virtual ~hierarchGeomDecomp() @@ -192,8 +184,7 @@ public: return true; } - //- Return for every coordinate the wanted processor number. Use the - // mesh connectivity (if needed) + //- Return for every coordinate the wanted processor number. virtual labelList decompose ( const pointField&, @@ -204,6 +195,26 @@ public: // so kept separate for now. virtual labelList decompose(const pointField&); + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList decompose + ( + const polyMesh& mesh, + const pointField& cc, + const scalarField& cWeights + ) + { + return decompose(cc, cWeights); + } + + //- Without weights. Code for weighted decomposition is a bit complex + // so kept separate for now. + virtual labelList decompose(const polyMesh& mesh, const pointField& cc) + { + return decompose(cc); + } + //- Return for every coordinate the wanted processor number. Explicitly // provided connectivity - does not use mesh_. // The connectivity is equal to mesh.cellCells() except for diff --git a/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.C b/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.C index 4c51c2a5914b5ab5922dcc00bc7f946e0d195a1d..b0a1377e444b8738b2d62ae5c1752fd09653a973 100644 --- a/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.C +++ b/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.C @@ -43,34 +43,14 @@ namespace Foam manualDecomp, dictionary ); - - addToRunTimeSelectionTable - ( - decompositionMethod, - manualDecomp, - dictionaryMesh - ); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::manualDecomp::manualDecomp(const dictionary& decompositionDict) -: - decompositionMethod(decompositionDict) -{ - notImplemented("manualDecomp(const dictionary&)"); -} - - -Foam::manualDecomp::manualDecomp -( - const dictionary& decompositionDict, - const polyMesh& mesh -) : decompositionMethod(decompositionDict), - meshPtr_(&mesh), decompDataFile_ ( decompositionDict.subDict(word(decompositionDict.lookup("method")) @@ -83,12 +63,11 @@ Foam::manualDecomp::manualDecomp Foam::labelList Foam::manualDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) { - const polyMesh& mesh = *meshPtr_; - labelIOList finalDecomp ( IOobject diff --git a/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.H b/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.H index e3da10ccacf815d369e221a4f3da764a7d436c9e..9976b9c08d06e49f0993a33b30c92e6c95c0e674 100644 --- a/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.H +++ b/src/parallel/decompose/decompositionMethods/manualDecomp/manualDecomp.H @@ -50,8 +50,6 @@ class manualDecomp { // Private data - const polyMesh* meshPtr_; - fileName decompDataFile_; @@ -73,14 +71,6 @@ public: //- Construct given the decomposition dictionary manualDecomp(const dictionary& decompositionDict); - //- Construct given the decomposition dictionary and mesh - manualDecomp - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); - - //- Destructor virtual ~manualDecomp() {} @@ -99,8 +89,9 @@ public: // mesh connectivity (if needed) virtual labelList decompose ( - const pointField& points, - const scalarField& pointWeights + const polyMesh& mesh, + const pointField& cc, + const scalarField& cWeights ); //- Return for every coordinate the wanted processor number. Explicitly @@ -117,8 +108,14 @@ public: const scalarField& cWeights ) { - return decompose(cc, cWeights); + notImplemented + ( + "decompose(const labelListList&, const pointField&" + ", const scalarField)" + ); + return labelList(0); } + }; diff --git a/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C new file mode 100644 index 0000000000000000000000000000000000000000..e9a61c729a56d7c57151594023b9b7b5de61318a --- /dev/null +++ b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.C @@ -0,0 +1,293 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "multiLevelDecomp.H" +#include "addToRunTimeSelectionTable.H" +#include "IFstream.H" +#include "globalIndex.H" +#include "mapDistribute.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(multiLevelDecomp, 0); + + addToRunTimeSelectionTable + ( + decompositionMethod, + multiLevelDecomp, + dictionary + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Given a subset of cells determine the new global indices. The problem +// is in the cells from neighbouring processors which need to be renumbered. +void Foam::multiLevelDecomp::subsetGlobalCellCells +( + const labelListList& cellCells, + const labelList& set, + labelListList& subCellCells, + label& cutConnections +) const +{ + // Determine new index for cells by inverting subset + labelList oldToNew(invert(cellCells.size(), set)); + + globalIndex globalCells(cellCells.size()); + + // Subset locally the elements for which I have data + subCellCells = UIndirectList<labelList>(cellCells, set); + + // Get new indices for neighbouring processors + List<Map<label> > compactMap; + mapDistribute map(globalCells, subCellCells, compactMap); + map.distribute(oldToNew); + + // Now subCellCells contains indices into oldToNew which are the + // new locations of the neighbouring cells. + + cutConnections = 0; + + forAll(subCellCells, subCellI) + { + labelList& cCells = subCellCells[subCellI]; + + // Keep the connections to valid mapped cells + label newI = 0; + forAll(cCells, i) + { + label subCellI = oldToNew[cCells[i]]; + if (subCellI == -1) + { + cutConnections++; + } + else + { + cCells[newI++] = subCellI; + } + } + cCells.setSize(newI); + } +} + + +void Foam::multiLevelDecomp::decompose +( + const labelListList& pointPoints, + const pointField& points, + const scalarField& pointWeights, + const labelList& pointMap, // map back to original points + const label levelI, + + labelField& finalDecomp +) +{ + labelList dist + ( + methods_[levelI].decompose + ( + pointPoints, + points, + pointWeights + ) + ); + +//Pout<< "At level " << levelI << endl; +//forAll(dist, i) +//{ +// Pout<< " " << i << " at:" << points[i] +// << " original:" << pointMap[i] << " dist:" << dist[i] +// << " connected to:" << pointField(points, pointPoints[i]) +// << endl; +//} +//Pout<< endl; + + forAll(pointMap, i) + { + label orig = pointMap[i]; + finalDecomp[orig] += dist[i]; + } + + if (levelI != methods_.size()-1) + { + // Recurse + + // Determine points per domain + label n = methods_[levelI].nDomains(); + labelListList domainToPoints(invertOneToMany(n, dist)); + + // 'Make space' for new levels of decomposition + finalDecomp *= methods_[levelI+1].nDomains(); + + // Extract processor+local index from point-point addressing + + forAll(domainToPoints, domainI) + { + const labelList& myPoints = domainToPoints[domainI]; + + // Subset point-wise data. + pointField subPoints(points, myPoints); + scalarField subWeights(pointWeights, myPoints); + labelList subPointMap(UIndirectList<label>(pointMap, myPoints)); + // Subset point-point addressing (adapt global numbering) + labelListList subPointPoints; + label nOutsideConnections; + subsetGlobalCellCells + ( + pointPoints, + myPoints, + subPointPoints, + nOutsideConnections + ); + + //Info<< "At level " << levelI << " domain " << domainI + // << " have connections to other domains " + // << returnReduce(nOutsideConnections, sumOp<label>()) + // << endl; + + decompose + ( + subPointPoints, + subPoints, + subWeights, + subPointMap, + levelI+1, + + finalDecomp + ); + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::multiLevelDecomp::multiLevelDecomp(const dictionary& decompositionDict) +: + decompositionMethod(decompositionDict) +{ + const dictionary& myDict = decompositionDict_.subDict(typeName + "Coeffs"); + + methods_.setSize(myDict.size()); + label i = 0; + forAllConstIter(dictionary, myDict, iter) + { + methods_.set(i++, decompositionMethod::New(iter().dict())); + } + + label n = 1; + Info<< "decompositionMethod " << type() << " :" << endl; + forAll(methods_, i) + { + Info<< " level " << i << " decomposing with " << methods_[i].type() + << " into " << methods_[i].nDomains() << " subdomains." << endl; + + n *= methods_[i].nDomains(); + } + + if (n != nDomains()) + { + FatalErrorIn("multiLevelDecomp::multiLevelDecomp(const dictionary&)") + << "Top level decomposition specifies " << nDomains() + << " domains which is not equal to the product of" + << " all sub domains " << n + << exit(FatalError); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::multiLevelDecomp::parallelAware() const +{ + forAll(methods_, i) + { + if (!methods_[i].parallelAware()) + { + return false; + } + } + return true; +} + + +Foam::labelList Foam::multiLevelDecomp::decompose +( + const polyMesh& mesh, + const pointField& cc, + const scalarField& cWeights +) +{ + CompactListList<label> cellCells; + calcCellCells(mesh, identity(cc.size()), cc.size(), cellCells); + + labelField finalDecomp(cc.size(), 0); + labelList cellMap(identity(cc.size())); + + decompose + ( + cellCells(), + cc, + cWeights, + cellMap, // map back to original cells + 0, + + finalDecomp + ); + + return finalDecomp; +} + + +Foam::labelList Foam::multiLevelDecomp::decompose +( + const labelListList& globalPointPoints, + const pointField& points, + const scalarField& pointWeights +) +{ + labelField finalDecomp(points.size(), 0); + labelList pointMap(identity(points.size())); + + decompose + ( + globalPointPoints, + points, + pointWeights, + pointMap, // map back to original points + 0, + + finalDecomp + ); + + return finalDecomp; +} + + +// ************************************************************************* // diff --git a/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.H b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.H new file mode 100644 index 0000000000000000000000000000000000000000..a45c01f28e6788b126a0fb875aa00e2b04bd4956 --- /dev/null +++ b/src/parallel/decompose/decompositionMethods/multiLevelDecomp/multiLevelDecomp.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::multiLevelDecomp + +Description + Decomposition given using consecutive application of decomposers. + +SourceFiles + multiLevelDecomp.C + +\*---------------------------------------------------------------------------*/ + +#ifndef multiLevelDecomp_H +#define multiLevelDecomp_H + +#include "decompositionMethod.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class multiLevelDecomp Declaration +\*---------------------------------------------------------------------------*/ + +class multiLevelDecomp +: + public decompositionMethod +{ + // Private data + + PtrList<decompositionMethod> methods_; + + + // Private Member Functions + + //- Given connectivity across processors work out connectivity + // for a (consistent) subset + void subsetGlobalCellCells + ( + const labelListList& cellCells, + const labelList& set, + labelListList& subCellCells, + label& cutConnections + ) const; + + //- Decompose level methodI without addressing + void decompose + ( + const labelListList& pointPoints, + const pointField& points, + const scalarField& pointWeights, + const labelList& pointMap, // map back to original points + const label levelI, + + labelField& finalDecomp + ); + + //- Disallow default bitwise copy construct and assignment + void operator=(const multiLevelDecomp&); + multiLevelDecomp(const multiLevelDecomp&); + + +public: + + //- Runtime type information + TypeName("multiLevel"); + + + // Constructors + + //- Construct given the decomposition dictionary + multiLevelDecomp(const dictionary& decompositionDict); + + + //- Destructor + virtual ~multiLevelDecomp() + {} + + + // Member Functions + + //- Is method parallel aware (i.e. does it synchronize domains across + // proc boundaries) + virtual bool parallelAware() const; + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList decompose + ( + const polyMesh& mesh, + const pointField& points, + const scalarField& pointWeights + ); + + //- Return for every coordinate the wanted processor number. Explicitly + // provided connectivity - does not use mesh_. + virtual labelList decompose + ( + const labelListList& globalCellCells, + const pointField& cc, + const scalarField& cWeights + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.C b/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.C index 6447c4fa74fe300f324992a9a7137f6a8352402b..f4963e2e5adf68c4b45f1f32b218cd9173909bba 100644 --- a/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.C +++ b/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.C @@ -39,13 +39,6 @@ namespace Foam simpleGeomDecomp, dictionary ); - - addToRunTimeSelectionTable - ( - decompositionMethod, - simpleGeomDecomp, - dictionaryMesh - ); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -133,26 +126,6 @@ void Foam::simpleGeomDecomp::assignToProcessorGroup } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::simpleGeomDecomp::simpleGeomDecomp(const dictionary& decompositionDict) -: - geomDecomp(decompositionDict, typeName) -{} - - -Foam::simpleGeomDecomp::simpleGeomDecomp -( - const dictionary& decompositionDict, - const polyMesh& -) -: - geomDecomp(decompositionDict, typeName) -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - Foam::labelList Foam::simpleGeomDecomp::decompose(const pointField& points) { // construct a list for the final result @@ -315,4 +288,16 @@ Foam::labelList Foam::simpleGeomDecomp::decompose return finalDecomp; } + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::simpleGeomDecomp::simpleGeomDecomp(const dictionary& decompositionDict) +: + geomDecomp(decompositionDict, typeName) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + // ************************************************************************* // diff --git a/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.H b/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.H index 714916f62d6893814f48d4239d736d04620d7064..7336b3b85d1140c853b74b1cd309ed310c7bf6bd 100644 --- a/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.H +++ b/src/parallel/decompose/decompositionMethods/simpleGeomDecomp/simpleGeomDecomp.H @@ -76,13 +76,6 @@ public: //- Construct given the decomposition dictionary simpleGeomDecomp(const dictionary& decompositionDict); - //- Construct given the decomposition dictionary and mesh - simpleGeomDecomp - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); - //- Destructor virtual ~simpleGeomDecomp() @@ -98,16 +91,24 @@ public: return false; } - virtual labelList decompose - ( - const pointField& points - ); + virtual labelList decompose(const pointField&); + + virtual labelList decompose(const pointField&, const scalarField&); + + virtual labelList decompose(const polyMesh&, const pointField& points) + { + return decompose(points); + } virtual labelList decompose ( + const polyMesh&, const pointField& points, const scalarField& pointWeights - ); + ) + { + return decompose(points, pointWeights); + } //- Explicitly provided connectivity virtual labelList decompose diff --git a/src/parallel/decompose/metisDecomp/metisDecomp.C b/src/parallel/decompose/metisDecomp/metisDecomp.C index b198c88415eaffd677580334c962483e2e62dcf6..0c24fc6ac794db62d655c7890a98876a766e98cd 100644 --- a/src/parallel/decompose/metisDecomp/metisDecomp.C +++ b/src/parallel/decompose/metisDecomp/metisDecomp.C @@ -41,12 +41,7 @@ namespace Foam { defineTypeNameAndDebug(metisDecomp, 0); - addToRunTimeSelectionTable - ( - decompositionMethod, - metisDecomp, - dictionaryMesh - ); + addToRunTimeSelectionTable(decompositionMethod, metisDecomp, dictionary); } @@ -170,31 +165,31 @@ Foam::label Foam::metisDecomp::decompose } } - if (metisCoeffs.readIfPresent("cellWeightsFile", weightsFile)) - { - Info<< "metisDecomp : Using cell-based weights." << endl; - - IOList<int> cellIOWeights - ( - IOobject - ( - weightsFile, - mesh_.time().timeName(), - mesh_, - IOobject::MUST_READ, - IOobject::AUTO_WRITE - ) - ); - cellWeights.transfer(cellIOWeights); - - if (cellWeights.size() != xadj.size()-1) - { - FatalErrorIn("metisDecomp::decompose(const pointField&)") - << "Number of cell weights " << cellWeights.size() - << " does not equal number of cells " << xadj.size()-1 - << exit(FatalError); - } - } + //if (metisCoeffs.readIfPresent("cellWeightsFile", weightsFile)) + //{ + // Info<< "metisDecomp : Using cell-based weights." << endl; + // + // IOList<int> cellIOWeights + // ( + // IOobject + // ( + // weightsFile, + // mesh_.time().timeName(), + // mesh_, + // IOobject::MUST_READ, + // IOobject::AUTO_WRITE + // ) + // ); + // cellWeights.transfer(cellIOWeights); + // + // if (cellWeights.size() != xadj.size()-1) + // { + // FatalErrorIn("metisDecomp::decompose(const pointField&)") + // << "Number of cell weights " << cellWeights.size() + // << " does not equal number of cells " << xadj.size()-1 + // << exit(FatalError); + // } + //} } int nProcs = nProcessors_; @@ -304,14 +299,9 @@ Foam::label Foam::metisDecomp::decompose // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::metisDecomp::metisDecomp -( - const dictionary& decompositionDict, - const polyMesh& mesh -) +Foam::metisDecomp::metisDecomp(const dictionary& decompositionDict) : - decompositionMethod(decompositionDict), - mesh_(mesh) + decompositionMethod(decompositionDict) {} @@ -319,11 +309,12 @@ Foam::metisDecomp::metisDecomp Foam::labelList Foam::metisDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) { - if (points.size() != mesh_.nCells()) + if (points.size() != mesh.nCells()) { FatalErrorIn ( @@ -332,71 +323,53 @@ Foam::labelList Foam::metisDecomp::decompose << endl << "and supply one coordinate (cellCentre) for every cell." << endl << "The number of coordinates " << points.size() << endl - << "The number of cells in the mesh " << mesh_.nCells() + << "The number of cells in the mesh " << mesh.nCells() << exit(FatalError); } - List<int> adjncy; - List<int> xadj; - calcCSR(mesh_, adjncy, xadj); + CompactListList<label> cellCells; + calcCellCells(mesh, identity(mesh.nCells()), mesh.nCells(), cellCells); // Decompose using default weights - List<int> finalDecomp; - decompose(adjncy, xadj, pointWeights, finalDecomp); + labelList decomp; + decompose(cellCells.m(), cellCells.offsets(), pointWeights, decomp); - // Copy back to labelList - labelList decomp(finalDecomp.size()); - forAll(decomp, i) - { - decomp[i] = finalDecomp[i]; - } return decomp; } Foam::labelList Foam::metisDecomp::decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& agglomPoints, const scalarField& agglomWeights ) { - if (agglom.size() != mesh_.nCells()) + if (agglom.size() != mesh.nCells()) { FatalErrorIn ( "metisDecomp::decompose" "(const labelList&, const pointField&, const scalarField&)" ) << "Size of cell-to-coarse map " << agglom.size() - << " differs from number of cells in mesh " << mesh_.nCells() + << " differs from number of cells in mesh " << mesh.nCells() << exit(FatalError); } // Make Metis CSR (Compressed Storage Format) storage // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - { - // Get cellCells on coarse mesh. - labelListList cellCells; - calcCellCells - ( - mesh_, - agglom, - agglomPoints.size(), - cellCells - ); - calcCSR(cellCells, adjncy, xadj); - } + CompactListList<label> cellCells; + calcCellCells(mesh, agglom, agglomPoints.size(), cellCells); // Decompose using default weights - List<int> finalDecomp; - decompose(adjncy, xadj, agglomWeights, finalDecomp); + labelList finalDecomp; + decompose(cellCells.m(), cellCells.offsets(), agglomWeights, finalDecomp); - // Rework back into decomposition for original mesh_ + // Rework back into decomposition for original mesh labelList fineDistribution(agglom.size()); forAll(fineDistribution, i) @@ -404,7 +377,7 @@ Foam::labelList Foam::metisDecomp::decompose fineDistribution[i] = finalDecomp[agglom[i]]; } - return fineDistribution; + return finalDecomp; } @@ -431,21 +404,12 @@ Foam::labelList Foam::metisDecomp::decompose // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - calcCSR(globalCellCells, adjncy, xadj); - + CompactListList<label> cellCells(globalCellCells); // Decompose using default weights - List<int> finalDecomp; - decompose(adjncy, xadj, cellWeights, finalDecomp); + labelList decomp; + decompose(cellCells.m(), cellCells.offsets(), cellWeights, decomp); - // Copy back to labelList - labelList decomp(finalDecomp.size()); - forAll(decomp, i) - { - decomp[i] = finalDecomp[i]; - } return decomp; } diff --git a/src/parallel/decompose/metisDecomp/metisDecomp.H b/src/parallel/decompose/metisDecomp/metisDecomp.H index f18ba8bd0f0731634a22eae4bab72e027517e8ec..d6c7e26e41139ca28a37f649e0df80086b68d8ad 100644 --- a/src/parallel/decompose/metisDecomp/metisDecomp.H +++ b/src/parallel/decompose/metisDecomp/metisDecomp.H @@ -48,10 +48,6 @@ class metisDecomp : public decompositionMethod { - // Private data - - const polyMesh& mesh_; - // Private Member Functions @@ -76,12 +72,8 @@ public: // Constructors - //- Construct given the decomposition dictionary and mesh - metisDecomp - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); + //- Construct given the decomposition dictionary + metisDecomp(const dictionary&); //- Destructor @@ -104,6 +96,7 @@ public: // value. The overall sum of weights might otherwise overflow. virtual labelList decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ); @@ -115,6 +108,7 @@ public: // See note on weights above. virtual labelList decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& regionPoints, const scalarField& regionWeights diff --git a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C index cded55bcd7a48f1d88c84e6e8e93d0cbf7d5fe4a..b4aae52f38d336b5298834064dca6f3084c9f8bc 100644 --- a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C +++ b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C @@ -141,12 +141,7 @@ namespace Foam { defineTypeNameAndDebug(ptscotchDecomp, 0); - addToRunTimeSelectionTable - ( - decompositionMethod, - ptscotchDecomp, - dictionaryMesh - ); + addToRunTimeSelectionTable(decompositionMethod, ptscotchDecomp, dictionary); } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -414,14 +409,9 @@ Foam::label Foam::ptscotchDecomp::decompose // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::ptscotchDecomp::ptscotchDecomp -( - const dictionary& decompositionDict, - const polyMesh& mesh -) +Foam::ptscotchDecomp::ptscotchDecomp(const dictionary& decompositionDict) : - decompositionMethod(decompositionDict), - mesh_(mesh) + decompositionMethod(decompositionDict) {} @@ -429,11 +419,12 @@ Foam::ptscotchDecomp::ptscotchDecomp Foam::labelList Foam::ptscotchDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) { - if (points.size() != mesh_.nCells()) + if (points.size() != mesh.nCells()) { FatalErrorIn ( @@ -443,7 +434,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose << endl << "and supply one coordinate (cellCentre) for every cell." << endl << "The number of coordinates " << points.size() << endl - << "The number of cells in the mesh " << mesh_.nCells() + << "The number of cells in the mesh " << mesh.nCells() << exit(FatalError); } @@ -457,20 +448,14 @@ Foam::labelList Foam::ptscotchDecomp::decompose // Make Metis CSR (Compressed Storage Format) storage // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli - // Connections - Field<int> adjncy; - // Offsets into adjncy - Field<int> xadj; - calcDistributedCSR - ( - mesh_, - adjncy, - xadj - ); + + + CompactListList<label> cellCells; + calcCellCells(mesh, identity(mesh.nCells()), mesh.nCells(), cellCells); // Decompose using default weights List<int> finalDecomp; - decompose(adjncy, xadj, pointWeights, finalDecomp); + decompose(cellCells.m(), cellCells.offsets(), pointWeights, finalDecomp); // Copy back to labelList labelList decomp(finalDecomp.size()); @@ -484,52 +469,40 @@ Foam::labelList Foam::ptscotchDecomp::decompose Foam::labelList Foam::ptscotchDecomp::decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& agglomPoints, const scalarField& pointWeights ) { - if (agglom.size() != mesh_.nCells()) + if (agglom.size() != mesh.nCells()) { FatalErrorIn ( "ptscotchDecomp::decompose(const labelList&, const pointField&)" ) << "Size of cell-to-coarse map " << agglom.size() - << " differs from number of cells in mesh " << mesh_.nCells() + << " differs from number of cells in mesh " << mesh.nCells() << exit(FatalError); } // // For running sequential ... // if (Pstream::nProcs() <= 1) // { -// return scotchDecomp(decompositionDict_, mesh_) +// return scotchDecomp(decompositionDict_, mesh) // .decompose(agglom, agglomPoints, pointWeights); // } // Make Metis CSR (Compressed Storage Format) storage // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - { - // Get cellCells on coarse mesh. - labelListList cellCells; - calcCellCells - ( - mesh_, - agglom, - agglomPoints.size(), - cellCells - ); - - calcCSR(cellCells, adjncy, xadj); - } + CompactListList<label> cellCells; + calcCellCells(mesh, agglom, agglomPoints.size(), cellCells); // Decompose using weights List<int> finalDecomp; - decompose(adjncy, xadj, pointWeights, finalDecomp); + decompose(cellCells.m(), cellCells.offsets(), pointWeights, finalDecomp); - // Rework back into decomposition for original mesh_ + // Rework back into decomposition for original mesh labelList fineDistribution(agglom.size()); forAll(fineDistribution, i) @@ -561,7 +534,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose // // For running sequential ... // if (Pstream::nProcs() <= 1) // { -// return scotchDecomp(decompositionDict_, mesh_) +// return scotchDecomp(decompositionDict_, mesh) // .decompose(globalCellCells, cellCentres, cWeights); // } @@ -570,13 +543,11 @@ Foam::labelList Foam::ptscotchDecomp::decompose // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - calcCSR(globalCellCells, adjncy, xadj); + CompactListList<label> cellCells(globalCellCells); // Decompose using weights List<int> finalDecomp; - decompose(adjncy, xadj, cWeights, finalDecomp); + decompose(cellCells.m(), cellCells.offsets(), cWeights, finalDecomp); // Copy back to labelList labelList decomp(finalDecomp.size()); diff --git a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H index 45649a0b818d28ce46cca95c2a835aac4605fb78..d276137d4f4cde495aee356b9eff0734c946da2e 100644 --- a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H +++ b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.H @@ -48,11 +48,6 @@ class ptscotchDecomp : public decompositionMethod { - // Private data - - const polyMesh& mesh_; - - // Private Member Functions //- Check and print error message @@ -80,11 +75,7 @@ public: // Constructors //- Construct given the decomposition dictionary and mesh - ptscotchDecomp - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); + ptscotchDecomp(const dictionary& decompositionDict); //- Destructor @@ -104,6 +95,7 @@ public: // mesh connectivity (if needed) virtual labelList decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ); @@ -114,6 +106,7 @@ public: // functionality natively. virtual labelList decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& regionPoints, const scalarField& regionWeights diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.C b/src/parallel/decompose/scotchDecomp/scotchDecomp.C index 534044646f0271cc2d5f65086cf8c020d04044aa..dc870abacd6f34a83a3e079b60313ebfcf86288a 100644 --- a/src/parallel/decompose/scotchDecomp/scotchDecomp.C +++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.C @@ -145,7 +145,7 @@ namespace Foam ( decompositionMethod, scotchDecomp, - dictionaryMesh + dictionary ); } @@ -165,6 +165,7 @@ void Foam::scotchDecomp::check(const int retVal, const char* str) // Call scotch with options from dictionary. Foam::label Foam::scotchDecomp::decompose ( + const fileName& meshPath, const List<int>& adjncy, const List<int>& xadj, const scalarField& cWeights, @@ -184,7 +185,7 @@ Foam::label Foam::scotchDecomp::decompose if (writeGraph) { - OFstream str(mesh_.time().path() / mesh_.name() + ".grf"); + OFstream str(meshPath + ".grf"); Info<< "Dumping Scotch graph file to " << str.name() << endl << "Use this in combination with gpart." << endl; @@ -408,14 +409,9 @@ Foam::label Foam::scotchDecomp::decompose // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::scotchDecomp::scotchDecomp -( - const dictionary& decompositionDict, - const polyMesh& mesh -) +Foam::scotchDecomp::scotchDecomp(const dictionary& decompositionDict) : - decompositionMethod(decompositionDict), - mesh_(mesh) + decompositionMethod(decompositionDict) {} @@ -423,11 +419,12 @@ Foam::scotchDecomp::scotchDecomp Foam::labelList Foam::scotchDecomp::decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ) { - if (points.size() != mesh_.nCells()) + if (points.size() != mesh.nCells()) { FatalErrorIn ( @@ -437,20 +434,24 @@ Foam::labelList Foam::scotchDecomp::decompose << endl << "and supply one coordinate (cellCentre) for every cell." << endl << "The number of coordinates " << points.size() << endl - << "The number of cells in the mesh " << mesh_.nCells() + << "The number of cells in the mesh " << mesh.nCells() << exit(FatalError); } - // Make Metis CSR (Compressed Storage Format) storage - // adjncy : contains neighbours (= edges in graph) - // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - calcCSR(mesh_, adjncy, xadj); + + CompactListList<label> cellCells; + calcCellCells(mesh, identity(mesh.nCells()), mesh.nCells(), cellCells); // Decompose using default weights List<int> finalDecomp; - decompose(adjncy, xadj, pointWeights, finalDecomp); + decompose + ( + mesh.time().path()/mesh.name(), + cellCells.m(), + cellCells.offsets(), + pointWeights, + finalDecomp + ); // Copy back to labelList labelList decomp(finalDecomp.size()); @@ -464,43 +465,35 @@ Foam::labelList Foam::scotchDecomp::decompose Foam::labelList Foam::scotchDecomp::decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& agglomPoints, const scalarField& pointWeights ) { - if (agglom.size() != mesh_.nCells()) + if (agglom.size() != mesh.nCells()) { FatalErrorIn ( "scotchDecomp::decompose(const labelList&, const pointField&)" ) << "Size of cell-to-coarse map " << agglom.size() - << " differs from number of cells in mesh " << mesh_.nCells() + << " differs from number of cells in mesh " << mesh.nCells() << exit(FatalError); } - // Make Metis CSR (Compressed Storage Format) storage - // adjncy : contains neighbours (= edges in graph) - // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - { - // Get cellCells on coarse mesh. - labelListList cellCells; - calcCellCells - ( - mesh_, - agglom, - agglomPoints.size(), - cellCells - ); - - calcCSR(cellCells, adjncy, xadj); - } + CompactListList<label> cellCells; + calcCellCells(mesh, agglom, agglomPoints.size(), cellCells); // Decompose using weights List<int> finalDecomp; - decompose(adjncy, xadj, pointWeights, finalDecomp); + decompose + ( + mesh.time().path()/mesh.name(), + cellCells.m(), + cellCells.offsets(), + pointWeights, + finalDecomp + ); // Rework back into decomposition for original mesh_ labelList fineDistribution(agglom.size()); @@ -537,13 +530,11 @@ Foam::labelList Foam::scotchDecomp::decompose // adjncy : contains neighbours (= edges in graph) // xadj(celli) : start of information in adjncy for celli - List<int> adjncy; - List<int> xadj; - calcCSR(globalCellCells, adjncy, xadj); + CompactListList<label> cellCells(globalCellCells); // Decompose using weights List<int> finalDecomp; - decompose(adjncy, xadj, cWeights, finalDecomp); + decompose(".", cellCells.m(), cellCells.offsets(), cWeights, finalDecomp); // Copy back to labelList labelList decomp(finalDecomp.size()); diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.H b/src/parallel/decompose/scotchDecomp/scotchDecomp.H index 249b191f6c90de9d32dbd5f632dec4dd0655648d..2cd376074ccf857ab3aee98fbab9dbbfbf841f8f 100644 --- a/src/parallel/decompose/scotchDecomp/scotchDecomp.H +++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.H @@ -48,11 +48,6 @@ class scotchDecomp : public decompositionMethod { - // Private data - - const polyMesh& mesh_; - - // Private Member Functions //- Check and print error message @@ -60,6 +55,7 @@ class scotchDecomp label decompose ( + const fileName& meshPath, const List<int>& adjncy, const List<int>& xadj, const scalarField& cWeights, @@ -80,11 +76,7 @@ public: // Constructors //- Construct given the decomposition dictionary and mesh - scotchDecomp - ( - const dictionary& decompositionDict, - const polyMesh& mesh - ); + scotchDecomp(const dictionary& decompositionDict); //- Destructor @@ -107,6 +99,7 @@ public: // might otherwise overflow. virtual labelList decompose ( + const polyMesh& mesh, const pointField& points, const scalarField& pointWeights ); @@ -118,6 +111,7 @@ public: // See note on weights above. virtual labelList decompose ( + const polyMesh& mesh, const labelList& agglom, const pointField& regionPoints, const scalarField& regionWeights