54 word methodType(decompositionDict.
lookup(
"method"));
58 methodType =
"ptscotch";
62 Info<<
"Selecting decompositionMethod " << methodType <<
endl;
64 dictionaryConstructorTable::iterator cstrIter =
65 dictionaryConstructorTablePtr_->find(methodType);
67 if (cstrIter == dictionaryConstructorTablePtr_->end())
71 "decompositionMethod::New" 72 "(const dictionary& decompositionDict)" 73 ) <<
"Unknown decompositionMethod " 74 << methodType <<
nl <<
nl 75 <<
"Valid decompositionMethods are : " << endl
76 << dictionaryConstructorTablePtr_->sortedToc()
92 return decompose(mesh, points, weights);
128 forAll(fineDistribution, i)
130 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
133 return fineDistribution;
164 return decompose(globalCellCells, cc, cWeights);
172 const label nLocalCoarse,
203 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
210 globalNeighbour[bFaceI] = globalAgglom.
toGlobal 212 agglom[faceOwner[faceI]]
229 labelList nFacesPerCell(nLocalCoarse, 0);
233 label own = agglom[faceOwner[faceI]];
234 label nei = agglom[faceNeighbour[faceI]];
236 nFacesPerCell[own]++;
237 nFacesPerCell[nei]++;
244 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
251 label own = agglom[faceOwner[faceI]];
253 label globalNei = globalNeighbour[bFaceI];
256 !globalAgglom.
isLocal(globalNei)
257 || globalAgglom.
toLocal(globalNei) != own
260 nFacesPerCell[own]++;
273 cellCells.
setSize(nFacesPerCell);
283 label own = agglom[faceOwner[faceI]];
284 label nei = agglom[faceNeighbour[faceI]];
286 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.
toGlobal(nei);
287 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.
toGlobal(own);
295 if (pp.
coupled() && (parallel || !isA<processorPolyPatch>(pp)))
302 label own = agglom[faceOwner[faceI]];
304 label globalNei = globalNeighbour[bFaceI];
308 !globalAgglom.
isLocal(globalNei)
309 || globalAgglom.
toLocal(globalNei) != own
312 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
329 if (cellCells.
size() == 0)
343 for (
label i = startIndex; i < endIndex; i++)
345 if (nbrCells.
insert(cellCells.
m()[i]))
347 cellCells.
m()[newIndex++] = cellCells.
m()[i];
350 startIndex = endIndex;
351 cellCells.
offsets()[cellI+1] = newIndex;
769 if (nWeights > 0 && cellWeights.
size() != mesh.
nCells())
773 "decompositionMethod::decompose\n" 775 " const polyMesh&,\n" 776 " const scalarField&,\n" 777 " const boolList&,\n" 778 " const PtrList<labelList>&,\n" 779 " const labelList&,\n" 780 " const List<labelPair>&\n" 781 ) <<
"Number of weights " << cellWeights.
size()
782 <<
" differs from number of cells " << mesh.
nCells()
789 forAll(specifiedProcessorFaces, setI)
791 nProcSets += specifiedProcessorFaces[setI].
size();
798 explicitConnections.
size(),
803 label nUnblocked = 0;
804 forAll(blockedFace, faceI)
806 if (!blockedFace[faceI])
820 if (nProcSets+nConnections+nUnblocked == 0)
826 finalDecomp = decompose
842 Info<<
"Constrained decomposition:" <<
endl 843 <<
" faces with same owner and neighbour processor : " 844 << nUnblocked <<
endl 845 <<
" baffle faces with same owner processor : " 846 << nConnections <<
endl 847 <<
" faces all on same processor : " 852 regionSplit localRegion(mesh, blockedFace, explicitConnections,
false);
857 Info<<
"Constrained decomposition:" <<
endl 873 forAll(localRegion, cellI)
875 label regionI = localRegion[cellI];
879 regionCentres[regionI] = mesh.
cellCentres()[cellI];
890 forAll(localRegion, cellI)
892 label regionI = localRegion[cellI];
894 regionWeights[regionI] += cellWeights[cellI];
899 forAll(localRegion, cellI)
901 label regionI = localRegion[cellI];
903 regionWeights[regionI] += 1.0;
907 finalDecomp = decompose
919 forAll(explicitConnections, i)
921 const labelPair& baffle = explicitConnections[i];
925 if (!blockedFace[f0] && !blockedFace[f1])
939 else if (blockedFace[f0] != blockedFace[f1])
943 "labelList decompose\n" 945 " const polyMesh&,\n" 946 " const scalarField&,\n" 947 " const boolList&,\n" 948 " const PtrList<labelList>&,\n" 949 " const labelList&,\n" 950 " const List<labelPair>&\n" 952 ) <<
"On explicit connection between faces " << f0
954 <<
" the two blockedFace status are not equal : " 955 << blockedFace[f0] <<
" and " << blockedFace[
f1]
975 label nUnblocked = 0;
976 forAll(blockedFace, faceI)
978 if (blockedFace[faceI])
980 faceData[faceI] =
minData(-123);
993 forAll(blockedFace, faceI)
995 if (!blockedFace[faceI])
998 seedFaces[nUnblocked] = faceI;
999 seedData[nUnblocked] =
minData(finalDecomp[own]);
1017 forAll(finalDecomp, cellI)
1019 if (cellData[cellI].valid(deltaCalc.data()))
1021 finalDecomp[cellI] = cellData[cellI].
data();
1040 forAll(specifiedProcessorFaces, setI)
1042 const labelList&
set = specifiedProcessorFaces[setI];
1044 label procI = specifiedProcessor[setI];
1049 procI = finalDecomp[mesh.
faceOwner()[
set[0]]];
1060 label faceI = pFaces[i];
1062 finalDecomp[mesh.
faceOwner()[faceI]] = procI;
1090 if (!blockedFace[faceI])
1092 label ownProc = finalDecomp[own];
1093 label nbrProc = nbrDecomp[bFaceI];
1094 if (ownProc != nbrProc)
1097 <<
"patch:" << pp.
name()
1098 <<
" face:" << faceI
1100 <<
" ownProc:" << ownProc
1101 <<
" nbrProc:" << nbrProc
1128 specifiedProcessorFaces.
clear();
1129 explicitConnections.
clear();
1132 if (decompositionDict_.found(
"preservePatches"))
1134 wordList pNames(decompositionDict_.lookup(
"preservePatches"));
1137 <<
"Keeping owner of faces in patches " << pNames
1138 <<
" on same processor. This only makes sense for cyclics." <<
endl;
1148 FatalErrorIn(
"decompositionMethod::decompose(const polyMesh&)")
1149 <<
"Unknown preservePatch " << pNames[i]
1150 << endl <<
"Valid patches are " << patches.
names()
1158 if (blockedFace[pp.
start() + i])
1160 blockedFace[pp.
start() + i] =
false;
1166 if (decompositionDict_.found(
"preserveFaceZones"))
1168 wordList zNames(decompositionDict_.lookup(
"preserveFaceZones"));
1171 <<
"Keeping owner and neighbour of faces in zones " << zNames
1172 <<
" on same processor" <<
endl;
1182 FatalErrorIn(
"decompositionMethod::decompose(const polyMesh&)")
1183 <<
"Unknown preserveFaceZone " << zNames[i]
1184 << endl <<
"Valid faceZones are " << fZones.
names()
1188 const faceZone& fz = fZones[zoneI];
1192 if (blockedFace[fz[i]])
1194 blockedFace[fz[i]] =
false;
1201 bool preserveBaffles = decompositionDict_.lookupOrDefault
1206 if (preserveBaffles)
1209 <<
"Keeping owner of faces in baffles " 1210 <<
" on same processor." <<
endl;
1213 forAll(explicitConnections, i)
1215 blockedFace[explicitConnections[i].
first()] =
false;
1216 blockedFace[explicitConnections[i].second()] =
false;
1222 decompositionDict_.found(
"preservePatches")
1223 || decompositionDict_.found(
"preserveFaceZones")
1235 label nProcSets = 0;
1236 if (decompositionDict_.found(
"singleProcessorFaceSets"))
1240 decompositionDict_.lookup(
"singleProcessorFaceSets")
1243 specifiedProcessorFaces.
setSize(zNameAndProcs.size());
1244 specifiedProcessor.
setSize(zNameAndProcs.size());
1246 forAll(zNameAndProcs, setI)
1248 Info<<
"Keeping all cells connected to faceSet " 1249 << zNameAndProcs[setI].first()
1250 <<
" on processor " << zNameAndProcs[setI].second() <<
endl;
1253 faceSet fz(mesh, zNameAndProcs[setI].first());
1256 specifiedProcessor[setI] = zNameAndProcs[setI].second();
1257 nProcSets += fz.
size();
1265 forAll(specifiedProcessorFaces, setI)
1267 const labelList&
set = specifiedProcessorFaces[setI];
1273 procFacePoint[f[fp]] =
true;
1280 forAll(procFacePoint, pointI)
1282 if (procFacePoint[pointI])
1287 blockedFace[pFaces[i]] =
false;
1310 specifiedProcessorFaces,
1324 specifiedProcessorFaces,
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
static bool & parRun()
Is this a parallel run?
const faceZoneMesh & faceZones() const
Return face zone mesh.
bool isLocal(const label i) const
Is on local processor.
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
label size() const
Return the primary size, i.e. the number of rows.
label size() const
Return the number of elements in the PtrList.
bool set(const label) const
Is element set.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
An ordered pair of two objects of type <T> with first() and second() elements.
const word & name() const
Return name.
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.
virtual labelList decompose(const pointField &points, const scalarField &pointWeights)
Return for every coordinate the wanted processor number.
List< Key > sortedToc() const
Return the table of contents as a sorted list.
A subset of mesh faces organised as a primitive patch.
const Type & second() const
Return second.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
A class for handling words, derived from string.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
void size(const label)
Override size to be inconsistent with allocated storage.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const List< label > & offsets() const
Return the offset table (= size()+1)
const vectorField & cellCentres() const
void setConstraints(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections)
Helper: extract constraints:
A list of keyword definitions, which are a keyword followed by any number of values (e...
static void syncFaceList(const polyMesh &mesh, UList< T > &l, const CombineOp &cop)
Synchronize values on all mesh faces.
T & first()
Return the first element of the list.
T * data()
Return a pointer to the first data element,.
A patch is a list of labels that address the faces in the global face list.
void setSize(const label nRows)
Reset size of CompactListList.
static labelPairList findDuplicateFacePairs(const polyMesh &)
Helper routine to find all baffles (two boundary faces.
wordList names() const
Return a list of patch names.
A face is a list of labels corresponding to mesh vertices.
void clear()
Clear the list, i.e. set size to zero.
void setSize(const label)
Reset size of List.
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 clear()
Clear all entries from table.
const List< T > & m() const
Return the packed matrix of data.
label nLocalRegions() const
Return local number of regions.
label nTotalCells() const
Return total number of cells in decomposed mesh.
static int & msgType()
Message tag of standard messages.
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &l)
Swap coupled boundary face values.
label size() const
Return number of elements in table.
static autoPtr< decompositionMethod > New(const dictionary &decompositionDict)
Return a reference to the selected decomposition method.
const labelListList & pointFaces() const
virtual const labelList & faceOwner() const
Return face owner.
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
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 FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
A packed storage unstructured matrix of objects of type <T> using an offset table for access...
label start() const
Return start label of this patch in the polyMesh face list.
label nInternalFaces() const
Mesh consisting of general polyhedral cells.
label toGlobal(const label i) const
From local to global.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
For use with FaceCellWave. Transports minimum passive data.
label toLocal(const label i) const
From global to local on current processor.
List< label > labelList
A List of labels.
const Type & first() const
Return first.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
label findZoneID(const word &zoneName) const
Find zone index given a name.
static void swapBoundaryCellList(const polyMesh &mesh, const UList< T > &cellData, List< T > &neighbourCellData)
Swap to obtain neighbour cell values for all boundary faces.
virtual const faceList & faces() const
Return raw faces.
wordList names() const
Return a list of zone names.
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,&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.
label findPatchID(const word &patchName) const
Find patch index given a name.
static label worldComm
Default communicator (all processors)
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
const globalMeshData & globalData() const
Return parallel info.
defineTypeNameAndDebug(combustionModel, 0)
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
const vectorField & faceCentres() const
bool insert(const Key &key)
Insert a new entry.