cellClassification.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2018 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "cellClassification.H"
30 #include "triSurfaceSearch.H"
31 #include "indexedOctree.H"
32 #include "treeDataFace.H"
33 #include "meshSearch.H"
34 #include "cellInfo.H"
35 #include "polyMesh.H"
36 #include "MeshWave.H"
37 #include "ListOps.H"
38 #include "meshTools.H"
39 #include "cpuTime.H"
40 #include "triSurface.H"
41 #include "globalMeshData.H"
42 
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 
45 namespace Foam
46 {
47 defineTypeNameAndDebug(cellClassification, 0);
48 }
49 
50 
51 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 
53 Foam::label Foam::cellClassification::count
54 (
55  const labelList& elems,
56  const label elem
57 )
58 {
59  label cnt = 0;
60 
61  forAll(elems, elemI)
62  {
63  if (elems[elemI] == elem)
64  {
65  cnt++;
66  }
67  }
68  return cnt;
69 
70 }
71 
72 
73 // Mark all faces that are cut by the surface. Two pass:
74 // Pass1: mark all mesh edges that intersect surface (quick since triangle
75 // pierce test).
76 // Pass2: Check for all point neighbours of these faces whether any of their
77 // faces are pierced.
78 Foam::boolList Foam::cellClassification::markFaces
79 (
80  const triSurfaceSearch& search
81 ) const
82 {
83  cpuTime timer;
84 
85  boolList cutFace(mesh_.nFaces(), false);
86 
87  label nCutFaces = 0;
88 
89  // Intersect mesh edges with surface (is fast) and mark all faces that
90  // use edge.
91 
92  forAll(mesh_.edges(), edgeI)
93  {
94  if (debug && (edgeI % 10000 == 0))
95  {
96  Pout<< "Intersecting mesh edge " << edgeI << " with surface"
97  << endl;
98  }
99 
100  const edge& e = mesh_.edges()[edgeI];
101 
102  const point& p0 = mesh_.points()[e.start()];
103  const point& p1 = mesh_.points()[e.end()];
104 
105  pointIndexHit pHit(search.tree().findLineAny(p0, p1));
106 
107  if (pHit.hit())
108  {
109  const labelList& myFaces = mesh_.edgeFaces()[edgeI];
110 
111  forAll(myFaces, myFacei)
112  {
113  label facei = myFaces[myFacei];
114 
115  if (!cutFace[facei])
116  {
117  cutFace[facei] = true;
118 
119  nCutFaces++;
120  }
121  }
122  }
123  }
124 
125  if (debug)
126  {
127  Pout<< "Intersected edges of mesh with surface in = "
128  << timer.cpuTimeIncrement() << " s\n" << endl << endl;
129  }
130 
131  //
132  // Construct octree on faces that have not yet been marked as cut
133  //
134 
135  labelList allFaces(mesh_.nFaces() - nCutFaces);
136 
137  label allFacei = 0;
138 
139  forAll(cutFace, facei)
140  {
141  if (!cutFace[facei])
142  {
143  allFaces[allFacei++] = facei;
144  }
145  }
146 
147  if (debug)
148  {
149  Pout<< "Testing " << allFacei << " faces for piercing by surface"
150  << endl;
151  }
152 
153  treeBoundBox allBb(mesh_.points());
154 
155  // Extend domain slightly (also makes it 3D if was 2D)
156  scalar tol = 1e-6 * allBb.avgDim();
157 
158  point& bbMin = allBb.min();
159  bbMin.x() -= tol;
160  bbMin.y() -= tol;
161  bbMin.z() -= tol;
162 
163  point& bbMax = allBb.max();
164  bbMax.x() += 2*tol;
165  bbMax.y() += 2*tol;
166  bbMax.z() += 2*tol;
167 
168  indexedOctree<treeDataFace> faceTree
169  (
170  treeDataFace(false, mesh_, allFaces),
171  allBb, // overall search domain
172  8, // maxLevel
173  10, // leafsize
174  3.0 // duplicity
175  );
176 
177  const triSurface& surf = search.surface();
178  const edgeList& edges = surf.edges();
179  const pointField& localPoints = surf.localPoints();
180 
181  label nAddFaces = 0;
182 
183  forAll(edges, edgeI)
184  {
185  if (debug && (edgeI % 10000 == 0))
186  {
187  Pout<< "Intersecting surface edge " << edgeI
188  << " with mesh faces" << endl;
189  }
190  const edge& e = edges[edgeI];
191 
192  const point& start = localPoints[e.start()];
193  const point& end = localPoints[e.end()];
194 
195  vector edgeNormal(end - start);
196  const scalar edgeMag = mag(edgeNormal);
197  const vector smallVec = 1e-9*edgeNormal;
198 
199  edgeNormal /= edgeMag+VSMALL;
200 
201  // Current start of pierce test
202  point pt = start;
203 
204  while (true)
205  {
206  pointIndexHit pHit(faceTree.findLine(pt, end));
207 
208  if (!pHit.hit())
209  {
210  break;
211  }
212  else
213  {
214  label facei = faceTree.shapes().faceLabels()[pHit.index()];
215 
216  if (!cutFace[facei])
217  {
218  cutFace[facei] = true;
219 
220  nAddFaces++;
221  }
222 
223  // Restart from previous endpoint
224  pt = pHit.hitPoint() + smallVec;
225 
226  if (((pt-start) & edgeNormal) >= edgeMag)
227  {
228  break;
229  }
230  }
231  }
232  }
233 
234  if (debug)
235  {
236  Pout<< "Detected an additional " << nAddFaces << " faces cut"
237  << endl;
238 
239  Pout<< "Intersected edges of surface with mesh faces in = "
240  << timer.cpuTimeIncrement() << " s\n" << endl << endl;
241  }
242 
243  return cutFace;
244 }
245 
246 
247 // Determine faces cut by surface and use to divide cells into types. See
248 // cellInfo. All cells reachable from outsidePts are considered to be of type
249 // 'outside'
250 void Foam::cellClassification::markCells
251 (
252  const meshSearch& queryMesh,
253  const boolList& piercedFace,
254  const pointField& outsidePts
255 )
256 {
257  // Use meshwave to partition mesh, starting from outsidePt
258 
259 
260  // Construct null; sets type to NOTSET
261  List<cellInfo> cellInfoList(mesh_.nCells());
262 
263  // Mark cut cells first
264  forAll(piercedFace, facei)
265  {
266  if (piercedFace[facei])
267  {
268  cellInfoList[mesh_.faceOwner()[facei]] =
269  cellInfo(cellClassification::CUT);
270 
271  if (mesh_.isInternalFace(facei))
272  {
273  cellInfoList[mesh_.faceNeighbour()[facei]] =
274  cellInfo(cellClassification::CUT);
275  }
276  }
277  }
278 
279  //
280  // Mark cells containing outside points as being outside
281  //
282 
283  // Coarse guess number of faces
284  labelHashSet outsideFacesMap(outsidePts.size() * 6 * 2);
285 
286  forAll(outsidePts, outsidePtI)
287  {
288  // Use linear search for points.
289  label celli = queryMesh.findCell(outsidePts[outsidePtI], -1, false);
290 
291  if (returnReduce(celli, maxOp<label>()) == -1)
292  {
294  << "outsidePoint " << outsidePts[outsidePtI]
295  << " is not inside any cell"
296  << nl << "It might be on a face or outside the geometry"
297  << exit(FatalError);
298  }
299 
300  if (celli >= 0)
301  {
302  cellInfoList[celli] = cellInfo(cellClassification::OUTSIDE);
303 
304  // Mark faces of celli
305  const labelList& myFaces = mesh_.cells()[celli];
306  outsideFacesMap.insert(myFaces);
307  }
308  }
309 
310 
311  //
312  // Mark faces to start wave from
313  //
314 
315  labelList changedFaces(outsideFacesMap.toc());
316 
317  List<cellInfo> changedFacesInfo
318  (
319  changedFaces.size(),
321  );
322 
323  MeshWave<cellInfo> cellInfoCalc
324  (
325  mesh_,
326  changedFaces, // Labels of changed faces
327  changedFacesInfo, // Information on changed faces
328  cellInfoList, // Information on all cells
329  mesh_.globalData().nTotalCells()+1 // max iterations
330  );
331 
332  // Get information out of cellInfoList
333  const List<cellInfo>& allInfo = cellInfoCalc.allCellInfo();
334 
335  forAll(allInfo, celli)
336  {
337  label t = allInfo[celli].type();
338 
340  {
342  }
343  operator[](celli) = t;
344  }
345 }
346 
347 
348 void Foam::cellClassification::classifyPoints
349 (
350  const label meshType,
351  const labelList& cellType,
352  List<pointStatus>& pointSide
353 ) const
354 {
355  pointSide.setSize(mesh_.nPoints());
356 
357  forAll(mesh_.pointCells(), pointi)
358  {
359  const labelList& pCells = mesh_.pointCells()[pointi];
360 
361  pointSide[pointi] = UNSET;
362 
363  forAll(pCells, i)
364  {
365  label type = cellType[pCells[i]];
366 
367  if (type == meshType)
368  {
369  if (pointSide[pointi] == UNSET)
370  {
371  pointSide[pointi] = MESH;
372  }
373  else if (pointSide[pointi] == NONMESH)
374  {
375  pointSide[pointi] = MIXED;
376 
377  break;
378  }
379  }
380  else
381  {
382  if (pointSide[pointi] == UNSET)
383  {
384  pointSide[pointi] = NONMESH;
385  }
386  else if (pointSide[pointi] == MESH)
387  {
388  pointSide[pointi] = MIXED;
389 
390  break;
391  }
392  }
393  }
394  }
395 }
396 
397 
398 bool Foam::cellClassification::usesMixedPointsOnly
399 (
400  const List<pointStatus>& pointSide,
401  const label celli
402 ) const
403 {
404  const faceList& faces = mesh_.faces();
405 
406  const cell& cFaces = mesh_.cells()[celli];
407 
408  forAll(cFaces, cFacei)
409  {
410  const face& f = faces[cFaces[cFacei]];
411 
412  forAll(f, fp)
413  {
414  if (pointSide[f[fp]] != MIXED)
415  {
416  return false;
417  }
418  }
419  }
420 
421  // All points are mixed.
422  return true;
423 }
424 
425 
426 void Foam::cellClassification::getMeshOutside
427 (
428  const label meshType,
429  faceList& outsideFaces,
430  labelList& outsideOwner
431 ) const
432 {
433  const labelList& own = mesh_.faceOwner();
434  const labelList& nbr = mesh_.faceNeighbour();
435  const faceList& faces = mesh_.faces();
436 
437  outsideFaces.setSize(mesh_.nFaces());
438  outsideOwner.setSize(mesh_.nFaces());
439  label outsideI = 0;
440 
441  // Get faces on interface between meshType and non-meshType
442 
443  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
444  {
445  label ownType = operator[](own[facei]);
446  label nbrType = operator[](nbr[facei]);
447 
448  if (ownType == meshType && nbrType != meshType)
449  {
450  outsideFaces[outsideI] = faces[facei];
451  outsideOwner[outsideI] = own[facei]; // meshType cell
452  outsideI++;
453  }
454  else if (ownType != meshType && nbrType == meshType)
455  {
456  outsideFaces[outsideI] = faces[facei];
457  outsideOwner[outsideI] = nbr[facei]; // meshType cell
458  outsideI++;
459  }
460  }
461 
462  // Get faces on outside of real mesh with cells of meshType.
463 
464  for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
465  {
466  if (operator[](own[facei]) == meshType)
467  {
468  outsideFaces[outsideI] = faces[facei];
469  outsideOwner[outsideI] = own[facei]; // meshType cell
470  outsideI++;
471  }
472  }
473  outsideFaces.setSize(outsideI);
474  outsideOwner.setSize(outsideI);
475 }
476 
477 
478 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
479 
480 // Construct from mesh and surface and point(s) on outside
482 (
483  const polyMesh& mesh,
484  const meshSearch& meshQuery,
485  const triSurfaceSearch& surfQuery,
486  const pointField& outsidePoints
487 )
488 :
490  mesh_(mesh)
491 {
492  markCells
493  (
494  meshQuery,
495  markFaces(surfQuery),
496  outsidePoints
497  );
498 }
499 
500 
501 // Construct from mesh and meshType.
503 (
504  const polyMesh& mesh,
505  const labelList& cellType
506 )
507 :
509  mesh_(mesh)
510 {
511  if (mesh_.nCells() != size())
512  {
514  << "Number of elements of cellType argument is not equal to the"
515  << " number of cells" << abort(FatalError);
516  }
517 }
518 
519 
520 // Construct as copy
522 :
523  labelList(cType),
524  mesh_(cType.mesh())
525 {}
526 
527 
528 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
529 
530 
531 // Makes cutCells further than nLayers away from meshType to
532 // fillType. Returns number of cells changed.
534 (
535  const label nLayers,
536  const label meshType,
537  const label fillType
538 )
539 {
540  // Temporary cell type for growing.
541  labelList newCellType(*this);
542 
543 // // Split types into outside and rest
544 // forAll(*this, celli)
545 // {
546 // label type = operator[](celli);
547 //
548 // if (type == meshType)
549 // {
550 // newCellType[celli] = type;
551 // }
552 // else
553 // {
554 // newCellType[celli] = fillType;
555 // }
556 // }
557 
558  newCellType = *this;
559 
560 
561  // Do point-cell-point walk on newCellType out from meshType cells
562  for (label iter = 0; iter < nLayers; iter++)
563  {
564  // Get status of points: visible from meshType (pointSide == MESH)
565  // or fillType/cutCells cells (pointSide == NONMESH) or
566  // both (pointSide == MIXED)
567  List<pointStatus> pointSide(mesh_.nPoints());
568  classifyPoints(meshType, newCellType, pointSide);
569 
570  // Grow layer of outside cells
571  forAll(pointSide, pointi)
572  {
573  if (pointSide[pointi] == MIXED)
574  {
575  // Make cut
576  const labelList& pCells = mesh_.pointCells()[pointi];
577 
578  forAll(pCells, i)
579  {
580  label type = newCellType[pCells[i]];
581 
583  {
584  // Found cut cell sharing point with
585  // mesh type cell. Grow.
586  newCellType[pCells[i]] = meshType;
587  }
588  }
589  }
590  }
591  }
592 
593  // Merge newCellType into *this:
594  // - leave meshType cells intact
595  // - leave nonMesh cells intact
596  // - make cutcells fillType if they were not marked in newCellType
597 
598  label nChanged = 0;
599 
600  forAll(newCellType, celli)
601  {
602  if (operator[](celli) == cellClassification::CUT)
603  {
604  if (newCellType[celli] != meshType)
605  {
606  // Cell was cutCell but further than nLayers away from
607  // meshType. Convert to fillType.
608  operator[](celli) = fillType;
609  nChanged++;
610  }
611  }
612  }
613 
614  return nChanged;
615 }
616 
617 
618 // Grow surface by pointNeighbours of type meshType
620 (
621  const label meshType,
622  const label fillType
623 )
624 {
625  boolList hasMeshType(mesh_.nPoints(), false);
626 
627  // Mark points used by meshType cells
628 
629  forAll(mesh_.pointCells(), pointi)
630  {
631  const labelList& myCells = mesh_.pointCells()[pointi];
632 
633  // Check if one of cells has meshType
634  forAll(myCells, myCelli)
635  {
636  label type = operator[](myCells[myCelli]);
637 
638  if (type == meshType)
639  {
640  hasMeshType[pointi] = true;
641 
642  break;
643  }
644  }
645  }
646 
647  // Change neighbours of marked points
648 
649  label nChanged = 0;
650 
651  forAll(hasMeshType, pointi)
652  {
653  if (hasMeshType[pointi])
654  {
655  const labelList& myCells = mesh_.pointCells()[pointi];
656 
657  forAll(myCells, myCelli)
658  {
659  if (operator[](myCells[myCelli]) != meshType)
660  {
661  operator[](myCells[myCelli]) = fillType;
662 
663  nChanged++;
664  }
665  }
666  }
667  }
668  return nChanged;
669 }
670 
671 
672 // Check all points used by cells of meshType for use of at least one point
673 // which is not on the outside. If all points are on the outside of the mesh
674 // this would probably result in a flattened cell when projecting the cell
675 // onto the surface.
677 (
678  const label meshType,
679  const label fillType,
680  const label maxIter
681 )
682 {
683  label nTotChanged = 0;
684 
685  for (label iter = 0; iter < maxIter; iter++)
686  {
687  label nChanged = 0;
688 
689  // Get status of points: visible from meshType or non-meshType cells
690  List<pointStatus> pointSide(mesh_.nPoints());
691  classifyPoints(meshType, *this, pointSide);
692 
693  // Check all cells using mixed point type for whether they use mixed
694  // points only. Note: could probably speed this up by counting number
695  // of mixed verts per face and mixed faces per cell or something?
696  forAll(pointSide, pointi)
697  {
698  if (pointSide[pointi] == MIXED)
699  {
700  const labelList& pCells = mesh_.pointCells()[pointi];
701 
702  forAll(pCells, i)
703  {
704  label celli = pCells[i];
705 
706  if (operator[](celli) == meshType)
707  {
708  if (usesMixedPointsOnly(pointSide, celli))
709  {
710  operator[](celli) = fillType;
711 
712  nChanged++;
713  }
714  }
715  }
716  }
717  }
718  nTotChanged += nChanged;
719 
720  Pout<< "removeHangingCells : changed " << nChanged
721  << " hanging cells" << endl;
722 
723  if (nChanged == 0)
724  {
725  break;
726  }
727  }
728 
729  return nTotChanged;
730 }
731 
732 
734 (
735  const label meshType,
736  const label fillType,
737  const label maxIter
738 )
739 {
740  label nTotChanged = 0;
741 
742  for (label iter = 0; iter < maxIter; iter++)
743  {
744  // Get interface between meshType cells and non-meshType cells as a list
745  // of faces and for each face the cell which is the meshType.
746  faceList outsideFaces;
747  labelList outsideOwner;
748 
749  getMeshOutside(meshType, outsideFaces, outsideOwner);
750 
751  // Build primitivePatch out of it and check it for problems.
752  primitiveFacePatch fp(outsideFaces, mesh_.points());
753 
754  const labelListList& edgeFaces = fp.edgeFaces();
755 
756  label nChanged = 0;
757 
758  // Check all edgeFaces for non-manifoldness
759 
760  forAll(edgeFaces, edgeI)
761  {
762  const labelList& eFaces = edgeFaces[edgeI];
763 
764  if (eFaces.size() > 2)
765  {
766  // patch connected through pinched edge. Remove first face using
767  // edge (and not yet changed)
768 
769  forAll(eFaces, i)
770  {
771  label patchFacei = eFaces[i];
772 
773  label ownerCell = outsideOwner[patchFacei];
774 
775  if (operator[](ownerCell) == meshType)
776  {
777  operator[](ownerCell) = fillType;
778 
779  nChanged++;
780 
781  break;
782  }
783  }
784  }
785  }
786 
787  nTotChanged += nChanged;
788 
789  Pout<< "fillRegionEdges : changed " << nChanged
790  << " cells using multiply connected edges" << endl;
791 
792  if (nChanged == 0)
793  {
794  break;
795  }
796  }
797 
798  return nTotChanged;
799 }
800 
801 
803 (
804  const label meshType,
805  const label fillType,
806  const label maxIter
807 )
808 {
809  label nTotChanged = 0;
810 
811  for (label iter = 0; iter < maxIter; ++iter)
812  {
813  // Get interface between meshType cells and non-meshType cells as a list
814  // of faces and for each face the cell which is the meshType.
815  faceList outsideFaces;
816  labelList outsideOwner;
817 
818  getMeshOutside(meshType, outsideFaces, outsideOwner);
819 
820  // Build primitivePatch out of it and check it for problems.
821  primitiveFacePatch fp(outsideFaces, mesh_.points());
822 
823  labelHashSet nonManifoldPoints;
824 
825  // Check for non-manifold points.
826  fp.checkPointManifold(false, &nonManifoldPoints);
827 
828  const Map<label>& meshPointMap = fp.meshPointMap();
829 
830  label nChanged = 0;
831 
832  for (const label nonManPti : nonManifoldPoints)
833  {
834  // Find a face on fp using point and remove it.
835  const label patchPointi = meshPointMap[nonManPti];
836 
837  const labelList& pFaces = fp.pointFaces()[patchPointi];
838 
839  // Remove any face using conflicting point. Does first face which
840  // has not yet been done. Could be more intelligent and decide which
841  // one would be best to remove.
842  for (const label patchFacei : pFaces)
843  {
844  const label ownerCell = outsideOwner[patchFacei];
845 
846  if (operator[](ownerCell) == meshType)
847  {
848  operator[](ownerCell) = fillType;
849 
850  ++nChanged;
851  break;
852  }
853  }
854  }
855 
856  nTotChanged += nChanged;
857 
858  Pout<< "fillRegionPoints : changed " << nChanged
859  << " cells using multiply connected points" << endl;
860 
861  if (nChanged == 0)
862  {
863  break;
864  }
865  }
866 
867  return nTotChanged;
868 }
869 
870 
872 {
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;
878 }
879 
880 
881 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
882 
884 {
886 }
887 
888 
889 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
cellClassification.H
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
meshTools.H
Foam::Vector::x
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
Foam::edgeList
List< edge > edgeList
A List of edges.
Definition: edgeList.H:63
Foam::meshSearch
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Definition: meshSearch.H:60
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
globalMeshData.H
indexedOctree.H
Foam::cellClassification::CUT
Definition: cellClassification.H:132
Foam::Map< label >
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:65
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::cellClassification::INSIDE
Definition: cellClassification.H:130
triSurface.H
polyMesh.H
Foam::HashSet< label, Hash< label > >
Foam::triSurfaceSearch
Helper class to search on triSurface.
Definition: triSurfaceSearch.H:58
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::cellClassification::trimCutCells
label trimCutCells(const label nLayers, const label meshType, const label fillType)
Definition: cellClassification.C:534
Foam::cellClassification::fillHangingCells
label fillHangingCells(const label meshType, const label fillType, const label maxIter)
Find hanging cells (cells with all points on outside) and set their.
Definition: cellClassification.C:677
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
treeDataFace.H
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::VectorSpace::min
static const Form min
Definition: VectorSpace.H:118
Foam::cpuTime
cpuTimeCxx cpuTime
Selection of preferred clock mechanism for the elapsed cpu time.
Definition: cpuTimeFwd.H:41
Foam::Field< vector >
Foam::cellClassification::cellClassification
cellClassification(const polyMesh &mesh, const meshSearch &meshQuery, const triSurfaceSearch &surfQuery, const pointField &outsidePoints)
Construct from mesh and surface and point(s) on outside.
Definition: cellClassification.C:482
MeshWave.H
Foam::cellClassification::operator=
void operator=(const cellClassification &)
Definition: cellClassification.C:883
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::cellClassification::OUTSIDE
Definition: cellClassification.H:131
Foam::cellClassification::fillRegionEdges
label fillRegionEdges(const label meshType, const label fillType, const label maxIter)
Find regionEdges and fill one neighbour. Iterate until nothing.
Definition: cellClassification.C:734
Foam::cellClassification::NOTSET
Definition: cellClassification.H:129
Foam::List::operator=
void operator=(const UList< T > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:498
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::cellClassification
'Cuts' a mesh with a surface.
Definition: cellClassification.H:117
Foam::cellClassification::writeStats
void writeStats(Ostream &os) const
Write statistics on cell types to Ostream.
Definition: cellClassification.C:871
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::pointIndexHit
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
meshSearch.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::VectorSpace::max
static const Form max
Definition: VectorSpace.H:117
f
labelList f(nPoints)
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::vtk::cellType
cellType
Equivalent to enumeration in "vtkCellType.h".
Definition: foamVtkCore.H:89
Foam::List< bool >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::cellClassification::fillRegionPoints
label fillRegionPoints(const label meshType, const label fillType, const label maxIter)
Find regionPoints and fill all neighbours. Iterate until nothing.
Definition: cellClassification.C:803
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::search
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:571
triSurfaceSearch.H
ListOps.H
Various functions to operate on Lists.
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
p0
const volScalarField & p0
Definition: EEqn.H:36
Foam::cellClassification::growSurface
label growSurface(const label meshType, const label fillType)
Sets vertex neighbours of meshType cells to fillType.
Definition: cellClassification.C:620
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
cellInfo.H
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::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].reset(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, &oldCyclicPolyPatch::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]
Definition: readKivaGrid.H:235
Foam::cellClassification::cType
cType
Type of cell.
Definition: cellClassification.H:127
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:79