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