diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index 5a7da19bb7..61d6f2bb9a 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -43,7 +43,6 @@ Description #include "refinementFeatures.H" #include "shellSurfaces.H" #include "decompositionMethod.H" -#include "noDecomp.H" #include "fvMeshDistribute.H" #include "wallPolyPatch.H" #include "refinementParameters.H" diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict index f1a97ca7cb..fc0edd941c 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict +++ b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict @@ -183,50 +183,56 @@ structuredCoeffs // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Decomposition constraints -//constraints -//{ -// preserveBaffles -// { -// //- Keep owner and neighbour of baffles on same processor (i.e. -// // keep it detectable as a baffle). Baffles are two boundary face -// // sharing the same points -// type preserveBaffles; -// } -// preserveFaceZones -// { -// //- Keep owner and neighbour on same processor for faces in zones -// type preserveFaceZones; -// zones (".*"); -// } -// preservePatches -// { -// //- Keep owner and neighbour on same processor for faces in patches -// // (only makes sense for cyclic patches. Not suitable for e.g. -// // cyclicAMI since these are not coupled on the patch level. Use -// // singleProcessorFaceSets for those) -// type preservePatches; -// patches (".*"); -// } -// singleProcessorFaceSets -// { -// //- Keep all of faceSet on a single processor. This puts all cells -// // connected with a point, edge or face on the same processor. -// // (just having face connected cells might not guarantee a balanced -// // decomposition) -// // The processor can be -1 (the decompositionMethod chooses the -// // processor for a good load balance) or explicitly provided (upsets -// // balance) -// type singleProcessorFaceSets; -// singleProcessorFaceSets ((f1 -1)); -// } -// refinementHistory -// { -// //- Decompose cells such that all cell originating from single cell -// // end up on same processor -// type refinementHistory; -// } -//} - +/* +constraints +{ + baffles + { + //- Keep owner and neighbour of baffles on same processor (i.e. + // keep it detectable as a baffle). Baffles are two boundary face + // sharing the same points + type preserveBaffles; + enabled false; + } + faces + { + //- Keep owner and neighbour on same processor for faces in zones + type preserveFaceZones; + zones (".*"); + enabled false; + } + patches + { + //- Keep owner and neighbour on same processor for faces in patches + // (only makes sense for cyclic patches. Not suitable for e.g. + // cyclicAMI since these are not coupled on the patch level. Use + // singleProcessorFaceSets for those) + type preservePatches; + patches (".*"); + enabled false; + } + processors + { + //- Keep all of faceSet on a single processor. This puts all cells + // connected with a point, edge or face on the same processor. + // (just having face connected cells might not guarantee a balanced + // decomposition) + // The processor can be -1 (the decompositionMethod chooses the + // processor for a good load balance) or explicitly provided (upsets + // balance) + type singleProcessorFaceSets; + sets ((f1 -1)); + enabled false; + } + refinement + { + //- Decompose cells such that all cell originating from single cell + // end up on same processor + type refinementHistory; + enabled false; + } +} +*/ // Deprecated form of specifying decomposition constraints: //- Keep owner and neighbour on same processor for faces in zones: @@ -251,5 +257,4 @@ structuredCoeffs // same points. //preserveBaffles true; - // ************************************************************************* // diff --git a/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C b/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C index 41a8cd3486..3c2f829aa6 100644 --- a/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C +++ b/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C @@ -33,8 +33,8 @@ Description processor has all triangles that overlap its mesh. Note - - best decomposition option is hierarchGeomDecomp since - guarantees square decompositions. + - best decomposition option is hierarchical since it guarantees + square decompositions. - triangles might be present on multiple processors. - merging uses geometric tolerance so take care with writing precision. diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C index 7b49cfa7b5..198f51586f 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C +++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C @@ -49,7 +49,6 @@ License #include "globalIndex.H" #include "meshTools.H" #include "OFstream.H" -#include "geomDecomp.H" #include "Random.H" #include "searchableSurfaces.H" #include "treeBoundBox.H" diff --git a/src/parallel/decompose/decomposition.dox b/src/parallel/decompose/decomposition.dox index 0256b48e4a..d9622448a5 100644 --- a/src/parallel/decompose/decomposition.dox +++ b/src/parallel/decompose/decomposition.dox @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -177,7 +177,7 @@ decomposition is termed a level. For example, method hierarchical; coeffs { - n (16 4 2); + n (16 4 2); } } cpus @@ -228,53 +228,80 @@ For example, \verbatim constraints { - preserveBaffles + // Keep owner and neighbour of baffles on same processor + // (ie, keep it detectable as a baffle). + // Baffles are two boundary face sharing the same points + baffles { - // Keep owner and neighbour of baffles on same processor - // (ie, keep it detectable as a baffle). - // Baffles are two boundary face sharing the same points - type preserveBaffles; + enabled true; } - preserveFaceZones + // Keep owner and neighbour on same processor for faces in zones + faces { - // Keep owner and neighbour on same processor for faces in zones - type preserveFaceZones; zones (".*"); + enabled true; } - preservePatches + // Keep owner and neighbour on same processor for faces in patches + // (only makes sense for cyclic patches. Not suitable for e.g. + // cyclicAMI since these are not coupled on the patch level. + // Use singleProcessorFaceSets for those. + patches { - // Keep owner and neighbour on same processor for faces in patches - // (only makes sense for cyclic patches. Not suitable for e.g. - // cyclicAMI since these are not coupled on the patch level. - // Use singleProcessorFaceSets for those. - type preservePatches; patches (".*"); + enabled true; } - singleProcessorFaceSets + // Keep all of faceSet on a single processor. This puts all cells + // connected with a point, edge or face on the same processor. + // (just having face connected cells might not guarantee a balanced + // decomposition) + // The processor can be -1 (the decompositionMethod chooses the + // processor for a good load balance) or explicitly provided (upsets + // balance) + processors { - // Keep all of faceSet on a single processor. This puts all cells - // connected with a point, edge or face on the same processor. - // (just having face connected cells might not guarantee a balanced - // decomposition) - // The processor can be -1 (the decompositionMethod chooses the - // processor for a good load balance) or explicitly provided (upsets - // balance) - type singleProcessorFaceSets; - singleProcessorFaceSets ((f1 -1)); + sets ((f1 -1)); + enabled true; } - refinementHistory + // Decompose cells such that all cell originating from single cell + // end up on same processor + refinement { - // Decompose cells such that all cell originating from single cell - // end up on same processor type refinementHistory; + enabled true; + } + + // Prevent decomposition splitting of the geometric regions + // Uses any topoSetFaceSource for selecting the constrained faces + geometric + { + type geometric; + + grow false; + + selection + { + box1 + { + source box; + min (-10 -10 -10); + max (1 1 1); + } + + ball1 + { + source sphere; + origin (-2 -2 1); + radius 1; + } + } } } \endverbatim diff --git a/src/parallel/decompose/decompositionMethods/Make/files b/src/parallel/decompose/decompositionMethods/Make/files index 0bae18c40d..575366dfae 100644 --- a/src/parallel/decompose/decompositionMethods/Make/files +++ b/src/parallel/decompose/decompositionMethods/Make/files @@ -9,14 +9,15 @@ structuredDecomp/structuredDecomp.C noDecomp/noDecomp.C -decompositionConstraints = decompositionConstraints +constraints = decompositionConstraints -$(decompositionConstraints)/decompositionConstraint/decompositionConstraint.C -$(decompositionConstraints)/preserveBaffles/preserveBafflesConstraint.C -$(decompositionConstraints)/preserveFaceZones/preserveFaceZonesConstraint.C -$(decompositionConstraints)/preservePatches/preservePatchesConstraint.C -$(decompositionConstraints)/singleProcessorFaceSets/singleProcessorFaceSetsConstraint.C -$(decompositionConstraints)/refinementHistory/refinementHistoryConstraint.C +$(constraints)/decompositionConstraint/decompositionConstraint.C +$(constraints)/preserveBaffles/preserveBafflesConstraint.C +$(constraints)/preserveFaceZones/preserveFaceZonesConstraint.C +$(constraints)/preservePatches/preservePatchesConstraint.C +$(constraints)/geometric/geometricConstraint.C +$(constraints)/singleProcessorFaceSets/singleProcessorFaceSetsConstraint.C +$(constraints)/refinementHistory/refinementHistoryConstraint.C LIB = $(FOAM_LIBBIN)/libdecompositionMethods diff --git a/src/parallel/decompose/decompositionMethods/Make/options b/src/parallel/decompose/decompositionMethods/Make/options index 45133caabb..487f3df83a 100644 --- a/src/parallel/decompose/decompositionMethods/Make/options +++ b/src/parallel/decompose/decompositionMethods/Make/options @@ -1,9 +1,11 @@ EXE_INC = \ + -I$(LIB_SRC)/fileFormats/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude LIB_LIBS = \ + -lfileFormats \ -lmeshTools \ -ldynamicMesh \ -lfiniteVolume diff --git a/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C b/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C index 3be42dbba3..eca00bb406 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C +++ b/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C @@ -37,16 +37,39 @@ namespace Foam Foam::decompositionConstraint::decompositionConstraint ( - const dictionary& constraintsDict, - const word& type + const dictionary& constraintDict ) : - coeffDict_(constraintsDict) + coeffDict_(constraintDict) +{} + + +Foam::decompositionConstraint::decompositionConstraint +( + const dictionary& constraintDict, + const word& +) +: + coeffDict_(constraintDict) {} // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // +Foam::autoPtr +Foam::decompositionConstraint::New +( + const dictionary& dict +) +{ + return decompositionConstraint::New + ( + dict, + dict.get("type") + ); +} + + Foam::autoPtr Foam::decompositionConstraint::New ( @@ -61,14 +84,14 @@ Foam::decompositionConstraint::New if (!cstrIter.found()) { FatalIOErrorInFunction(dict) - << "Unknown decompositionConstraint type " + << "Unknown decompositionConstraint: " << modelType << nl << nl - << "Valid decompositionConstraint types :" << endl + << "Valid types:" << nl << dictionaryConstructorTablePtr_->sortedToc() << exit(FatalIOError); } - return autoPtr(cstrIter()(dict, modelType)); + return autoPtr(cstrIter()(dict)); } diff --git a/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.H b/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.H index 58ad56379d..a1e8b75b15 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.H +++ b/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.H @@ -25,6 +25,7 @@ Class Foam::decompositionConstraint Description + Abstract class for handling decomposition constraints. SourceFiles decompositionConstraint.C @@ -35,10 +36,10 @@ SourceFiles #define decompositionConstraint_H #include "dictionary.H" -#include "runTimeSelectionTables.H" #include "boolList.H" #include "labelList.H" #include "labelPair.H" +#include "runTimeSelectionTables.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -58,12 +59,11 @@ protected: // Protected data - //- Model coefficients dictionary + //- Constraint coefficients dictionary dictionary coeffDict_; -private: - // Private Member Functions + // Protected Member Functions //- No copy construct decompositionConstraint(const decompositionConstraint&) = delete; @@ -71,7 +71,6 @@ private: //- No copy assignment void operator=(const decompositionConstraint&) = delete; - public: //- Runtime type information @@ -86,20 +85,24 @@ public: decompositionConstraint, dictionary, ( - const dictionary& constraintsDict, - const word& type + const dictionary& dict ), - (constraintsDict, type) + (dict) ); // Constructors - //- Construct with generic dictionary with optional entry for type + //- Construct with constraint dictionary + explicit decompositionConstraint(const dictionary& constraintDict); + + //- Construct with constraint dictionary and model type. + // The model type could be used for defining a coefficients + // sub-dictionary. decompositionConstraint ( - const dictionary& constraintsDict, - const word& type + const dictionary& constraintDict, + const word& modelType ); @@ -108,8 +111,14 @@ public: //- Return a reference to the selected decompositionConstraint static autoPtr New ( - const dictionary& constraintsDict, - const word& type + const dictionary& constraintDict + ); + + //- Return a reference to the selected decompositionConstraint + static autoPtr New + ( + const dictionary& constraintDict, + const word& modelType ); @@ -119,7 +128,7 @@ public: // Member Functions - //- Add my constraints to list of constraints + //- Add this constraint to list of constraints virtual void add ( const polyMesh& mesh, diff --git a/src/parallel/decompose/decompositionMethods/decompositionConstraints/geometric/geometricConstraint.C b/src/parallel/decompose/decompositionMethods/decompositionConstraints/geometric/geometricConstraint.C new file mode 100644 index 0000000000..98b6af9c35 --- /dev/null +++ b/src/parallel/decompose/decompositionMethods/decompositionConstraints/geometric/geometricConstraint.C @@ -0,0 +1,226 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +\*---------------------------------------------------------------------------*/ + +#include "geometricConstraint.H" +#include "addToRunTimeSelectionTable.H" +#include "syncTools.H" +#include "polyMesh.H" +#include "Time.H" +#include "BitOps.H" +#include "faceBoolSet.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace decompositionConstraints +{ + defineTypeName(geometric); + + addToRunTimeSelectionTable + ( + decompositionConstraint, + geometric, + dictionary + ); +} +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::decompositionConstraints::geometric::geometric +( + const dictionary& dict +) +: + decompositionConstraint(dict, typeName), + sources_(), + selection_(coeffDict_.subDict("selection")), + grow_(dict.lookupOrDefault("grow", false)) +{ + // Stored as dictionary, since we do not have the mesh at this stage + + if (decompositionConstraint::debug) + { + Info<< type() + << " : adding " << selection_.size() + << " geometric constraints for faces" << endl; + } +} + + +Foam::decompositionConstraints::geometric::geometric +( + PtrList&& selections +) +: + decompositionConstraint(dictionary(), typeName), + sources_(std::move(selections)), + selection_(), + grow_(false) +{ + if (decompositionConstraint::debug) + { + Info<< type() + << " : adding " << sources_.size() + << " geometric constraints for faces" << endl; + } +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::decompositionConstraints::geometric::add +( + const polyMesh& mesh, + boolList& blockedFace, + PtrList& specifiedProcessorFaces, + labelList& specifiedProcessor, + List& explicitConnections +) const +{ + const label nFaces = mesh.nFaces(); + + blockedFace.resize(nFaces, true); + + label nchanged = 0; + if (decompositionConstraint::debug) + { + nchanged = BitOps::count(blockedFace, false); + } + + // Modify via topoSetFaceSource + faceBoolSet facesToBlock(mesh, std::move(blockedFace)); + + for (const topoSetFaceSource& source : sources_) + { + // source.verbose(false); + source.applyToSet(topoSetSource::SUBTRACT, facesToBlock); + } + + for (const entry& dEntry : selection_) + { + if (!dEntry.isDict()) + { + WarningInFunction + << "Ignoring non-dictionary entry " + << dEntry << endl; + continue; + } + + const dictionary& spec = dEntry.dict(); + + auto source = topoSetFaceSource::New + ( + spec.get("source"), + mesh, + spec.optionalSubDict("sourceInfo") + ); + // source->verbose(false); + + source->applyToSet(topoSetSource::SUBTRACT, facesToBlock); + } + + + // Finished with topo changes + blockedFace.transfer(facesToBlock.addressing()); + + if (decompositionConstraint::debug) + { + nchanged = BitOps::count(blockedFace, false) - nchanged; + } + else + { + nchanged = 0; + } + + // Grow mode. + // Include the faces of cells for which there are already two + // or more faces in a constraint. + if (grow_) + { + bitSet moreUnblocking(nFaces, false); + + label nUnblocked = 0; + + for (label celli=0; celli < mesh.nCells(); ++celli) + { + const cell& cFaces = mesh.cells()[celli]; + + nUnblocked = 0; + for (const label facei : cFaces) + { + if (!blockedFace[facei]) + { + ++nUnblocked; + if (nUnblocked > 2) + { + break; + } + } + } + + if (nUnblocked > 2) + { + moreUnblocking.set(cFaces); + } + } + + nUnblocked = 0; + + for (label facei : moreUnblocking) + { + if (blockedFace[facei]) + { + blockedFace[facei] = false; + ++nUnblocked; + } + } + + if (decompositionConstraint::debug) + { + Info<< type() + << " : geometric constraint grow added " + << returnReduce(nUnblocked, sumOp