polyMeshZipUpCells.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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "polyMeshZipUpCells.H"
29 #include "polyMesh.H"
30 #include "Time.H"
31 
32 // #define DEBUG_ZIPUP 1
33 // #define DEBUG_CHAIN 1
34 // #define DEBUG_ORDER 1
35 
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 
39 {
40  if (polyMesh::debug)
41  {
42  Info<< "bool polyMeshZipUpCells(polyMesh& mesh) const: "
43  << "zipping up topologically open cells" << endl;
44  }
45 
46  // Algorithm:
47  // Take the original mesh and visit all cells. For every cell
48  // calculate the edges of all faces on the cells. A cell is
49  // correctly topologically closed when all the edges are referenced
50  // by exactly two faces. If the edges are referenced only by a
51  // single face, additional vertices need to be inserted into some
52  // of the faces (topological closedness). If an edge is
53  // referenced by more that two faces, there is an error in
54  // topological closedness.
55  // Point insertion into the faces is done by attempting to create
56  // closed loops and inserting the intermediate points into the
57  // defining edge
58  // Note:
59  // The algorithm is recursive and changes the mesh faces in each
60  // pass. It is therefore essential to discard the addressing
61  // after every pass. The algorithm is completed when the mesh
62  // stops changing.
63 
64  label nChangedFacesInMesh = 0;
65  label nCycles = 0;
66 
67  labelHashSet problemCells;
68 
69  do
70  {
71  nChangedFacesInMesh = 0;
72 
73  const cellList& Cells = mesh.cells();
74  const pointField& Points = mesh.points();
75 
76  faceList newFaces = mesh.faces();
77 
78  const faceList& oldFaces = mesh.faces();
79  const labelListList& pFaces = mesh.pointFaces();
80 
81  forAll(Cells, celli)
82  {
83  const labelList& curFaces = Cells[celli];
84  const edgeList cellEdges = Cells[celli].edges(oldFaces);
85  const labelList cellPoints = Cells[celli].labels(oldFaces);
86 
87  // Find the edges used only once in the cell
88 
89  labelList edgeUsage(cellEdges.size(), Zero);
90 
91  forAll(curFaces, facei)
92  {
93  edgeList curFaceEdges = oldFaces[curFaces[facei]].edges();
94 
95  forAll(curFaceEdges, faceEdgeI)
96  {
97  const edge& curEdge = curFaceEdges[faceEdgeI];
98 
99  forAll(cellEdges, cellEdgeI)
100  {
101  if (cellEdges[cellEdgeI] == curEdge)
102  {
103  edgeUsage[cellEdgeI]++;
104  break;
105  }
106  }
107  }
108  }
109 
110  edgeList singleEdges(cellEdges.size());
111  label nSingleEdges = 0;
112 
113  forAll(edgeUsage, edgeI)
114  {
115  if (edgeUsage[edgeI] == 1)
116  {
117  singleEdges[nSingleEdges] = cellEdges[edgeI];
118  nSingleEdges++;
119  }
120  else if (edgeUsage[edgeI] != 2)
121  {
123  << "edge " << cellEdges[edgeI] << " in cell " << celli
124  << " used " << edgeUsage[edgeI] << " times. " << nl
125  << "Should be 1 or 2 - serious error "
126  << "in mesh structure. " << endl;
127 
128  #ifdef DEBUG_ZIPUP
129  forAll(curFaces, facei)
130  {
131  Info<< "face: " << oldFaces[curFaces[facei]]
132  << endl;
133  }
134 
135  Info<< "Cell edges: " << cellEdges << nl
136  << "Edge usage: " << edgeUsage << nl
137  << "Cell points: " << cellPoints << endl;
138 
139  forAll(cellPoints, cpI)
140  {
141  Info<< "vertex create \"" << cellPoints[cpI]
142  << "\" coordinates "
143  << Points[cellPoints[cpI]] << endl;
144  }
145  #endif
146 
147  // Gather the problem cell
148  problemCells.insert(celli);
149  }
150  }
151 
152  // Check if the cell is already zipped up
153  if (nSingleEdges == 0) continue;
154 
155  singleEdges.setSize(nSingleEdges);
156 
157  #ifdef DEBUG_ZIPUP
158  Info<< "Cell " << celli << endl;
159 
160  forAll(curFaces, facei)
161  {
162  Info<< "face: " << oldFaces[curFaces[facei]] << endl;
163  }
164 
165  Info<< "Cell edges: " << cellEdges << nl
166  << "Edge usage: " << edgeUsage << nl
167  << "Single edges: " << singleEdges << nl
168  << "Cell points: " << cellPoints << endl;
169 
170  forAll(cellPoints, cpI)
171  {
172  Info<< "vertex create \"" << cellPoints[cpI]
173  << "\" coordinates "
174  << points()[cellPoints[cpI]] << endl;
175  }
176  #endif
177 
178  // Loop through all single edges and mark the points they use
179  // points marked twice are internal to edge; those marked more than
180  // twice are corners
181 
182  labelList pointUsage(cellPoints.size(), Zero);
183 
184  forAll(singleEdges, edgeI)
185  {
186  const edge& curEdge = singleEdges[edgeI];
187 
188  forAll(cellPoints, pointi)
189  {
190  if
191  (
192  cellPoints[pointi] == curEdge.start()
193  || cellPoints[pointi] == curEdge.end()
194  )
195  {
196  pointUsage[pointi]++;
197  }
198  }
199  }
200 
201  boolList singleEdgeUsage(singleEdges.size(), false);
202 
203  // loop through all edges and eliminate the ones that are
204  // blocked out
205  forAll(singleEdges, edgeI)
206  {
207  bool blockedHead = false;
208  bool blockedTail = false;
209 
210  label newEdgeStart = singleEdges[edgeI].start();
211  label newEdgeEnd = singleEdges[edgeI].end();
212 
213  // check that the edge has not got all ends blocked
214  forAll(cellPoints, pointi)
215  {
216  if (cellPoints[pointi] == newEdgeStart)
217  {
218  if (pointUsage[pointi] > 2)
219  {
220  blockedHead = true;
221  }
222  }
223  else if (cellPoints[pointi] == newEdgeEnd)
224  {
225  if (pointUsage[pointi] > 2)
226  {
227  blockedTail = true;
228  }
229  }
230  }
231 
232  if (blockedHead && blockedTail)
233  {
234  // Eliminating edge singleEdges[edgeI] as blocked
235  singleEdgeUsage[edgeI] = true;
236  }
237  }
238 
239  // Go through the points and start from the point used twice
240  // check all the edges to find the edges starting from this point
241  // add the
242 
243  labelListList edgesToInsert(singleEdges.size());
244  label nEdgesToInsert = 0;
245 
246  // Find a good edge
247  forAll(singleEdges, edgeI)
248  {
249  SLList<label> pointChain;
250 
251  bool blockHead = false;
252  bool blockTail = false;
253 
254  if (!singleEdgeUsage[edgeI])
255  {
256  // found a new edge
257  singleEdgeUsage[edgeI] = true;
258 
259  label newEdgeStart = singleEdges[edgeI].start();
260  label newEdgeEnd = singleEdges[edgeI].end();
261 
262  pointChain.insert(newEdgeStart);
263  pointChain.append(newEdgeEnd);
264 
265  #ifdef DEBUG_CHAIN
266  Info<< "found edge to start with: "
267  << singleEdges[edgeI] << endl;
268  #endif
269 
270  // Check if head or tail are blocked
271  forAll(cellPoints, pointi)
272  {
273  if (cellPoints[pointi] == newEdgeStart)
274  {
275  if (pointUsage[pointi] > 2)
276  {
277  #ifdef DEBUG_CHAIN
278  Info<< "start head blocked" << endl;
279  #endif
280 
281  blockHead = true;
282  }
283  }
284  else if (cellPoints[pointi] == newEdgeEnd)
285  {
286  if (pointUsage[pointi] > 2)
287  {
288  #ifdef DEBUG_CHAIN
289  Info<< "start tail blocked" << endl;
290  #endif
291 
292  blockTail = true;
293  }
294  }
295  }
296 
297  bool stopSearching = false;
298 
299  // Go through the unused edges and try to chain them up
300  do
301  {
302  stopSearching = false;
303 
304  forAll(singleEdges, addEdgeI)
305  {
306  if (!singleEdgeUsage[addEdgeI])
307  {
308  // Grab start and end of the candidate
309  label addStart =
310  singleEdges[addEdgeI].start();
311 
312  label addEnd =
313  singleEdges[addEdgeI].end();
314 
315  #ifdef DEBUG_CHAIN
316  Info<< "Trying candidate "
317  << singleEdges[addEdgeI] << endl;
318  #endif
319 
320  // Try to add the edge onto the head
321  if (!blockHead)
322  {
323  if (pointChain.first() == addStart)
324  {
325  // Added at start mark as used
326  pointChain.insert(addEnd);
327 
328  singleEdgeUsage[addEdgeI] = true;
329  }
330  else if (pointChain.first() == addEnd)
331  {
332  pointChain.insert(addStart);
333 
334  singleEdgeUsage[addEdgeI] = true;
335  }
336  }
337 
338  // Try the other end only if the first end
339  // did not add it
340  if (!blockTail && !singleEdgeUsage[addEdgeI])
341  {
342  if (pointChain.last() == addStart)
343  {
344  // Added at start mark as used
345  pointChain.append(addEnd);
346 
347  singleEdgeUsage[addEdgeI] = true;
348  }
349  else if (pointChain.last() == addEnd)
350  {
351  pointChain.append(addStart);
352 
353  singleEdgeUsage[addEdgeI] = true;
354  }
355  }
356 
357  // check if the new head or tail are blocked
358  label curEdgeStart = pointChain.first();
359  label curEdgeEnd = pointChain.last();
360 
361  #ifdef DEBUG_CHAIN
362  Info<< "curEdgeStart: " << curEdgeStart
363  << " curEdgeEnd: " << curEdgeEnd << endl;
364  #endif
365 
366  forAll(cellPoints, pointi)
367  {
368  if (cellPoints[pointi] == curEdgeStart)
369  {
370  if (pointUsage[pointi] > 2)
371  {
372  #ifdef DEBUG_CHAIN
373  Info<< "head blocked" << endl;
374  #endif
375 
376  blockHead = true;
377  }
378  }
379  else if (cellPoints[pointi] == curEdgeEnd)
380  {
381  if (pointUsage[pointi] > 2)
382  {
383  #ifdef DEBUG_CHAIN
384  Info<< "tail blocked" << endl;
385  #endif
386 
387  blockTail = true;
388  }
389  }
390  }
391 
392  // Check if the loop is closed
393  if (curEdgeStart == curEdgeEnd)
394  {
395  #ifdef DEBUG_CHAIN
396  Info<< "closed loop" << endl;
397  #endif
398 
399  pointChain.removeHead();
400 
401  blockHead = true;
402  blockTail = true;
403 
404  stopSearching = true;
405  }
406 
407  #ifdef DEBUG_CHAIN
408  Info<< "current pointChain: " << pointChain
409  << endl;
410  #endif
411 
412  if (stopSearching) break;
413  }
414  }
415  } while (stopSearching);
416  }
417 
418  #ifdef DEBUG_CHAIN
419  Info<< "completed patch chain: " << pointChain << endl;
420  #endif
421 
422  if (pointChain.size() > 2)
423  {
424  edgesToInsert[nEdgesToInsert] = pointChain;
425  nEdgesToInsert++;
426  }
427  }
428 
429  edgesToInsert.setSize(nEdgesToInsert);
430 
431  #ifdef DEBUG_ZIPUP
432  Info<< "edgesToInsert: " << edgesToInsert << endl;
433  #endif
434 
435  // Insert the edges into a list of faces
436  forAll(edgesToInsert, edgeToInsertI)
437  {
438  // Order the points of the edge
439  // Warning: the ordering must be parametric, because in
440  // the case of multiple point insertion onto the same edge
441  // it is possible to get non-cyclic loops
442  //
443 
444  const labelList& unorderedEdge = edgesToInsert[edgeToInsertI];
445 
446  scalarField dist(unorderedEdge.size());
447 
448  // Calculate distance
449  point startPoint = Points[unorderedEdge[0]];
450  dist[0] = 0;
451 
452  vector dir = Points[unorderedEdge.last()] - startPoint;
453 
454  for (label i = 1; i < dist.size(); i++)
455  {
456  dist[i] = (Points[unorderedEdge[i]] - startPoint) & dir;
457  }
458 
459  // Sort points
460  labelList orderedEdge(unorderedEdge.size(), -1);
461  boolList used(unorderedEdge.size(), false);
462 
463  forAll(orderedEdge, epI)
464  {
465  label nextPoint = -1;
466  scalar minDist = GREAT;
467 
468  forAll(dist, i)
469  {
470  if (!used[i] && dist[i] < minDist)
471  {
472  minDist = dist[i];
473  nextPoint = i;
474  }
475  }
476 
477  // Insert the next point
478  orderedEdge[epI] = unorderedEdge[nextPoint];
479  used[nextPoint] = true;
480  }
481 
482  #ifdef DEBUG_ORDER
483  Info<< "unorderedEdge: " << unorderedEdge << nl
484  << "orderedEdge: " << orderedEdge << endl;
485  #endif
486 
487  // check for duplicate points in the ordered edge
488  forAll(orderedEdge, checkI)
489  {
490  for
491  (
492  label checkJ = checkI + 1;
493  checkJ < orderedEdge.size();
494  checkJ++
495  )
496  {
497  if (orderedEdge[checkI] == orderedEdge[checkJ])
498  {
500  << "Duplicate point found in edge to insert. "
501  << nl << "Point: " << orderedEdge[checkI]
502  << " edge: " << orderedEdge << endl;
503 
504  problemCells.insert(celli);
505  }
506  }
507  }
508 
509  edge testEdge
510  (
511  orderedEdge[0],
512  orderedEdge.last()
513  );
514 
515  // In order to avoid edge-to-edge comparison, get faces using
516  // point-face addressing in two goes.
517  const labelList& startPF = pFaces[testEdge.start()];
518  const labelList& endPF = pFaces[testEdge.start()];
519 
520  labelList facesSharingEdge(startPF.size() + endPF.size());
521  label nfse = 0;
522 
523  forAll(startPF, pfI)
524  {
525  facesSharingEdge[nfse++] = startPF[pfI];
526  }
527  forAll(endPF, pfI)
528  {
529  facesSharingEdge[nfse++] = endPF[pfI];
530  }
531 
532  forAll(facesSharingEdge, facei)
533  {
534  bool faceChanges = false;
535 
536  // Label of the face being analysed
537  const label currentFaceIndex = facesSharingEdge[facei];
538 
539  const edgeList curFaceEdges =
540  oldFaces[currentFaceIndex].edges();
541 
542  forAll(curFaceEdges, cfeI)
543  {
544  if (curFaceEdges[cfeI] == testEdge)
545  {
546  faceChanges = true;
547  break;
548  }
549  }
550 
551  if (faceChanges)
552  {
553  nChangedFacesInMesh++;
554  // In order to avoid losing point from multiple
555  // insertions into the same face, the new face
556  // will be change incrementally.
557  // 1) Check if all the internal points of the edge
558  // to add already exist in the face. If so, the
559  // edge has already been included 2) Check if the
560  // point insertion occurs on an edge which is
561  // still untouched. If so, simply insert
562  // additional points into the face. 3) If not,
563  // the edge insertion occurs on an already
564  // modified edge. ???
565 
566  face& newFace = newFaces[currentFaceIndex];
567 
568  bool allPointsPresent = true;
569 
570  forAll(orderedEdge, oeI)
571  {
572  bool curPointFound = false;
573 
574  forAll(newFace, nfI)
575  {
576  if (newFace[nfI] == orderedEdge[oeI])
577  {
578  curPointFound = true;
579  break;
580  }
581  }
582 
583  allPointsPresent =
584  allPointsPresent && curPointFound;
585  }
586 
587  #ifdef DEBUG_ZIPUP
588  if (allPointsPresent)
589  {
590  Info<< "All points present" << endl;
591  }
592  #endif
593 
594  if (!allPointsPresent)
595  {
596  // Not all points are already present. The
597  // new edge will need to be inserted into the
598  // face.
599 
600  // Check to see if a new edge fits onto an
601  // untouched edge of the face. Make sure the
602  // edges are grabbed before the face is
603  // resized.
604  edgeList newFaceEdges = newFace.edges();
605 
606  #ifdef DEBUG_ZIPUP
607  Info<< "Not all points present." << endl;
608  #endif
609 
610  label nNewFacePoints = 0;
611 
612  bool edgeAdded = false;
613 
614  forAll(newFaceEdges, curFacEdgI)
615  {
616  // Does the current edge change?
617  if (newFaceEdges[curFacEdgI] == testEdge)
618  {
619  // Found an edge match
620  edgeAdded = true;
621 
622  // Resize the face to accept additional
623  // points
624  newFace.setSize
625  (
626  newFace.size()
627  + orderedEdge.size() - 2
628  );
629 
630  if
631  (
632  newFaceEdges[curFacEdgI].start()
633  == testEdge.start()
634  )
635  {
636  // insertion in ascending order
637  for
638  (
639  label i = 0;
640  i < orderedEdge.size() - 1;
641  i++
642  )
643  {
644  newFace[nNewFacePoints] =
645  orderedEdge[i];
646  nNewFacePoints++;
647  }
648  }
649  else
650  {
651  // insertion in reverse order
652  for
653  (
654  label i = orderedEdge.size() - 1;
655  i > 0;
656  i--
657  )
658  {
659  newFace[nNewFacePoints] =
660  orderedEdge[i];
661  nNewFacePoints++;
662  }
663  }
664  }
665  else
666  {
667  // Does not fit onto this edge.
668  // Copy the next point into the face
669  newFace[nNewFacePoints] =
670  newFaceEdges[curFacEdgI].start();
671  nNewFacePoints++;
672  }
673  }
674 
675  #ifdef DEBUG_ZIPUP
676  Info<< "oldFace: "
677  << oldFaces[currentFaceIndex] << nl
678  << "newFace: " << newFace << endl;
679  #endif
680 
681  // Check for duplicate points in the new face
682  forAll(newFace, checkI)
683  {
684  for
685  (
686  label checkJ = checkI + 1;
687  checkJ < newFace.size();
688  checkJ++
689  )
690  {
691  if (newFace[checkI] == newFace[checkJ])
692  {
694  << "Duplicate point found "
695  << "in the new face. " << nl
696  << "Point: "
697  << orderedEdge[checkI]
698  << " face: "
699  << newFace << endl;
700 
701  problemCells.insert(celli);
702  }
703  }
704  }
705 
706  // Check if the edge is added.
707  // If not, then it comes on top of an already
708  // modified edge and they need to be
709  // merged in together.
710  if (!edgeAdded)
711  {
712  Info<< "This edge modifies an already modified "
713  << "edge. Point insertions skipped."
714  << endl;
715  }
716  }
717  }
718  }
719  }
720  }
721 
722  if (problemCells.size())
723  {
724  // This cycle has failed. Print out the problem cells
726  << "Found " << problemCells.size() << " problem cells." << nl
727  << "Cells: " << problemCells.sortedToc()
728  << abort(FatalError);
729  }
730 
731  Info<< "Cycle " << ++nCycles
732  << " changed " << nChangedFacesInMesh << " faces." << endl;
733 
734 
735  const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
736 
737  // Reset the polyMesh. Number of points/faces/cells/patches stays the
738  // same, only the faces themselves have changed so clear all derived
739  // (edge, point) addressing.
740 
741  // Collect the patch sizes
742  labelList patchSizes(bMesh.size(), Zero);
743  labelList patchStarts(bMesh.size(), Zero);
744 
745  forAll(bMesh, patchi)
746  {
747  patchSizes[patchi] = bMesh[patchi].size();
748  patchStarts[patchi] = bMesh[patchi].start();
749  }
750 
751  // Reset the mesh. Number of active faces is one beyond the last patch
752  // (patches guaranteed to be in increasing order)
753  mesh.resetPrimitives
754  (
755  autoPtr<pointField>(), // <- null: leaves points untouched
756  autoPtr<faceList>::New(std::move(newFaces)),
757  autoPtr<labelList>(), // <- null: leaves owner untouched
758  autoPtr<labelList>(), // <- null: leaves neighbour untouched
759  patchSizes,
760  patchStarts,
761  true // boundary forms valid boundary mesh.
762  );
763 
764  // Reset any addressing on face zones.
765  mesh.faceZones().clearAddressing();
766 
767  // Clear the addressing
768  mesh.clearOut();
769 
770  } while (nChangedFacesInMesh > 0 || nCycles > 100);
771 
772  // Flags the mesh files as being changed
773  mesh.setInstance(mesh.time().timeName());
774 
775  if (nChangedFacesInMesh > 0)
776  {
778  << "with the original mesh"
779  << abort(FatalError);
780  }
781 
782  return nCycles != 1;
783 }
784 
785 
786 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::LList::append
void append(const T &item)
Add copy at tail of list.
Definition: LList.H:237
Foam::LList::first
reference first()
The first entry in the list.
Definition: LList.H:199
polyMeshZipUpCells.H
Cell zip-up tool. This function modifies the list of faces such that all the cells are topologically ...
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
polyMesh.H
Foam::HashSet< label, Hash< label > >
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::LList::end
const iterator & end()
End of list for forward iterators.
Definition: LList.H:534
Foam::LList
Template class for non-intrusive linked lists.
Definition: LList.H:54
Foam::edge::start
label start() const
Return start (first) vertex label.
Definition: edgeI.H:95
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::polyMeshZipUpCells
bool polyMeshZipUpCells(polyMesh &mesh)
Definition: polyMeshZipUpCells.C:38
Foam::edge::end
label end() const
Return end (last/second) vertex label.
Definition: edgeI.H:106
Foam::FatalError
error FatalError
Foam::face::edges
edgeList edges() const
Return list of edges in forward walk order.
Definition: face.C:773
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Vector< scalar >
Foam::List< cell >
Foam::HashSetOps::used
labelHashSet used(const bitSet &select)
Convert a bitset to a labelHashSet of the indices used.
Definition: HashOps.C:35
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
Foam::vtk::Tools::Points
vtkSmartPointer< vtkPoints > Points(const UList< point > &pts)
Return a list of points as vtkPoints.
Definition: foamVtkToolsI.H:59
Foam::LList::last
reference last()
The last entry in the list.
Definition: LList.H:211
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::LList::insert
void insert(const T &item)
Add copy at head of list.
Definition: LList.H:224
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
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::LList::removeHead
T removeHead()
Remove and return head.
Definition: LList.H:250
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:79