65 const word& coeffsName,
66 const bool allowDefault
70 if (!dictptr && allowDefault)
72 dictptr =
dict.findDict(
"coeffs");
88 label nDomainsRegion = 0;
94 decompDict.readEntry<label>
107 if (regionDict.readIfPresent(
"numberOfSubdomains", nDomainsRegion))
109 if (nDomainsRegion >= 1 && nDomainsRegion <= nDomainsGlobal)
111 return nDomainsRegion;
116 <<
"] numberOfSubdomains: " << nDomainsRegion
117 <<
", using global: " << nDomainsGlobal <<
nl
122 return nDomainsGlobal;
136 && (dictptr = decompDict.findDict(
"regions")) !=
nullptr
147bool Foam::decompositionMethod::constraintCompat(
const word& modelType)
const
149 bool usable = decompDict_.found(modelType);
155 for (
const auto& item : constraints_)
157 if (modelType == item.type())
167 <<
nl <<
" Using '" << modelType
168 <<
"' constraint specification." <<
nl;
173 <<
nl <<
" Ignoring '" << modelType
174 <<
"' constraint specification - was already specified." <<
nl;
184void Foam::decompositionMethod::readConstraints()
186 constraints_.clear();
192 for (
const entry& dEntry : *dictptr)
194 if (!dEntry.isDict())
210 if (constraintCompat(
"preserveBaffles"))
218 if (constraintCompat(
"preservePatches"))
224 decompDict_.get<
wordRes>(
"preservePatches")
229 if (constraintCompat(
"preserveFaceZones"))
235 decompDict_.get<
wordRes>(
"preserveFaceZones")
240 if (constraintCompat(
"singleProcessorFaceSets"))
246 decompDict_.lookup(
"singleProcessorFaceSets")
257 const word& coeffsName,
261 const bool allowDefault = !(select & selectionType::EXACT);
272 if (select & selectionType::MANDATORY)
275 <<
"'" << coeffsName <<
"' dictionary not found in dictionary "
280 if (select & selectionType::NULL_DICT)
291 const word& coeffsName,
295 const bool allowDefault = !(select & selectionType::EXACT);
316 if (select & selectionType::MANDATORY)
319 <<
"'" << coeffsName <<
"' dictionary not found in dictionary "
320 << decompDict_.name() <<
endl
324 if (select & selectionType::NULL_DICT)
349 decompDict_(decompDict),
373 auto* ctorPtr = dictionaryConstructorTable(methodType);
380 "decompositionMethod",
382 *dictionaryConstructorTablePtr_
388 Info<<
"Decomposition method " << methodType
389 <<
" [" << (nDomains(decompDict,
regionName)) <<
']';
404 const polyMesh&
mesh,
410 CompactListList<label> coarseCellCells;
440 const label nLocalCoarse,
460 const label nLocalCoarse,
503 if (hasWeights && (cellWeights.
size() !=
mesh.nCells()))
506 <<
"Number of weights (" << cellWeights.
size()
507 <<
") != number of cells (" <<
mesh.nCells() <<
")"
512 const bool hasUnblocked =
515 !blockedFace.
empty() && !blockedFace.
all()
522 explicitConnections.
size(),
529 for (
const labelList& procset : specifiedProcessorFaces)
531 nProcSets += procset.size();
538 if (!hasUnblocked && !nConnections && !nProcSets)
556 regionSplit localRegion(
mesh, blockedFace, explicitConnections,
false);
561 const label nUnblocked =
572 Info<<
"Constrained decomposition:" <<
nl
573 <<
" faces with same owner and neighbour processor : "
575 <<
" baffle faces with same owner processor : "
576 << nConnections <<
nl
577 <<
" faces all on same processor : "
579 <<
" split into " << localRegion.nLocalRegions()
592 scalarField regionWeights(localRegion.nLocalRegions(), Foam::zero{});
598 forAll(localRegion, celli)
600 const label regioni = localRegion[celli];
602 regionWeights[regioni] += cellWeights[celli];
612 forAll(localRegion, celli)
614 const label regioni = localRegion[celli];
616 regionWeights[regioni] += 1.0;
639 for (
const labelPair& baffle : explicitConnections)
641 const label f0 = baffle.first();
642 const label f1 = baffle.second();
644 if (!blockedFace[f0] && !blockedFace[f1])
658 else if (blockedFace[f0] != blockedFace[f1])
661 <<
"On explicit connection between faces " << f0
663 <<
" the two blockedFace status are not equal : "
664 << blockedFace[f0] <<
" and " << blockedFace[f1]
687 label nUnblocked = 0;
688 forAll(blockedFace, facei)
690 if (blockedFace[facei])
692 faceData[facei] =
minData(-123);
705 forAll(blockedFace, facei)
707 if (!blockedFace[facei])
710 seedFaces[nUnblocked] = facei;
711 seedData[nUnblocked] =
minData(finalDecomp[own]);
729 forAll(finalDecomp, celli)
731 if (cellData[celli].valid(deltaCalc.data()))
733 finalDecomp[celli] = cellData[celli].data();
752 forAll(specifiedProcessorFaces, seti)
756 label proci = specifiedProcessor[seti];
771 for (
const label facei : set)
774 for (
const label pointi :
f)
777 for (
const label pFacei :
pFaces)
802 const label facei =
pp.start()+i;
806 if (!blockedFace[facei])
808 const label ownProc = finalDecomp[own];
809 const label nbrProc = nbrDecomp[bFacei];
811 if (ownProc != nbrProc)
814 <<
"patch:" <<
pp.name()
817 <<
" ownProc:" << ownProc
818 <<
" nbrProc:" << nbrProc
843 specifiedProcessorFaces.
clear();
844 explicitConnections.
clear();
852 specifiedProcessorFaces,
872 decompConstraint.apply
876 specifiedProcessorFaces,
901 specifiedProcessorFaces,
915 specifiedProcessorFaces,
927 specifiedProcessorFaces,
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A packed storage of objects of type <T> using an offset table for access.
Wave propagation of information through grid. Every iteration information goes through one layer of c...
const TrackingData & data() const noexcept
Additional data to be passed into container.
@ MUST_READ
Reading required.
@ LAZY_READ
Reading is optional [identical to READ_IF_PRESENT].
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
void clear()
Clear the list, i.e. set size to zero.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
bool all() const
True if all entries are 'true' or if the list is empty.
T * data() noexcept
Return pointer to the underlying array serving as data storage.
void size(const label n)
Older name for setAddressableSize.
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
static bool & parRun() noexcept
Test if this a parallel run.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Abstract class for handling decomposition constraints.
static autoPtr< decompositionConstraint > New(const dictionary &constraintDict)
Return a reference to the selected decompositionConstraint.
Detects baffles and keeps owner and neighbour on same processor.
Constraint to keep/move owner and neighbour of faceZone onto same processor.
Constraint to keep owner and neighbour of (cyclic) patch on same processor.
Constraint to keep all cells connected to face or point of faceSet on a single processor.
Abstract base class for domain decomposition.
@ EXACT
No fallback to "coeffs" if main name not found.
@ MANDATORY
Fatal if dictionary could not be found.
const dictionary & decompRegionDict_
Region-specific decomposition dictionary information.
label nDomains_
Number of domains for the decomposition.
PtrList< decompositionConstraint > constraints_
Optional constraints.
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.
const dictionary & decompDict_
Top-level decomposition dictionary (eg, decomposeParDict).
static label nDomains(const dictionary &decompDict, const word ®ionName="")
Return region-specific or top-level numberOfSubdomains entry.
void setConstraints(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Helper: extract constraints:
decompositionMethod(const label numDomains)
Construct with specified number of domains, no coefficients or constraints.
static autoPtr< decompositionMethod > New(const dictionary &decompDict, const word ®ionName="")
Return a reference to the selected decomposition method, optionally region-specific.
virtual labelList decompose(const pointField &points, const scalarField &pointWeights=scalarField::null()) const
Return the wanted processor number for every coordinate, using uniform or specified point weights.
static FOAM_NO_DANGLING_REFERENCE 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.
static void calcCellCells(const polyMesh &mesh, const labelList &agglom, const label nLocalCoarse, const bool parallel, CompactListList< label > &cellCells)
Determine (local or global) cellCells from mesh agglomeration.
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...
label nDomains() const noexcept
Number of domains.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
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.
const fileName & name() const noexcept
The dictionary name.
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...
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,...
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...
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
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...
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
A keyword and a list of tokens is an 'entry'.
static bool warnAboutAge(const int version) noexcept
Test if an age warning should be emitted.
A face is a list of labels corresponding to mesh vertices.
static void calcCellCells(const polyMesh &mesh, const labelUList &agglom, const label nLocalCoarse, const bool parallel, CompactListList< label > &cellCells)
Determine (local or global) cellCells from mesh agglomeration.
label nTotalCells() const noexcept
Total global number of mesh cells.
@ REGEX
Regular expression.
virtual labelList decompose(const polyMesh &mesh, const pointField &points=pointField::null(), const scalarField &pointWeights=scalarField::null()) const
Return for every coordinate the wanted processor number.
For use with FaceCellWave. Transports minimum passive data.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
Mesh consisting of general polyhedral cells.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
virtual const faceList & faces() const
Return raw faces.
virtual const labelList & faceOwner() const
Return face owner.
const globalMeshData & globalData() const
Return parallel info (demand-driven).
virtual const labelList & faceNeighbour() const
Return face neighbour.
A patch is a list of labels that address the faces in the global face list.
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
const vectorField & faceCentres() const
label nInternalFaces() const noexcept
Number of internal faces.
const vectorField & cellCentres() const
label nCells() const noexcept
Number of mesh cells.
label nFaces() const noexcept
Number of mesh faces.
const labelListList & pointFaces() const
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
label nLocalRegions() const
Return local number of regions.
A List of wordRe with additional matching capabilities.
A class for handling words, derived from Foam::string.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
void set(List< bool > &bools, const labelUList &locations)
Set the listed locations (assign 'true').
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Namespace for handling debugging switches.
Pair< label > labelPair
A pair of labels.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
static const dictionary * cfindCoeffsDict(const dictionary &dict, const word &coeffsName, const bool allowDefault)
List< label > labelList
A List of labels.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
errorManip< error > abort(error &err)
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
List< bool > boolList
A List of bools.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
messageStream Warning
Warning stream (stdout output on master, null elsewhere), with additional 'FOAM Warning' header text.
constexpr char nl
The newline '\n' character (0x0a).
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];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } 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};constexpr 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< DynamicList< face > > pFaces[nBCs]
#define defineRunTimeSelectionTable(baseType, argNames)
Define run-time selection table.
#define forAll(list, i)
Loop across all elements in list.