64 const word& coeffsName,
65 const bool allowDefault
69 if (!dictptr && allowDefault)
87 const label nDomainsGlobal = decompDict.
get<label>(
"numberOfSubdomains");
95 if (regionDict.
readIfPresent(
"numberOfSubdomains", nDomainsRegion))
97 if (nDomainsRegion >= 1 && nDomainsRegion <= nDomainsGlobal)
99 return nDomainsRegion;
103 <<
"ignoring out of range numberOfSubdomains " 104 << nDomainsRegion <<
" for region " <<
regionName 110 return nDomainsGlobal;
116 const dictionary& decompDict,
120 const dictionary* dictptr =
nullptr;
124 && (dictptr = decompDict.findDict(
"regions")) !=
nullptr 135 bool Foam::decompositionMethod::constraintCompat(
const word& modelType)
const 137 bool usable = decompDict_.found(modelType);
143 for (
const auto& item : constraints_)
145 if (modelType == item.type())
155 <<
nl <<
" Using '" << modelType
156 <<
"' constraint specification." <<
nl;
161 <<
nl <<
" Ignoring '" << modelType
162 <<
"' constraint specification - was already specified." <<
nl;
172 void Foam::decompositionMethod::readConstraints()
174 constraints_.clear();
176 const dictionary* dictptr = decompDict_.findDict(
"constraints");
180 for (
const entry& dEntry : *dictptr)
182 if (!dEntry.isDict())
188 const dictionary&
dict = dEntry.dict();
198 if (constraintCompat(
"preserveBaffles"))
202 new decompositionConstraints::preserveBaffles()
206 if (constraintCompat(
"preservePatches"))
210 new decompositionConstraints::preservePatches
212 decompDict_.get<wordRes>(
"preservePatches")
217 if (constraintCompat(
"preserveFaceZones"))
221 new decompositionConstraints::preserveFaceZones
223 decompDict_.get<wordRes>(
"preserveFaceZones")
228 if (constraintCompat(
"singleProcessorFaceSets"))
232 new decompositionConstraints::singleProcessorFaceSets
234 decompDict_.lookup(
"singleProcessorFaceSets")
244 const dictionary&
dict,
245 const word& coeffsName,
249 const bool allowDefault = !(
select & selectionType::EXACT);
251 const dictionary* dictptr =
260 if (
select & selectionType::MANDATORY)
263 <<
"'" << coeffsName <<
"' dictionary not found in dictionary " 268 if (
select & selectionType::NULL_DICT)
279 const word& coeffsName,
283 const bool allowDefault = !(
select & selectionType::EXACT);
285 const dictionary* dictptr =
nullptr;
287 if (!decompRegionDict_.empty())
290 dictptr =
cfindCoeffsDict(decompRegionDict_, coeffsName, allowDefault);
304 if (
select & selectionType::MANDATORY)
307 <<
"'" << coeffsName <<
"' dictionary not found in dictionary " 308 << decompDict_.name() <<
endl 312 if (
select & selectionType::NULL_DICT)
323 Foam::decompositionMethod::decompositionMethod
329 decompDict_(decompDict),
353 auto* ctorPtr = dictionaryConstructorTable(methodType);
360 "decompositionMethod",
362 *dictionaryConstructorTablePtr_
368 Info<<
"Decomposition method " << methodType
369 <<
" [" << (nDomains(decompDict,
regionName)) <<
']';
384 const polyMesh&
mesh,
426 forAll(fineDistribution, i)
428 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
431 return fineDistribution;
437 const polyMesh&
mesh,
442 scalarField weights(coarsePoints.size(), scalar(1));
462 return decompose(globalCellCells, cc, weights);
470 const label nLocalCoarse,
493 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
495 label facei = pp.start();
500 globalNeighbour[bFacei] = globalAgglom.toGlobal
502 agglom[faceOwner[facei]]
523 const label own = agglom[faceOwner[facei]];
524 const label nei = agglom[faceNeighbour[facei]];
526 nFacesPerCell[own]++;
527 nFacesPerCell[nei]++;
530 for (
const polyPatch& pp :
patches)
532 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
534 label facei = pp.start();
539 const label own = agglom[faceOwner[facei]];
540 const label globalNei = globalNeighbour[bFacei];
544 !globalAgglom.isLocal(globalNei)
545 || globalAgglom.toLocal(globalNei) != own
548 nFacesPerCell[own]++;
561 cellCells.
setSize(nFacesPerCell);
571 const label own = agglom[faceOwner[facei]];
572 const label nei = agglom[faceNeighbour[facei]];
574 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.toGlobal(nei);
575 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.toGlobal(own);
579 for (
const polyPatch& pp :
patches)
581 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
583 label facei = pp.start();
588 const label own = agglom[faceOwner[facei]];
589 const label globalNei = globalNeighbour[bFacei];
593 !globalAgglom.isLocal(globalNei)
594 || globalAgglom.toLocal(globalNei) != own
597 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
611 if (cellCells.
size() == 0)
619 label startIndex = cellCells.
offsets()[0];
624 nbrCells.insert(globalAgglom.toGlobal(celli));
626 const label endIndex = cellCells.
offsets()[celli+1];
628 for (label i = startIndex; i < endIndex; ++i)
630 if (nbrCells.insert(cellCells.
m()[i]))
632 cellCells.
m()[newIndex++] = cellCells.
m()[i];
635 startIndex = endIndex;
636 cellCells.
offsets()[celli+1] = newIndex;
662 const label nLocalCoarse,
686 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
688 label facei = pp.start();
693 globalNeighbour[bFacei] = globalAgglom.
toGlobal 695 agglom[faceOwner[facei]]
716 const label own = agglom[faceOwner[facei]];
717 const label nei = agglom[faceNeighbour[facei]];
719 nFacesPerCell[own]++;
720 nFacesPerCell[nei]++;
723 for (
const polyPatch& pp :
patches)
725 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
727 label facei = pp.start();
732 const label own = agglom[faceOwner[facei]];
733 const label globalNei = globalNeighbour[bFacei];
737 !globalAgglom.
isLocal(globalNei)
738 || globalAgglom.
toLocal(globalNei) != own
741 nFacesPerCell[own]++;
754 cellCells.
setSize(nFacesPerCell);
755 cellCellWeights.
setSize(nFacesPerCell);
766 const label own = agglom[faceOwner[facei]];
767 const label nei = agglom[faceNeighbour[facei]];
769 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
770 const label neiIndex = offsets[nei] + nFacesPerCell[nei]++;
772 m[ownIndex] = globalAgglom.
toGlobal(nei);
774 m[neiIndex] = globalAgglom.
toGlobal(own);
779 for (
const polyPatch& pp :
patches)
781 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
783 label facei = pp.start();
788 const label own = agglom[faceOwner[facei]];
789 const label globalNei = globalNeighbour[bFacei];
793 !globalAgglom.
isLocal(globalNei)
794 || globalAgglom.
toLocal(globalNei) != own
797 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
798 m[ownIndex] = globalNei;
813 if (cellCells.
size() == 0)
821 label startIndex = cellCells.
offsets()[0];
826 nbrCells.insert(globalAgglom.
toGlobal(celli));
828 const label endIndex = cellCells.
offsets()[celli+1];
830 for (label i = startIndex; i < endIndex; ++i)
832 if (nbrCells.insert(cellCells.
m()[i]))
834 cellCells.
m()[newIndex] = cellCells.
m()[i];
835 cellCellWeights.
m()[newIndex] = cellCellWeights.
m()[i];
839 startIndex = endIndex;
840 cellCells.
offsets()[celli+1] = newIndex;
841 cellCellWeights.
offsets()[celli+1] = newIndex;
845 cellCellWeights.
m().
setSize(newIndex);
877 <<
"Number of weights " << cellWeights.
size()
878 <<
" differs from number of cells " <<
mesh.
nCells()
883 const bool hasUnblocked =
893 explicitConnections.
size(),
900 for (
const labelList& procset : specifiedProcessorFaces)
902 nProcSets += procset.size();
909 if (!hasUnblocked && !nConnections && !nProcSets)
927 regionSplit localRegion(
mesh, blockedFace, explicitConnections,
false);
932 const label nUnblocked =
943 Info<<
"Constrained decomposition:" <<
nl 944 <<
" faces with same owner and neighbour processor : " 946 <<
" baffle faces with same owner processor : " 947 << nConnections <<
nl 948 <<
" faces all on same processor : " 969 forAll(localRegion, celli)
971 const label regioni = localRegion[celli];
973 regionWeights[regioni] += cellWeights[celli];
983 forAll(localRegion, celli)
985 const label regioni = localRegion[celli];
987 regionWeights[regioni] += 1.0;
1010 for (
const labelPair& baffle : explicitConnections)
1012 const label f0 = baffle.first();
1013 const label f1 = baffle.second();
1015 if (!blockedFace[f0] && !blockedFace[f1])
1029 else if (blockedFace[f0] != blockedFace[f1])
1032 <<
"On explicit connection between faces " << f0
1034 <<
" the two blockedFace status are not equal : " 1035 << blockedFace[f0] <<
" and " << blockedFace[f1]
1058 label nUnblocked = 0;
1059 forAll(blockedFace, facei)
1061 if (blockedFace[facei])
1063 faceData[facei] =
minData(-123);
1076 forAll(blockedFace, facei)
1078 if (!blockedFace[facei])
1081 seedFaces[nUnblocked] = facei;
1082 seedData[nUnblocked] =
minData(finalDecomp[own]);
1100 forAll(finalDecomp, celli)
1102 if (cellData[celli].valid(deltaCalc.data()))
1104 finalDecomp[celli] = cellData[celli].
data();
1123 forAll(specifiedProcessorFaces, seti)
1125 const labelList&
set = specifiedProcessorFaces[seti];
1127 label proci = specifiedProcessor[seti];
1142 for (
const label facei :
set)
1145 for (
const label pointi :
f)
1148 for (
const label pFacei :
pFaces)
1173 const label facei = pp.start()+i;
1177 if (!blockedFace[facei])
1179 const label ownProc = finalDecomp[own];
1180 const label nbrProc = nbrDecomp[bFacei];
1182 if (ownProc != nbrProc)
1185 <<
"patch:" << pp.name()
1186 <<
" face:" << facei
1188 <<
" ownProc:" << ownProc
1189 <<
" nbrProc:" << nbrProc
1214 specifiedProcessorFaces.
clear();
1215 explicitConnections.
clear();
1219 decompConstraint.add
1223 specifiedProcessorFaces,
1243 decompConstraint.apply
1247 specifiedProcessorFaces,
1249 explicitConnections,
1272 specifiedProcessorFaces,
1286 specifiedProcessorFaces,
1298 specifiedProcessorFaces,
1300 explicitConnections,
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
bool isLocal(const label i) const
Is on local processor.
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
Abstract class for handling decomposition constraints.
void size(const label n)
Older name for setAddressableSize.
label nLocalRegions() const
Return local number of regions.
errorManipArg< error, int > exit(error &err, const int errNo=1)
label size() const noexcept
The primary size (the number of rows/sublists)
A face is a list of labels corresponding to mesh vertices.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const labelList & offsets() const noexcept
Return the offset table (= size()+1)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual const labelList & faceNeighbour() const
Return face neighbour.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
constexpr char nl
The newline '\n' character (0x0a)
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
T * data() noexcept
Return pointer to the underlying array serving as data storage.
virtual labelList decompose(const pointField &points, const scalarField &pointWeights) const
Return the wanted processor number for every coordinate.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Wave propagation of information through grid. Every iteration information goes through one layer of c...
void setConstraints(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Helper: extract constraints:
static bool & parRun() noexcept
Test if this a parallel run.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
static label worldComm
Default world communicator (all processors). May differ from globalComm if local worlds are in use...
label nFaces() const noexcept
Number of mesh faces.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
const fileName & name() const noexcept
The dictionary name.
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
static bool warnAboutAge(const int version) noexcept
Test if an age warning should be emitted.
static void calcCellCells(const polyMesh &mesh, const labelList &agglom, const label nLocalCoarse, const bool global, CompactListList< label > &cellCells)
Helper: determine (local or global) cellCells from mesh.
#define forAll(list, i)
Loop across all elements in list.
static autoPtr< decompositionConstraint > New(const dictionary &constraintDict)
Return a reference to the selected decompositionConstraint.
void applyConstraints(const polyMesh &mesh, const boolList &blockedFace, const PtrList< labelList > &specifiedProcessorFaces, const labelList &specifiedProcessor, const List< labelPair > &explicitConnections, labelList &finalDecomp) const
Helper: apply constraints to a decomposition.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Foam::word regionName(Foam::polyMesh::defaultRegion)
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
List< SubListType > unpack() const
Return non-compact list of lists.
void clear()
Clear the list, i.e. set size to zero.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
List< scalar > scalarList
A List of scalars.
virtual const labelList & faceOwner() const
Return face owner.
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
const globalMeshData & globalData() const
Return parallel info.
label toLocal(const label i) const
From global to local on current processor.
label nInternalFaces() const noexcept
Number of internal faces.
virtual const faceList & faces() const
Return raw faces.
const vectorField & cellCentres() const
errorManip< error > abort(error &err)
static const dictionary & findCoeffsDict(const dictionary &dict, const word &coeffsName, int select=selectionType::DEFAULT)
Locate coeffsName dictionary or the fallback "coeffs" dictionary within an enclosing dictionary...
label nDomains() const noexcept
Number of domains.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
A packed storage unstructured matrix of objects of type <T> using an offset table for access...
void setSize(const label mRows)
Redimension - same as resize()
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
defineTypeNameAndDebug(combustionModel, 0)
label nTotalCells() const noexcept
Return total number of cells in decomposed mesh.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
messageStream Warning
Warning stream (stdout output on master, null elsewhere), with additional 'FOAM Warning' header text...
const vectorField & faceCentres() const
static autoPtr< decompositionMethod > New(const dictionary &decompDict, const word ®ionName="")
Return a reference to the selected decomposition method, optionally region-specific.
label toGlobal(const label i) const
From local to global index.
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
const vectorField & faceAreas() const
const polyBoundaryMesh & patches
static const dictionary & optionalRegionDict(const dictionary &decompDict, const word ®ionName)
Return an optional region-specific dictionary from "regions" sub-dictionary, or dictionary::null on f...
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
bool all(const UList< bool > &bools)
True if all entries are 'true' or if the set is empty.
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const labelListList & pointFaces() const
static const dictionary * cfindCoeffsDict(const dictionary &dict, const word &coeffsName, const bool allowDefault)
Mesh consisting of general polyhedral cells.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
List< label > labelList
A List of labels.
A patch is a list of labels that address the faces in the global face list.
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
For use with FaceCellWave. Transports minimum passive data.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
const List< T > & m() const noexcept
Const access to the packed matrix of values.
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and a sub-dictionary) otherwise return nullptr...
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)