59 if (elems[elemI] == elem)
76 const triSurfaceSearch&
search
81 boolList cutFace(mesh_.nFaces(),
false);
88 forAll(mesh_.edges(), edgeI)
90 if (debug && (edgeI % 10000 == 0))
92 Pout<<
"Intersecting mesh edge " << edgeI <<
" with surface"
96 const edge&
e = mesh_.edges()[edgeI];
98 const point& p0 = mesh_.points()[
e.start()];
99 const point& p1 = mesh_.points()[
e.end()];
105 const labelList& myFaces = mesh_.edgeFaces()[edgeI];
109 label facei = myFaces[myFacei];
113 cutFace[facei] =
true;
123 Pout<<
"Intersected edges of mesh with surface in = "
124 << timer.cpuTimeIncrement() <<
" s\n" <<
endl <<
endl;
131 labelList allFaces(mesh_.nFaces() - nCutFaces);
139 allFaces[allFacei++] = facei;
145 Pout<<
"Testing " << allFacei <<
" faces for piercing by surface"
149 treeBoundBox allBb(mesh_.points());
152 scalar tol = 1
e-6 * allBb.avgDim();
164 indexedOctree<treeDataFace> faceTree
166 treeDataFace(
false, mesh_, allFaces),
173 const triSurface& surf =
search.surface();
174 const edgeList& edges = surf.edges();
175 const pointField& localPoints = surf.localPoints();
181 if (debug && (edgeI % 10000 == 0))
183 Pout<<
"Intersecting surface edge " << edgeI
184 <<
" with mesh faces" <<
endl;
186 const edge&
e = edges[edgeI];
188 const point& start = localPoints[
e.start()];
189 const point& end = localPoints[
e.end()];
191 vector edgeNormal(end - start);
192 const scalar edgeMag =
mag(edgeNormal);
193 const vector smallVec = 1
e-9*edgeNormal;
195 edgeNormal /= edgeMag+vSmall;
210 label facei = faceTree.shapes().faceLabels()[pHit.index()];
214 cutFace[facei] =
true;
220 pt = pHit.hitPoint() + smallVec;
222 if (((pt-start) & edgeNormal) >= edgeMag)
232 Pout<<
"Detected an additional " << nAddFaces <<
" faces cut"
235 Pout<<
"Intersected edges of surface with mesh faces in = "
236 << timer.cpuTimeIncrement() <<
" s\n" <<
endl <<
endl;
246 void Foam::cellClassification::markCells
258 forAll(piercedFace, facei)
260 if (piercedFace[facei])
262 cellInfoList[mesh_.faceOwner()[facei]] =
265 if (mesh_.isInternalFace(facei))
267 cellInfoList[mesh_.faceNeighbour()[facei]] =
279 labelHashSet outsideFacesMap(outsidePts.size() * 6 * 2);
281 forAll(outsidePts, outsidePtI)
289 <<
"outsidePoint " << outsidePts[outsidePtI]
290 <<
" is not inside any cell"
291 <<
nl <<
"It might be on a face or outside the geometry"
300 const labelList& myFaces = mesh_.cells()[celli];
303 outsideFacesMap.insert(myFaces[myFacei]);
313 labelList changedFaces(outsideFacesMap.toc());
322 FaceCellWave<cellInfo> cellInfoCalc
329 mesh_.globalData().nTotalCells() + 1
332 forAll(cellInfoList, celli)
334 label t = cellInfoList[celli].type();
340 operator[](celli) = t;
345 void Foam::cellClassification::classifyPoints
347 const label meshType,
352 pointSide.setSize(mesh_.nPoints());
354 forAll(mesh_.pointCells(), pointi)
356 const labelList& pCells = mesh_.pointCells()[pointi];
358 pointSide[pointi] = UNSET;
364 if (
type == meshType)
366 if (pointSide[pointi] == UNSET)
368 pointSide[pointi] = MESH;
370 else if (pointSide[pointi] == NONMESH)
372 pointSide[pointi] = MIXED;
379 if (pointSide[pointi] == UNSET)
381 pointSide[pointi] = NONMESH;
383 else if (pointSide[pointi] == MESH)
385 pointSide[pointi] = MIXED;
395 bool Foam::cellClassification::usesMixedPointsOnly
401 const faceList& faces = mesh_.faces();
403 const cell& cFaces = mesh_.cells()[celli];
407 const face&
f = faces[cFaces[cFacei]];
411 if (pointSide[
f[fp]] != MIXED)
423 void Foam::cellClassification::getMeshOutside
425 const label meshType,
430 const labelList& own = mesh_.faceOwner();
431 const labelList& nbr = mesh_.faceNeighbour();
432 const faceList& faces = mesh_.faces();
434 outsideFaces.
setSize(mesh_.nFaces());
435 outsideOwner.setSize(mesh_.nFaces());
440 for (
label facei = 0; facei < mesh_.nInternalFaces(); facei++)
442 label ownType = operator[](own[facei]);
443 label nbrType = operator[](nbr[facei]);
445 if (ownType == meshType && nbrType != meshType)
447 outsideFaces[outsideI] = faces[facei];
448 outsideOwner[outsideI] = own[facei];
451 else if (ownType != meshType && nbrType == meshType)
453 outsideFaces[outsideI] = faces[facei];
454 outsideOwner[outsideI] = nbr[facei];
461 for (
label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
463 if (
operator[](own[facei]) == meshType)
465 outsideFaces[outsideI] = faces[facei];
466 outsideOwner[outsideI] = own[facei];
470 outsideFaces.setSize(outsideI);
471 outsideOwner.setSize(outsideI);
488 markCells(markFaces(surfQuery), outsidePoints);
505 <<
"Number of elements of cellType argument is not equal to the"
527 const label meshType,
553 for (
label iter = 0; iter < nLayers; iter++)
559 classifyPoints(meshType, newCellType, pointSide);
564 if (pointSide[pointi] == MIXED)
567 const labelList& pCells = mesh_.pointCells()[pointi];
577 newCellType[pCells[i]] = meshType;
591 forAll(newCellType, celli)
595 if (newCellType[celli] != meshType)
599 operator[](celli) = fillType;
612 const label meshType,
616 boolList hasMeshType(mesh_.nPoints(),
false);
620 forAll(mesh_.pointCells(), pointi)
622 const labelList& myCells = mesh_.pointCells()[pointi];
627 label type = operator[](myCells[myCelli]);
629 if (
type == meshType)
631 hasMeshType[pointi] =
true;
642 forAll(hasMeshType, pointi)
644 if (hasMeshType[pointi])
646 const labelList& myCells = mesh_.pointCells()[pointi];
650 if (
operator[](myCells[myCelli]) != meshType)
652 operator[](myCells[myCelli]) = fillType;
669 const label meshType,
670 const label fillType,
674 label nTotChanged = 0;
676 for (
label iter = 0; iter < maxIter; iter++)
682 classifyPoints(meshType, *
this, pointSide);
689 if (pointSide[pointi] == MIXED)
691 const labelList& pCells = mesh_.pointCells()[pointi];
695 label celli = pCells[i];
697 if (
operator[](celli) == meshType)
699 if (usesMixedPointsOnly(pointSide, celli))
701 operator[](celli) = fillType;
709 nTotChanged += nChanged;
711 Pout<<
"removeHangingCells : changed " << nChanged
712 <<
" hanging cells" <<
endl;
726 const label meshType,
727 const label fillType,
731 label nTotChanged = 0;
733 for (
label iter = 0; iter < maxIter; iter++)
740 getMeshOutside(meshType, outsideFaces, outsideOwner);
753 const labelList& eFaces = edgeFaces[edgeI];
755 if (eFaces.
size() > 2)
762 label patchFacei = eFaces[i];
764 label ownerCell = outsideOwner[patchFacei];
766 if (
operator[](ownerCell) == meshType)
768 operator[](ownerCell) = fillType;
778 nTotChanged += nChanged;
780 Pout<<
"fillRegionEdges : changed " << nChanged
781 <<
" cells using multiply connected edges" <<
endl;
795 const label meshType,
796 const label fillType,
800 label nTotChanged = 0;
802 for (
label iter = 0; iter < maxIter; iter++)
809 getMeshOutside(meshType, outsideFaces, outsideOwner);
826 const label patchPointi = meshPointMap[iter.key()];
836 const label ownerCell = outsideOwner[patchFacei];
838 if (
operator[](ownerCell) == meshType)
840 operator[](ownerCell) = fillType;
848 nTotChanged += nChanged;
850 Pout<<
"fillRegionPoints : changed " << nChanged
851 <<
" cells using multiply connected points" <<
endl;
865 os <<
"Cells:" << size() <<
endl
866 <<
" notset : " <<
count(*
this, NOTSET) <<
endl
867 <<
" cut : " <<
count(*
this, CUT) <<
endl
868 <<
" inside : " <<
count(*
this, INSIDE) <<
endl
869 <<
" 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.
cellClassification(const polyMesh &mesh, const triSurfaceSearch &surfQuery, const List< point > &outsidePoints)
Construct from mesh and surface and point(s) on outside.
label fillHangingCells(const label meshType, const label fillType, const label maxIter)
Find hanging cells (cells with all points on outside) and set their.
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.
static label findCellNoTree(const polyMesh &mesh, const point &p, const pointInCellShapes=pointInCellShapes::tets)
Find the cell containing the given point. Do a.
Motion of the mesh specified as a list of pointMeshMovers.
Mesh consisting of general polyhedral cells.
Helper class to search on triSurface.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#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)
prefixOSstream Pout(cout, "Pout")
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
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]