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::calculateProtectedCells
77 PackedBoolList& unrefineableCells
80 if (protectedCells_.empty())
82 unrefineableCells.clear();
86 const labelList& cellLevel = meshCutter_.cellLevel();
88 unrefineableCells = protectedCells_;
114 const bool ownProtected = unrefineableCells.get(own);
116 const bool neiProtected = unrefineableCells.get(nei);
118 if (ownProtected && (cellLevel[nei] > cellLevel[own]))
120 seedFace[facei] =
true;
122 else if (neiProtected && (cellLevel[own] > cellLevel[nei]))
124 seedFace[facei] =
true;
136 const bool ownProtected = unrefineableCells.get(own);
141 && (neiLevel[facei-
mesh().nInternalFaces()] > cellLevel[own])
144 seedFace[facei] =
true;
152 bool hasExtended =
false;
159 if (unrefineableCells.get(own) == 0)
161 unrefineableCells.set(own, 1);
166 if (unrefineableCells.get(nei) == 0)
168 unrefineableCells.set(nei, 1);
185 if (unrefineableCells.get(own) == 0)
187 unrefineableCells.set(own, 1);
201 void Foam::fvMeshTopoChangers::refiner::readDict()
203 refineInterval_ = dict_.lookup<
label>(
"refineInterval");
205 if (refineInterval_ < 0)
208 <<
"Illegal refineInterval " << refineInterval_ <<
nl
209 <<
"The refineInterval setting in the dynamicMeshDict should"
214 maxCells_ = dict_.lookup<
label>(
"maxCells");
219 <<
"Illegal maximum number of cells " << maxCells_ <<
nl
220 <<
"The maxCells setting in the dynamicMeshDict should"
225 nBufferLayers_ = dict_.lookup<
label>(
"nBufferLayers");
227 if (dict_.found(
"correctFluxes"))
229 const List<Pair<word>> fluxVelocities = List<Pair<word>>
231 dict_.lookup(
"correctFluxes")
235 correctFluxes_.resize(fluxVelocities.size());
238 correctFluxes_.insert(fluxVelocities[i][0], fluxVelocities[i][1]);
242 dumpLevel_ = Switch(dict_.lookup(
"dumpLevel"));
247 Foam::fvMeshTopoChangers::refiner::refine
255 polyTopoChange meshMod(
mesh());
258 meshCutter_.setRefinement(cellsToRefine, meshMod);
262 autoPtr<polyTopoChangeMap> map = meshMod.changeMesh(
mesh());
264 Info<<
"Refined from "
273 const label oldFacei = map().faceMap()[facei];
275 if (oldFacei >=
mesh().nInternalFaces())
278 <<
"New internal face:" << facei
280 <<
" originates from boundary oldFace:" << oldFacei
293 const labelList& reverseFaceMap = map().reverseFaceMap();
306 const label masterFacei = reverseFaceMap[oldFacei];
311 <<
"Problem: should not have removed faces"
315 else if (masterFacei != facei)
317 masterFaces.insert(masterFacei);
323 Pout<<
"Found " << masterFaces.size() <<
" split faces " <<
endl;
326 refineFluxes(masterFaces, map());
327 refineUfs(masterFaces, map());
331 if (protectedCells_.size())
333 PackedBoolList newProtectedCell(
mesh().nCells());
335 forAll(newProtectedCell, celli)
337 const label oldCelli = map().cellMap()[celli];
338 newProtectedCell.set(celli, protectedCells_.get(oldCelli));
340 protectedCells_.transfer(newProtectedCell);
344 meshCutter_.checkRefinementLevels(-1,
labelList(0));
351 Foam::fvMeshTopoChangers::refiner::unrefine
359 polyTopoChange meshMod(
mesh());
362 meshCutter_.setUnrefinement(splitPoints, meshMod);
371 Map<label> faceToSplitPoint(3*splitPoints.size());
376 const label pointi = splitPoints[i];
381 const label otherPointi =
382 mesh().
edges()[pEdges[j]].otherVertex(pointi);
388 faceToSplitPoint.insert(
pFaces[pFacei], otherPointi);
396 autoPtr<polyTopoChangeMap> map = meshMod.changeMesh(
mesh());
398 Info<<
"Unrefined from "
407 unrefineFluxes(faceToSplitPoint, map());
410 unrefineUfs(faceToSplitPoint, map());
413 if (protectedCells_.size())
415 PackedBoolList newProtectedCell(
mesh().nCells());
417 forAll(newProtectedCell, celli)
419 const label oldCelli = map().cellMap()[celli];
422 newProtectedCell.set(celli, protectedCells_.get(oldCelli));
425 protectedCells_.transfer(newProtectedCell);
429 meshCutter_.checkRefinementLevels(-1,
labelList(0));
435 Foam::word Foam::fvMeshTopoChangers::refiner::Uname
440 const word UfName(Uf.member());
446 ? word(UfName(UfName.size() - 1))
447 : UfName.compare(UfName.size() - 3, 3,
"f_0") == 0
448 ? word(UfName(UfName.size() - 3) +
"_0")
455 void Foam::fvMeshTopoChangers::refiner::refineFluxes
458 const polyTopoChangeMap& map
461 if (correctFluxes_.size())
463 UPtrList<surfaceScalarField> fluxes
465 mesh().fields<surfaceScalarField>()
472 if (!correctFluxes_.found(
flux.name()))
475 <<
"Cannot find surfaceScalarField " <<
flux.name()
476 <<
" in user-provided flux mapping table "
477 << correctFluxes_ <<
endl
478 <<
" The flux mapping table is used to recreate the"
479 <<
" flux on newly created faces." <<
endl
480 <<
" Either add the entry if it is a flux or use ("
481 <<
flux.name() <<
" none) to suppress this warning."
486 const word& method = correctFluxes_[
flux.name()];
488 if (method ==
"none")
490 else if (method ==
"NaN")
492 Pout<<
"Setting surfaceScalarField " <<
flux.name()
493 <<
" to NaN" <<
endl;
500 <<
"Unknown refinement method " << method
501 <<
" for surfaceScalarField " <<
flux.name()
502 <<
" in user-provided flux mapping table "
512 void Foam::fvMeshTopoChangers::refiner::unrefineFluxes
514 const Map<label>& faceToSplitPoint,
515 const polyTopoChangeMap& map
518 if (correctFluxes_.size())
520 UPtrList<surfaceScalarField> fluxes
522 mesh().fields<surfaceScalarField>()
529 if (!correctFluxes_.found(
flux.name()))
532 <<
"Cannot find surfaceScalarField " <<
flux.name()
533 <<
" in user-provided flux mapping table "
534 << correctFluxes_ <<
endl
535 <<
" The flux mapping table is used to recreate the"
536 <<
" flux on newly created faces." <<
endl
537 <<
" Either add the entry if it is a flux or use ("
538 <<
flux.name() <<
" none) to suppress this warning."
543 const word& method = correctFluxes_[
flux.name()];
545 if (method !=
"none")
548 <<
"Unknown unrefinement method " << method
549 <<
" for surfaceScalarField " <<
flux.name()
550 <<
" in user-provided flux mapping table "
560 void Foam::fvMeshTopoChangers::refiner::refineUfs
563 const polyTopoChangeMap& map
567 const labelList& reverseFaceMap = map.reverseFaceMap();
570 UPtrList<surfaceVectorField> Ufs(
mesh().fields<surfaceVectorField>());
576 const word Uname(this->Uname(Uf));
593 Uf[facei] = UfU[facei];
595 else if (reverseFaceMap[oldFacei] != facei)
598 Uf[facei] = UfU[facei];
608 UfU.boundaryField()[
patchi];
610 label facei = patchUf.patch().start();
619 patchUf[i] = patchUfU[i];
621 else if (reverseFaceMap[oldFacei] != facei)
624 patchUf[i] = patchUfU[i];
634 label facei = iter.key();
636 if (
mesh().isInternalFace(facei))
638 Uf[facei] = UfU[facei];
648 UfU.boundaryField()[
patchi];
652 patchUf[i] = patchUfU[i];
660 void Foam::fvMeshTopoChangers::refiner::unrefineUfs
662 const Map<label>& faceToSplitPoint,
663 const polyTopoChangeMap& map
666 const labelList& reversePointMap = map.reversePointMap();
667 const labelList& reverseFaceMap = map.reverseFaceMap();
670 UPtrList<surfaceVectorField> Ufs(
mesh().fields<surfaceVectorField>());
676 const word Uname(this->Uname(Uf));
689 const label oldFacei = iter.key();
690 const label oldPointi = iter();
692 if (reversePointMap[oldPointi] < 0)
695 const label facei = reverseFaceMap[oldFacei];
699 if (
mesh().isInternalFace(facei))
701 Uf[facei] = UfU[facei];
720 const Foam::cellZone& Foam::fvMeshTopoChangers::refiner::findCellZone
722 const word& cellZoneName
727 bool cellZoneFound = (cellZoneID != -1);
728 reduce(cellZoneFound, orOp<bool>());
733 <<
"cannot find cellZone " << cellZoneName
742 Foam::fvMeshTopoChangers::refiner::cellToPoint(
const scalarField& vFld)
const
753 sum += vFld[pCells[i]];
755 pFld[pointi] =
sum/pCells.size();
765 const scalar minLevel,
766 const scalar maxLevel
773 scalar err =
min(
fld[celli] - minLevel, maxLevel -
fld[celli]);
789 const scalar minLevel,
790 const scalar maxLevel
799 scalar err =
min(
fld[celli] - minLevel, maxLevel -
fld[celli]);
811 void Foam::fvMeshTopoChangers::refiner::selectRefineCandidates
813 PackedBoolList& candidateCells,
814 const scalar lowerRefineLevel,
815 const scalar upperRefineLevel,
816 const scalar maxRefinement,
824 error(vFld, lowerRefineLevel, upperRefineLevel)
830 if (cellError[celli] > 0)
832 candidateCells.set(celli, 1);
838 void Foam::fvMeshTopoChangers::refiner::selectRefineCandidates
840 PackedBoolList& candidateCells,
841 const scalar lowerRefineLevel,
842 const scalar upperRefineLevel,
843 const scalar maxRefinement,
852 error(vFld,
cells, lowerRefineLevel, upperRefineLevel)
858 if (cellError[celli] > 0)
860 candidateCells.set(celli, 1);
866 Foam::scalar Foam::fvMeshTopoChangers::refiner::selectRefineCandidates
868 PackedBoolList& candidateCells,
869 const dictionary& refineDict
872 const word fieldName(refineDict.lookup(
"field"));
876 const scalar lowerRefineLevel =
877 refineDict.lookup<scalar>(
"lowerRefineLevel");
878 const scalar upperRefineLevel =
879 refineDict.lookup<scalar>(
"upperRefineLevel");
881 const label maxRefinement = refineDict.lookup<
label>(
"maxRefinement");
883 if (maxRefinement <= 0)
886 <<
"Illegal maximum refinement level " << maxRefinement <<
nl
887 <<
"The maxCells setting in the dynamicMeshDict should"
892 if (refineDict.found(
"cellZone"))
895 selectRefineCandidates
902 findCellZone(refineDict.lookup(
"cellZone"))
908 selectRefineCandidates
918 return maxRefinement;
924 const label maxCells,
925 const label maxRefinement,
926 const PackedBoolList& candidateCells
932 const labelList& cellLevel = meshCutter_.cellLevel();
936 PackedBoolList unrefineableCells;
937 calculateProtectedCells(unrefineableCells);
940 const label nLocalCandidates =
count(candidateCells, 1);
944 DynamicList<label> candidates(nLocalCandidates);
946 if (nCandidates < nTotToRefine)
948 forAll(candidateCells, celli)
952 candidateCells.get(celli)
954 unrefineableCells.empty()
955 || !unrefineableCells.get(celli)
959 candidates.append(celli);
966 for (
label level = 0; level < maxRefinement; level++)
968 forAll(candidateCells, celli)
972 cellLevel[celli] == level
973 && candidateCells.get(celli)
975 unrefineableCells.empty()
976 || !unrefineableCells.get(celli)
980 candidates.append(celli);
984 if (
returnReduce(candidates.size(), sumOp<label>()) > nTotToRefine)
994 meshCutter_.consistentRefinement
1005 return consistentSet;
1009 Foam::labelList Foam::fvMeshTopoChangers::refiner::selectUnrefinePoints
1011 const PackedBoolList& markedCell
1015 const labelList splitPoints(meshCutter_.getSplitPoints());
1017 DynamicList<label> newSplitPoints(splitPoints.size());
1021 const label pointi = splitPoints[i];
1026 bool hasMarked =
false;
1030 if (markedCell.get(pCells[pCelli]))
1039 newSplitPoints.append(pointi);
1044 newSplitPoints.shrink();
1049 meshCutter_.consistentUnrefinement
1057 <<
" split points out of a possible "
1061 return consistentSet;
1065 void Foam::fvMeshTopoChangers::refiner::extendMarkedCells
1067 PackedBoolList& markedCell
1073 forAll(markedCell, celli)
1075 if (markedCell.get(celli))
1081 markedFace[cFaces[i]] =
true;
1091 if (markedFace[facei])
1105 if (markedFace[facei])
1113 void Foam::fvMeshTopoChangers::refiner::checkEightAnchorPoints
1115 PackedBoolList& protectedCell,
1119 const labelList& cellLevel = meshCutter_.cellLevel();
1120 const labelList& pointLevel = meshCutter_.pointLevel();
1124 forAll(pointLevel, pointi)
1130 const label celli = pCells[pCelli];
1132 if (pointLevel[pointi] <= cellLevel[celli])
1135 if (nAnchorPoints[celli] == 8)
1137 if (protectedCell.set(celli,
true))
1143 if (!protectedCell[celli])
1145 nAnchorPoints[celli]++;
1151 forAll(protectedCell, celli)
1153 if (!protectedCell[celli] && nAnchorPoints[celli] != 8)
1155 protectedCell.set(celli,
true);
1170 nRefinementIterations_(0),
1171 protectedCells_(
mesh.nCells(), 0),
1172 changedSinceWrite_(false),
1191 label nProtected = 0;
1199 const label celli = pCells[i];
1201 if (!protectedCells_.
get(celli))
1203 if (pointLevel[pointi] <= cellLevel[celli])
1207 if (nAnchors[celli] > 8)
1209 protectedCells_.
set(celli, 1);
1259 if (pointLevel[
f[fp]] <= faceLevel)
1265 protectedFace[facei] =
true;
1276 if (protectedFace[facei])
1292 if (protectedFace[facei])
1304 if (cFaces.
size() < 6)
1306 if (protectedCells_.
set(celli, 1))
1317 if (protectedCells_.
set(celli, 1))
1328 checkEightAnchorPoints(protectedCells_, nProtected);
1333 protectedCells_.
clear();
1337 cellSet protectedCells(
mesh,
"protectedCells", nProtected);
1338 forAll(protectedCells_, celli)
1340 if (protectedCells_[celli])
1342 protectedCells.
insert(celli);
1347 <<
" cells that are protected from refinement."
1348 <<
" Writing these to cellSet "
1349 << protectedCells.
name()
1352 protectedCells.
write();
1377 bool hasChanged =
false;
1379 if (refineInterval_ == 0)
1396 label maxRefinement = 0;
1398 if (dict_.isDict(
"refinementRegions"))
1402 dict_.subDict(
"refinementRegions")
1409 selectRefineCandidates
1420 maxRefinement = selectRefineCandidates(refineCells, dict_);
1425 for (
label i = 0; i < nBufferLayers_; i++)
1427 extendMarkedCells(refineCells);
1433 const labelList& cellLevel = meshCutter_.cellLevel();
1438 if (cellLevel[celli] >= maxRefinement)
1440 refinableCells.
unset(celli);
1445 if (
mesh().globalData().nTotalCells() < maxCells_)
1464 if (nCellsToRefine > 0)
1472 const labelList& cellMap = map().cellMap();
1473 const labelList& reverseCellMap = map().reverseCellMap();
1479 const label oldCelli = cellMap[celli];
1483 newRefineCell.
set(celli, 1);
1485 else if (reverseCellMap[oldCelli] != celli)
1487 newRefineCell.
set(celli, 1);
1494 refinableCells.
get(oldCelli)
1498 refinableCells.
transfer(newRefineCell);
1507 const labelList pointsToUnrefine(selectUnrefinePoints(refineCells));
1511 pointsToUnrefine.
size(),
1515 if (nSplitPoints > 0)
1518 unrefine(pointsToUnrefine);
1525 if ((nRefinementIterations_ % 10) == 0)
1531 nRefinementIterations_++;
1536 changedSinceWrite_ =
true;
1546 meshCutter_.topoChange(map);
1565 meshCutter_.distribute(map);
1571 if (changedSinceWrite_)
1595 const labelList& cellLevel = meshCutter_.cellLevel();
1599 scalarCellLevel[celli] = cellLevel[celli];
1602 writeOk = writeOk && scalarCellLevel.
write();
1605 changedSinceWrite_ =
false;
#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.
Generic GeometricField class.
GeometricBoundaryField< Type, GeoMesh, PrimitiveField > Boundary
Type of the boundary field.
bool insert(const Key &key)
Insert a new entry.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
const word & name() const
Return name.
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.
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 cell is defined as a list of faces with extra functionality.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
const word & name() const
Return const reference to name.
A face is a list of labels corresponding to mesh vertices.
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 write(const bool write=true) const
Write using given format, version and compression.
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.
label nTotalCells() const
Return total number of cells in decomposed mesh.
Refinement of (split) hexes using polyTopoChange.
bool write(const bool write=true) const
Force writing refinement+history to polyMesh directory.
const labelIOList & cellLevel() const
const labelIOList & pointLevel() const
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type and name.
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.
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.
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 NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
#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.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
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)
const dimensionSet dimless
SurfaceField< scalar > surfaceScalarField
List< bool > boolList
Bool container classes.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
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 > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
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
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
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]