64 const word& coeffsName,
65 const bool allowDefault
69 if (!dictptr && allowDefault)
87 label nDomainsRegion = 0;
106 if (regionDict.
readIfPresent(
"numberOfSubdomains", nDomainsRegion))
108 if (nDomainsRegion >= 1 && nDomainsRegion <= nDomainsGlobal)
110 return nDomainsRegion;
115 <<
"] numberOfSubdomains: " << nDomainsRegion
116 <<
", using global: " << nDomainsGlobal <<
nl 121 return nDomainsGlobal;
127 const dictionary& decompDict,
131 const dictionary* dictptr =
nullptr;
135 && (dictptr = decompDict.findDict(
"regions")) !=
nullptr 146 bool Foam::decompositionMethod::constraintCompat(
const word& modelType)
const 148 bool usable = decompDict_.found(modelType);
154 for (
const auto& item : constraints_)
156 if (modelType == item.type())
166 <<
nl <<
" Using '" << modelType
167 <<
"' constraint specification." <<
nl;
172 <<
nl <<
" Ignoring '" << modelType
173 <<
"' constraint specification - was already specified." <<
nl;
183 void Foam::decompositionMethod::readConstraints()
185 constraints_.clear();
187 const dictionary* dictptr = decompDict_.findDict(
"constraints");
191 for (
const entry& dEntry : *dictptr)
193 if (!dEntry.isDict())
199 const dictionary&
dict = dEntry.dict();
209 if (constraintCompat(
"preserveBaffles"))
213 new decompositionConstraints::preserveBaffles()
217 if (constraintCompat(
"preservePatches"))
221 new decompositionConstraints::preservePatches
223 decompDict_.get<wordRes>(
"preservePatches")
228 if (constraintCompat(
"preserveFaceZones"))
232 new decompositionConstraints::preserveFaceZones
234 decompDict_.get<wordRes>(
"preserveFaceZones")
239 if (constraintCompat(
"singleProcessorFaceSets"))
243 new decompositionConstraints::singleProcessorFaceSets
245 decompDict_.lookup(
"singleProcessorFaceSets")
255 const dictionary&
dict,
256 const word& coeffsName,
260 const bool allowDefault = !(
select & selectionType::EXACT);
262 const dictionary* dictptr =
271 if (
select & selectionType::MANDATORY)
274 <<
"'" << coeffsName <<
"' dictionary not found in dictionary " 279 if (
select & selectionType::NULL_DICT)
290 const word& coeffsName,
294 const bool allowDefault = !(
select & selectionType::EXACT);
296 const dictionary* dictptr =
nullptr;
298 if (!decompRegionDict_.empty())
301 dictptr =
cfindCoeffsDict(decompRegionDict_, coeffsName, allowDefault);
315 if (
select & selectionType::MANDATORY)
318 <<
"'" << coeffsName <<
"' dictionary not found in dictionary " 319 << decompDict_.name() <<
endl 323 if (
select & selectionType::NULL_DICT)
334 Foam::decompositionMethod::decompositionMethod
340 decompDict_(decompDict),
364 auto* ctorPtr = dictionaryConstructorTable(methodType);
371 "decompositionMethod",
373 *dictionaryConstructorTablePtr_
379 Info<<
"Decomposition method " << methodType
380 <<
" [" << (nDomains(decompDict,
regionName)) <<
']';
395 const polyMesh&
mesh,
437 forAll(fineDistribution, i)
439 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
442 return fineDistribution;
448 const polyMesh&
mesh,
453 scalarField weights(coarsePoints.size(), scalar(1));
473 return decompose(globalCellCells, cc, weights);
481 const label nLocalCoarse,
504 if (
pp.coupled() && (parallel || !isA<processorPolyPatch>(
pp)))
506 label facei =
pp.start();
511 globalNeighbour[bFacei] = globalAgglom.toGlobal
513 agglom[faceOwner[facei]]
534 const label own = agglom[faceOwner[facei]];
535 const label nei = agglom[faceNeighbour[facei]];
537 nFacesPerCell[own]++;
538 nFacesPerCell[nei]++;
543 if (
pp.coupled() && (parallel || !isA<processorPolyPatch>(
pp)))
545 label facei =
pp.start();
550 const label own = agglom[faceOwner[facei]];
551 const label globalNei = globalNeighbour[bFacei];
555 !globalAgglom.isLocal(globalNei)
556 || globalAgglom.toLocal(globalNei) != own
559 nFacesPerCell[own]++;
572 cellCells.
setSize(nFacesPerCell);
582 const label own = agglom[faceOwner[facei]];
583 const label nei = agglom[faceNeighbour[facei]];
585 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.toGlobal(nei);
586 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.toGlobal(own);
592 if (
pp.coupled() && (parallel || !isA<processorPolyPatch>(
pp)))
594 label facei =
pp.start();
599 const label own = agglom[faceOwner[facei]];
600 const label globalNei = globalNeighbour[bFacei];
604 !globalAgglom.isLocal(globalNei)
605 || globalAgglom.toLocal(globalNei) != own
608 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
622 if (cellCells.
size() == 0)
630 label startIndex = cellCells.
offsets()[0];
635 nbrCells.insert(globalAgglom.toGlobal(celli));
637 const label endIndex = cellCells.
offsets()[celli+1];
639 for (label i = startIndex; i < endIndex; ++i)
641 if (nbrCells.insert(cellCells.
m()[i]))
643 cellCells.
m()[newIndex++] = cellCells.
m()[i];
646 startIndex = endIndex;
647 cellCells.
offsets()[celli+1] = newIndex;
673 const label nLocalCoarse,
697 if (
pp.coupled() && (parallel || !isA<processorPolyPatch>(
pp)))
699 label facei =
pp.start();
704 globalNeighbour[bFacei] = globalAgglom.
toGlobal 706 agglom[faceOwner[facei]]
727 const label own = agglom[faceOwner[facei]];
728 const label nei = agglom[faceNeighbour[facei]];
730 nFacesPerCell[own]++;
731 nFacesPerCell[nei]++;
736 if (
pp.coupled() && (parallel || !isA<processorPolyPatch>(
pp)))
738 label facei =
pp.start();
743 const label own = agglom[faceOwner[facei]];
744 const label globalNei = globalNeighbour[bFacei];
748 !globalAgglom.
isLocal(globalNei)
749 || globalAgglom.
toLocal(globalNei) != own
752 nFacesPerCell[own]++;
765 cellCells.
setSize(nFacesPerCell);
766 cellCellWeights.
setSize(nFacesPerCell);
777 const label own = agglom[faceOwner[facei]];
778 const label nei = agglom[faceNeighbour[facei]];
780 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
781 const label neiIndex = offsets[nei] + nFacesPerCell[nei]++;
783 m[ownIndex] = globalAgglom.
toGlobal(nei);
785 m[neiIndex] = globalAgglom.
toGlobal(own);
792 if (
pp.coupled() && (parallel || !isA<processorPolyPatch>(
pp)))
794 label facei =
pp.start();
799 const label own = agglom[faceOwner[facei]];
800 const label globalNei = globalNeighbour[bFacei];
804 !globalAgglom.
isLocal(globalNei)
805 || globalAgglom.
toLocal(globalNei) != own
808 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
809 m[ownIndex] = globalNei;
824 if (cellCells.
size() == 0)
832 label startIndex = cellCells.
offsets()[0];
837 nbrCells.insert(globalAgglom.
toGlobal(celli));
839 const label endIndex = cellCells.
offsets()[celli+1];
841 for (label i = startIndex; i < endIndex; ++i)
843 if (nbrCells.insert(cellCells.
m()[i]))
845 cellCells.
m()[newIndex] = cellCells.
m()[i];
846 cellCellWeights.
m()[newIndex] = cellCellWeights.
m()[i];
850 startIndex = endIndex;
851 cellCells.
offsets()[celli+1] = newIndex;
852 cellCellWeights.
offsets()[celli+1] = newIndex;
856 cellCellWeights.
m().
setSize(newIndex);
888 <<
"Number of weights " << cellWeights.
size()
889 <<
" differs from number of cells " <<
mesh.
nCells()
894 const bool hasUnblocked =
904 explicitConnections.
size(),
911 for (
const labelList& procset : specifiedProcessorFaces)
913 nProcSets += procset.size();
920 if (!hasUnblocked && !nConnections && !nProcSets)
938 regionSplit localRegion(
mesh, blockedFace, explicitConnections,
false);
943 const label nUnblocked =
954 Info<<
"Constrained decomposition:" <<
nl 955 <<
" faces with same owner and neighbour processor : " 957 <<
" baffle faces with same owner processor : " 958 << nConnections <<
nl 959 <<
" faces all on same processor : " 980 forAll(localRegion, celli)
982 const label regioni = localRegion[celli];
984 regionWeights[regioni] += cellWeights[celli];
994 forAll(localRegion, celli)
996 const label regioni = localRegion[celli];
998 regionWeights[regioni] += 1.0;
1021 for (
const labelPair& baffle : explicitConnections)
1023 const label f0 = baffle.first();
1024 const label f1 = baffle.second();
1026 if (!blockedFace[f0] && !blockedFace[f1])
1040 else if (blockedFace[f0] != blockedFace[f1])
1043 <<
"On explicit connection between faces " << f0
1045 <<
" the two blockedFace status are not equal : " 1046 << blockedFace[f0] <<
" and " << blockedFace[f1]
1069 label nUnblocked = 0;
1070 forAll(blockedFace, facei)
1072 if (blockedFace[facei])
1074 faceData[facei] =
minData(-123);
1087 forAll(blockedFace, facei)
1089 if (!blockedFace[facei])
1092 seedFaces[nUnblocked] = facei;
1093 seedData[nUnblocked] =
minData(finalDecomp[own]);
1111 forAll(finalDecomp, celli)
1113 if (cellData[celli].valid(deltaCalc.data()))
1115 finalDecomp[celli] = cellData[celli].
data();
1134 forAll(specifiedProcessorFaces, seti)
1136 const labelList&
set = specifiedProcessorFaces[seti];
1138 label proci = specifiedProcessor[seti];
1153 for (
const label facei :
set)
1156 for (
const label pointi :
f)
1159 for (
const label pFacei :
pFaces)
1184 const label facei =
pp.start()+i;
1188 if (!blockedFace[facei])
1190 const label ownProc = finalDecomp[own];
1191 const label nbrProc = nbrDecomp[bFacei];
1193 if (ownProc != nbrProc)
1196 <<
"patch:" <<
pp.name()
1197 <<
" face:" << facei
1199 <<
" ownProc:" << ownProc
1200 <<
" nbrProc:" << nbrProc
1225 specifiedProcessorFaces.
clear();
1226 explicitConnections.
clear();
1230 decompConstraint.add
1234 specifiedProcessorFaces,
1254 decompConstraint.apply
1258 specifiedProcessorFaces,
1260 explicitConnections,
1283 specifiedProcessorFaces,
1297 specifiedProcessorFaces,
1309 specifiedProcessorFaces,
1311 explicitConnections,
List< scalar > scalarList
List of scalar.
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 List 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
Communicator for all ranks. May differ from commGlobal() 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.
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect...
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...
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
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.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
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)
Reading is optional [identical to READ_IF_PRESENT].
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.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
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)