Go to the documentation of this file.
65 const word& coeffsName,
66 const bool allowDefault
70 if (!dictptr && allowDefault)
88 const label nDomainsGlobal = decompDict.
get<label>(
"numberOfSubdomains");
96 if (regionDict.
readIfPresent(
"numberOfSubdomains", nDomainsRegion))
98 if (nDomainsRegion >= 1 && nDomainsRegion <= nDomainsGlobal)
100 return nDomainsRegion;
104 <<
"ignoring out of range numberOfSubdomains "
105 << nDomainsRegion <<
" for region " <<
regionName
111 return nDomainsGlobal;
125 && (dictptr = decompDict.
findDict(
"regions")) !=
nullptr
130 return (dictptr ? *dictptr : dictionary::null);
136 bool Foam::decompositionMethod::constraintCompat(
const word& modelType)
const
146 if (modelType == item.type())
156 <<
nl <<
" Using '" << modelType
157 <<
"' constraint specification." <<
nl;
162 <<
nl <<
" Ignoring '" << modelType
163 <<
"' constraint specification - was already specified." <<
nl;
173 void Foam::decompositionMethod::readConstraints()
175 constraints_.clear();
177 const dictionary* dictptr = decompDict_.findDict(
"constraints");
181 for (
const entry& dEntry : *dictptr)
183 if (!dEntry.isDict())
189 const dictionary&
dict = dEntry.dict();
199 if (constraintCompat(
"preserveBaffles"))
203 new decompositionConstraints::preserveBaffles()
207 if (constraintCompat(
"preservePatches"))
211 new decompositionConstraints::preservePatches
213 decompDict_.get<wordRes>(
"preservePatches")
218 if (constraintCompat(
"preserveFaceZones"))
222 new decompositionConstraints::preserveFaceZones
224 decompDict_.get<wordRes>(
"preserveFaceZones")
229 if (constraintCompat(
"singleProcessorFaceSets"))
233 new decompositionConstraints::singleProcessorFaceSets
235 decompDict_.lookup(
"singleProcessorFaceSets")
246 const word& coeffsName,
250 const bool allowDefault = !(select & selectionType::EXACT);
261 if (select & selectionType::MANDATORY)
264 <<
"'" << coeffsName <<
"' dictionary not found in dictionary "
269 if (select & selectionType::NULL_DICT)
280 const word& coeffsName,
284 const bool allowDefault = !(select & selectionType::EXACT);
288 if (!decompRegionDict_.empty())
291 dictptr =
cfindCoeffsDict(decompRegionDict_, coeffsName, allowDefault);
305 if (select & selectionType::MANDATORY)
308 <<
"'" << coeffsName <<
"' dictionary not found in dictionary "
309 << decompDict_.name() <<
endl
313 if (select & selectionType::NULL_DICT)
324 Foam::decompositionMethod::decompositionMethod
330 decompDict_(decompDict),
354 auto* ctorPtr = dictionaryConstructorTable(methodType);
361 "decompositionMethod",
363 *dictionaryConstructorTablePtr_
369 Info<<
"Decomposition method " << methodType
370 <<
" [" << (nDomains(decompDict,
regionName)) <<
']';
425 labelList fineDistribution(fineToCoarse.size());
427 forAll(fineDistribution, i)
429 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
432 return fineDistribution;
443 scalarField weights(coarsePoints.size(), scalar(1));
463 return decompose(globalCellCells, cc, weights);
471 const label nLocalCoarse,
500 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
502 label facei = pp.start();
507 globalNeighbour[bFacei] = globalAgglom.
toGlobal
509 agglom[faceOwner[facei]]
530 const label own = agglom[faceOwner[facei]];
531 const label nei = agglom[faceNeighbour[facei]];
533 nFacesPerCell[own]++;
534 nFacesPerCell[nei]++;
539 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
541 label facei = pp.start();
546 const label own = agglom[faceOwner[facei]];
547 const label globalNei = globalNeighbour[bFacei];
551 !globalAgglom.
isLocal(globalNei)
552 || globalAgglom.
toLocal(globalNei) != own
555 nFacesPerCell[own]++;
568 cellCells.
setSize(nFacesPerCell);
578 const label own = agglom[faceOwner[facei]];
579 const label nei = agglom[faceNeighbour[facei]];
581 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.
toGlobal(nei);
582 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.
toGlobal(own);
588 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
590 label facei = pp.start();
595 const label own = agglom[faceOwner[facei]];
596 const label globalNei = globalNeighbour[bFacei];
600 !globalAgglom.
isLocal(globalNei)
601 || globalAgglom.
toLocal(globalNei) != own
604 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
618 if (cellCells.
size() == 0)
626 label startIndex = cellCells.
offsets()[0];
633 const label endIndex = cellCells.
offsets()[celli+1];
635 for (label i = startIndex; i < endIndex; ++i)
637 if (nbrCells.
insert(cellCells.
m()[i]))
639 cellCells.
m()[newIndex++] = cellCells.
m()[i];
642 startIndex = endIndex;
643 cellCells.
offsets()[celli+1] = newIndex;
669 const label nLocalCoarse,
699 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
701 label facei = pp.start();
706 globalNeighbour[bFacei] = globalAgglom.
toGlobal
708 agglom[faceOwner[facei]]
729 const label own = agglom[faceOwner[facei]];
730 const label nei = agglom[faceNeighbour[facei]];
732 nFacesPerCell[own]++;
733 nFacesPerCell[nei]++;
738 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
740 label facei = pp.start();
745 const label own = agglom[faceOwner[facei]];
746 const label globalNei = globalNeighbour[bFacei];
750 !globalAgglom.
isLocal(globalNei)
751 || globalAgglom.
toLocal(globalNei) != own
754 nFacesPerCell[own]++;
767 cellCells.
setSize(nFacesPerCell);
768 cellCellWeights.
setSize(nFacesPerCell);
779 const label own = agglom[faceOwner[facei]];
780 const label nei = agglom[faceNeighbour[facei]];
782 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
783 const label neiIndex = offsets[nei] + nFacesPerCell[nei]++;
785 m[ownIndex] = globalAgglom.
toGlobal(nei);
787 m[neiIndex] = globalAgglom.
toGlobal(own);
794 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
796 label facei = pp.start();
801 const label own = agglom[faceOwner[facei]];
802 const label globalNei = globalNeighbour[bFacei];
806 !globalAgglom.
isLocal(globalNei)
807 || globalAgglom.
toLocal(globalNei) != own
810 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
811 m[ownIndex] = globalNei;
826 if (cellCells.
size() == 0)
834 label startIndex = cellCells.
offsets()[0];
841 const label endIndex = cellCells.
offsets()[celli+1];
843 for (label i = startIndex; i < endIndex; ++i)
845 if (nbrCells.
insert(cellCells.
m()[i]))
847 cellCells.
m()[newIndex] = cellCells.
m()[i];
848 cellCellWeights.
m()[newIndex] = cellCellWeights.
m()[i];
852 startIndex = endIndex;
853 cellCells.
offsets()[celli+1] = newIndex;
854 cellCellWeights.
offsets()[celli+1] = newIndex;
858 cellCellWeights.
m().
setSize(newIndex);
887 if (hasWeights && cellWeights.size() !=
mesh.
nCells())
890 <<
"Number of weights " << cellWeights.size()
891 <<
" differs from number of cells " <<
mesh.
nCells()
896 const bool hasUnblocked =
899 (!blockedFace.empty() && !
BitOps::all(blockedFace)),
907 explicitConnections.size(),
914 for (
const labelList& procset : specifiedProcessorFaces)
916 nProcSets += procset.size();
923 if (!hasUnblocked && !nConnections && !nProcSets)
941 regionSplit localRegion(
mesh, blockedFace, explicitConnections,
false);
946 const label nUnblocked =
957 Info<<
"Constrained decomposition:" <<
nl
958 <<
" faces with same owner and neighbour processor : "
960 <<
" baffle faces with same owner processor : "
961 << nConnections <<
nl
962 <<
" faces all on same processor : "
983 forAll(localRegion, celli)
985 const label regioni = localRegion[celli];
987 regionWeights[regioni] += cellWeights[celli];
997 forAll(localRegion, celli)
999 const label regioni = localRegion[celli];
1001 regionWeights[regioni] += 1.0;
1024 for (
const labelPair& baffle : explicitConnections)
1026 const label f0 = baffle.first();
1027 const label f1 = baffle.second();
1029 if (!blockedFace[f0] && !blockedFace[f1])
1043 else if (blockedFace[f0] != blockedFace[f1])
1046 <<
"On explicit connection between faces " << f0
1048 <<
" the two blockedFace status are not equal : "
1049 << blockedFace[f0] <<
" and " << blockedFace[f1]
1072 label nUnblocked = 0;
1073 forAll(blockedFace, facei)
1075 if (blockedFace[facei])
1077 faceData[facei] =
minData(-123);
1090 forAll(blockedFace, facei)
1092 if (!blockedFace[facei])
1095 seedFaces[nUnblocked] = facei;
1096 seedData[nUnblocked] =
minData(finalDecomp[own]);
1114 forAll(finalDecomp, celli)
1116 if (cellData[celli].valid(deltaCalc.data()))
1118 finalDecomp[celli] = cellData[celli].data();
1137 forAll(specifiedProcessorFaces, seti)
1141 label proci = specifiedProcessor[seti];
1156 for (
const label facei :
set)
1159 for (
const label pointi :
f)
1162 for (
const label pFacei :
pFaces)
1187 const label facei = pp.start()+i;
1191 if (!blockedFace[facei])
1193 const label ownProc = finalDecomp[own];
1194 const label nbrProc = nbrDecomp[bFacei];
1196 if (ownProc != nbrProc)
1199 <<
"patch:" << pp.name()
1200 <<
" face:" << facei
1202 <<
" ownProc:" << ownProc
1203 <<
" nbrProc:" << nbrProc
1228 specifiedProcessorFaces.
clear();
1229 explicitConnections.
clear();
1233 decompConstraint.add
1237 specifiedProcessorFaces,
1257 decompConstraint.apply
1261 specifiedProcessorFaces,
1263 explicitConnections,
1286 specifiedProcessorFaces,
1300 specifiedProcessorFaces,
1312 specifiedProcessorFaces,
1314 explicitConnections,
const List< label > & offsets() const
Return the offset table (= size()+1)
int debug
Static debugging option.
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
List< label > labelList
A List of labels.
const List< T > & m() const
Return the packed matrix of data.
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.
Abstract class for handling decomposition constraints.
const dictionary & decompDict_
Top-level decomposition dictionary (eg, decomposeParDict)
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
For use with FaceCellWave. Transports minimum passive data.
A class for handling words, derived from Foam::string.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
static const dictionary & optionalRegionDict(const dictionary &decompDict, const word ®ionName)
static constexpr const zero Zero
Global zero (0)
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
A packed storage unstructured matrix of objects of type <T> using an offset table for access.
const labelListList & pointFaces() const
static const dictionary * cfindCoeffsDict(const dictionary &dict, const word &coeffsName, const bool allowDefault)
bool isLocal(const label i) const
Is on local processor.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Ostream & endl(Ostream &os)
Add newline and flush stream.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
void setConstraints(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Helper: extract constraints:
const fileName & name() const noexcept
The dictionary name.
Mesh consisting of general polyhedral cells.
bool all(const UList< bool > &bools)
True if all entries are 'true' or if the set is empty.
static autoPtr< decompositionConstraint > New(const dictionary &constraintDict)
Return a reference to the selected decompositionConstraint.
#define forAll(list, i)
Loop across all elements in list.
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
label nCells() const noexcept
Number of mesh cells.
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
void setSize(const label mRows)
Reset size of CompactListList.
messageStream Info
Information stream (stdout output on master, null elsewhere)
A patch is a list of labels that address the faces in the global face list.
void setSize(const label n)
Alias for resize()
virtual const labelList & faceOwner() const
Return face owner.
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
errorManip< error > abort(error &err)
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Wave propagation of information through grid. Every iteration information goes through one layer of c...
label toLocal(const label i) const
From global to local on current processor.
const vectorField & cellCentres() const
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
virtual const faceList & faces() const
Return raw faces.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual labelList decompose(const pointField &points, const scalarField &pointWeights) const
Return the wanted processor number for every coordinate.
static int & msgType() noexcept
Message tag of standard messages.
static const Vector< Cmpt > max
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
static label worldComm
Default communicator (all processors)
label nInternalFaces() const noexcept
Number of internal faces.
static bool & parRun() noexcept
Test if this a parallel run.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const vectorField & faceCentres() const
void clear()
Clear the list, i.e. set size to zero.
static autoPtr< decompositionMethod > New(const dictionary &decompDict, const word ®ionName="")
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
const polyBoundaryMesh & patches
label size() const noexcept
The primary size (the number of rows)
label nTotalCells() const noexcept
Return total number of cells in decomposed mesh.
static bool warnAboutAge(const int version) noexcept
Test if an age warning should be emitted.
label nDomains() const noexcept
Number of domains.
label nFaces() const noexcept
Number of mesh faces.
A face is a list of labels corresponding to mesh vertices.
const globalMeshData & globalData() const
Return parallel info.
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.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
defineTypeNameAndDebug(combustionModel, 0)
#define WarningInFunction
Report a warning using Foam::Warning.
label nLocalRegions() const
Return local number of regions.
static const dictionary & findCoeffsDict(const dictionary &dict, const word &coeffsName, int select=selectionType::DEFAULT)
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]
virtual const labelList & faceNeighbour() const
Return face neighbour.
PtrList< decompositionConstraint > constraints_
Optional constraints.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
label toGlobal(const label i) const
From local to global index.
const vectorField & faceAreas() const