60 if (elems[elemI] == elem)
77 const triSurfaceSearch&
search
82 boolList cutFace(mesh_.nFaces(),
false);
89 forAll(mesh_.edges(), edgeI)
91 if (debug && (edgeI % 10000 == 0))
93 Pout<<
"Intersecting mesh edge " << edgeI <<
" with surface"
97 const edge&
e = mesh_.edges()[edgeI];
99 const point& p0 = mesh_.points()[
e.start()];
100 const point& p1 = mesh_.points()[
e.end()];
106 const labelList& myFaces = mesh_.edgeFaces()[edgeI];
110 label facei = myFaces[myFacei];
114 cutFace[facei] =
true;
124 Pout<<
"Intersected edges of mesh with surface in = "
125 << timer.cpuTimeIncrement() <<
" s\n" <<
endl <<
endl;
132 labelList allFaces(mesh_.nFaces() - nCutFaces);
140 allFaces[allFacei++] = facei;
146 Pout<<
"Testing " << allFacei <<
" faces for piercing by surface"
150 treeBoundBox allBb(mesh_.points());
153 scalar tol = 1
e-6 * allBb.avgDim();
165 indexedOctree<treeDataFace> faceTree
167 treeDataFace(
false, mesh_, allFaces),
174 const triSurface& surf =
search.surface();
175 const edgeList& edges = surf.edges();
176 const pointField& localPoints = surf.localPoints();
182 if (debug && (edgeI % 10000 == 0))
184 Pout<<
"Intersecting surface edge " << edgeI
185 <<
" with mesh faces" <<
endl;
187 const edge&
e = edges[edgeI];
189 const point& start = localPoints[
e.start()];
190 const point& end = localPoints[
e.end()];
192 vector edgeNormal(end - start);
193 const scalar edgeMag =
mag(edgeNormal);
194 const vector smallVec = 1
e-9*edgeNormal;
196 edgeNormal /= edgeMag+vSmall;
211 label facei = faceTree.shapes().faceLabels()[pHit.index()];
215 cutFace[facei] =
true;
221 pt = pHit.hitPoint() + smallVec;
223 if (((pt-start) & edgeNormal) >= edgeMag)
233 Pout<<
"Detected an additional " << nAddFaces <<
" faces cut"
236 Pout<<
"Intersected edges of surface with mesh faces in = "
237 << timer.cpuTimeIncrement() <<
" s\n" <<
endl <<
endl;
247 void Foam::cellClassification::markCells
249 const meshSearch& queryMesh,
251 const List<point>& outsidePts
258 List<cellInfo> cellInfoList(mesh_.nCells());
261 forAll(piercedFace, facei)
263 if (piercedFace[facei])
265 cellInfoList[mesh_.faceOwner()[facei]] =
268 if (mesh_.isInternalFace(facei))
270 cellInfoList[mesh_.faceNeighbour()[facei]] =
281 labelHashSet outsideFacesMap(outsidePts.size() * 6 * 2);
283 forAll(outsidePts, outsidePtI)
286 label celli = queryMesh.findCell(outsidePts[outsidePtI], -1,
false);
291 <<
"outsidePoint " << outsidePts[outsidePtI]
292 <<
" is not inside any cell"
293 <<
nl <<
"It might be on a face or outside the geometry"
302 const labelList& myFaces = mesh_.cells()[celli];
305 outsideFacesMap.insert(myFaces[myFacei]);
315 labelList changedFaces(outsideFacesMap.toc());
317 List<cellInfo> changedFacesInfo
323 List<cellInfo> faceInfoList(mesh().nFaces());
324 FaceCellWave<cellInfo> cellInfoCalc
331 mesh_.globalData().nTotalCells() + 1
334 forAll(cellInfoList, celli)
336 label t = cellInfoList[celli].type();
342 operator[](celli) = t;
347 void Foam::cellClassification::classifyPoints
349 const label meshType,
351 List<pointStatus>& pointSide
354 pointSide.setSize(mesh_.nPoints());
356 forAll(mesh_.pointCells(), pointi)
358 const labelList& pCells = mesh_.pointCells()[pointi];
360 pointSide[pointi] = UNSET;
366 if (
type == meshType)
368 if (pointSide[pointi] == UNSET)
370 pointSide[pointi] = MESH;
372 else if (pointSide[pointi] == NONMESH)
374 pointSide[pointi] = MIXED;
381 if (pointSide[pointi] == UNSET)
383 pointSide[pointi] = NONMESH;
385 else if (pointSide[pointi] == MESH)
387 pointSide[pointi] = MIXED;
397 bool Foam::cellClassification::usesMixedPointsOnly
399 const List<pointStatus>& pointSide,
403 const faceList& faces = mesh_.faces();
405 const cell& cFaces = mesh_.cells()[celli];
409 const face&
f = faces[cFaces[cFacei]];
413 if (pointSide[
f[fp]] != MIXED)
425 void Foam::cellClassification::getMeshOutside
427 const label meshType,
432 const labelList& own = mesh_.faceOwner();
433 const labelList& nbr = mesh_.faceNeighbour();
434 const faceList& faces = mesh_.faces();
436 outsideFaces.
setSize(mesh_.nFaces());
437 outsideOwner.setSize(mesh_.nFaces());
442 for (
label facei = 0; facei < mesh_.nInternalFaces(); facei++)
444 label ownType = operator[](own[facei]);
445 label nbrType = operator[](nbr[facei]);
447 if (ownType == meshType && nbrType != meshType)
449 outsideFaces[outsideI] = faces[facei];
450 outsideOwner[outsideI] = own[facei];
453 else if (ownType != meshType && nbrType == meshType)
455 outsideFaces[outsideI] = faces[facei];
456 outsideOwner[outsideI] = nbr[facei];
463 for (
label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
465 if (
operator[](own[facei]) == meshType)
467 outsideFaces[outsideI] = faces[facei];
468 outsideOwner[outsideI] = own[facei];
472 outsideFaces.setSize(outsideI);
473 outsideOwner.setSize(outsideI);
494 markFaces(surfQuery),
513 <<
"Number of elements of cellType argument is not equal to the"
535 const label meshType,
561 for (
label iter = 0; iter < nLayers; iter++)
567 classifyPoints(meshType, newCellType, pointSide);
572 if (pointSide[pointi] == MIXED)
575 const labelList& pCells = mesh_.pointCells()[pointi];
585 newCellType[pCells[i]] = meshType;
599 forAll(newCellType, celli)
603 if (newCellType[celli] != meshType)
607 operator[](celli) = fillType;
620 const label meshType,
624 boolList hasMeshType(mesh_.nPoints(),
false);
628 forAll(mesh_.pointCells(), pointi)
630 const labelList& myCells = mesh_.pointCells()[pointi];
635 label type = operator[](myCells[myCelli]);
637 if (
type == meshType)
639 hasMeshType[pointi] =
true;
650 forAll(hasMeshType, pointi)
652 if (hasMeshType[pointi])
654 const labelList& myCells = mesh_.pointCells()[pointi];
658 if (
operator[](myCells[myCelli]) != meshType)
660 operator[](myCells[myCelli]) = fillType;
677 const label meshType,
678 const label fillType,
682 label nTotChanged = 0;
684 for (
label iter = 0; iter < maxIter; iter++)
690 classifyPoints(meshType, *
this, pointSide);
697 if (pointSide[pointi] == MIXED)
699 const labelList& pCells = mesh_.pointCells()[pointi];
703 label celli = pCells[i];
705 if (
operator[](celli) == meshType)
707 if (usesMixedPointsOnly(pointSide, celli))
709 operator[](celli) = fillType;
717 nTotChanged += nChanged;
719 Pout<<
"removeHangingCells : changed " << nChanged
720 <<
" hanging cells" <<
endl;
734 const label meshType,
735 const label fillType,
739 label nTotChanged = 0;
741 for (
label iter = 0; iter < maxIter; iter++)
748 getMeshOutside(meshType, outsideFaces, outsideOwner);
761 const labelList& eFaces = edgeFaces[edgeI];
763 if (eFaces.
size() > 2)
770 label patchFacei = eFaces[i];
772 label ownerCell = outsideOwner[patchFacei];
774 if (
operator[](ownerCell) == meshType)
776 operator[](ownerCell) = fillType;
786 nTotChanged += nChanged;
788 Pout<<
"fillRegionEdges : changed " << nChanged
789 <<
" cells using multiply connected edges" <<
endl;
803 const label meshType,
804 const label fillType,
808 label nTotChanged = 0;
810 for (
label iter = 0; iter < maxIter; iter++)
817 getMeshOutside(meshType, outsideFaces, outsideOwner);
834 const label patchPointi = meshPointMap[iter.key()];
844 const label ownerCell = outsideOwner[patchFacei];
846 if (
operator[](ownerCell) == meshType)
848 operator[](ownerCell) = fillType;
856 nTotChanged += nChanged;
858 Pout<<
"fillRegionPoints : changed " << nChanged
859 <<
" cells using multiply connected points" <<
endl;
873 os <<
"Cells:" << size() <<
endl
874 <<
" notset : " <<
count(*
this, NOTSET) <<
endl
875 <<
" cut : " <<
count(*
this, CUT) <<
endl
876 <<
" inside : " <<
count(*
this, INSIDE) <<
endl
877 <<
" outside : " <<
count(*
this, OUTSIDE) <<
endl;
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.
label size() const
Return the number of elements in the UList.
void size(const label)
Override size to be inconsistent with allocated storage.
void operator=(const UList< label > &)
Assignment to UList operator. Takes linear time.
void setSize(const label)
Reset size of List.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
A list of faces which address into the list of points.
const Map< label > & meshPointMap() const
Mesh point map. Given the global point index find its.
bool checkPointManifold(const bool report=false, labelHashSet *setPtr=nullptr) const
Checks primitivePatch for faces sharing point but not edge.
const labelListList & pointFaces() const
Return point-face addressing.
const labelListList & edgeFaces() const
Return edge-face addressing.
'Cuts' a mesh with a surface.
label fillRegionPoints(const label meshType, const label fillType, const label maxIter)
Find regionPoints and fill all neighbours. Iterate until nothing.
label fillHangingCells(const label meshType, const label fillType, const label maxIter)
Find hanging cells (cells with all points on outside) and set their.
cellClassification(const polyMesh &mesh, const meshSearch &meshQuery, const triSurfaceSearch &surfQuery, const List< point > &outsidePoints)
Construct from mesh and surface and point(s) on outside.
label growSurface(const label meshType, const label fillType)
Sets vertex neighbours of meshType cells to fillType.
void operator=(const cellClassification &)
label trimCutCells(const label nLayers, const label meshType, const label fillType)
void writeStats(Ostream &os) const
Write statistics on cell types to Ostream.
label fillRegionEdges(const label meshType, const label fillType, const label maxIter)
Find regionEdges and fill one neighbour. Iterate until nothing.
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Mesh consisting of general polyhedral cells.
Helper class to search on triSurface.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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.
PointIndexHit< point > pointIndexHit
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
vectorField pointField
pointField is a vectorField.
List< bool > boolList
Bool container classes.
vector point
Point is a vector.
Vector< scalar > vector
A scalar version of the templated Vector.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensioned< scalar > mag(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
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.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
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]