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 = 1e-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 = 1e-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,
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;
364 label type = cellType[pCells[i]];
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),
510 if (mesh_.nCells() != size())
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)
579 label type = newCellType[pCells[i]];
585 newCellType[pCells[i]] = meshType;
599 forAll(newCellType, celli)
603 if (newCellType[celli] != meshType)
620 const label meshType,
637 if (type == meshType)
639 hasMeshType[pointi] =
true;
650 forAll(hasMeshType, pointi)
652 if (hasMeshType[pointi])
658 if (
operator[](myCells[myCelli]) != meshType)
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)
703 label celli = pCells[i];
705 if (
operator[](celli) == meshType)
707 if (usesMixedPointsOnly(pointSide, celli))
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)
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);
825 fp.checkPointManifold(
false, &nonManifoldPoints);
827 const Map<label>& meshPointMap = fp.meshPointMap();
834 const label patchPointi = meshPointMap[iter.key()];
843 const label patchFacei = pFaces[i];
844 const label ownerCell = outsideOwner[patchFacei];
846 if (
operator[](ownerCell) == meshType)
856 nTotChanged += nChanged;
858 Pout<<
"fillRegionPoints : changed " << nChanged
859 <<
" cells using multiply connected points" <<
endl;
874 <<
" notset : " << count(*
this,
NOTSET) <<
endl 875 <<
" cut : " << count(*
this,
CUT) <<
endl 876 <<
" inside : " << count(*
this,
INSIDE) <<
endl Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search...
label trimCutCells(const label nLayers, const label meshType, const label fillType)
#define forAll(list, i)
Loop across all elements in list.
FvWallInfoData< WallInfo, label > 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)
T & operator[](const label)
Return element of UList.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
void size(const label)
Override size to be inconsistent with allocated storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Holds information (coordinate and normal) regarding nearest wall point.
PointIndexHit< point > pointIndexHit
Vector< scalar > vector
A scalar version of the templated Vector.
void operator=(const cellClassification &)
Various functions to operate on Lists.
virtual const pointField & points() const
Return raw points.
List< bool > boolList
Bool container classes.
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
cellClassification(const polyMesh &mesh, const meshSearch &meshQuery, const triSurfaceSearch &surfQuery, const pointField &outsidePoints)
Construct from mesh and surface and point(s) on outside.
Helper class to search on triSurface.
A list of faces which address into the list of points.
vectorField pointField
pointField is a vectorField.
'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.
List< label > labelList
A List of labels.
errorManip< error > abort(error &err)
const labelListList & pointCells() const
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]
An Ostream is an abstract base class for all output systems (streams, files, token lists...
defineTypeNameAndDebug(combustionModel, 0)
void operator=(const UList< label > &)
Assignment to UList operator. Takes linear time.
void setSize(const label)
Reset size of List.
vector point
Point is a vector.
label growSurface(const label meshType, const label fillType)
Sets vertex neighbours of meshType cells to fillType.
prefixOSstream Pout(cout, "Pout")
dimensioned< scalar > mag(const dimensioned< Type > &)
label fillRegionEdges(const label meshType, const label fillType, const label maxIter)
Find regionEdges and fill one neighbour. Iterate until nothing.
void writeStats(Ostream &os) const
Write statistics on cell types to Ostream.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Mesh consisting of general polyhedral cells.
label fillHangingCells(const label meshType, const label fillType, const label maxIter)
Find hanging cells (cells with all points on outside) and set their.
label size() const
Return the number of elements in the UList.