44 bool Foam::isoSurface::isTriCut
50 bool aLower = (pointValues[tri[0]] < iso_);
51 bool bLower = (pointValues[tri[1]] < iso_);
52 bool cLower = (pointValues[tri[2]] < iso_);
54 return !(aLower == bLower && aLower == cLower);
58 Foam::isoSurface::cellCutType Foam::isoSurface::calcCutType
64 const cell& cFaces = mesh_.cells()[celli];
70 const face& f = mesh_.faces()[cFaces[cFacei]];
72 for (
label fp = 1; fp < f.size() - 1; fp++)
74 triFace tri(f[0], f[fp], f[f.fcIndex(fp)]);
76 if (isTriCut(tri, pVals_))
86 bool cellLower = (cVals_[celli] < iso_);
93 label facei = cFaces[cFacei];
94 const face& f = mesh_.faces()[facei];
99 if ((pVals_[f[fp]] < iso_) != cellLower)
111 const label fp0 = tetBasePtIs_[facei] < 0 ? 0 : tetBasePtIs_[facei];
113 label fp = f.fcIndex(fp0);
114 for (
label i = 2; i < f.size(); i++)
116 label nextFp = f.fcIndex(fp);
118 if (isTriCut(
triFace(f[fp0], f[fp], f[nextFp]), pVals_))
139 const labelList& cPoints = mesh_.cellPoints(celli);
145 if ((pVals_[cPoints[i]] < iso_) != cellLower)
151 if (nPyrCuts == cPoints.size())
171 List<cellCutType>& cellCutTypes
174 const cellList& cells = mesh_.cells();
176 cellCutTypes.
setSize(cells.size());
180 cellCutTypes[celli] = calcCutType(tet.isA(mesh_, celli), celli);
182 if (cellCutTypes[celli] == CUT)
190 Pout<<
"isoSurface : detected " << nCutCells
191 <<
" candidate cut cells." <<
endl;
197 Foam::scalar Foam::isoSurface::minTetQ
200 const label faceBasePtI
206 mesh_.cellCentres()[mesh_.faceOwner()[facei]],
212 if (mesh_.isInternalFace(facei))
220 mesh_.cellCentres()[mesh_.faceNeighbour()[facei]],
231 void Foam::isoSurface::fixTetBasePtIs()
234 const cellList& cells = mesh_.cells();
235 const faceList& faces = mesh_.faces();
236 const labelList& faceOwner = mesh_.faceOwner();
237 const labelList& faceNeighbour = mesh_.faceNeighbour();
241 tetBasePtIs_ = mesh_.tetBasePtIs();
245 PackedBoolList problemCells(cells.size(),
false);
246 forAll(tetBasePtIs_, facei)
248 if (tetBasePtIs_[facei] == -1)
250 problemCells[faceOwner[facei]] =
true;
251 if (mesh_.isInternalFace(facei))
253 problemCells[faceNeighbour[facei]] =
true;
261 PackedBoolList problemPoints(mesh_.points().size(),
false);
264 if (problemCells[celli])
266 const cell& cFaces = cells[celli];
268 Map<label> pointCount;
271 const label facei = cFaces[i];
272 const face& f = faces[facei];
275 const label pointi = f[fp];
278 if (pointFnd == pointCount.end())
280 pointCount.insert(pointi, 1);
294 <<
" at:" << mesh_.points()[iter.key()]
299 problemPoints[iter.key()] =
true;
310 forAll(tetBasePtIs_, facei)
314 problemCells[faceOwner[facei]]
315 || (mesh_.isInternalFace(facei) && problemCells[faceNeighbour[facei]])
318 const face& f = faces[facei];
322 const label fp0 = tetBasePtIs_[facei] < 0 ? 0 : tetBasePtIs_[facei];
324 const bool prevPointIsProblem = problemPoints[f[f.rcIndex(fp0)]];
325 const bool nextPointIsProblem = problemPoints[f[f.fcIndex(fp0)]];
327 if (!prevPointIsProblem && !nextPointIsProblem)
335 scalar maxQ = -
GREAT;
339 const bool prevPointIsProblem = problemPoints[f[f.rcIndex(fp)]];
340 const bool nextPointIsProblem = problemPoints[f[f.fcIndex(fp)]];
342 if (!prevPointIsProblem && !nextPointIsProblem)
344 const scalar q = minTetQ(facei, fp);
356 tetBasePtIs_[facei] = maxFp;
371 Pout<<
"isoSurface : adapted starting point of triangulation on " 372 << nAdapted <<
" faces." <<
endl;
380 const bool edgeIsDiag,
381 const edge& vertices,
383 DynamicList<edge>& pointToVerts,
384 DynamicList<label>& pointToFace,
385 DynamicList<bool>& pointFromDiag,
386 EdgeMap<label>& vertsToPoint
390 if (edgeFnd != vertsToPoint.end())
397 label pointi = pointToVerts.size();
399 pointToVerts.append(vertices);
400 pointToFace.append(facei);
401 pointFromDiag.append(edgeIsDiag);
402 vertsToPoint.insert(vertices, pointi);
408 void Foam::isoSurface::generateTriPoints
411 const FixedList<scalar, 4>& s,
412 const FixedList<point, 4>& p,
413 const FixedList<label, 4>& pIndex,
414 const FixedList<bool, 6>& edgeIsDiag,
416 DynamicList<edge>& pointToVerts,
417 DynamicList<label>& pointToFace,
418 DynamicList<bool>& pointFromDiag,
420 EdgeMap<label>& vertsToPoint,
421 DynamicList<label>& verts
458 edge(pIndex[0], pIndex[1]),
459 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
468 edge(pIndex[0], pIndex[2]),
469 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
478 edge(pIndex[0], pIndex[3]),
479 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
483 if (triIndex == 0x0E)
486 label sz = verts.size();
487 Swap(verts[sz-2], verts[sz-1]);
501 edge(pIndex[1], pIndex[0]),
502 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
511 edge(pIndex[1], pIndex[3]),
512 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
521 edge(pIndex[1], pIndex[2]),
522 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
526 if (triIndex == 0x0D)
529 label sz = verts.size();
530 Swap(verts[sz-2], verts[sz-1]);
544 edge(pIndex[0], pIndex[2]),
545 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
554 edge(pIndex[1], pIndex[3]),
555 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
565 edge(pIndex[0], pIndex[3]),
566 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
578 edge(pIndex[1], pIndex[2]),
579 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
584 if (triIndex == 0x0C)
587 label sz = verts.size();
588 Swap(verts[sz-5], verts[sz-4]);
589 Swap(verts[sz-2], verts[sz-1]);
603 edge(pIndex[2], pIndex[0]),
604 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
613 edge(pIndex[2], pIndex[1]),
614 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
623 edge(pIndex[2], pIndex[3]),
624 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
628 if (triIndex == 0x0B)
631 label sz = verts.size();
632 Swap(verts[sz-2], verts[sz-1]);
646 edge(pIndex[0], pIndex[1]),
647 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
656 edge(pIndex[2], pIndex[3]),
657 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
669 edge(pIndex[0], pIndex[3]),
670 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
680 edge(pIndex[1], pIndex[2]),
681 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
686 if (triIndex == 0x0A)
689 label sz = verts.size();
690 Swap(verts[sz-5], verts[sz-4]);
691 Swap(verts[sz-2], verts[sz-1]);
705 edge(pIndex[0], pIndex[1]),
706 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
715 edge(pIndex[2], pIndex[3]),
716 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
727 edge(pIndex[1], pIndex[3]),
728 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
740 edge(pIndex[0], pIndex[2]),
741 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
745 if (triIndex == 0x09)
748 label sz = verts.size();
749 Swap(verts[sz-5], verts[sz-4]);
750 Swap(verts[sz-2], verts[sz-1]);
764 edge(pIndex[3], pIndex[0]),
765 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
774 edge(pIndex[3], pIndex[2]),
775 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
784 edge(pIndex[3], pIndex[1]),
785 pointToVerts, pointToFace, pointFromDiag, vertsToPoint
788 if (triIndex == 0x07)
791 label sz = verts.size();
792 Swap(verts[sz-2], verts[sz-1]);
800 void Foam::isoSurface::generateTriPoints
805 DynamicList<edge>& pointToVerts,
806 DynamicList<label>& pointToFace,
807 DynamicList<bool>& pointFromDiag,
809 EdgeMap<label>& vertsToPoint,
810 DynamicList<label>& verts,
811 DynamicList<label>& faceLabels
814 const faceList& faces = mesh_.faces();
815 const labelList& faceOwner = mesh_.faceOwner();
817 const cell& cFaces = mesh_.cells()[celli];
824 label facei = cFaces[0];
825 const face& f0 = faces[facei];
828 const face& f1 = faces[cFaces[1]];
829 label oppositeI = -1;
843 FixedList<bool, 6> edgeIsDiag(
false);
845 if (faceOwner[facei] == celli)
858 label startTrii = verts.size();
892 label nTris = (verts.size()-startTrii)/3;
893 for (
label i = 0; i < nTris; i++)
895 faceLabels.append(facei);
900 const pointField& cellCentres = mesh_.cellCentres();
904 label facei = cFaces[cFacei];
905 const face& f = faces[facei];
907 const label fp0 = tetBasePtIs_[facei] < 0 ? 0 : tetBasePtIs_[facei];
909 label startTrii = verts.size();
911 label fp = f.fcIndex(fp0);
912 for (
label i = 2; i < f.size(); i++)
914 label nextFp = f.fcIndex(fp);
916 FixedList<bool, 6> edgeIsDiag(
false);
920 label p2 = f[nextFp];
921 if (faceOwner[facei] == celli)
924 if (i != 2) edgeIsDiag[1] =
true;
925 if (i != f.size()-1) edgeIsDiag[0] =
true;
929 if (i != 2) edgeIsDiag[0] =
true;
930 if (i != f.size()-1) edgeIsDiag[1] =
true;
963 mesh_.nPoints()+celli
977 label nTris = (verts.size()-startTrii)/3;
978 for (
label i = 0; i < nTris; i++)
980 faceLabels.append(facei);
987 void Foam::isoSurface::triangulateOutside
989 const bool filterDiag,
995 DynamicList<face>& compactFaces,
996 DynamicList<label>& compactCellIDs
1011 const labelList& loop = edgeLoops[loopi];
1013 if (loop.size() > 2)
1015 compactFaces.
append(face(0));
1016 face& f = compactFaces.last();
1018 f.setSize(loop.size());
1022 label pointi = mp[loop[i]];
1023 if (filterDiag && pointFromDiag[pointi])
1025 label prevPointi = mp[loop[loop.fcIndex(i)]];
1028 pointFromDiag[prevPointi]
1029 && (pointToFace[pointi] != pointToFace[prevPointi])
1054 label pointi = mp[loop[i]];
1058 compactCellIDs.append(cellID);
1066 const bool filterDiag,
1067 const MeshedSurface<face>& s,
1071 DynamicList<label>& pointCompactMap,
1072 DynamicList<label>& compactCellIDs
1077 pointCompactMap.
clear();
1078 compactCellIDs.clear();
1080 DynamicList<face> compactFaces(s.size()/8);
1082 for (
label celli = 0; celli < start.size()-1; celli++)
1086 label nTris = start[celli+1]-start[celli];
1090 const SubList<face> cellFaces(s, nTris, start[celli]);
1111 labelList oldToCompact(points.size(), -1);
1112 DynamicField<point> compactPoints(points.size());
1113 pointCompactMap.
clear();
1117 face& f = compactFaces[i];
1120 label pointi = f[fp];
1121 label compacti = oldToCompact[pointi];
1124 compacti = compactPoints.size();
1125 oldToCompact[pointi] = compacti;
1126 compactPoints.append(points[pointi]);
1127 pointCompactMap.append(pointi);
1134 MeshedSurface<face> cpSurface;
1137 move(compactPoints),
1164 Pout<<
"isoSurface : iso:" << iso_ <<
" filter:" << filter <<
endl;
1173 const label nCutCells = calcCutTypes(tet, cellCutTypes);
1193 labelList startTri(mesh_.nCells()+1, 0);
1195 for (
label celli = 0; celli < mesh_.nCells(); celli++)
1197 startTri[celli] = faceLabels.
size();
1198 if (cellCutTypes[celli] != NOTCUT)
1203 tet.
isA(mesh_, celli),
1214 for (
label i = startTri[celli]; i < faceLabels.
size(); i++)
1216 cellLabels.
append(celli);
1220 startTri[mesh_.nCells()] = faceLabels.
size();
1223 pointToVerts_.transfer(pointToVerts);
1224 meshCells_.transfer(cellLabels);
1225 pointToFace_.transfer(pointToFace);
1231 mesh_.cellCentres(),
1242 allTris[i].setSize(3);
1243 allTris[i][0] = verts[verti++];
1244 allTris[i][1] = verts[verti++];
1245 allTris[i][2] = verts[verti++];
1260 move(allPoints.
ref()),
1277 Pout<<
"isoSurface : generated " << size() <<
" faces." <<
endl;
1291 (filter == DIAGCELL ?
true :
false),
1304 meshCells_.transfer(compactCellIDs);
1308 Pout<<
"isoSurface :" 1309 <<
" after removing cell centre and face-diag triangles : " 1314 if (filter == DIAGCELL)
1335 isBoundaryPoint.
set(mesh.
faces()[facei]);
1350 const labelList& eFaces = edgeFaces[edgei];
1351 if (eFaces.
size() == 1)
1355 const edge&
e = edges()[edgei];
1356 const edge& verts0 = pointToVerts_[mp[e[0]]];
1357 const edge& verts1 = pointToVerts_[mp[e[1]]];
1360 isBoundaryPoint[verts0[0]]
1361 && isBoundaryPoint[verts0[1]]
1362 && isBoundaryPoint[verts1[0]]
1363 && isBoundaryPoint[verts1[1]]
1371 if (removeFace.
set(eFaces[0]))
1382 Pout<<
"isoSurface :" 1383 <<
" removing " << nFaces
1384 <<
" faces since on open edges" <<
endl;
1394 forAll(removeFace, facei)
1396 if (!removeFace[facei])
List< labelList > labelListList
A List of labelList.
static const scalar GREAT
tetrahedron< point, const point & > tetPointRef
A cellMatcher for tet cells.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManipArg< error, int > exit(error &err, const int errNo=1)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label nInternalFaces() const
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
HashTable< label, label, Hash< label > >::iterator iterator
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
T & ref() const
Return non-const reference or generate a fatal error.
A surface zone on a MeshedSurface.
void size(const label)
Override size to be inconsistent with allocated storage.
static scalar minQuality(const polyMesh &mesh, const point &cC, const label fI, const bool isOwner, const label faceBasePtI)
Given a face and cc and starting index for triangulation determine.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void transfer(MeshedSurface< Face > &)
Transfer the contents of the argument and annul the argument.
bool insert(const Key &key)
Insert a new entry.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
isoSurface(const polyMesh &mesh, const scalarField &cellValues, const scalarField &pointValues, const scalar iso, const filterType filter=DIAGCELL)
Construct from dictionary.
List< bool > boolList
Bool container classes.
vectorField pointField
pointField is a vectorField.
void set(const PackedList< 1 > &)
Set specified bits.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
void clear()
Clear the list, i.e. set size to zero.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
friend class const_iterator
Declare friendship with the const_iterator.
void append(const T &)
Append an element at the end of the list.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
const labelListList & edgeFaces() const
Return edge-face addressing.
List< label > labelList
A List of labels.
virtual const faceList & faces() const
Return raw faces.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
virtual void reset(pointField &&points, List< Face > &&faces, surfZoneList &&zones)
Reset primitive data (points, faces and zones)
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
Addressing for a faceList slice.
List< surfZone > surfZoneList
virtual bool isA(const primitiveMesh &mesh, const label celli)
Exact match. Uses faceSizeMatch.
void setSize(const label)
Reset size of List.
prefixOSstream Pout(cout, "Pout")
A List with indirect addressing.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
const doubleScalar e
Elementary charge.
Mesh consisting of general polyhedral cells.
A class for managing temporary objects.
List< cell > cellList
list of cells