67 for (
label i = 0; i < nElems; i++)
88 result[labels[
labelI]] =
true;
114 const Map<label>& map
119 if (!map.found(lst[i]))
130 void Foam::cellCuts::syncProc()
142 const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
166 const polyBoundaryMesh& pbm = mesh().boundaryMesh();
170 const polyPatch& pp = pbm[
patchi];
172 if (isA<processorPolyPatch>(pp) || isA<cyclicPolyPatch>(pp))
176 label facei = pp.start()+i;
177 label bFacei = facei-mesh().nInternalFaces();
180 faceSplitCut_.find(facei);
181 if (iter != faceSplitCut_.end())
183 const face&
f = mesh().faces()[facei];
184 const labelList& fEdges = mesh().faceEdges()[facei];
185 const edge& cuts = iter();
191 label edgei = getEdge(cuts[i]);
193 relCuts[bFacei][i] = -index-1;
198 relCuts[bFacei][i] = index+1;
218 const polyPatch& pp = pbm[
patchi];
220 if (isA<processorPolyPatch>(pp) || isA<cyclicPolyPatch>(pp))
224 label facei = pp.start()+i;
225 label bFacei = facei-mesh().nInternalFaces();
227 const edge& relCut = relCuts[bFacei];
228 if (relCut != edge(0, 0))
230 const face&
f = mesh().faces()[facei];
231 const labelList& fEdges = mesh().faceEdges()[facei];
233 edge absoluteCut(0, 0);
238 label oppFp = -relCut[i]-1;
240 absoluteCut[i] = edgeToEVert(fEdges[fp]);
244 label oppFp = relCut[i]-1;
246 absoluteCut[i] = vertToEVert(
f[fp]);
252 !faceSplitCut_.insert(facei, absoluteCut)
253 && faceSplitCut_[facei] != absoluteCut
257 <<
"Cut " << faceSplitCut_[facei]
258 <<
" on face " << mesh().faceCentres()[facei]
259 <<
" of coupled patch " << pp.name()
260 <<
" is not consistent with coupled cut "
272 void Foam::cellCuts::writeUncutOBJ
279 OFstream cutsStream(dir /
"cell_" +
name(celli) +
".obj");
281 Pout<<
"Writing cell for time " << mesh().time().
name()
282 <<
" to " << cutsStream.
name() <<
nl;
294 OFstream cutStream(dir /
"cellCuts_" +
name(celli) +
".obj");
296 Pout<<
"Writing raw cuts on cell for time " << mesh().time().
name()
297 <<
" to " << cutStream.
name() <<
nl;
299 const labelList& cPoints = mesh().cellPoints()[celli];
303 label pointi = cPoints[i];
304 if (pointIsCut_[pointi])
312 const labelList& cEdges = mesh().cellEdges()[celli];
316 label edgeI = cEdges[i];
318 if (edgeIsCut_[edgeI])
320 const edge&
e = mesh().edges()[edgeI];
322 const scalar w = edgeWeight_[edgeI];
330 void Foam::cellCuts::writeOBJ
339 OFstream cutsStream(dir /
"cell_" +
name(celli) +
".obj");
341 Pout<<
"Writing cell for time " << mesh().time().
name()
342 <<
" to " << cutsStream.
name() <<
nl;
355 OFstream loopStream(dir /
"cellLoop_" +
name(celli) +
".obj");
357 Pout<<
"Writing loop for time " << mesh().time().
name()
358 <<
" to " << loopStream.
name() <<
nl;
362 writeOBJ(loopStream, loopPoints, vertI);
366 OFstream anchorStream(dir /
"anchors_" +
name(celli) +
".obj");
368 Pout<<
"Writing anchors for time " << mesh().time().
name()
369 <<
" to " << anchorStream.
name() <<
endl;
385 const labelList& cFaces = mesh().cells()[celli];
389 label facei = cFaces[cFacei];
391 const labelList& fEdges = mesh().faceEdges()[facei];
407 <<
"cellCuts : Cannot find face on cell "
408 << celli <<
" that has both edges " << edgeA <<
' ' << edgeB <<
endl
409 <<
"faces : " << cFaces <<
endl
410 <<
"edgeA : " << mesh().edges()[edgeA] <<
endl
411 <<
"edgeB : " << mesh().edges()[edgeB] <<
endl
412 <<
"Marking the loop across this cell as invalid" <<
endl;
425 const labelList& cFaces = mesh().cells()[celli];
429 label facei = cFaces[cFacei];
431 const face&
f = mesh().faces()[facei];
433 const labelList& fEdges = mesh().faceEdges()[facei];
446 <<
"cellCuts : Cannot find face on cell "
447 << celli <<
" that has both edge " << edgeI <<
" and vertex "
449 <<
"faces : " << cFaces <<
endl
450 <<
"edge : " << mesh().edges()[edgeI] <<
endl
451 <<
"Marking the loop across this cell as invalid" <<
endl;
464 const labelList& cFaces = mesh().cells()[celli];
468 label facei = cFaces[cFacei];
470 const face&
f = mesh().faces()[facei];
483 <<
"cellCuts : Cannot find face on cell "
484 << celli <<
" that has vertex " << vertA <<
" and vertex "
486 <<
"faces : " << cFaces <<
endl
487 <<
"Marking the loop across this cell as invalid" <<
endl;
493 void Foam::cellCuts::calcFaceCuts()
const
495 if (faceCutsPtr_.valid())
501 const faceList& faces = mesh().faces();
506 for (
label facei = 0; facei < mesh().nFaces(); facei++)
508 const face&
f = faces[facei];
514 cuts.setSize(2*
f.
size());
537 && !edgeIsCut_[
findEdge(facei, v0, vMin1)]
540 cuts[cutI++] = vertToEVert(v0);
559 if (edgeIsCut_[edgeI] && !pointIsCut_[v0])
561 cuts[cutI++] = edgeToEVert(edgeI);
578 bool allVerticesCut =
true;
592 cuts[cutI++] = vertToEVert(v0);
597 allVerticesCut =
false;
600 if (edgeIsCut_[edgeI])
602 cuts[cutI++] = edgeToEVert(edgeI);
612 <<
"Face " << facei <<
" vertices " <<
f
613 <<
" has all its vertices cut. Not cutting face." <<
endl;
619 if (cutI > 1 && cuts[cutI-1] == cuts[0])
635 const edgeList& edges = mesh().edges();
637 const labelList& fEdges = mesh().faceEdges()[facei];
641 const edge&
e = edges[fEdges[i]];
645 (
e[0] == v0 &&
e[1] == v1)
646 || (
e[0] == v1 &&
e[1] == v0)
663 const cell& cFaces = mesh().cells()[celli];
667 label facei = cFaces[cFacei];
669 const labelList& fEdges = mesh().faceEdges()[facei];
670 const face&
f = mesh().faces()[facei];
672 bool allOnFace =
true;
680 if (
findIndex(fEdges, getEdge(cut)) == -1)
708 bool Foam::cellCuts::walkPoint
711 const label startCut,
713 const label exclude0,
714 const label exclude1,
716 const label otherCut,
722 label vertI = getVertex(otherCut);
732 otherFacei != exclude0
733 && otherFacei != exclude1
737 label oldNVisited = nVisited;
756 nVisited = oldNVisited;
763 bool Foam::cellCuts::crossEdge
766 const label startCut,
768 const label otherCut,
775 label edgeI = getEdge(otherCut);
780 label oldNVisited = nVisited;
801 nVisited = oldNVisited;
808 bool Foam::cellCuts::addCut
817 if (findPartIndex(visited, nVisited, cut) != -1)
821 truncVisited.setSize(nVisited);
823 Pout<<
"For cell " << celli <<
" : trying to add duplicate cut " << cut;
825 writeCuts(
Pout, cuts, loopWeights(cuts));
828 writeCuts(
Pout, truncVisited, loopWeights(truncVisited));
835 visited[nVisited++] = cut;
842 bool Foam::cellCuts::walkFace
845 const label startCut,
850 label& beforeLastCut,
857 if (fCuts.size() < 2)
863 if (fCuts.size() == 2)
867 if (!addCut(celli, cut, nVisited, visited))
879 if (!addCut(celli, cut, nVisited, visited))
896 for (
label i = 0; i < fCuts.size()-1; i++)
898 if (!addCut(celli, fCuts[i], nVisited, visited))
903 beforeLastCut = fCuts[fCuts.size()-2];
904 lastCut = fCuts[fCuts.size()-1];
906 else if (fCuts[fCuts.size()-1] == cut)
908 for (
label i = fCuts.size()-1; i >= 1; --i)
910 if (!addCut(celli, fCuts[i], nVisited, visited))
915 beforeLastCut = fCuts[1];
921 <<
"In middle of cut. cell:" << celli <<
" face:" << facei
922 <<
" cuts:" << fCuts <<
" current cut:" << cut <<
endl;
932 bool Foam::cellCuts::walkCell
935 const label startCut,
945 label beforeLastCut = -1;
950 Pout<<
"For cell:" << celli <<
" walked across face " << facei
953 writeCuts(
Pout, cuts, loopWeights(cuts));
977 Pout<<
" to last cut ";
979 writeCuts(
Pout, cuts, loopWeights(cuts));
984 if (lastCut == startCut)
992 truncVisited.setSize(nVisited);
994 Pout<<
"For cell " << celli <<
" : found closed path:";
995 writeCuts(
Pout, truncVisited, loopWeights(truncVisited));
996 Pout<<
" closed by " << lastCut <<
endl;
1024 if (isEdge(beforeLastCut))
1026 if (isEdge(lastCut))
1060 if (isEdge(lastCut))
1081 getVertex(beforeLastCut),
1125 void Foam::cellCuts::calcCellLoops(
const labelList& cutCells)
1138 labelList nCutFaces(mesh().nCells(), 0);
1140 forAll(allFaceCuts, facei)
1142 const labelList& fCuts = allFaceCuts[facei];
1144 if (fCuts.size() == mesh().faces()[facei].size())
1147 nCutFaces[mesh().faceOwner()[facei]] =
labelMin;
1149 if (mesh().isInternalFace(facei))
1151 nCutFaces[mesh().faceNeighbour()[facei]] =
labelMin;
1154 else if (fCuts.size() >= 2)
1157 nCutFaces[mesh().faceOwner()[facei]]++;
1159 if (mesh().isInternalFace(facei))
1161 nCutFaces[mesh().faceNeighbour()[facei]]++;
1173 label celli = cutCells[i];
1175 bool validLoop =
false;
1178 if (nCutFaces[celli] >= 3)
1180 const labelList& cFaces = mesh().cells()[celli];
1184 Pout<<
"cell:" << celli <<
" cut faces:" <<
endl;
1187 label facei = cFaces[i];
1188 const labelList& fCuts = allFaceCuts[facei];
1190 Pout<<
" face:" << facei <<
" cuts:";
1191 writeCuts(
Pout, fCuts, loopWeights(fCuts));
1201 label facei = cFaces[cFacei];
1203 const labelList& fCuts = allFaceCuts[facei];
1209 if (fCuts.size() >= 2)
1216 Pout<<
"cell:" << celli
1217 <<
" start walk at face:" << facei
1220 writeCuts(
Pout, cuts, loopWeights(cuts));
1255 for (
label i = 0; i < nVisited; i++)
1257 loop[i] = visited[i];
1264 Pout<<
"calcCellLoops(const labelList&) : did not find valid"
1265 <<
" loop for cell " << celli <<
endl;
1267 writeUncutOBJ(
".", celli);
1269 cellLoops_[celli].setSize(0);
1277 cellLoops_[celli].setSize(0);
1283 void Foam::cellCuts::walkEdges
1289 Map<label>& edgeStatus,
1290 Map<label>& pointStatus
1293 if (pointStatus.insert(pointi, status))
1297 const labelList& pEdges = mesh().pointEdges()[pointi];
1301 label edgeI = pEdges[pEdgeI];
1306 && edgeStatus.insert(edgeI, status)
1311 label v2 = mesh().edges()[edgeI].otherVertex(pointi);
1313 walkEdges(celli, v2, status, edgeStatus, pointStatus);
1332 label pointi = cellPoints[i];
1337 &&
findIndex(loop, vertToEVert(pointi)) == -1
1340 newElems[newElemI++] = pointi;
1350 bool Foam::cellCuts::loopAnchorConsistent
1360 const vector a =
f.area(loopPts);
1361 const point ctr =
f.centre(loopPts);
1366 forAll(anchorPoints, ptI)
1368 avg += mesh().points()[anchorPoints[ptI]];
1370 avg /= anchorPoints.
size();
1372 if (((avg - ctr) & a) > 0)
1383 bool Foam::cellCuts::calcAnchors
1392 const edgeList& edges = mesh().edges();
1394 const labelList& cPoints = mesh().cellPoints()[celli];
1395 const labelList& cEdges = mesh().cellEdges()[celli];
1396 const cell& cFaces = mesh().cells()[celli];
1404 Map<label> pointStatus(2*cPoints.size());
1405 Map<label> edgeStatus(2*cEdges.size());
1410 label cut = loop[i];
1414 edgeStatus.insert(getEdge(cut), 0);
1418 pointStatus.insert(getVertex(cut), 0);
1425 label edgeI = cEdges[i];
1426 const edge&
e = edges[edgeI];
1428 if (pointStatus.found(
e[0]) && pointStatus.found(
e[1]))
1430 edgeStatus.insert(edgeI, 0);
1436 label uncutIndex = firstUnique(cPoints, pointStatus);
1438 if (uncutIndex == -1)
1441 <<
"Invalid loop " << loop <<
" for cell " << celli <<
endl
1442 <<
"Can not find point on cell which is not cut by loop."
1451 walkEdges(celli, cPoints[uncutIndex], 1, edgeStatus, pointStatus);
1454 uncutIndex = firstUnique(cPoints, pointStatus);
1456 if (uncutIndex == -1)
1461 <<
"Invalid loop " << loop <<
" for cell " << celli <<
endl
1462 <<
"All vertices of cell are either in loop or in anchor set"
1472 walkEdges(celli, cPoints[uncutIndex], 2, edgeStatus, pointStatus);
1475 DynamicList<label> connectedPoints(cPoints.size());
1476 DynamicList<label> otherPoints(cPoints.size());
1482 connectedPoints.append(iter.key());
1484 else if (iter() == 2)
1486 otherPoints.append(iter.key());
1489 connectedPoints.shrink();
1490 otherPoints.shrink();
1493 uncutIndex = firstUnique(cPoints, pointStatus);
1495 if (uncutIndex != -1)
1498 <<
"Invalid loop " << loop <<
" for cell " << celli
1499 <<
" since it splits the cell into more than two cells" <<
endl;
1501 writeOBJ(
".", celli, loopPts, connectedPoints);
1513 label pointi = iter.key();
1523 connectedFaces.insert(
pFaces[pFacei]);
1527 else if (iter() == 2)
1533 otherFaces.insert(
pFaces[pFacei]);
1539 if (connectedFaces.size() < 3)
1542 <<
"Invalid loop " << loop <<
" for cell " << celli
1543 <<
" since would have too few faces on one side." <<
nl
1544 <<
"All faces:" << cFaces <<
endl;
1546 writeOBJ(
".", celli, loopPts, connectedPoints);
1551 if (otherFaces.size() < 3)
1554 <<
"Invalid loop " << loop <<
" for cell " << celli
1555 <<
" since would have too few faces on one side." <<
nl
1556 <<
"All faces:" << cFaces <<
endl;
1558 writeOBJ(
".", celli, loopPts, otherPoints);
1571 label facei = cFaces[i];
1573 const face&
f = mesh().faces()[facei];
1575 bool hasSet1 =
false;
1576 bool hasSet2 =
false;
1578 label prevStat = pointStatus[
f[0]];
1583 label pStat = pointStatus[v0];
1585 if (pStat == prevStat)
1588 else if (pStat == 0)
1592 else if (pStat == 1)
1598 <<
"Invalid loop " << loop <<
" for cell " << celli
1599 <<
" since face " <<
f <<
" would be split into"
1600 <<
" more than two faces" <<
endl;
1602 writeOBJ(
".", celli, loopPts, otherPoints);
1609 else if (pStat == 2)
1615 <<
"Invalid loop " << loop <<
" for cell " << celli
1616 <<
" since face " <<
f <<
" would be split into"
1617 <<
" more than two faces" <<
endl;
1619 writeOBJ(
".", celli, loopPts, otherPoints);
1635 label v1 =
f.nextLabel(fp);
1638 label eStat = edgeStatus[edgeI];
1640 if (eStat == prevStat)
1643 else if (eStat == 0)
1647 else if (eStat == 1)
1653 <<
"Invalid loop " << loop <<
" for cell " << celli
1654 <<
" since face " <<
f <<
" would be split into"
1655 <<
" more than two faces" <<
endl;
1657 writeOBJ(
".", celli, loopPts, otherPoints);
1664 else if (eStat == 2)
1670 <<
"Invalid loop " << loop <<
" for cell " << celli
1671 <<
" since face " <<
f <<
" would be split into"
1672 <<
" more than two faces" <<
endl;
1674 writeOBJ(
".", celli, loopPts, otherPoints);
1690 bool loopOk = loopAnchorConsistent(celli, loopPts, connectedPoints);
1695 bool otherLoopOk = loopAnchorConsistent(celli, loopPts, otherPoints);
1697 if (loopOk == otherLoopOk)
1703 <<
" For cell:" << celli
1704 <<
" achorpoints and nonanchorpoints are geometrically"
1705 <<
" on same side!" <<
endl
1706 <<
"cellPoints:" << cPoints <<
endl
1707 <<
"loop:" << loop <<
endl
1708 <<
"anchors:" << connectedPoints <<
endl
1709 <<
"otherPoints:" << otherPoints <<
endl;
1711 writeOBJ(
".", celli, loopPts, connectedPoints);
1718 anchorPoints.transfer(connectedPoints);
1719 connectedPoints.clear();
1723 anchorPoints.transfer(otherPoints);
1724 otherPoints.clear();
1740 loopPts[fp] = coord(loop[fp], loopWeights[fp]);
1752 label cut = loop[fp];
1756 label edgeI = getEdge(cut);
1758 weights[fp] = edgeWeight_[edgeI];
1762 weights[fp] = -great;
1769 bool Foam::cellCuts::validEdgeLoop
1777 label cut = loop[fp];
1781 label edgeI = getEdge(cut);
1784 if (edgeIsCut_[edgeI])
1786 scalar edgeLen = mesh().edges()[edgeI].mag(mesh().
points());
1790 mag(loopWeights[fp] - edgeWeight_[edgeI])
1817 const face&
f = mesh().faces()[facei];
1827 || (
findIndex(loop, vertToEVert(vertI)) != -1)
1835 const labelList& fEdges = mesh().faceEdges()[facei];
1839 label edgeI = fEdges[fEdgeI];
1845 || (
findIndex(loop, edgeToEVert(edgeI)) != -1)
1856 bool Foam::cellCuts::conservativeValidLoop
1863 if (loop.size() < 2)
1870 if (isEdge(loop[cutI]))
1872 label edgeI = getEdge(loop[cutI]);
1874 if (edgeIsCut_[edgeI])
1881 const edge&
e = mesh().edges()[edgeI];
1883 if (pointIsCut_[
e.start()] || pointIsCut_[
e.end()])
1890 const labelList& eFaces = mesh().edgeFaces()[edgeI];
1894 label nCuts = countFaceCuts(eFaces[eFacei], loop);
1907 label vertI = getVertex(loop[cutI]);
1909 if (!pointIsCut_[vertI])
1914 const labelList& pEdges = mesh().pointEdges()[vertI];
1918 label edgeI = pEdges[pEdgeI];
1920 if (edgeIsCut_[edgeI])
1931 label nCuts = countFaceCuts(
pFaces[pFacei], loop);
1947 bool Foam::cellCuts::validLoop
1953 Map<edge>& newFaceSplitCut,
1962 if (loop.size() < 2)
1971 if (!conservativeValidLoop(celli, loop))
1973 Info <<
"Invalid conservative loop: " << loop <<
endl;
1980 label cut = loop[fp];
1981 label nextCut = loop[(fp+1) % loop.size()];
1984 label meshFacei = -1;
1988 label edgeI = getEdge(cut);
1992 if (isEdge(nextCut))
1995 label nextEdgeI = getEdge(nextCut);
1998 meshFacei = edgeEdgeToFace(celli, edgeI, nextEdgeI);
2000 if (meshFacei == -1)
2010 label nextVertI = getVertex(nextCut);
2011 const edge&
e = mesh().edges()[edgeI];
2013 if (
e.start() != nextVertI &&
e.end() != nextVertI)
2016 meshFacei = edgeVertexToFace(celli, edgeI, nextVertI);
2018 if (meshFacei == -1)
2029 label vertI = getVertex(cut);
2031 if (isEdge(nextCut))
2034 label nextEdgeI = getEdge(nextCut);
2036 const edge& nextE = mesh().edges()[nextEdgeI];
2038 if (nextE.start() != vertI && nextE.end() != vertI)
2041 meshFacei = edgeVertexToFace(celli, nextEdgeI, vertI);
2043 if (meshFacei == -1)
2052 label nextVertI = getVertex(nextCut);
2057 meshFacei = vertexVertexToFace(celli, vertI, nextVertI);
2059 if (meshFacei == -1)
2067 if (meshFacei != -1)
2071 edge cutEdge(cut, nextCut);
2075 if (iter == faceSplitCut_.end())
2078 newFaceSplitCut.insert(meshFacei, cutEdge);
2083 if (iter() != cutEdge)
2092 label faceContainingLoop = loopFace(celli, loop);
2094 if (faceContainingLoop != -1)
2097 <<
"Found loop on cell " << celli <<
" with all points"
2098 <<
" on face " << faceContainingLoop <<
endl;
2111 loopPoints(loop, loopWeights),
2117 void Foam::cellCuts::setFromCellLoops()
2120 pointIsCut_ =
false;
2124 faceSplitCut_.clear();
2126 forAll(cellLoops_, celli)
2128 const labelList& loop = cellLoops_[celli];
2133 Map<edge> faceSplitCuts(loop.size());
2152 <<
"Illegal loop " << loop
2153 <<
" when recreating cut-addressing"
2154 <<
" from existing cellLoops for cell " << celli
2157 cellLoops_[celli].setSize(0);
2158 cellAnchorPoints_[celli].setSize(0);
2163 cellAnchorPoints_[celli].transfer(anchorPoints);
2168 faceSplitCut_.insert(iter.key(), iter());
2174 label cut = loop[cutI];
2178 edgeIsCut_[getEdge(cut)] =
true;
2182 pointIsCut_[getVertex(cut)] =
true;
2190 forAll(edgeIsCut_, edgeI)
2192 if (!edgeIsCut_[edgeI])
2195 edgeWeight_[edgeI] = -great;
2201 bool Foam::cellCuts::setFromCellLoop
2214 OFstream str(
"last_cell.obj");
2216 str<<
"# edges of cell " << celli <<
nl;
2228 OFstream loopStr(
"last_loop.obj");
2230 loopStr<<
"# looppoints for cell " << celli <<
nl;
2232 pointField pointsOfLoop = loopPoints(loop, loopWeights);
2243 str <<
' ' << i + 1;
2245 str <<
' ' << 1 <<
nl;
2248 bool okLoop =
false;
2250 if (validEdgeLoop(loop, loopWeights))
2253 Map<edge> faceSplitCuts(loop.size());
2258 validLoop(celli, loop, loopWeights, faceSplitCuts, anchorPoints);
2263 cellLoops_[celli] = loop;
2264 cellAnchorPoints_[celli].transfer(anchorPoints);
2269 faceSplitCut_.insert(iter.key(), iter());
2276 label cut = loop[cutI];
2280 label edgeI = getEdge(cut);
2282 edgeIsCut_[edgeI] =
true;
2284 edgeWeight_[edgeI] = loopWeights[cutI];
2288 label vertI = getVertex(cut);
2290 pointIsCut_[vertI] =
true;
2300 void Foam::cellCuts::setFromCellLoops
2304 const List<scalarField>& cellLoopWeights
2308 pointIsCut_ =
false;
2312 forAll(cellLabels, cellLabelI)
2314 label celli = cellLabels[cellLabelI];
2316 const labelList& loop = cellLoops[cellLabelI];
2320 const scalarField& loopWeights = cellLoopWeights[cellLabelI];
2322 if (setFromCellLoop(celli, loop, loopWeights))
2336 void Foam::cellCuts::setFromCellCutter
2338 const cellLooper& cellCutter,
2339 const List<refineCell>& refCells
2343 pointIsCut_ =
false;
2352 DynamicList<label> invalidCutCells(2);
2353 DynamicList<labelList> invalidCutLoops(2);
2354 DynamicList<scalarField> invalidCutLoopWeights(2);
2357 forAll(refCells, refCelli)
2359 const refineCell& refCell = refCells[refCelli];
2361 label celli = refCell.cellNo();
2363 const vector& refDir = refCell.direction();
2385 if (setFromCellLoop(celli, cellLoop, cellLoopWeights))
2391 cellLoops_[celli].setSize(0);
2394 <<
"Found loop on cell " << celli
2395 <<
" that resulted in an unexpected bad cut." <<
nl
2396 <<
" Suggestions:" <<
nl
2397 <<
" - Turn on the debug switch for 'cellCuts' to get"
2398 <<
" geometry files that identify this cell." <<
nl
2399 <<
" - Also keep in mind to check the defined"
2400 <<
" reference directions, as these are most likely the"
2401 <<
" origin of the problem."
2407 invalidCutCells.append(celli);
2408 invalidCutLoops.append(cellLoop);
2409 invalidCutLoopWeights.append(cellLoopWeights);
2416 cellLoops_[celli].setSize(0);
2420 if (debug && invalidCutCells.size())
2422 invalidCutCells.shrink();
2423 invalidCutLoops.shrink();
2424 invalidCutLoopWeights.shrink();
2426 fileName cutsFile(
"invalidLoopCells.obj");
2428 Pout<<
"cellCuts : writing inValidLoops cells to " << cutsFile <<
endl;
2430 OFstream cutsStream(cutsFile);
2441 fileName loopsFile(
"invalidLoops.obj");
2443 Pout<<
"cellCuts : writing inValidLoops loops to " << loopsFile <<
endl;
2445 OFstream loopsStream(loopsFile);
2449 forAll(invalidCutLoops, i)
2454 loopPoints(invalidCutLoops[i], invalidCutLoopWeights[i]),
2462 void Foam::cellCuts::setFromCellCutter
2464 const cellLooper& cellCutter,
2466 const List<plane>& cellCutPlanes
2470 pointIsCut_ =
false;
2479 DynamicList<label> invalidCutCells(2);
2480 DynamicList<labelList> invalidCutLoops(2);
2481 DynamicList<scalarField> invalidCutLoopWeights(2);
2486 label celli = cellLabels[i];
2507 if (setFromCellLoop(celli, cellLoop, cellLoopWeights))
2513 cellLoops_[celli].setSize(0);
2518 invalidCutCells.append(celli);
2519 invalidCutLoops.append(cellLoop);
2520 invalidCutLoopWeights.append(cellLoopWeights);
2527 cellLoops_[celli].setSize(0);
2531 if (debug && invalidCutCells.size())
2533 invalidCutCells.shrink();
2534 invalidCutLoops.shrink();
2535 invalidCutLoopWeights.shrink();
2537 fileName cutsFile(
"invalidLoopCells.obj");
2539 Pout<<
"cellCuts : writing inValidLoops cells to " << cutsFile <<
endl;
2541 OFstream cutsStream(cutsFile);
2552 fileName loopsFile(
"invalidLoops.obj");
2554 Pout<<
"cellCuts : writing inValidLoops loops to " << loopsFile <<
endl;
2556 OFstream loopsStream(loopsFile);
2560 forAll(invalidCutLoops, i)
2565 loopPoints(invalidCutLoops[i], invalidCutLoopWeights[i]),
2573 void Foam::cellCuts::orientPlanesAndLoops()
2576 forAll(cellLoops_, celli)
2578 const labelList& loop = cellLoops_[celli];
2580 if (loop.size() && cellAnchorPoints_[celli].empty())
2588 cellAnchorPoints_[celli]
2595 Pout<<
"cellAnchorPoints:" <<
endl;
2597 forAll(cellAnchorPoints_, celli)
2599 if (cellLoops_[celli].size())
2601 if (cellAnchorPoints_[celli].empty())
2604 <<
"No anchor points for cut cell " << celli <<
endl
2610 Pout<<
" cell:" << celli <<
" anchored at "
2611 << cellAnchorPoints_[celli] <<
endl;
2619 forAll(cellLoops_, celli)
2621 if (cellLoops_[celli].size())
2629 void Foam::cellCuts::calcLoopsAndAddressing(
const labelList& cutCells)
2632 forAll(edgeIsCut_, edgeI)
2634 if (edgeIsCut_[edgeI])
2636 scalar weight = edgeWeight_[edgeI];
2638 if (weight < 0 || weight > 1)
2641 <<
"Weight out of range [0,1]. Edge " << edgeI
2642 <<
" verts:" << mesh().edges()[edgeI]
2649 edgeWeight_[edgeI] = -great;
2655 calcCellLoops(cutCells);
2660 forAll(cellLoops_, celli)
2662 const labelList& loop = cellLoops_[celli];
2666 Pout<<
"cell:" << celli <<
" ";
2667 writeCuts(
Pout, loop, loopWeights(loop));
2679 void Foam::cellCuts::check()
const
2682 forAll(edgeIsCut_, edgeI)
2684 if (edgeIsCut_[edgeI])
2694 <<
"edge:" << edgeI <<
" vertices:"
2695 << mesh().edges()[edgeI]
2696 <<
" weight:" << edgeWeight_[edgeI] <<
" should have been"
2697 <<
" snapped to one of its endpoints"
2703 if (edgeWeight_[edgeI] > - 1)
2706 <<
"edge:" << edgeI <<
" vertices:"
2707 << mesh().edges()[edgeI]
2708 <<
" weight:" << edgeWeight_[edgeI] <<
" is not cut but"
2709 <<
" its weight is not marked invalid"
2716 forAll(cellLoops_, celli)
2718 const labelList& loop = cellLoops_[celli];
2722 label cut = loop[i];
2726 (isEdge(cut) && !edgeIsCut_[getEdge(cut)])
2727 || (!isEdge(cut) && !pointIsCut_[getVertex(cut)])
2731 writeCuts(
Pout, cuts, loopWeights(cuts));
2734 <<
"cell:" << celli <<
" loop:"
2736 <<
" cut:" << cut <<
" is not marked as cut"
2743 forAll(cellLoops_, celli)
2745 const labelList& anchors = cellAnchorPoints_[celli];
2747 const labelList& loop = cellLoops_[celli];
2749 if (loop.size() && anchors.empty())
2752 <<
"cell:" << celli <<
" loop:" << loop
2753 <<
" has no anchor points"
2760 label cut = loop[i];
2765 &&
findIndex(anchors, getVertex(cut)) != -1
2769 <<
"cell:" << celli <<
" loop:" << loop
2770 <<
" anchor points:" << anchors
2771 <<
" anchor:" << getVertex(cut) <<
" is part of loop"
2781 boolList cellIsCut(mesh().nCells(),
false);
2782 forAll(cellLoops_, celli)
2784 cellIsCut[celli] = cellLoops_[celli].size();
2791 label facei = iter.key();
2793 if (mesh().isInternalFace(facei))
2795 label own = mesh().faceOwner()[facei];
2796 label nei = mesh().faceNeighbour()[facei];
2798 if (cellLoops_[own].empty() && cellLoops_[nei].empty())
2801 <<
"Internal face:" << facei <<
" cut by " << iter()
2802 <<
" has owner:" << own
2803 <<
" and neighbour:" << nei
2804 <<
" that are both uncut"
2810 label bFacei = facei - mesh().nInternalFaces();
2812 label own = mesh().faceOwner()[facei];
2814 if (cellLoops_[own].empty() && !nbrCellIsCut[bFacei])
2817 <<
"Boundary face:" << facei <<
" cut by " << iter()
2818 <<
" has owner:" << own
2840 edgeIsCut_(
expand(mesh.nEdges(), meshEdges)),
2841 edgeWeight_(
expand(mesh.nEdges(), meshEdges, meshEdgeWeights)),
2842 faceSplitCut_(cutCells.size()),
2843 cellLoops_(mesh.nCells()),
2845 cellAnchorPoints_(mesh.nCells())
2849 Pout<<
"cellCuts : constructor from cut verts and edges" <<
endl;
2852 calcLoopsAndAddressing(cutCells);
2855 orientPlanesAndLoops();
2866 Pout<<
"cellCuts : leaving constructor from cut verts and edges"
2882 edgeIsCut_(
expand(mesh.nEdges(), meshEdges)),
2883 edgeWeight_(
expand(mesh.nEdges(), meshEdges, meshEdgeWeights)),
2884 faceSplitCut_(mesh.nFaces()/10 + 1),
2885 cellLoops_(mesh.nCells()),
2887 cellAnchorPoints_(mesh.nCells())
2894 Pout<<
"cellCuts : constructor from cellLoops" <<
endl;
2903 orientPlanesAndLoops();
2914 Pout<<
"cellCuts : leaving constructor from cellLoops" <<
endl;
2928 pointIsCut_(mesh.
nPoints(), false),
2929 edgeIsCut_(mesh.nEdges(), false),
2930 edgeWeight_(mesh.nEdges(), -great),
2931 faceSplitCut_(cellLabels.size()),
2932 cellLoops_(mesh.nCells()),
2934 cellAnchorPoints_(mesh.nCells())
2938 Pout<<
"cellCuts : constructor from cellLoops" <<
endl;
2943 setFromCellLoops(cellLabels,
cellLoops, cellEdgeWeights);
2949 orientPlanesAndLoops();
2960 Pout<<
"cellCuts : leaving constructor from cellLoops" <<
endl;
2973 pointIsCut_(mesh.
nPoints(), false),
2974 edgeIsCut_(mesh.nEdges(), false),
2975 edgeWeight_(mesh.nEdges(), -great),
2976 faceSplitCut_(refCells.size()),
2977 cellLoops_(mesh.nCells()),
2979 cellAnchorPoints_(mesh.nCells())
2983 Pout<<
"cellCuts : constructor from cellCutter" <<
endl;
2988 setFromCellCutter(cellCutter, refCells);
2994 orientPlanesAndLoops();
3005 Pout<<
"cellCuts : leaving constructor from cellCutter" <<
endl;
3023 pointIsCut_(pointIsCut),
3024 edgeIsCut_(edgeIsCut),
3025 edgeWeight_(edgeWeight),
3026 faceSplitCut_(faceSplitCut),
3027 cellLoops_(cellLoops),
3029 cellAnchorPoints_(cellAnchorPoints)
3033 Pout<<
"cellCuts : constructor from components" <<
endl;
3034 Pout<<
"cellCuts : leaving constructor from components" <<
endl;
3049 faceCutsPtr_.clear();
3057 const labelList& loop = cellLoops_[celli];
3063 label cut = loop[fp];
3067 label edgeI = getEdge(cut);
3069 loopPts[fp] = coord(cut, edgeWeight_[edgeI]);
3073 loopPts[fp] = coord(cut, -great);
3087 cellAnchorPoints_[celli] =
3090 mesh().cellPoints()[celli],
3091 cellAnchorPoints_[celli],
3105 void Foam::cellCuts::writeOBJ
3112 label startVertI = vertI;
3116 const point& pt = loopPts[fp];
3118 os <<
"v " << pt.
x() <<
' ' << pt.
y() <<
' ' << pt.
z() <<
endl;
3126 os <<
' ' << startVertI + fp + 1;
3136 forAll(cellLoops_, celli)
3138 writeOBJ(os, loopPoints(celli), vertI);
3145 const labelList& anchors = cellAnchorPoints_[celli];
3147 writeOBJ(dir, celli, loopPoints(celli), anchors);
Various functions to operate on Lists.
#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.
friend class const_iterator
Declare friendship with the const_iterator.
void size(const label)
Override size to be inconsistent with allocated storage.
void setSize(const label)
Reset size of List.
A HashTable to objects of type <T> with a label key.
virtual const fileName & name() const
Return the name of the stream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
static bool & parRun()
Is this a parallel run?
Description of cuts across cells.
cellCuts(const polyMesh &mesh, const labelList &cutCells, const labelList &meshVerts, const labelList &meshEdges, const scalarField &meshEdgeWeights)
Construct from cells to cut and pattern of cuts.
void writeCellOBJ(const fileName &dir, const label celli) const
debugging:Write edges of cell and loop
void flipLoopOnly(const label celli)
Flip loop for celli. Does not update anchors. Use with care.
void flip(const label celli)
Flip loop for celli. Updates anchor points as well.
const labelListList & cellLoops() const
For each cut cell the cut along the circumference.
labelList nonAnchorPoints(const labelList &cellPoints, const labelList &anchorPoints, const labelList &loop) const
Invert anchor point selection.
void clearOut()
Clear out demand driven storage.
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
const polyMesh & mesh() const
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
word name() const
Return file name (part beyond last /)
edge cmptType
Component type.
Traits class for primitives.
Mesh consisting of general polyhedral cells.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
List< labelPair > faceCuts(const face &f, const scalarField &pAlphas, const scalar isoAlpha)
Return the cuts for a given face. This returns a list of pairs of.
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.
word name(const bool)
Return a word representation of a bool.
static const labelSphericalTensor labelI(1)
Identity labelTensor.
errorManip< error > abort(error &err)
vectorField pointField
pointField is a vectorField.
List< bool > boolList
Bool container classes.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void reverse(UList< T > &, const label n)
Vector< scalar > vector
A scalar version of the templated Vector.
List< labelList > labelListList
A List of labelList.
dimensioned< scalar > mag(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
static const label labelMin
string expand(const string &s, string::size_type &index, const dictionary &dict, const bool allowEnvVars, const bool allowEmpty)
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]