60 const label localnWeights =
65 if (localnWeights && localnWeights !=
nWeights)
68 <<
"Number of weights on this processor " << localnWeights
69 <<
" does not equal the maximum number of weights " <<
nWeights
83 const label nWeights = this->nWeights(
points, pointWeights);
88 <<
"decompositionMethod " <<
type()
89 <<
" does not support multiple constraints"
104 nProcessors_(decompositionDict.lookup<
label>(
"numberOfSubdomains"))
109 if (decompositionDict.
found(
"constraints"))
126 constraintTypes_.
last()
142 const word methodType
146 {
"decomposer",
"method"}
150 Info<<
"Selecting decomposer " << methodType <<
endl;
156 decomposerConstructorTablePtr_
159 decomposerConstructorTable::iterator cstrIter =
160 decomposerConstructorTablePtr_->find(methodType);
162 if (cstrIter == decomposerConstructorTablePtr_->end())
165 <<
"Unknown decomposer "
166 << methodType <<
nl <<
nl
167 <<
"Valid decomposers are : " <<
endl
168 << decomposerConstructorTablePtr_->sortedToc()
195 const word methodType
197 distributionDict.lookupBackwardsCompatible<
word>
199 {
"distributor",
"method"}
203 Info<<
"Selecting distributor " << methodType <<
endl;
209 distributorConstructorTablePtr_
212 distributorConstructorTable::iterator cstrIter =
213 distributorConstructorTablePtr_->find(methodType);
215 if (cstrIter == distributorConstructorTablePtr_->end())
218 <<
"Unknown distributor "
219 << methodType <<
nl <<
nl
220 <<
"Valid distributors are : " <<
endl
221 << distributorConstructorTablePtr_->sortedToc()
232 distributionDict.subOrEmptyDict(methodType +
"Coeffs")
294 coarseCellCells.
list(),
303 forAll(fineDistribution, i)
305 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
308 return fineDistribution;
339 return decompose(globalCellCells, cellCentres, cellWeights);
347 const bool distributed
355 const scalar sumWeights
363 const scalar scale = INT32_MAX/(2*sumWeights);
371 intWeights[i] = ceil(scale*weights[i]);
413 sumIntWeights[i % nWeights] += intWeights[i];
422 boolList nonZeroWeights(nWeights,
false);
423 label nNonZeroWeights = 0;
426 if (sumIntWeights[i] != 0)
428 nonZeroWeights[i] =
true;
434 if (nNonZeroWeights != nWeights)
439 if (nonZeroWeights[i % nWeights])
441 intWeights[j++] = intWeights[i];
446 intWeights.
setSize(nNonZeroWeights*(intWeights.
size()/nWeights));
449 nWeights = nNonZeroWeights;
461 const label nLocalCoarse,
492 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
499 globalNeighbour[bFacei] = globalAgglom.
toGlobal
501 agglom[faceOwner[facei]]
518 labelList nFacesPerCell(nLocalCoarse, 0);
522 label own = agglom[faceOwner[facei]];
523 label nei = agglom[faceNeighbour[facei]];
525 nFacesPerCell[own]++;
526 nFacesPerCell[nei]++;
533 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
540 label own = agglom[faceOwner[facei]];
542 label globalNei = globalNeighbour[bFacei];
545 !globalAgglom.
isLocal(globalNei)
546 || globalAgglom.
toLocal(globalNei) != own
549 nFacesPerCell[own]++;
562 cellCells.
setSize(nFacesPerCell);
572 label own = agglom[faceOwner[facei]];
573 label nei = agglom[faceNeighbour[facei]];
575 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.
toGlobal(nei);
576 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.
toGlobal(own);
584 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
591 label own = agglom[faceOwner[facei]];
593 label globalNei = globalNeighbour[bFacei];
597 !globalAgglom.
isLocal(globalNei)
598 || globalAgglom.
toLocal(globalNei) != own
601 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
618 if (cellCells.
size() == 0)
632 for (
label i = startIndex; i < endIndex; i++)
634 if (nbrCells.
insert(cellCells.
m()[i]))
636 cellCells.
m()[newIndex++] = cellCells.
m()[i];
639 startIndex = endIndex;
640 cellCells.
offsets()[celli+1] = newIndex;
651 const label nLocalCoarse,
683 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
690 globalNeighbour[bFaceI] = globalAgglom.
toGlobal
692 agglom[faceOwner[faceI]]
709 labelList nFacesPerCell(nLocalCoarse, 0);
713 label own = agglom[faceOwner[faceI]];
714 label nei = agglom[faceNeighbour[faceI]];
716 nFacesPerCell[own]++;
717 nFacesPerCell[nei]++;
724 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
731 label own = agglom[faceOwner[faceI]];
733 label globalNei = globalNeighbour[bFaceI];
736 !globalAgglom.
isLocal(globalNei)
737 || globalAgglom.
toLocal(globalNei) != own
740 nFacesPerCell[own]++;
753 cellCells.
setSize(nFacesPerCell);
754 cellCellWeights.
setSize(nFacesPerCell);
765 label own = agglom[faceOwner[faceI]];
766 label nei = agglom[faceNeighbour[faceI]];
768 label ownIndex = offsets[own] + nFacesPerCell[own]++;
769 label neiIndex = offsets[nei] + nFacesPerCell[nei]++;
771 m[ownIndex] = globalAgglom.
toGlobal(nei);
773 m[neiIndex] = globalAgglom.
toGlobal(own);
782 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
789 label own = agglom[faceOwner[faceI]];
791 label globalNei = globalNeighbour[bFaceI];
795 !globalAgglom.
isLocal(globalNei)
796 || globalAgglom.
toLocal(globalNei) != own
799 label ownIndex = offsets[own] + nFacesPerCell[own]++;
800 m[ownIndex] = globalNei;
818 if (cellCells.
size() == 0)
832 for (
label i = startIndex; i < endIndex; i++)
834 if (nbrCells.
insert(cellCells.
m()[i]))
836 cellCells.
m()[newIndex] = cellCells.
m()[i];
837 cellCellWeights.
m()[newIndex] = cellCellWeights.
m()[i];
841 startIndex = endIndex;
842 cellCells.
offsets()[cellI+1] = newIndex;
843 cellCellWeights.
offsets()[cellI+1] = newIndex;
847 cellCellWeights.
setSize(cellCells.
size(), newIndex);
862 const bool hasWeights =
867 forAll(specifiedProcessorFaces, setI)
869 nProcSets += specifiedProcessorFaces[setI].
size();
876 explicitConnections.
size(),
881 label nUnblocked = 0;
882 forAll(blockedFace, facei)
884 if (!blockedFace[facei])
897 if (nProcSets+nConnections+nUnblocked == 0)
903 finalDecomp = decompose
919 Info<<
"Constrained decomposition:" <<
endl
920 <<
" faces with same owner and neighbour processor : "
921 << nUnblocked <<
endl
922 <<
" baffle faces with same owner processor : "
923 << nConnections <<
endl
924 <<
" faces all on same processor : "
929 regionSplit localRegion(
mesh, blockedFace, explicitConnections,
false);
934 Info<<
"Constrained decomposition:" <<
endl
950 forAll(localRegion, celli)
952 label regionI = localRegion[celli];
967 forAll(localRegion, celli)
969 const label regionI = localRegion[celli];
971 regionWeights[regionI] += cellWeights[celli];
976 forAll(localRegion, celli)
978 label regionI = localRegion[celli];
980 regionWeights[regionI] += 1.0;
984 finalDecomp = decompose
996 forAll(explicitConnections, i)
998 const labelPair& baffle = explicitConnections[i];
1002 if (!blockedFace[f0] && !blockedFace[f1])
1016 else if (blockedFace[f0] != blockedFace[f1])
1019 <<
"On explicit connection between faces " << f0
1021 <<
" the two blockedFace status are not equal : "
1022 << blockedFace[f0] <<
" and " << blockedFace[f1]
1042 label nUnblocked = 0;
1043 forAll(blockedFace, facei)
1045 if (blockedFace[facei])
1060 forAll(blockedFace, facei)
1062 if (!blockedFace[facei])
1065 seedFaces[nUnblocked] = facei;
1066 seedData[nUnblocked] =
minData(finalDecomp[own]);
1084 forAll(finalDecomp, celli)
1086 if (cellData[celli].
valid(deltaCalc.
data()))
1088 finalDecomp[celli] = cellData[celli].
data();
1107 forAll(specifiedProcessorFaces, setI)
1109 const labelList& set = specifiedProcessorFaces[setI];
1111 label proci = specifiedProcessor[setI];
1157 if (!blockedFace[facei])
1159 label ownProc = finalDecomp[own];
1160 label nbrProc = nbrDecomp[bFacei];
1161 if (ownProc != nbrProc)
1164 <<
"patch:" << pp.
name()
1165 <<
" face:" << facei
1167 <<
" ownProc:" << ownProc
1168 <<
" nbrProc:" << nbrProc
1194 specifiedProcessorFaces.
clear();
1195 explicitConnections.
clear();
1197 forAll(constraints_, constraintI)
1199 constraints_[constraintI].add
1203 specifiedProcessorFaces,
1221 forAll(constraints_, constraintI)
1223 constraints_[constraintI].apply
1227 specifiedProcessorFaces,
1229 explicitConnections,
1252 specifiedProcessorFaces,
1266 specifiedProcessorFaces,
1278 specifiedProcessorFaces,
1280 explicitConnections,
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
void setSize(const label mRows)
Reset size of CompactListList.
Wave propagation of information through grid. Every iteration information goes through one layer of c...
const TrackingData & data() const
Additional data to be passed into container.
bool insert(const Key &key)
Insert a new entry.
void clear()
Clear all entries from table.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
void append(const T &)
Append an element at the end of the list.
void size(const label)
Override size to be inconsistent with allocated storage.
void clear()
Clear the list, i.e. set size to zero.
void setSize(const label)
Reset size of List.
const Type & second() const
Return second.
const Type & first() const
Return first.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
void clear()
Clear the PtrList, i.e. set size to zero deleting all the.
static const word & system()
Return system name.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
List< Container > list() const
Convert to List<Container>
const UList< label > & offsets() const
Return the offset table (= size()+1)
const UList< T > & m() const
Return the packed matrix of data.
label size() const
Return the primary size, i.e. the number of rows.
T * data()
Return a pointer to the first data element,.
T & last()
Return the last element of the list.
static label worldComm
Default communicator (all processors)
static bool & parRun()
Is this a parallel run?
static int & msgType()
Message tag of standard messages.
label size() const
Return the number of elements in the UPtrList.
static autoPtr< decompositionConstraint > New(const dictionary &constraintsDict, const word &type)
Return a reference to the selected decompositionConstraint.
Abstract base class for decomposition.
decompositionMethod(const dictionary &decompositionDict)
Construct given the decomposition dictionary.
static IOdictionary decomposeParDict(const Time &time)
Read and return the decomposeParDict.
PtrList< decompositionConstraint > constraints_
Optional constraints.
label nWeights(const pointField &points, const scalarField &pointWeights) const
Return the number of weights per point.
virtual labelList decompose(const pointField &points, const scalarField &pointWeights)
Return for every coordinate the wanted processor number.
void setConstraints(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections)
Helper: extract constraints:
label checkWeights(const pointField &points, const scalarField &pointWeights) const
Check the weights against the points.
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.
static autoPtr< decompositionMethod > NewDistributor(const dictionary &decompositionDict)
Return a reference to the selected decomposition method.
static labelList scaleWeights(const scalarField &weights, label &nWeights, const bool distributed=true)
Convert the given scalar weights to labels.
void applyConstraints(const polyMesh &mesh, const boolList &blockedFace, const PtrList< labelList > &specifiedProcessorFaces, const labelList &specifiedProcessor, const List< labelPair > &explicitConnections, labelList &finalDecomp)
Helper: apply constraints to a decomposition. This gives.
static autoPtr< decompositionMethod > NewDecomposer(const dictionary &decompositionDict)
Return a reference to the selected decomposition method.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
const dictionary & subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary.
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
ITstream & lookupBackwardsCompatible(const wordList &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream, trying a list of keywords.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
bool open(const fileName &libName, const bool verbose=true)
Open the named library, optionally with warnings if problems occur.
Base class for classes which manage incomplete sets of face data.
A face is a list of labels corresponding to mesh vertices.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
label toGlobal(const label i) const
From local to global.
label toLocal(const label i) const
From global to local on current processor.
bool isLocal(const label i) const
Is on local processor.
label nTotalCells() const
Return total number of cells in decomposed mesh.
For use with FaceCellWave. Transports minimum passive data.
const word & name() const
Return name.
Mesh consisting of general polyhedral cells.
virtual const faceList & faces() const
Return raw faces.
virtual const labelList & faceOwner() const
Return face owner.
const globalMeshData & globalData() const
Return parallel info.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
virtual const labelList & faceNeighbour() const
Return face neighbour.
A patch is a list of labels that address the faces in the global face list.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
label start() const
Return start label of this patch in the polyMesh face list.
const vectorField & faceCentres() const
label nInternalFaces() const
const vectorField & cellCentres() const
const scalarField & magFaceAreas() const
const labelListList & pointFaces() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
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 class for handling words, derived from string.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const fvPatchList & patches
bool valid(const PtrList< ModelType > &l)
errorManipArg< error, int > exit(error &err, const int errNo=1)
dlLibraryTable libs
Table of loaded dynamic libraries.
Type gSum(const FieldField< Field, Type > &f)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
defineTypeNameAndDebug(combustionModel, 0)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("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]=cellShape(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, &mergedCyclicPolyPatch::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]
Operator to apply a binary operation to a pair of lists.