53 { decompositionType::FACE_CENTRE_TRIS,
"faceCentre" },
54 { decompositionType::FACE_DIAG_TRIS,
"faceDiagonal" },
55 { decompositionType::PYRAMID,
"pyramid" },
56 { decompositionType::FACE_DIAG_QUADS,
"faceDiagonalQuads" },
62 void Foam::tetDecomposer::modifyFace
64 polyTopoChange& meshMod,
77 <<
"Problem own:" << own
82 if (nei == -1 || own < nei)
113 void Foam::tetDecomposer::addFace
115 polyTopoChange& meshMod,
120 const label masterPointID,
121 const label masterEdgeID,
122 const label masterFaceID,
131 <<
"Problem own:" << own
136 if (nei == -1 || own < nei)
174 Foam::label Foam::tetDecomposer::triIndex(
const label facei,
const label fp)
177 const face&
f = mesh_.faces()[facei];
178 const label fp0 =
max(0, mesh_.tetBasePtIs()[facei]);
206 thisTrii =
f.
size()-3;
210 const label fpB = fp+
f.
size();
211 thisTrii = (fpB-fp0-1);
215 thisTrii = (fp-fp0-1);
221 void Foam::tetDecomposer::splitBoundaryFaces
223 List<faceList>& boundaryQuads,
224 List<faceList>& boundaryTris
231 const auto&
pbm = mesh_.boundaryMesh();
232 for (
const auto&
pp :
pbm)
234 if (
pp.coupled() && refCast<const coupledPolyPatch>(
pp).owner())
238 const label facei =
pp.start()+i;
239 const face& meshFace =
pp[i];
241 if (meshFace.size() > 4)
245 meshFace.trianglesQuads
254 const label bFacei = facei-mesh_.nInternalFaces();
257 auto& faces = boundaryTris[bFacei];
260 for (label i = 0; i < trii; i++)
262 const auto&
f = triFaces[i];
263 auto& verts = faces[i];
267 verts[fp] = meshFace.find(
f[fp]);
272 auto& faces = boundaryQuads[bFacei];
273 faces.setSize(quadi);
275 for (label i = 0; i < quadi; i++)
277 const auto&
f = quadFaces[i];
278 auto& verts = faces[i];
282 verts[fp] = meshFace.find(
f[fp]);
322 void Foam::tetDecomposer::relativeIndicesToFace
325 const face& meshFace,
336 const auto& verts = indexLists[facei];
337 auto&
f = faces[facei];
342 f[fp] = meshFace[verts[fp]];
350 const auto& verts = indexLists[facei];
351 auto&
f = faces[facei];
356 label destFp = verts.size()-1;
361 f[destFp] = meshFace[0];
365 f[destFp] = meshFace[meshFace.size()-verts[fp]];
374 void Foam::tetDecomposer::splitFace
376 const List<faceList>& boundaryQuads,
377 const List<faceList>& boundaryTris,
388 const face&
f = mesh_.faces()[facei];
392 if (patchi != -1 && mesh_.boundaryMesh()[patchi].coupled())
394 const auto&
pp = mesh_.boundaryMesh()[patchi];
396 refCast<const coupledPolyPatch>(
pp).owner();
397 const label bFacei = facei-mesh_.nInternalFaces();
400 trii = boundaryTris[bFacei].size();
401 relativeIndicesToFace
405 boundaryTris[bFacei],
410 quadi = boundaryQuads[bFacei].size();
411 relativeIndicesToFace
415 boundaryQuads[bFacei],
419 else if (
f.
size() == 4)
421 quadFaces[quadi++] =
f;
437 void Foam::tetDecomposer::splitFace
439 const List<faceList>& boundaryQuads,
440 const List<faceList>& boundaryTris,
448 const face&
f = mesh_.faces()[facei];
472 subFaces.resize_nocopy(quadi+trii);
475 for (label i = 0; i < quadi; i++)
477 subFaces[subFacei++] = quadFaces[i];
479 for (label i = 0; i < trii; i++)
481 subFaces[subFacei++] = triFaces[i];
490 Foam::tetDecomposer::tetDecomposer(
const polyMesh&
mesh)
500 const decompositionType decomposeType,
501 const bitSet& decomposeCell,
506 bitSet decomposeFace(mesh_.nFaces());
508 for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
510 label own = mesh_.faceOwner()[facei];
511 label nei = mesh_.faceNeighbour()[facei];
512 if (decomposeCell[own] || decomposeCell[nei])
514 decomposeFace[facei] =
true;
518 boolList neiDecomposeCell(mesh_.nBoundaryFaces());
519 forAll(neiDecomposeCell, bFacei)
521 label facei = mesh_.nInternalFaces()+bFacei;
522 label own = mesh_.faceOwner()[facei];
523 neiDecomposeCell[bFacei] = decomposeCell[own];
529 label facei = mesh_.nInternalFaces();
530 facei < mesh_.nFaces();
534 label own = mesh_.faceOwner()[facei];
535 label bFacei = facei-mesh_.nInternalFaces();
536 if (decomposeCell[own] || neiDecomposeCell[bFacei])
538 decomposeFace[facei] =
true;
542 setRefinement(decomposeType, decomposeCell, decomposeFace, meshMod);
548 const decompositionType decomposeType,
549 const bitSet& decomposeCell,
550 const bitSet& decomposeFace,
551 polyTopoChange& meshMod
557 const auto& faces = mesh_.faces();
561 nVerts[facei] = faces[facei].size();
566 if (nVerts[facei] != faces[facei].size())
576 bitSet newDecomposeFace(decomposeFace);
578 forAll(newDecomposeFace, facei)
580 if (decomposeFace[facei] != newDecomposeFace[facei])
594 List<faceList> boundaryQuads;
595 List<faceList> boundaryTris;
598 if (decomposeType == FACE_DIAG_QUADS)
607 triFaces.resize_nocopy(1000);
608 boundaryQuads.resize_nocopy(mesh_.nBoundaryFaces());
609 boundaryTris.resize_nocopy(mesh_.nBoundaryFaces());
610 splitBoundaryFaces(boundaryQuads, boundaryTris);
614 cellToPoint_.setSize(mesh_.nCells(), -1);
615 forAll(mesh_.cellCentres(), celli)
617 if (decomposeCell[celli])
620 label masterPointi = mesh_.faces()[mesh_.cells()[celli][0]][0];
622 cellToPoint_[celli] = meshMod.addPoint
624 mesh_.cellCentres()[celli],
634 if (decomposeType == FACE_CENTRE_TRIS)
636 faceToPoint_.setSize(mesh_.nFaces(), -1);
637 forAll(mesh_.faceCentres(), facei)
639 if (decomposeFace[facei])
642 const label masterPointi = mesh_.faces()[facei][0];
644 faceToPoint_[facei] = meshMod.addPoint
646 mesh_.faceCentres()[facei],
658 faceOwnerCells_.setSize(mesh_.nFaces());
659 faceNeighbourCells_.setSize(mesh_.nFaces());
661 if (decomposeType == FACE_CENTRE_TRIS)
663 forAll(faceOwnerCells_, facei)
665 if (decomposeFace[facei])
667 const face&
f = mesh_.faces()[facei];
669 faceNeighbourCells_[facei].setSize(
f.
size(), -1);
673 faceOwnerCells_[facei].setSize(1, -1);
674 faceNeighbourCells_[facei].setSize(1, -1);
678 else if (decomposeType == FACE_DIAG_TRIS)
681 (void)mesh_.tetBasePtIs();
683 forAll(faceOwnerCells_, facei)
685 if (decomposeFace[facei])
687 const face&
f = mesh_.faces()[facei];
689 faceNeighbourCells_[facei].setSize(
f.
size()-2, -1);
693 faceOwnerCells_[facei].setSize(1, -1);
694 faceNeighbourCells_[facei].setSize(1, -1);
698 else if (decomposeType == FACE_DIAG_QUADS)
706 const auto&
pbm = mesh_.boundaryMesh();
707 for (
const auto&
pp :
pbm)
713 const label facei =
pp.start()+i;
714 if (decomposeFace[facei])
716 const label bFacei =
pp.offset()+i;
718 boundaryQuads[bFacei].size()
719 + boundaryTris[bFacei].size();
721 faceOwnerCells_[facei].setSize(
n, -1);
722 faceNeighbourCells_[facei].setSize(
n, -1);
729 forAll(faceOwnerCells_, facei)
731 if (faceOwnerCells_[facei].empty())
733 if (decomposeFace[facei])
735 const face&
f = mesh_.faces()[facei];
741 const label nSubFaces =
f.nTrianglesQuads
748 faceOwnerCells_[facei].
setSize(nSubFaces, -1);
749 faceNeighbourCells_[facei].setSize(nSubFaces, -1);
753 faceOwnerCells_[facei].setSize(1, -1);
754 faceNeighbourCells_[facei].setSize(1, -1);
761 forAll(faceOwnerCells_, facei)
763 faceOwnerCells_[facei].setSize(1, -1);
764 faceNeighbourCells_[facei].setSize(1, -1);
771 forAll(mesh_.cells(), celli)
773 const cell& cFaces = mesh_.cells()[celli];
776 bool modifiedCell =
false;
780 label facei = cFaces[cFacei];
785 (mesh_.faceOwner()[facei] == celli)
786 ? faceOwnerCells_[facei]
787 : faceNeighbourCells_[facei]
790 if (decomposeCell[celli])
792 if (decomposeType == FACE_CENTRE_TRIS)
804 added[i] = meshMod.addCell
810 mesh_.cellZones().whichZone(celli)
817 decomposeType == FACE_DIAG_TRIS
818 || decomposeType == FACE_DIAG_QUADS
831 added[subi] = meshMod.addCell
837 mesh_.cellZones().whichZone(celli)
847 if (added.size() != 1)
850 <<
"For cell:" << celli
851 <<
" at:" << mesh_.cellCentres()[celli]
853 <<
" at:" << mesh_.faceCentres()[facei]
854 <<
" added cells:" << added
867 added = meshMod.addCell
873 mesh_.cellZones().whichZone(celli)
891 forAll(mesh_.faces(), facei)
893 label own = mesh_.faceOwner()[facei];
894 const auto& addedOwn = faceOwnerCells_[facei];
895 const auto& addedNei = faceNeighbourCells_[facei];
896 const face&
f = mesh_.faces()[facei];
901 if (facei >= mesh_.nInternalFaces())
903 patchi = mesh_.boundaryMesh().whichPatch(facei);
907 nei = mesh_.faceNeighbour()[facei];
910 label zonei = mesh_.faceZones().whichZone(facei);
911 bool zoneFlip =
false;
914 const faceZone& fz = mesh_.faceZones()[zonei];
915 zoneFlip = fz.flipMap()[fz.whichFace(facei)];
918 if (decomposeType == FACE_CENTRE_TRIS && decomposeFace[facei])
927 triangle[2] = faceToPoint_[facei];
977 if (decomposeCell[own])
979 label newOwn = addedOwn[
f.
rcIndex(fp)];
980 label newNei = addedOwn[fp];
983 triangle[1] = cellToPoint_[own];
984 triangle[2] = faceToPoint_[facei];
1002 if (facei < mesh_.nInternalFaces() && decomposeCell[nei])
1004 label newOwn = addedNei[
f.
rcIndex(fp)];
1005 label newNei = addedNei[fp];
1007 triangle[0] =
f[fp];
1008 triangle[1] = faceToPoint_[facei];
1009 triangle[2] = cellToPoint_[nei];
1028 else if (decomposeType == FACE_DIAG_TRIS && decomposeFace[facei])
1030 label fp0 =
max(mesh_.tetBasePtIs()[facei], 0);
1033 for (label trii = 0; trii <
f.
size()-2; trii++)
1035 label nextTri = trii+1;
1036 if (nextTri >=
f.
size()-2)
1038 nextTri -=
f.
size()-2;
1051 addedOwn.size() == 1
1057 addedNei.size() == 1
1062 triangle[0] =
f[fp0];
1063 triangle[1] =
f[fp];
1064 triangle[2] =
f[nextFp];
1101 if (trii <
f.
size()-3)
1103 if (decomposeCell[own])
1105 label newOwn = addedOwn[trii];
1106 label newNei = addedOwn[nextTri];
1108 triangle[0] =
f[fp0];
1109 triangle[1] =
f[nextFp];
1110 triangle[2] = cellToPoint_[own];
1129 if (facei < mesh_.nInternalFaces() && decomposeCell[nei])
1131 label newOwn = addedNei[trii];
1132 label newNei = addedNei[nextTri];
1134 triangle[0] =
f[nextFp];
1135 triangle[1] =
f[fp0];
1136 triangle[2] = cellToPoint_[nei];
1159 else if (decomposeType == FACE_DIAG_QUADS && decomposeFace[facei])
1173 EdgeMap<labelPair> edgeFaces(subFaces.size());
1175 forAll(subFaces, subFacei)
1177 const face& subF = subFaces[subFacei];
1184 addedOwn.size() == 1
1186 : addedOwn[subFacei]
1190 addedNei.size() == 1
1192 : addedNei[subFacei]
1232 const edge
e(subF.edge(fp));
1233 auto eFnd = edgeFaces.find(
e);
1236 edgeFaces.insert(
e,
labelPair(subFacei, -1));
1240 auto& eFaces = eFnd();
1241 if (eFaces[1] != -1)
1246 eFaces[1] = subFacei;
1254 const auto&
e = iter.key();
1255 const auto& eFaces = iter();
1257 if (eFaces.find(-1) != -1)
1265 if (decomposeCell[own])
1267 const label newOwn(addedOwn[eFaces[0]]);
1268 const label newNei(addedOwn[eFaces[1]]);
1276 triangle[2] = cellToPoint_[own];
1297 facei < mesh_.nInternalFaces()
1298 && decomposeCell[nei]
1301 const label newOwn(addedNei[eFaces[0]]);
1302 const label newNei(addedNei[eFaces[1]]);
1309 triangle[2] = cellToPoint_[nei];
1347 EdgeMap<label> edgeToFace;
1349 forAll(mesh_.cells(), celli)
1351 if (decomposeCell[celli])
1353 const cell& cFaces = mesh_.cells()[celli];
1359 const label facei = cFaces[cFacei];
1360 const label patchi = mesh_.boundaryMesh().whichPatch(facei);
1361 const face&
f = mesh_.faces()[facei];
1369 const edge
e(
p0, p1);
1371 EdgeMap<label>::const_iterator edgeFnd = edgeToFace.find(
e);
1372 if (edgeFnd == edgeToFace.end())
1374 edgeToFace.insert(
e, facei);
1379 label otherFacei = edgeFnd();
1380 const face& otherF = mesh_.faces()[otherFacei];
1386 label otherFp = otherF.find(
p0);
1387 if (otherF.nextLabel(otherFp) == p1)
1391 else if (otherF.prevLabel(otherFp) == p1)
1393 otherFp = otherF.rcIndex(otherFp);
1403 if (mesh_.faceOwner()[facei] == celli)
1407 triangle[2] = cellToPoint_[celli];
1413 triangle[2] = cellToPoint_[celli];
1418 const auto& thisCells =
1420 (mesh_.faceOwner()[facei] == celli)
1421 ? faceOwnerCells_[facei]
1422 : faceNeighbourCells_[facei]
1424 const auto& otherCells =
1426 (mesh_.faceOwner()[otherFacei] == celli)
1427 ? faceOwnerCells_[otherFacei]
1428 : faceNeighbourCells_[otherFacei]
1432 label otherTet = -1;
1434 if (decomposeType == FACE_CENTRE_TRIS)
1436 if (thisCells.size() == 1)
1438 thisTet = thisCells[0];
1442 thisTet = thisCells[fp];
1445 if (otherCells.size() == 1)
1447 otherTet = otherCells[0];
1451 otherTet = otherCells[otherFp];
1454 else if (decomposeType == FACE_DIAG_TRIS)
1456 if (thisCells.size() == 1)
1458 thisTet = thisCells[0];
1462 thisTet = thisCells[triIndex(facei, fp)];
1465 if (otherCells.size() == 1)
1467 otherTet = otherCells[0];
1472 otherCells[triIndex(otherFacei, otherFp)];
1475 else if (decomposeType == FACE_DIAG_QUADS)
1478 if (thisCells.size() == 1)
1480 thisTet = thisCells[0];
1500 forAll(subFaces, subFacei)
1502 const auto& subF = subFaces[subFacei];
1503 if (subF.find(
e) != -1)
1505 thisTet = thisCells[subFacei];
1512 <<
"For cell:" << celli
1513 <<
" at:" << mesh_.cellCentres()[celli]
1514 <<
" patch:" << patchi
1515 <<
" face:" << facei
1516 <<
" at:" << mesh_.faceCentres()[facei]
1517 <<
" did not find edge:" <<
e 1518 <<
" at:" <<
e.line(mesh_.points())
1519 <<
" in OWNER-side decomposed faces:" 1527 if (otherCells.size() == 1)
1529 otherTet = otherCells[0];
1538 mesh_.boundaryMesh().whichPatch(otherFacei),
1546 forAll(subFaces, subFacei)
1548 const auto& subF = subFaces[subFacei];
1549 if (subF.find(
e) != -1)
1551 otherTet = otherCells[subFacei];
1558 <<
"For cell:" << celli
1559 <<
" at:" << mesh_.cellCentres()[celli]
1561 << mesh_.boundaryMesh().whichPatch(otherFacei)
1562 <<
" face:" << otherFacei
1564 << mesh_.faceCentres()[otherFacei]
1565 <<
" did not find edge:" <<
e 1566 <<
" at:" <<
e.line(mesh_.points())
1567 <<
" in decomposed faces:" 1575 thisTet = thisCells[0];
1576 otherTet = otherCells[0];
1606 forAll(faceOwnerCells_, facei)
1610 forAll(faceNeighbourCells_, facei)
const polyBoundaryMesh & pbm
void size(const label n)
Older name for setAddressableSize.
errorManipArg< error, int > exit(error &err, const int errNo=1)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
static const Enum< decompositionType > decompositionTypeNames
#define forAll(list, i)
Loop across all elements in list.
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
List< face > faceList
List of faces.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
static Istream & input(Istream &is, IntRange< T > &range)
errorManip< error > abort(error &err)
void setRefinement(const decompositionType decomposeType, const bitSet &decomposeCell, polyTopoChange &meshMod)
Insert all changes into meshMod to convert the polyMesh into.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
defineTypeNameAndDebug(combustionModel, 0)
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Direct mesh changes based on v1.3 polyTopoChange syntax.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
List< label > labelList
A List of labels.
label rcIndex(const label i) const noexcept
The reverse circular index. The previous index in the list which returns to the last at the beginning...
List< bool > boolList
A List of bools.
void updateMesh(const mapPolyMesh &)
Force recalculation of locally stored data on topological change.
const volScalarField & p0
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
forAllConstIters(mixture.phases(), phase)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.