27 #include "surfaceInterpolate.H"
39 namespace fvMeshTopoChangers
49 Foam::label Foam::fvMeshTopoChangers::refiner::count
51 const PackedBoolList& l,
52 const unsigned int val
75 void Foam::fvMeshTopoChangers::refiner::calcProtectedCells
77 PackedBoolList& protectedCells
83 const labelList& cellLevel = meshCutter_.cellLevel();
84 const labelList& pointLevel = meshCutter_.pointLevel();
95 const label celli = pCells[pci];
96 if (pointLevel[pointi] < cellLevel[celli])
98 cellNParentAnchors[celli] ++;
100 if (pointLevel[pointi] <= cellLevel[celli])
102 cellNAnchors[celli] ++;
112 protectedCells[celli] =
113 (cellNAnchors[celli] != 8)
114 || (cellLevel[celli] > 0 && cellNParentAnchors[celli] != 1)
115 || (cellLevel[celli] == 0 && cellNParentAnchors[celli] != 0);
120 for (
label facei = 0; facei < nInternalFaces; facei ++)
124 for (
label facei = nInternalFaces; facei < nFaces; facei ++)
136 max(cellLevel[
mesh()().faceOwner()[facei]], neiLevel[facei]);
140 if (pointLevel[
f[fpi]] < fLevel)
142 faceNParentAnchors[facei] ++;
144 if (pointLevel[
f[fpi]] <= fLevel)
146 faceNAnchors[facei] ++;
158 boolList faceProtected(nFaces,
false);
162 max(cellLevel[
mesh().faceOwner()[facei]], neiLevel[facei]);
164 faceProtected[facei] =
165 (faceNAnchors[facei] != 4)
166 || (fLevel > 0 && faceNParentAnchors[facei] > 1)
167 || (fLevel == 0 && faceNParentAnchors[facei] != 0);
180 max(cellLevel[
mesh().faceOwner()[facei]], neiLevel[facei]);
185 pointLevel[
f[fpi]] > fLevel
186 && pointLevel[
f[fpi]] == pointLevel[
f[
f.fcIndex(fpi)]]
189 faceProtected[facei] =
true;
197 for (
label facei = 0; facei < nFaces; facei ++)
200 protectedCells[own] = protectedCells[own] || faceProtected[facei];
201 if (facei < nInternalFaces)
204 protectedCells[nei] = protectedCells[nei] || faceProtected[facei];
210 void Foam::fvMeshTopoChangers::refiner::calcAdditionallyProtectedCells
212 const PackedBoolList& protectedCells,
213 PackedBoolList& additionallyProtectedCells
216 if (protectedCells_.empty())
218 additionallyProtectedCells.clear();
222 const labelList& cellLevel = meshCutter_.cellLevel();
224 additionallyProtectedCells = protectedCells_;
250 const bool ownProtected = additionallyProtectedCells.get(own);
252 const bool neiProtected = additionallyProtectedCells.get(nei);
254 if (ownProtected && (cellLevel[nei] > cellLevel[own]))
256 seedFace[facei] =
true;
258 else if (neiProtected && (cellLevel[own] > cellLevel[nei]))
260 seedFace[facei] =
true;
272 const bool ownProtected = additionallyProtectedCells.get(own);
277 && (neiLevel[facei-
mesh().nInternalFaces()] > cellLevel[own])
280 seedFace[facei] =
true;
288 bool hasExtended =
false;
295 if (additionallyProtectedCells.get(own) == 0)
297 additionallyProtectedCells.set(own, 1);
302 if (additionallyProtectedCells.get(nei) == 0)
304 additionallyProtectedCells.set(nei, 1);
321 if (additionallyProtectedCells.get(own) == 0)
323 additionallyProtectedCells.set(own, 1);
337 void Foam::fvMeshTopoChangers::refiner::readDict()
339 refineInterval_ = dict_.lookup<
label>(
"refineInterval");
341 if (refineInterval_ < 0)
344 <<
"Illegal refineInterval " << refineInterval_ <<
nl
345 <<
"The refineInterval setting in the dynamicMeshDict should"
350 maxCells_ = dict_.lookup<
label>(
"maxCells");
355 <<
"Illegal maximum number of cells " << maxCells_ <<
nl
356 <<
"The maxCells setting in the dynamicMeshDict should"
361 nBufferLayers_ = dict_.lookup<
label>(
"nBufferLayers");
363 if (dict_.found(
"correctFluxes"))
367 dict_.lookup(
"correctFluxes")
371 correctFluxes_.resize(fluxVelocities.size());
374 correctFluxes_.insert(fluxVelocities[i][0], fluxVelocities[i][1]);
378 dumpLevel_ = Switch(dict_.lookup(
"dumpLevel"));
383 Foam::fvMeshTopoChangers::refiner::refine
391 polyTopoChange meshMod(
mesh());
394 meshCutter_.setRefinement(cellsToRefine, meshMod);
398 autoPtr<polyTopoChangeMap> map = meshMod.changeMesh(
mesh());
400 Info<<
"Refined from "
409 const label oldFacei = map().faceMap()[facei];
411 if (oldFacei >=
mesh().nInternalFaces())
414 <<
"New internal face:" << facei
416 <<
" originates from boundary oldFace:" << oldFacei
429 const labelList& reverseFaceMap = map().reverseFaceMap();
442 const label masterFacei = reverseFaceMap[oldFacei];
447 <<
"Problem: should not have removed faces"
451 else if (masterFacei != facei)
453 masterFaces.insert(masterFacei);
459 Pout<<
"Found " << masterFaces.size() <<
" split faces " <<
endl;
462 refineFluxes(masterFaces, map());
463 refineUfs(masterFaces, map());
467 if (protectedCells_.size())
469 PackedBoolList newProtectedCell(
mesh().nCells());
471 forAll(newProtectedCell, celli)
473 const label oldCelli = map().cellMap()[celli];
474 newProtectedCell.set(celli, protectedCells_.get(oldCelli));
476 protectedCells_.transfer(newProtectedCell);
480 meshCutter_.checkRefinementLevels(-1,
labelList(0));
487 Foam::fvMeshTopoChangers::refiner::unrefine
495 polyTopoChange meshMod(
mesh());
498 meshCutter_.setUnrefinement(splitPoints, meshMod);
507 Map<label> faceToSplitPoint(3*splitPoints.size());
512 const label pointi = splitPoints[i];
517 const label otherPointi =
518 mesh().
edges()[pEdges[j]].otherVertex(pointi);
524 faceToSplitPoint.insert(
pFaces[pFacei], otherPointi);
532 autoPtr<polyTopoChangeMap> map = meshMod.changeMesh(
mesh());
534 Info<<
"Unrefined from "
543 unrefineFluxes(faceToSplitPoint, map());
546 unrefineUfs(faceToSplitPoint, map());
549 if (protectedCells_.size())
551 PackedBoolList newProtectedCell(
mesh().nCells());
553 forAll(newProtectedCell, celli)
555 const label oldCelli = map().cellMap()[celli];
558 newProtectedCell.set(celli, protectedCells_.get(oldCelli));
561 protectedCells_.transfer(newProtectedCell);
565 meshCutter_.checkRefinementLevels(-1,
labelList(0));
571 Foam::word Foam::fvMeshTopoChangers::refiner::Uname
576 const word UfName(Uf.member());
582 ? word(UfName(UfName.size() - 1))
583 : UfName.compare(UfName.size() - 3, 3,
"f_0") == 0
584 ? word(UfName(UfName.size() - 3) +
"_0")
591 void Foam::fvMeshTopoChangers::refiner::refineFluxes
594 const polyTopoChangeMap& map
597 if (correctFluxes_.size())
599 UPtrList<surfaceScalarField> fluxes
601 mesh().fields<surfaceScalarField>()
608 if (!correctFluxes_.found(
flux.name()))
611 <<
"Cannot find surfaceScalarField " <<
flux.name()
612 <<
" in user-provided flux mapping table "
613 << correctFluxes_ <<
endl
614 <<
" The flux mapping table is used to recreate the"
615 <<
" flux on newly created faces." <<
endl
616 <<
" Either add the entry if it is a flux or use ("
617 <<
flux.name() <<
" none) to suppress this warning."
622 const word& method = correctFluxes_[
flux.name()];
624 if (method ==
"none")
626 else if (method ==
"NaN")
628 Pout<<
"Setting surfaceScalarField " <<
flux.name()
629 <<
" to NaN" <<
endl;
636 <<
"Unknown refinement method " << method
637 <<
" for surfaceScalarField " <<
flux.name()
638 <<
" in user-provided flux mapping table "
648 void Foam::fvMeshTopoChangers::refiner::unrefineFluxes
650 const Map<label>& faceToSplitPoint,
651 const polyTopoChangeMap& map
654 if (correctFluxes_.size())
656 UPtrList<surfaceScalarField> fluxes
658 mesh().fields<surfaceScalarField>()
665 if (!correctFluxes_.found(
flux.name()))
668 <<
"Cannot find surfaceScalarField " <<
flux.name()
669 <<
" in user-provided flux mapping table "
670 << correctFluxes_ <<
endl
671 <<
" The flux mapping table is used to recreate the"
672 <<
" flux on newly created faces." <<
endl
673 <<
" Either add the entry if it is a flux or use ("
674 <<
flux.name() <<
" none) to suppress this warning."
679 const word& method = correctFluxes_[
flux.name()];
681 if (method !=
"none")
684 <<
"Unknown unrefinement method " << method
685 <<
" for surfaceScalarField " <<
flux.name()
686 <<
" in user-provided flux mapping table "
696 void Foam::fvMeshTopoChangers::refiner::refineUfs
699 const polyTopoChangeMap& map
703 const labelList& reverseFaceMap = map.reverseFaceMap();
706 UPtrList<surfaceVectorField> Ufs(
mesh().fields<surfaceVectorField>());
712 const word Uname(this->Uname(Uf));
729 Uf[facei] = UfU[facei];
731 else if (reverseFaceMap[oldFacei] != facei)
734 Uf[facei] = UfU[facei];
744 UfU.boundaryField()[
patchi];
746 label facei = patchUf.patch().start();
755 patchUf[i] = patchUfU[i];
757 else if (reverseFaceMap[oldFacei] != facei)
760 patchUf[i] = patchUfU[i];
770 label facei = iter.key();
772 if (
mesh().isInternalFace(facei))
774 Uf[facei] = UfU[facei];
784 UfU.boundaryField()[
patchi];
788 patchUf[i] = patchUfU[i];
796 void Foam::fvMeshTopoChangers::refiner::unrefineUfs
798 const Map<label>& faceToSplitPoint,
799 const polyTopoChangeMap& map
802 const labelList& reversePointMap = map.reversePointMap();
803 const labelList& reverseFaceMap = map.reverseFaceMap();
806 UPtrList<surfaceVectorField> Ufs(
mesh().fields<surfaceVectorField>());
812 const word Uname(this->Uname(Uf));
825 const label oldFacei = iter.key();
826 const label oldPointi = iter();
828 if (reversePointMap[oldPointi] < 0)
831 const label facei = reverseFaceMap[oldFacei];
835 if (
mesh().isInternalFace(facei))
837 Uf[facei] = UfU[facei];
857 const Foam::cellZone& Foam::fvMeshTopoChangers::refiner::findCellZone
859 const word& cellZoneName
864 bool cellZoneFound = (cellZoneID != -1);
865 reduce(cellZoneFound, orOp<bool>());
870 <<
"cannot find cellZone " << cellZoneName
879 Foam::fvMeshTopoChangers::refiner::cellToPoint(
const scalarField& vFld)
const
890 sum += vFld[pCells[i]];
892 pFld[pointi] =
sum/pCells.size();
902 const scalar minLevel,
903 const scalar maxLevel
910 scalar err =
min(
fld[celli] - minLevel, maxLevel -
fld[celli]);
926 const scalar minLevel,
927 const scalar maxLevel
936 scalar err =
min(
fld[celli] - minLevel, maxLevel -
fld[celli]);
948 void Foam::fvMeshTopoChangers::refiner::selectRefineCandidates
950 PackedBoolList& candidateCells,
951 const scalar lowerRefineLevel,
952 const scalar upperRefineLevel,
953 const scalar maxRefinement,
961 error(vFld, lowerRefineLevel, upperRefineLevel)
967 if (cellError[celli] > 0)
969 candidateCells.set(celli, 1);
975 void Foam::fvMeshTopoChangers::refiner::selectRefineCandidates
977 PackedBoolList& candidateCells,
978 const scalar lowerRefineLevel,
979 const scalar upperRefineLevel,
980 const scalar maxRefinement,
989 error(vFld,
cells, lowerRefineLevel, upperRefineLevel)
995 if (cellError[celli] > 0)
997 candidateCells.set(celli, 1);
1003 Foam::scalar Foam::fvMeshTopoChangers::refiner::selectRefineCandidates
1005 PackedBoolList& candidateCells,
1006 const dictionary& refineDict
1009 const word fieldName(refineDict.lookup(
"field"));
1013 const scalar lowerRefineLevel =
1014 refineDict.lookup<scalar>(
"lowerRefineLevel");
1015 const scalar upperRefineLevel =
1016 refineDict.lookup<scalar>(
"upperRefineLevel");
1018 const label maxRefinement = refineDict.lookup<
label>(
"maxRefinement");
1020 if (maxRefinement <= 0)
1023 <<
"Illegal maximum refinement level " << maxRefinement <<
nl
1024 <<
"The maxCells setting in the dynamicMeshDict should"
1029 if (refineDict.found(
"cellZone"))
1032 selectRefineCandidates
1039 findCellZone(refineDict.lookup(
"cellZone"))
1045 selectRefineCandidates
1055 return maxRefinement;
1061 const label maxCells,
1062 const label maxRefinement,
1063 const PackedBoolList& candidateCells
1069 const labelList& cellLevel = meshCutter_.cellLevel();
1073 PackedBoolList additionallyProtectedCells;
1074 calcAdditionallyProtectedCells(protectedCells_, additionallyProtectedCells);
1077 const label nLocalCandidates =
count(candidateCells, 1);
1081 DynamicList<label> candidates(nLocalCandidates);
1083 if (nCandidates < nTotToRefine)
1085 forAll(candidateCells, celli)
1089 candidateCells.get(celli)
1091 additionallyProtectedCells.empty()
1092 || !additionallyProtectedCells.get(celli)
1096 candidates.append(celli);
1103 for (
label level = 0; level < maxRefinement; level++)
1105 forAll(candidateCells, celli)
1109 cellLevel[celli] == level
1110 && candidateCells.get(celli)
1112 additionallyProtectedCells.empty()
1113 || !additionallyProtectedCells.get(celli)
1117 candidates.append(celli);
1121 if (
returnReduce(candidates.size(), sumOp<label>()) > nTotToRefine)
1131 meshCutter_.consistentRefinement
1133 candidates.shrink(),
1142 return consistentSet;
1146 Foam::labelList Foam::fvMeshTopoChangers::refiner::selectUnrefinePoints
1148 const PackedBoolList& markedCell
1152 const labelList splitPoints(meshCutter_.getSplitPoints());
1154 DynamicList<label> newSplitPoints(splitPoints.size());
1158 const label pointi = splitPoints[i];
1163 bool hasMarked =
false;
1167 if (markedCell.get(pCells[pCelli]))
1176 newSplitPoints.append(pointi);
1181 newSplitPoints.shrink();
1186 meshCutter_.consistentUnrefinement
1194 <<
" split points out of a possible "
1198 return consistentSet;
1202 void Foam::fvMeshTopoChangers::refiner::extendMarkedCells
1204 PackedBoolList& markedCell
1210 forAll(markedCell, celli)
1212 if (markedCell.get(celli))
1218 markedFace[cFaces[i]] =
true;
1228 if (markedFace[facei])
1242 if (markedFace[facei])
1258 nRefinementIterations_(0),
1259 protectedCells_(
mesh.nCells(), 0),
1266 calcProtectedCells(protectedCells_);
1270 const label nProtectedCells =
1272 if (nProtectedCells)
1274 Info<<
"Detected " << nProtectedCells <<
" cells that are protected "
1275 <<
"from refinement. Writing these to cell-set 'protectedCells'."
1282 protectedCells_.
clear();
1307 bool hasChanged =
false;
1309 if (refineInterval_ == 0)
1326 label maxRefinement = 0;
1328 if (dict_.isDict(
"refinementRegions"))
1332 dict_.subDict(
"refinementRegions")
1339 selectRefineCandidates
1350 maxRefinement = selectRefineCandidates(refineCells, dict_);
1355 for (
label i = 0; i < nBufferLayers_; i++)
1357 extendMarkedCells(refineCells);
1363 const labelList& cellLevel = meshCutter_.cellLevel();
1368 if (cellLevel[celli] >= maxRefinement)
1370 refinableCells.
unset(celli);
1375 if (
mesh().globalData().nTotalCells() < maxCells_)
1394 if (nCellsToRefine > 0)
1402 const labelList& cellMap = map().cellMap();
1403 const labelList& reverseCellMap = map().reverseCellMap();
1409 const label oldCelli = cellMap[celli];
1413 newRefineCell.
set(celli, 1);
1415 else if (reverseCellMap[oldCelli] != celli)
1417 newRefineCell.
set(celli, 1);
1424 refinableCells.
get(oldCelli)
1428 refinableCells.
transfer(newRefineCell);
1437 const labelList pointsToUnrefine(selectUnrefinePoints(refineCells));
1441 pointsToUnrefine.
size(),
1445 if (nSplitPoints > 0)
1448 unrefine(pointsToUnrefine);
1455 if ((nRefinementIterations_ % 10) == 0)
1461 nRefinementIterations_++;
#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.
Macros for easy insertion into run-time selection tables.
GeometricBoundaryField< Type, GeoMesh, PrimitiveField > Boundary
Type of the boundary field.
static word groupName(Name name, const word &group)
void size(const label)
Override size to be inconsistent with allocated storage.
void set(const PackedList< 1 > &)
Set specified bits.
labelList used() const
Return indices of the used (true) elements as a list of labels.
void transfer(PackedBoolList &)
Transfer the contents of the argument list into this list.
void unset(const PackedList< 1 > &)
Unset specified bits.
unsigned int get(const label) const
Get value at index I.
void clear()
Clear the list, i.e. set addressable size to zero.
label findIndex(const word &key) const
Return the index of the given the key or -1 if not found.
label timeIndex() const
Return current time index.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
A collection of cell labels.
Named list of cell indices representing a sub-set of the mesh.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Abstract base class for fvMesh topology changers.
fvMesh & mesh()
Return the fvMesh.
Dynamic mesh refinement/unrefinement based on volScalarField values.
virtual void topoChange(const polyTopoChangeMap &)
Update corresponding to the given map.
virtual void distribute(const polyDistributionMap &)
Update corresponding to the given distribution map.
virtual ~refiner()
Destructor.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
virtual bool update()
Update the mesh for both mesh motion and topology change.
refiner(fvMesh &mesh, const dictionary &dict)
Construct from fvMesh and dictionary.
Mesh data needed to do the Finite Volume discretisation.
const Time & time() const
Return the top-level database.
void preChange()
Prepare for a mesh change.
virtual void topoChange(const polyTopoChangeMap &map)
Update mesh corresponding to the given map.
const polyMesh & poly() const
Return reference to polyMesh.
label nTotalCells() const
Return total number of cells in decomposed mesh.
Refinement of (split) hexes using polyTopoChange.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type and name.
Motion of the mesh specified as a list of pointMeshMovers.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
const cellZoneList & cellZones() const
Return cell zones.
const polyBoundaryMesh & boundary() const
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.
virtual const labelList & faceNeighbour() const
Return face neighbour.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelListList & pointEdges() const
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
const vectorField & faceCentres() const
const labelListList & pointCells() const
label nInternalFaces() const
const labelListList & pointFaces() const
const cellList & cells() const
All refinement history. Used in unrefinement.
Encapsulates queries for volume refinement ('refine all cells within shell').
virtual bool write(const bool write=true) const
Write using setting from DB.
static void fillNan(UList< scalar > &)
Fill block of data with NaN.
A class for handling words, derived from string.
static const word null
An empty word.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
gmvFile<< "tracers "<< particles.size()<< nl;{ pointField positions(particles.size());label particlei=0;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter) { positions[particlei++]=iter().position(mesh);} for(i=0;i< pTraits< point >::nComponents;i++) { forAll(positions, particlei) { gmvFile<< component(positions[particlei], i)<< ' ';} gmvFile<< nl;}}forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
defineTypeNameAndDebug(list, 0)
addToRunTimeSelectionTable(fvMeshTopoChanger, list, fvMesh)
tmp< SurfaceField< typename innerProduct< vector, Type >::type > > flux(const VolField< Type > &vf)
Return the face-flux field obtained from the given volVectorField.
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< label > labelList
A List of labels.
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.
errorManip< error > abort(error &err)
SurfaceField< scalar > surfaceScalarField
List< bool > boolList
Bool container classes.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
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)
VolField< scalar > volScalarField
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
prefixOSstream Pout(cout, "Pout")
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
SurfaceField< vector > surfaceVectorField
fvsPatchField< vector > fvsPatchVectorField
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
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]