polyTopoChange.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-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2019 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 "polyTopoChange.H"
30 #include "SortableList.H"
31 #include "polyMesh.H"
32 #include "polyAddPoint.H"
33 #include "polyModifyPoint.H"
34 #include "polyRemovePoint.H"
35 #include "polyAddFace.H"
36 #include "polyModifyFace.H"
37 #include "polyRemoveFace.H"
38 #include "polyAddCell.H"
39 #include "polyModifyCell.H"
40 #include "polyRemoveCell.H"
41 #include "objectMap.H"
42 #include "processorPolyPatch.H"
43 #include "CompactListList.H"
44 #include "ListOps.H"
45 
46 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
47 
48 namespace Foam
49 {
50  defineTypeNameAndDebug(polyTopoChange, 0);
51 }
52 
53 
54 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
55 
56 // Renumber with special handling for merged items (marked with <-1)
57 void Foam::polyTopoChange::renumberReverseMap
58 (
59  const labelUList& oldToNew,
60  DynamicList<label>& elems
61 )
62 {
63  forAll(elems, elemI)
64  {
65  const label val = elems[elemI];
66 
67  if (val >= 0)
68  {
69  elems[elemI] = oldToNew[val];
70  }
71  else if (val < -1)
72  {
73  const label mergedVal = -val-2;
74  elems[elemI] = -oldToNew[mergedVal]-2;
75  }
76  }
77 }
78 
79 
80 void Foam::polyTopoChange::renumber
81 (
82  const labelUList& oldToNew,
83  labelHashSet& labels
84 )
85 {
86  labelHashSet newSet(labels.capacity());
87 
88  for (const label val : labels)
89  {
90  const label newVal = oldToNew[val];
91 
92  if (newVal >= 0)
93  {
94  newSet.insert(newVal);
95  }
96  }
97 
98  labels.transfer(newSet);
99 }
100 
101 
102 // Renumber and remove -1 elements.
103 void Foam::polyTopoChange::renumberCompact
104 (
105  const labelUList& oldToNew,
106  labelList& elems
107 )
108 {
109  label nElem = 0;
110 
111  for (const label val : elems)
112  {
113  const label newVal = oldToNew[val];
114 
115  if (newVal != -1)
116  {
117  elems[nElem++] = newVal;
118  }
119  }
120  elems.setSize(nElem);
121 }
122 
123 
124 void Foam::polyTopoChange::countMap
125 (
126  const labelUList& map,
127  const labelUList& reverseMap,
128  label& nAdd,
129  label& nInflate,
130  label& nMerge,
131  label& nRemove
132 )
133 {
134  nAdd = 0;
135  nInflate = 0;
136  nMerge = 0;
137  nRemove = 0;
138 
139  forAll(map, newCelli)
140  {
141  const label oldCelli = map[newCelli];
142 
143  if (oldCelli >= 0)
144  {
145  if
146  (
147  oldCelli < reverseMap.size()
148  && reverseMap[oldCelli] == newCelli
149  )
150  {
151  // unchanged
152  }
153  else
154  {
155  // Added (from another cell v.s. inflated from face/point)
156  nAdd++;
157  }
158  }
159  else if (oldCelli == -1)
160  {
161  // Created from nothing
162  nInflate++;
163  }
164  else
165  {
167  << " new:" << newCelli << abort(FatalError);
168  }
169  }
170 
171  forAll(reverseMap, oldCelli)
172  {
173  const label newCelli = reverseMap[oldCelli];
174 
175  if (newCelli >= 0)
176  {
177  // unchanged
178  }
179  else if (newCelli == -1)
180  {
181  // removed
182  nRemove++;
183  }
184  else
185  {
186  // merged into -newCelli-2
187  nMerge++;
188  }
189  }
190 }
191 
192 
193 void Foam::polyTopoChange::writeMeshStats(const polyMesh& mesh, Ostream& os)
194 {
195  const polyBoundaryMesh& patches = mesh.boundaryMesh();
196 
197  labelList patchSizes(patches.size());
198  labelList patchStarts(patches.size());
199  forAll(patches, patchi)
200  {
201  patchSizes[patchi] = patches[patchi].size();
202  patchStarts[patchi] = patches[patchi].start();
203  }
204 
205  os << " Points : " << mesh.nPoints() << nl
206  << " Faces : " << mesh.nFaces() << nl
207  << " Cells : " << mesh.nCells() << nl
208  << " PatchSizes : " << patchSizes << nl
209  << " PatchStarts : " << patchStarts << nl
210  << endl;
211 }
212 
213 
214 void Foam::polyTopoChange::getMergeSets
215 (
216  const labelUList& reverseCellMap,
217  const labelUList& cellMap,
218  List<objectMap>& cellsFromCells
219 )
220 {
221  // Per new cell the number of old cells that have been merged into it
222  labelList nMerged(cellMap.size(), 1);
223 
224  forAll(reverseCellMap, oldCelli)
225  {
226  const label newCelli = reverseCellMap[oldCelli];
227 
228  if (newCelli < -1)
229  {
230  label mergeCelli = -newCelli-2;
231 
232  nMerged[mergeCelli]++;
233  }
234  }
235 
236  // From merged cell to set index
237  labelList cellToMergeSet(cellMap.size(), -1);
238 
239  label nSets = 0;
240 
241  forAll(nMerged, celli)
242  {
243  if (nMerged[celli] > 1)
244  {
245  cellToMergeSet[celli] = nSets++;
246  }
247  }
248 
249  // Collect cell labels.
250  // Each objectMap will have
251  // - index : new mesh cell label
252  // - masterObjects : list of old cells that have been merged. Element 0
253  // will be the original destination cell label.
254 
255  cellsFromCells.setSize(nSets);
256 
257  forAll(reverseCellMap, oldCelli)
258  {
259  const label newCelli = reverseCellMap[oldCelli];
260 
261  if (newCelli < -1)
262  {
263  const label mergeCelli = -newCelli-2;
264 
265  // oldCelli was merged into mergeCelli
266 
267  const label setI = cellToMergeSet[mergeCelli];
268 
269  objectMap& mergeSet = cellsFromCells[setI];
270 
271  if (mergeSet.masterObjects().empty())
272  {
273  // First occurrence of master cell mergeCelli
274 
275  mergeSet.index() = mergeCelli;
276  mergeSet.masterObjects().setSize(nMerged[mergeCelli]);
277 
278  // old master label
279  mergeSet.masterObjects()[0] = cellMap[mergeCelli];
280 
281  // old slave label
282  mergeSet.masterObjects()[1] = oldCelli;
283 
284  nMerged[mergeCelli] = 2;
285  }
286  else
287  {
288  mergeSet.masterObjects()[nMerged[mergeCelli]++] = oldCelli;
289  }
290  }
291  }
292 }
293 
294 
295 bool Foam::polyTopoChange::hasValidPoints(const face& f) const
296 {
297  for (const label fp : f)
298  {
299  if (fp < 0 || fp >= points_.size())
300  {
301  return false;
302  }
303  }
304  return true;
305 }
306 
307 
308 Foam::pointField Foam::polyTopoChange::facePoints(const face& f) const
309 {
310  pointField points(f.size());
311  forAll(f, fp)
312  {
313  if (f[fp] < 0 && f[fp] >= points_.size())
314  {
316  << "Problem." << abort(FatalError);
317  }
318  points[fp] = points_[f[fp]];
319  }
320  return points;
321 }
322 
323 
324 void Foam::polyTopoChange::checkFace
325 (
326  const face& f,
327  const label facei,
328  const label own,
329  const label nei,
330  const label patchi,
331  const label zoneI
332 ) const
333 {
334  if (nei == -1)
335  {
336  if (own == -1 && zoneI != -1)
337  {
338  // retired face
339  }
340  else if (patchi == -1 || patchi >= nPatches_)
341  {
343  << "Face has no neighbour (so external) but does not have"
344  << " a valid patch" << nl
345  << "f:" << f
346  << " facei(-1 if added face):" << facei
347  << " own:" << own << " nei:" << nei
348  << " patchi:" << patchi << nl;
349  if (hasValidPoints(f))
350  {
351  FatalError
352  << "points (removed points marked with "
353  << vector::max << ") " << facePoints(f);
354  }
356  }
357  }
358  else
359  {
360  if (patchi != -1)
361  {
363  << "Cannot both have valid patchi and neighbour" << nl
364  << "f:" << f
365  << " facei(-1 if added face):" << facei
366  << " own:" << own << " nei:" << nei
367  << " patchi:" << patchi << nl;
368  if (hasValidPoints(f))
369  {
370  FatalError
371  << "points (removed points marked with "
372  << vector::max << ") : " << facePoints(f);
373  }
375  }
376 
377  if (nei <= own)
378  {
380  << "Owner cell label should be less than neighbour cell label"
381  << nl
382  << "f:" << f
383  << " facei(-1 if added face):" << facei
384  << " own:" << own << " nei:" << nei
385  << " patchi:" << patchi << nl;
386  if (hasValidPoints(f))
387  {
388  FatalError
389  << "points (removed points marked with "
390  << vector::max << ") : " << facePoints(f);
391  }
393  }
394  }
395 
396  if (f.size() < 3 || f.found(-1))
397  {
399  << "Illegal vertices in face"
400  << nl
401  << "f:" << f
402  << " facei(-1 if added face):" << facei
403  << " own:" << own << " nei:" << nei
404  << " patchi:" << patchi << nl;
405  if (hasValidPoints(f))
406  {
407  FatalError
408  << "points (removed points marked with "
409  << vector::max << ") : " << facePoints(f);
410  }
412  }
413  if (facei >= 0 && facei < faces_.size() && faceRemoved(facei))
414  {
416  << "Face already marked for removal"
417  << nl
418  << "f:" << f
419  << " facei(-1 if added face):" << facei
420  << " own:" << own << " nei:" << nei
421  << " patchi:" << patchi << nl;
422  if (hasValidPoints(f))
423  {
424  FatalError
425  << "points (removed points marked with "
426  << vector::max << ") : " << facePoints(f);
427  }
429  }
430  forAll(f, fp)
431  {
432  if (f[fp] < points_.size() && pointRemoved(f[fp]))
433  {
435  << "Face uses removed vertices"
436  << nl
437  << "f:" << f
438  << " facei(-1 if added face):" << facei
439  << " own:" << own << " nei:" << nei
440  << " patchi:" << patchi << nl;
441  if (hasValidPoints(f))
442  {
443  FatalError
444  << "points (removed points marked with "
445  << vector::max << ") : " << facePoints(f);
446  }
448  }
449  }
450 }
451 
452 
453 void Foam::polyTopoChange::makeCells
454 (
455  const label nActiveFaces,
456  labelList& cellFaces,
457  labelList& cellFaceOffsets
458 ) const
459 {
460  cellFaces.setSize(2*nActiveFaces);
461  cellFaceOffsets.setSize(cellMap_.size() + 1);
462 
463  // Faces per cell
464  labelList nNbrs(cellMap_.size(), Zero);
465 
466  // 1. Count faces per cell
467 
468  for (label facei = 0; facei < nActiveFaces; facei++)
469  {
470  if (faceOwner_[facei] < 0)
471  {
472  pointField newPoints;
473  if (facei < faces_.size())
474  {
475  const face& f = faces_[facei];
476  newPoints.setSize(f.size(), vector::max);
477  forAll(f, fp)
478  {
479  if (f[fp] < points_.size())
480  {
481  newPoints[fp] = points_[f[fp]];
482  }
483  }
484  }
485 
486 
488  << "Face " << facei << " is active but its owner has"
489  << " been deleted. This is usually due to deleting cells"
490  << " without modifying exposed faces to be boundary faces."
491  << exit(FatalError);
492  }
493  nNbrs[faceOwner_[facei]]++;
494  }
495  for (label facei = 0; facei < nActiveFaces; facei++)
496  {
497  if (faceNeighbour_[facei] >= 0)
498  {
499  nNbrs[faceNeighbour_[facei]]++;
500  }
501  }
502 
503  // 2. Calculate offsets
504 
505  cellFaceOffsets[0] = 0;
506  forAll(nNbrs, celli)
507  {
508  cellFaceOffsets[celli+1] = cellFaceOffsets[celli] + nNbrs[celli];
509  }
510 
511  // 3. Fill faces per cell
512 
513  // reset the whole list to use as counter
514  nNbrs = 0;
515 
516  for (label facei = 0; facei < nActiveFaces; facei++)
517  {
518  label celli = faceOwner_[facei];
519 
520  cellFaces[cellFaceOffsets[celli] + nNbrs[celli]++] = facei;
521  }
522 
523  for (label facei = 0; facei < nActiveFaces; facei++)
524  {
525  label celli = faceNeighbour_[facei];
526 
527  if (celli >= 0)
528  {
529  cellFaces[cellFaceOffsets[celli] + nNbrs[celli]++] = facei;
530  }
531  }
532 
533  // Last offset points to beyond end of cellFaces.
534  cellFaces.setSize(cellFaceOffsets[cellMap_.size()]);
535 }
536 
537 
538 // Create cell-cell addressing. Called after compaction (but before ordering)
539 // of faces
540 void Foam::polyTopoChange::makeCellCells
541 (
542  const label nActiveFaces,
543  CompactListList<label>& cellCells
544 ) const
545 {
546  // Neighbours per cell
547  labelList nNbrs(cellMap_.size(), Zero);
548 
549  // 1. Count neighbours (through internal faces) per cell
550 
551  for (label facei = 0; facei < nActiveFaces; facei++)
552  {
553  if (faceNeighbour_[facei] >= 0)
554  {
555  nNbrs[faceOwner_[facei]]++;
556  nNbrs[faceNeighbour_[facei]]++;
557  }
558  }
559 
560  // 2. Construct csr
561  cellCells.setSize(nNbrs);
562 
563 
564  // 3. Fill faces per cell
565 
566  // reset the whole list to use as counter
567  nNbrs = 0;
568 
569  for (label facei = 0; facei < nActiveFaces; facei++)
570  {
571  label nei = faceNeighbour_[facei];
572 
573  if (nei >= 0)
574  {
575  label own = faceOwner_[facei];
576  cellCells.m()[cellCells.index(own, nNbrs[own]++)] = nei;
577  cellCells.m()[cellCells.index(nei, nNbrs[nei]++)] = own;
578  }
579  }
580 }
581 
582 
583 // Cell ordering (based on bandCompression).
584 // Handles removed cells. Returns number of remaining cells.
585 Foam::label Foam::polyTopoChange::getCellOrder
586 (
587  const CompactListList<label, labelList>& cellCellAddressing,
588  labelList& oldToNew
589 ) const
590 {
591  labelList newOrder(cellCellAddressing.size());
592 
593  // Fifo buffer for string of cells
594  SLList<label> nextCell;
595 
596  // Whether cell has been done already
597  bitSet visited(cellCellAddressing.size());
598 
599  label cellInOrder = 0;
600 
601 
602  // Work arrays. Kept outside of loop to minimise allocations.
603  // - neighbour cells
604  DynamicList<label> nbrs;
605  // - corresponding weights
606  DynamicList<label> weights;
607 
608  // - ordering
609  labelList order;
610 
611 
612  while (true)
613  {
614  // For a disconnected region find the lowest connected cell.
615 
616  label currentCell = -1;
617  label minWeight = labelMax;
618 
619  forAll(visited, celli)
620  {
621  // find the lowest connected cell that has not been visited yet
622  if (!cellRemoved(celli) && !visited.test(celli))
623  {
624  if (cellCellAddressing[celli].size() < minWeight)
625  {
626  minWeight = cellCellAddressing[celli].size();
627  currentCell = celli;
628  }
629  }
630  }
631 
632 
633  if (currentCell == -1)
634  {
635  break;
636  }
637 
638 
639  // Starting from currentCell walk breadth-first
640 
641 
642  // use this cell as a start
643  nextCell.append(currentCell);
644 
645  // loop through the nextCell list. Add the first cell into the
646  // cell order if it has not already been visited and ask for its
647  // neighbours. If the neighbour in question has not been visited,
648  // add it to the end of the nextCell list
649 
650  while (nextCell.size())
651  {
652  currentCell = nextCell.removeHead();
653 
654  if (visited.set(currentCell))
655  {
656  // On first visit...
657 
658  // add into cellOrder
659  newOrder[cellInOrder] = currentCell;
660  cellInOrder++;
661 
662  // find if the neighbours have been visited
663  const labelUList neighbours = cellCellAddressing[currentCell];
664 
665  // Add in increasing order of connectivity
666 
667  // 1. Count neighbours of unvisited neighbours
668  nbrs.clear();
669  weights.clear();
670 
671  for (const label nbr : neighbours)
672  {
673  if (!cellRemoved(nbr) && !visited.test(nbr))
674  {
675  // not visited, add to the list
676  nbrs.append(nbr);
677  weights.append(cellCellAddressing[nbr].size());
678  }
679  }
680  // 2. Sort
681  sortedOrder(weights, order);
682  // 3. Add in sorted order
683  for (const label nbri : order)
684  {
685  nextCell.append(nbrs[nbri]);
686  }
687  }
688  }
689  }
690 
691  // Now we have new-to-old in newOrder.
692  newOrder.setSize(cellInOrder);
693 
694  // Invert to get old-to-new. Make sure removed (i.e. unmapped) cells are -1.
695  oldToNew = invert(cellCellAddressing.size(), newOrder);
696 
697  return cellInOrder;
698 }
699 
700 
701 // Determine order for faces:
702 // - upper-triangular order for internal faces
703 // - external faces after internal faces and in patch order.
704 void Foam::polyTopoChange::getFaceOrder
705 (
706  const label nActiveFaces,
707  const labelUList& cellFaces,
708  const labelUList& cellFaceOffsets,
709 
710  labelList& oldToNew,
711  labelList& patchSizes,
712  labelList& patchStarts
713 ) const
714 {
715  oldToNew.setSize(faceOwner_.size());
716  oldToNew = -1;
717 
718  // First unassigned face
719  label newFacei = 0;
720 
721  labelList nbr;
722  labelList order;
723 
724  forAll(cellMap_, celli)
725  {
726  label startOfCell = cellFaceOffsets[celli];
727  label nFaces = cellFaceOffsets[celli+1] - startOfCell;
728 
729  // Neighbouring cells
730  nbr.setSize(nFaces);
731 
732  for (label i = 0; i < nFaces; i++)
733  {
734  label facei = cellFaces[startOfCell + i];
735 
736  label nbrCelli = faceNeighbour_[facei];
737 
738  if (facei >= nActiveFaces)
739  {
740  // Retired face.
741  nbr[i] = -1;
742  }
743  else if (nbrCelli != -1)
744  {
745  // Internal face. Get cell on other side.
746  if (nbrCelli == celli)
747  {
748  nbrCelli = faceOwner_[facei];
749  }
750 
751  if (celli < nbrCelli)
752  {
753  // Celli is master
754  nbr[i] = nbrCelli;
755  }
756  else
757  {
758  // nbrCell is master. Let it handle this face.
759  nbr[i] = -1;
760  }
761  }
762  else
763  {
764  // External face. Do later.
765  nbr[i] = -1;
766  }
767  }
768 
769  sortedOrder(nbr, order);
770 
771  for (const label index : order)
772  {
773  if (nbr[index] != -1)
774  {
775  oldToNew[cellFaces[startOfCell + index]] = newFacei++;
776  }
777  }
778  }
779 
780 
781  // Pick up all patch faces in patch face order.
782  patchStarts.setSize(nPatches_);
783  patchStarts = 0;
784  patchSizes.setSize(nPatches_);
785  patchSizes = 0;
786 
787  if (nPatches_ > 0)
788  {
789  patchStarts[0] = newFacei;
790 
791  for (label facei = 0; facei < nActiveFaces; facei++)
792  {
793  if (region_[facei] >= 0)
794  {
795  patchSizes[region_[facei]]++;
796  }
797  }
798 
799  label facei = patchStarts[0];
800 
801  forAll(patchStarts, patchi)
802  {
803  patchStarts[patchi] = facei;
804  facei += patchSizes[patchi];
805  }
806  }
807 
808  //if (debug)
809  //{
810  // Pout<< "patchSizes:" << patchSizes << nl
811  // << "patchStarts:" << patchStarts << endl;
812  //}
813 
814  labelList workPatchStarts(patchStarts);
815 
816  for (label facei = 0; facei < nActiveFaces; facei++)
817  {
818  if (region_[facei] >= 0)
819  {
820  oldToNew[facei] = workPatchStarts[region_[facei]]++;
821  }
822  }
823 
824  // Retired faces.
825  for (label facei = nActiveFaces; facei < oldToNew.size(); facei++)
826  {
827  oldToNew[facei] = facei;
828  }
829 
830  // Check done all faces.
831  forAll(oldToNew, facei)
832  {
833  if (oldToNew[facei] == -1)
834  {
836  << "Did not determine new position"
837  << " for face " << facei
838  << " owner " << faceOwner_[facei]
839  << " neighbour " << faceNeighbour_[facei]
840  << " region " << region_[facei] << endl
841  << "This is usually caused by not specifying a patch for"
842  << " a boundary face." << nl
843  << "Switch on the polyTopoChange::debug flag to catch"
844  << " this error earlier." << nl;
845  if (hasValidPoints(faces_[facei]))
846  {
847  FatalError
848  << "points (removed points marked with "
849  << vector::max << ") " << facePoints(faces_[facei]);
850  }
852  }
853  }
854 }
855 
856 
857 // Reorder and compact faces according to map.
858 void Foam::polyTopoChange::reorderCompactFaces
859 (
860  const label newSize,
861  const labelUList& oldToNew
862 )
863 {
864  reorder(oldToNew, faces_);
865  faces_.setCapacity(newSize);
866 
867  reorder(oldToNew, region_);
868  region_.setCapacity(newSize);
869 
870  reorder(oldToNew, faceOwner_);
871  faceOwner_.setCapacity(newSize);
872 
873  reorder(oldToNew, faceNeighbour_);
874  faceNeighbour_.setCapacity(newSize);
875 
876  // Update faceMaps.
877  reorder(oldToNew, faceMap_);
878  faceMap_.setCapacity(newSize);
879 
880  renumberReverseMap(oldToNew, reverseFaceMap_);
881 
882  renumberKey(oldToNew, faceFromPoint_);
883  renumberKey(oldToNew, faceFromEdge_);
884  inplaceReorder(oldToNew, flipFaceFlux_);
885  flipFaceFlux_.setCapacity(newSize);
886  renumberKey(oldToNew, faceZone_);
887  inplaceReorder(oldToNew, faceZoneFlip_);
888  faceZoneFlip_.setCapacity(newSize);
889 }
890 
891 
892 // Compact all and orders points and faces:
893 // - points into internal followed by external points
894 // - internalfaces upper-triangular
895 // - externalfaces after internal ones.
896 void Foam::polyTopoChange::compact
897 (
898  const bool orderCells,
899  const bool orderPoints,
900  label& nInternalPoints,
901  labelList& patchSizes,
902  labelList& patchStarts
903 )
904 {
905  points_.shrink();
906  pointMap_.shrink();
907  reversePointMap_.shrink();
908 
909  faces_.shrink();
910  region_.shrink();
911  faceOwner_.shrink();
912  faceNeighbour_.shrink();
913  faceMap_.shrink();
914  reverseFaceMap_.shrink();
915 
916  cellMap_.shrink();
917  reverseCellMap_.shrink();
918  cellZone_.shrink();
919 
920 
921  // Compact points
922  label nActivePoints = 0;
923  {
924  labelList localPointMap(points_.size(), -1);
925  label newPointi = 0;
926 
927  if (!orderPoints)
928  {
929  nInternalPoints = -1;
930 
931  forAll(points_, pointi)
932  {
933  if (!pointRemoved(pointi) && !retiredPoints_.found(pointi))
934  {
935  localPointMap[pointi] = newPointi++;
936  }
937  }
938  nActivePoints = newPointi;
939  }
940  else
941  {
942  forAll(points_, pointi)
943  {
944  if (!pointRemoved(pointi) && !retiredPoints_.found(pointi))
945  {
946  nActivePoints++;
947  }
948  }
949 
950  // Mark boundary points
951  forAll(faceOwner_, facei)
952  {
953  if
954  (
955  !faceRemoved(facei)
956  && faceOwner_[facei] >= 0
957  && faceNeighbour_[facei] < 0
958  )
959  {
960  // Valid boundary face
961  const face& f = faces_[facei];
962 
963  forAll(f, fp)
964  {
965  label pointi = f[fp];
966 
967  if (localPointMap[pointi] == -1)
968  {
969  if
970  (
971  pointRemoved(pointi)
972  || retiredPoints_.found(pointi)
973  )
974  {
976  << "Removed or retired point " << pointi
977  << " in face " << f
978  << " at position " << facei << endl
979  << "Probably face has not been adapted for"
980  << " removed points." << abort(FatalError);
981  }
982  localPointMap[pointi] = newPointi++;
983  }
984  }
985  }
986  }
987 
988  label nBoundaryPoints = newPointi;
989  nInternalPoints = nActivePoints - nBoundaryPoints;
990 
991  // Move the boundary addressing up
992  forAll(localPointMap, pointi)
993  {
994  if (localPointMap[pointi] != -1)
995  {
996  localPointMap[pointi] += nInternalPoints;
997  }
998  }
999 
1000  newPointi = 0;
1001 
1002  // Mark internal points
1003  forAll(faceOwner_, facei)
1004  {
1005  if
1006  (
1007  !faceRemoved(facei)
1008  && faceOwner_[facei] >= 0
1009  && faceNeighbour_[facei] >= 0
1010  )
1011  {
1012  // Valid internal face
1013  const face& f = faces_[facei];
1014 
1015  forAll(f, fp)
1016  {
1017  label pointi = f[fp];
1018 
1019  if (localPointMap[pointi] == -1)
1020  {
1021  if
1022  (
1023  pointRemoved(pointi)
1024  || retiredPoints_.found(pointi)
1025  )
1026  {
1028  << "Removed or retired point " << pointi
1029  << " in face " << f
1030  << " at position " << facei << endl
1031  << "Probably face has not been adapted for"
1032  << " removed points." << abort(FatalError);
1033  }
1034  localPointMap[pointi] = newPointi++;
1035  }
1036  }
1037  }
1038  }
1039 
1040  if (newPointi != nInternalPoints)
1041  {
1043  << "Problem." << abort(FatalError);
1044  }
1045  newPointi = nActivePoints;
1046  }
1047 
1048  for (const label pointi : retiredPoints_)
1049  {
1050  localPointMap[pointi] = newPointi++;
1051  }
1052 
1053 
1054  if (debug)
1055  {
1056  Pout<< "Points : active:" << nActivePoints
1057  << " removed:" << points_.size()-newPointi << endl;
1058  }
1059 
1060  reorder(localPointMap, points_);
1061  points_.setCapacity(newPointi);
1062 
1063  // Update pointMaps
1064  reorder(localPointMap, pointMap_);
1065  pointMap_.setCapacity(newPointi);
1066  renumberReverseMap(localPointMap, reversePointMap_);
1067 
1068  renumberKey(localPointMap, pointZone_);
1069  renumber(localPointMap, retiredPoints_);
1070 
1071  // Use map to relabel face vertices
1072  forAll(faces_, facei)
1073  {
1074  face& f = faces_[facei];
1075 
1076  //labelList oldF(f);
1077  renumberCompact(localPointMap, f);
1078 
1079  if (!faceRemoved(facei) && f.size() < 3)
1080  {
1082  << "Created illegal face " << f
1083  //<< " from face " << oldF
1084  << " at position:" << facei
1085  << " when filtering removed points"
1086  << abort(FatalError);
1087  }
1088  }
1089  }
1090 
1091 
1092  // Compact faces.
1093  {
1094  labelList localFaceMap(faces_.size(), -1);
1095  label newFacei = 0;
1096 
1097  forAll(faces_, facei)
1098  {
1099  if (!faceRemoved(facei) && faceOwner_[facei] >= 0)
1100  {
1101  localFaceMap[facei] = newFacei++;
1102  }
1103  }
1104  nActiveFaces_ = newFacei;
1105 
1106  forAll(faces_, facei)
1107  {
1108  if (!faceRemoved(facei) && faceOwner_[facei] < 0)
1109  {
1110  // Retired face
1111  localFaceMap[facei] = newFacei++;
1112  }
1113  }
1114 
1115  if (debug)
1116  {
1117  Pout<< "Faces : active:" << nActiveFaces_
1118  << " removed:" << faces_.size()-newFacei << endl;
1119  }
1120 
1121  // Reorder faces.
1122  reorderCompactFaces(newFacei, localFaceMap);
1123  }
1124 
1125  // Compact cells.
1126  {
1127  labelList localCellMap;
1128  label newCelli;
1129 
1130  if (orderCells)
1131  {
1132  // Construct cellCell addressing
1133  CompactListList<label> cellCells;
1134  makeCellCells(nActiveFaces_, cellCells);
1135 
1136  // Cell ordering (based on bandCompression). Handles removed cells.
1137  newCelli = getCellOrder(cellCells, localCellMap);
1138  }
1139  else
1140  {
1141  // Compact out removed cells
1142  localCellMap.setSize(cellMap_.size());
1143  localCellMap = -1;
1144 
1145  newCelli = 0;
1146  forAll(cellMap_, celli)
1147  {
1148  if (!cellRemoved(celli))
1149  {
1150  localCellMap[celli] = newCelli++;
1151  }
1152  }
1153  }
1154 
1155  if (debug)
1156  {
1157  Pout<< "Cells : active:" << newCelli
1158  << " removed:" << cellMap_.size()-newCelli << endl;
1159  }
1160 
1161  // Renumber -if cells reordered or -if cells removed
1162  if (orderCells || (newCelli != cellMap_.size()))
1163  {
1164  reorder(localCellMap, cellMap_);
1165  cellMap_.setCapacity(newCelli);
1166  renumberReverseMap(localCellMap, reverseCellMap_);
1167 
1168  reorder(localCellMap, cellZone_);
1169  cellZone_.setCapacity(newCelli);
1170 
1171  renumberKey(localCellMap, cellFromPoint_);
1172  renumberKey(localCellMap, cellFromEdge_);
1173  renumberKey(localCellMap, cellFromFace_);
1174 
1175  // Renumber owner/neighbour. Take into account if neighbour suddenly
1176  // gets lower cell than owner.
1177  forAll(faceOwner_, facei)
1178  {
1179  label own = faceOwner_[facei];
1180  label nei = faceNeighbour_[facei];
1181 
1182  if (own >= 0)
1183  {
1184  // Update owner
1185  faceOwner_[facei] = localCellMap[own];
1186 
1187  if (nei >= 0)
1188  {
1189  // Update neighbour.
1190  faceNeighbour_[facei] = localCellMap[nei];
1191 
1192  // Check if face needs reversing.
1193  if
1194  (
1195  faceNeighbour_[facei] >= 0
1196  && faceNeighbour_[facei] < faceOwner_[facei]
1197  )
1198  {
1199  faces_[facei].flip();
1200  Swap(faceOwner_[facei], faceNeighbour_[facei]);
1201  flipFaceFlux_.flip(facei);
1202  faceZoneFlip_.flip(facei);
1203  }
1204  }
1205  }
1206  else if (nei >= 0)
1207  {
1208  // Update neighbour.
1209  faceNeighbour_[facei] = localCellMap[nei];
1210  }
1211  }
1212  }
1213  }
1214 
1215  // Reorder faces into upper-triangular and patch ordering
1216  {
1217  // Create cells (packed storage)
1218  labelList cellFaces;
1219  labelList cellFaceOffsets;
1220  makeCells(nActiveFaces_, cellFaces, cellFaceOffsets);
1221 
1222  // Do upper triangular order and patch sorting
1223  labelList localFaceMap;
1224  getFaceOrder
1225  (
1226  nActiveFaces_,
1227  cellFaces,
1228  cellFaceOffsets,
1229 
1230  localFaceMap,
1231  patchSizes,
1232  patchStarts
1233  );
1234 
1235  // Reorder faces.
1236  reorderCompactFaces(localFaceMap.size(), localFaceMap);
1237  }
1238 }
1239 
1240 
1241 // Find faces to interpolate to create value for new face. Only used if
1242 // face was inflated from edge or point. Internal faces should only be
1243 // created from internal faces, external faces only from external faces
1244 // (and ideally the same patch)
1245 // Is bit problematic if there are no faces to select, i.e. in polyDualMesh
1246 // an internal face can be created from a boundary edge with no internal
1247 // faces connected to it.
1248 Foam::labelList Foam::polyTopoChange::selectFaces
1249 (
1250  const primitiveMesh& mesh,
1251  const labelUList& faceLabels,
1252  const bool internalFacesOnly
1253 )
1254 {
1255  label nFaces = 0;
1256 
1257  forAll(faceLabels, i)
1258  {
1259  label facei = faceLabels[i];
1260 
1261  if (internalFacesOnly == mesh.isInternalFace(facei))
1262  {
1263  nFaces++;
1264  }
1265  }
1266 
1267  labelList collectedFaces;
1268 
1269  if (nFaces == 0)
1270  {
1271  // Did not find any faces of the correct type so just use any old
1272  // face.
1273  collectedFaces = faceLabels;
1274  }
1275  else
1276  {
1277  collectedFaces.setSize(nFaces);
1278 
1279  nFaces = 0;
1280 
1281  forAll(faceLabels, i)
1282  {
1283  label facei = faceLabels[i];
1284 
1285  if (internalFacesOnly == mesh.isInternalFace(facei))
1286  {
1287  collectedFaces[nFaces++] = facei;
1288  }
1289  }
1290  }
1291 
1292  return collectedFaces;
1293 }
1294 
1295 
1296 // Calculate pointMap per patch (so from patch point label to old patch point
1297 // label)
1298 void Foam::polyTopoChange::calcPatchPointMap
1299 (
1300  const UList<Map<label>>& oldPatchMeshPointMaps,
1301  const polyBoundaryMesh& boundary,
1302  labelListList& patchPointMap
1303 ) const
1304 {
1305  patchPointMap.setSize(boundary.size());
1306 
1307  forAll(boundary, patchi)
1308  {
1309  const labelList& meshPoints = boundary[patchi].meshPoints();
1310 
1311  const Map<label>& oldMeshPointMap = oldPatchMeshPointMaps[patchi];
1312 
1313  labelList& curPatchPointRnb = patchPointMap[patchi];
1314 
1315  curPatchPointRnb.setSize(meshPoints.size());
1316 
1317  forAll(meshPoints, i)
1318  {
1319  if (meshPoints[i] < pointMap_.size())
1320  {
1321  // Check if old point was part of same patch
1322  curPatchPointRnb[i] = oldMeshPointMap.lookup
1323  (
1324  pointMap_[meshPoints[i]],
1325  -1
1326  );
1327  }
1328  else
1329  {
1330  curPatchPointRnb[i] = -1;
1331  }
1332  }
1333  }
1334 }
1335 
1336 
1337 void Foam::polyTopoChange::calcFaceInflationMaps
1338 (
1339  const polyMesh& mesh,
1340  List<objectMap>& facesFromPoints,
1341  List<objectMap>& facesFromEdges,
1342  List<objectMap>& facesFromFaces
1343 ) const
1344 {
1345  // Faces inflated from points
1346  // ~~~~~~~~~~~~~~~~~~~~~~~~~~
1347 
1348  facesFromPoints.setSize(faceFromPoint_.size());
1349 
1350  if (faceFromPoint_.size())
1351  {
1352  label nFacesFromPoints = 0;
1353 
1354  // Collect all still existing faces connected to this point.
1355  forAllConstIters(faceFromPoint_, iter)
1356  {
1357  const label facei = iter.key();
1358  const label pointi = iter.val();
1359 
1360  // Get internal or patch faces using point on old mesh
1361  const bool internal = (region_[facei] == -1);
1362 
1363  facesFromPoints[nFacesFromPoints++] = objectMap
1364  (
1365  facei,
1366  selectFaces
1367  (
1368  mesh,
1369  mesh.pointFaces()[pointi],
1370  internal
1371  )
1372  );
1373  }
1374  }
1375 
1376 
1377  // Faces inflated from edges
1378  // ~~~~~~~~~~~~~~~~~~~~~~~~~
1379 
1380  facesFromEdges.setSize(faceFromEdge_.size());
1381 
1382  if (faceFromEdge_.size())
1383  {
1384  label nFacesFromEdges = 0;
1385 
1386  // Collect all still existing faces connected to this edge.
1387  forAllConstIters(faceFromEdge_, iter)
1388  {
1389  const label facei = iter.key();
1390  const label edgei = iter.val();
1391 
1392  // Get internal or patch faces using edge on old mesh
1393  const bool internal = (region_[facei] == -1);
1394 
1395  facesFromEdges[nFacesFromEdges++] = objectMap
1396  (
1397  facei,
1398  selectFaces
1399  (
1400  mesh,
1401  mesh.edgeFaces(edgei),
1402  internal
1403  )
1404  );
1405  }
1406  }
1407 
1408 
1409  // Faces from face merging
1410  // ~~~~~~~~~~~~~~~~~~~~~~~
1411 
1412  getMergeSets
1413  (
1414  reverseFaceMap_,
1415  faceMap_,
1416  facesFromFaces
1417  );
1418 }
1419 
1420 
1421 void Foam::polyTopoChange::calcCellInflationMaps
1422 (
1423  const polyMesh& mesh,
1424  List<objectMap>& cellsFromPoints,
1425  List<objectMap>& cellsFromEdges,
1426  List<objectMap>& cellsFromFaces,
1427  List<objectMap>& cellsFromCells
1428 ) const
1429 {
1430  cellsFromPoints.setSize(cellFromPoint_.size());
1431 
1432  if (cellFromPoint_.size())
1433  {
1434  label nCellsFromPoints = 0;
1435 
1436  // Collect all still existing cells connected to this point.
1437  forAllConstIters(cellFromPoint_, iter)
1438  {
1439  const label celli = iter.key();
1440  const label pointi = iter.val();
1441 
1442  cellsFromPoints[nCellsFromPoints++] = objectMap
1443  (
1444  celli,
1445  mesh.pointCells()[pointi]
1446  );
1447  }
1448  }
1449 
1450 
1451  cellsFromEdges.setSize(cellFromEdge_.size());
1452 
1453  if (cellFromEdge_.size())
1454  {
1455  label nCellsFromEdges = 0;
1456 
1457  // Collect all still existing cells connected to this edge.
1458  forAllConstIters(cellFromEdge_, iter)
1459  {
1460  const label celli = iter.key();
1461  const label edgei = iter.val();
1462 
1463  cellsFromEdges[nCellsFromEdges++] = objectMap
1464  (
1465  celli,
1466  mesh.edgeCells()[edgei]
1467  );
1468  }
1469  }
1470 
1471 
1472  cellsFromFaces.setSize(cellFromFace_.size());
1473 
1474  if (cellFromFace_.size())
1475  {
1476  label nCellsFromFaces = 0;
1477 
1478  labelList twoCells(2);
1479 
1480  // Collect all still existing faces connected to this point.
1481  forAllConstIters(cellFromFace_, iter)
1482  {
1483  const label celli = iter.key();
1484  const label oldFacei = iter.val();
1485 
1486  if (mesh.isInternalFace(oldFacei))
1487  {
1488  twoCells[0] = mesh.faceOwner()[oldFacei];
1489  twoCells[1] = mesh.faceNeighbour()[oldFacei];
1490  cellsFromFaces[nCellsFromFaces++] = objectMap
1491  (
1492  celli,
1493  twoCells
1494  );
1495  }
1496  else
1497  {
1498  cellsFromFaces[nCellsFromFaces++] = objectMap
1499  (
1500  celli,
1501  labelList(1, mesh.faceOwner()[oldFacei])
1502  );
1503  }
1504  }
1505  }
1506 
1507 
1508  // Cells from cell merging
1509  // ~~~~~~~~~~~~~~~~~~~~~~~
1510 
1511  getMergeSets
1512  (
1513  reverseCellMap_,
1514  cellMap_,
1515  cellsFromCells
1516  );
1517 }
1518 
1519 
1520 void Foam::polyTopoChange::resetZones
1521 (
1522  const polyMesh& mesh,
1523  polyMesh& newMesh,
1524  labelListList& pointZoneMap,
1525  labelListList& faceZoneFaceMap,
1526  labelListList& cellZoneMap
1527 ) const
1528 {
1529  // pointZones
1530  // ~~~~~~~~~~
1531 
1532  pointZoneMap.setSize(mesh.pointZones().size());
1533  {
1534  const pointZoneMesh& pointZones = mesh.pointZones();
1535 
1536  // Count points per zone
1537 
1538  labelList nPoints(pointZones.size(), Zero);
1539 
1540  forAllConstIters(pointZone_, iter)
1541  {
1542  const label pointi = iter.key();
1543  const label zonei = iter.val();
1544 
1545  if (zonei < 0 || zonei >= pointZones.size())
1546  {
1548  << "Illegal zoneID " << zonei << " for point "
1549  << pointi << " coord " << mesh.points()[pointi]
1550  << abort(FatalError);
1551  }
1552  nPoints[zonei]++;
1553  }
1554 
1555  // Distribute points per zone
1556 
1557  labelListList addressing(pointZones.size());
1558  forAll(addressing, zonei)
1559  {
1560  addressing[zonei].setSize(nPoints[zonei]);
1561  }
1562  nPoints = 0;
1563 
1564  forAllConstIters(pointZone_, iter)
1565  {
1566  const label pointi = iter.key();
1567  const label zonei = iter.val();
1568 
1569  addressing[zonei][nPoints[zonei]++] = pointi;
1570  }
1571  // Sort the addressing
1572  forAll(addressing, zonei)
1573  {
1574  stableSort(addressing[zonei]);
1575  }
1576 
1577  // So now we both have old zones and the new addressing.
1578  // Invert the addressing to get pointZoneMap.
1579  forAll(addressing, zonei)
1580  {
1581  const pointZone& oldZone = pointZones[zonei];
1582  const labelList& newZoneAddr = addressing[zonei];
1583 
1584  labelList& curPzRnb = pointZoneMap[zonei];
1585  curPzRnb.setSize(newZoneAddr.size());
1586 
1587  forAll(newZoneAddr, i)
1588  {
1589  if (newZoneAddr[i] < pointMap_.size())
1590  {
1591  curPzRnb[i] = oldZone.whichPoint(pointMap_[newZoneAddr[i]]);
1592  }
1593  else
1594  {
1595  curPzRnb[i] = -1;
1596  }
1597  }
1598  }
1599 
1600  // Reset the addressing on the zone
1601  newMesh.pointZones().clearAddressing();
1602  forAll(newMesh.pointZones(), zonei)
1603  {
1604  if (debug)
1605  {
1606  Pout<< "pointZone:" << zonei
1607  << " name:" << newMesh.pointZones()[zonei].name()
1608  << " size:" << addressing[zonei].size()
1609  << endl;
1610  }
1611 
1612  newMesh.pointZones()[zonei] = addressing[zonei];
1613  }
1614  }
1615 
1616 
1617  // faceZones
1618  // ~~~~~~~~~
1619 
1620  faceZoneFaceMap.setSize(mesh.faceZones().size());
1621  {
1622  const faceZoneMesh& faceZones = mesh.faceZones();
1623 
1624  labelList nFaces(faceZones.size(), Zero);
1625 
1626  forAllConstIters(faceZone_, iter)
1627  {
1628  const label facei = iter.key();
1629  const label zonei = iter.val();
1630 
1631  if (zonei < 0 || zonei >= faceZones.size())
1632  {
1634  << "Illegal zoneID " << zonei << " for face "
1635  << facei
1636  << abort(FatalError);
1637  }
1638  nFaces[zonei]++;
1639  }
1640 
1641  labelListList addressing(faceZones.size());
1642  boolListList flipMode(faceZones.size());
1643 
1644  forAll(addressing, zonei)
1645  {
1646  addressing[zonei].setSize(nFaces[zonei]);
1647  flipMode[zonei].setSize(nFaces[zonei]);
1648  }
1649  nFaces = 0;
1650 
1651  forAllConstIters(faceZone_, iter)
1652  {
1653  const label facei = iter.key();
1654  const label zonei = iter.val();
1655 
1656  const label index = nFaces[zonei]++;
1657 
1658  addressing[zonei][index] = facei;
1659  flipMode[zonei][index] = faceZoneFlip_.test(facei);
1660  }
1661 
1662  // Sort the addressing
1663  forAll(addressing, zonei)
1664  {
1665  labelList newToOld(sortedOrder(addressing[zonei]));
1666  {
1667  labelList newAddressing(addressing[zonei].size());
1668  forAll(newAddressing, i)
1669  {
1670  newAddressing[i] = addressing[zonei][newToOld[i]];
1671  }
1672  addressing[zonei].transfer(newAddressing);
1673  }
1674  {
1675  boolList newFlipMode(flipMode[zonei].size());
1676  forAll(newFlipMode, i)
1677  {
1678  newFlipMode[i] = flipMode[zonei][newToOld[i]];
1679  }
1680  flipMode[zonei].transfer(newFlipMode);
1681  }
1682  }
1683 
1684  // So now we both have old zones and the new addressing.
1685  // Invert the addressing to get faceZoneFaceMap.
1686  forAll(addressing, zonei)
1687  {
1688  const faceZone& oldZone = faceZones[zonei];
1689  const labelList& newZoneAddr = addressing[zonei];
1690 
1691  labelList& curFzFaceRnb = faceZoneFaceMap[zonei];
1692 
1693  curFzFaceRnb.setSize(newZoneAddr.size());
1694 
1695  forAll(newZoneAddr, i)
1696  {
1697  if (newZoneAddr[i] < faceMap_.size())
1698  {
1699  curFzFaceRnb[i] =
1700  oldZone.whichFace(faceMap_[newZoneAddr[i]]);
1701  }
1702  else
1703  {
1704  curFzFaceRnb[i] = -1;
1705  }
1706  }
1707  }
1708 
1709 
1710  // Reset the addressing on the zone
1711  newMesh.faceZones().clearAddressing();
1712  forAll(newMesh.faceZones(), zonei)
1713  {
1714  if (debug)
1715  {
1716  Pout<< "faceZone:" << zonei
1717  << " name:" << newMesh.faceZones()[zonei].name()
1718  << " size:" << addressing[zonei].size()
1719  << endl;
1720  }
1721 
1722  newMesh.faceZones()[zonei].resetAddressing
1723  (
1724  addressing[zonei],
1725  flipMode[zonei]
1726  );
1727  }
1728  }
1729 
1730 
1731  // cellZones
1732  // ~~~~~~~~~
1733 
1734  cellZoneMap.setSize(mesh.cellZones().size());
1735  {
1736  const cellZoneMesh& cellZones = mesh.cellZones();
1737 
1738  labelList nCells(cellZones.size(), Zero);
1739 
1740  forAll(cellZone_, celli)
1741  {
1742  const label zonei = cellZone_[celli];
1743 
1744  if (zonei >= cellZones.size())
1745  {
1747  << "Illegal zoneID " << zonei << " for cell "
1748  << celli << abort(FatalError);
1749  }
1750 
1751  if (zonei >= 0)
1752  {
1753  nCells[zonei]++;
1754  }
1755  }
1756 
1757  labelListList addressing(cellZones.size());
1758  forAll(addressing, zonei)
1759  {
1760  addressing[zonei].setSize(nCells[zonei]);
1761  }
1762  nCells = 0;
1763 
1764  forAll(cellZone_, celli)
1765  {
1766  const label zonei = cellZone_[celli];
1767 
1768  if (zonei >= 0)
1769  {
1770  addressing[zonei][nCells[zonei]++] = celli;
1771  }
1772  }
1773  // Sort the addressing
1774  forAll(addressing, zonei)
1775  {
1776  stableSort(addressing[zonei]);
1777  }
1778 
1779  // So now we both have old zones and the new addressing.
1780  // Invert the addressing to get cellZoneMap.
1781  forAll(addressing, zonei)
1782  {
1783  const cellZone& oldZone = cellZones[zonei];
1784  const labelList& newZoneAddr = addressing[zonei];
1785 
1786  labelList& curCellRnb = cellZoneMap[zonei];
1787 
1788  curCellRnb.setSize(newZoneAddr.size());
1789 
1790  forAll(newZoneAddr, i)
1791  {
1792  if (newZoneAddr[i] < cellMap_.size())
1793  {
1794  curCellRnb[i] =
1795  oldZone.whichCell(cellMap_[newZoneAddr[i]]);
1796  }
1797  else
1798  {
1799  curCellRnb[i] = -1;
1800  }
1801  }
1802  }
1803 
1804  // Reset the addressing on the zone
1805  newMesh.cellZones().clearAddressing();
1806  forAll(newMesh.cellZones(), zonei)
1807  {
1808  if (debug)
1809  {
1810  Pout<< "cellZone:" << zonei
1811  << " name:" << newMesh.cellZones()[zonei].name()
1812  << " size:" << addressing[zonei].size()
1813  << endl;
1814  }
1815 
1816  newMesh.cellZones()[zonei] = addressing[zonei];
1817  }
1818  }
1819 }
1820 
1821 
1822 void Foam::polyTopoChange::calcFaceZonePointMap
1823 (
1824  const polyMesh& mesh,
1825  const UList<Map<label>>& oldFaceZoneMeshPointMaps,
1826  labelListList& faceZonePointMap
1827 ) const
1828 {
1829  const faceZoneMesh& faceZones = mesh.faceZones();
1830 
1831  faceZonePointMap.setSize(faceZones.size());
1832 
1833  forAll(faceZones, zonei)
1834  {
1835  const faceZone& newZone = faceZones[zonei];
1836 
1837  const labelList& newZoneMeshPoints = newZone().meshPoints();
1838 
1839  const Map<label>& oldZoneMeshPointMap = oldFaceZoneMeshPointMaps[zonei];
1840 
1841  labelList& curFzPointRnb = faceZonePointMap[zonei];
1842 
1843  curFzPointRnb.setSize(newZoneMeshPoints.size());
1844 
1845  forAll(newZoneMeshPoints, pointi)
1846  {
1847  if (newZoneMeshPoints[pointi] < pointMap_.size())
1848  {
1849  curFzPointRnb[pointi] =
1850  oldZoneMeshPointMap.lookup
1851  (
1852  pointMap_[newZoneMeshPoints[pointi]],
1853  -1
1854  );
1855  }
1856  else
1857  {
1858  curFzPointRnb[pointi] = -1;
1859  }
1860  }
1861  }
1862 }
1863 
1864 
1865 void Foam::polyTopoChange::reorderCoupledFaces
1866 (
1867  const bool syncParallel,
1868  const polyBoundaryMesh& boundary,
1869  const labelUList& patchStarts,
1870  const labelUList& patchSizes,
1871  const pointField& points
1872 )
1873 {
1874  // Mapping for faces (old to new). Extends over all mesh faces for
1875  // convenience (could be just the external faces)
1876  labelList oldToNew(identity(faces_.size()));
1877 
1878  // Rotation on new faces.
1879  labelList rotation(faces_.size(), Zero);
1880 
1881  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
1882 
1883  // Send ordering
1884  forAll(boundary, patchi)
1885  {
1886  if (syncParallel || !isA<processorPolyPatch>(boundary[patchi]))
1887  {
1888  boundary[patchi].initOrder
1889  (
1890  pBufs,
1892  (
1893  SubList<face>
1894  (
1895  faces_,
1896  patchSizes[patchi],
1897  patchStarts[patchi]
1898  ),
1899  points
1900  )
1901  );
1902  }
1903  }
1904 
1905  if (syncParallel)
1906  {
1907  pBufs.finishedSends();
1908  }
1909 
1910  // Receive and calculate ordering
1911 
1912  bool anyChanged = false;
1913 
1914  forAll(boundary, patchi)
1915  {
1916  if (syncParallel || !isA<processorPolyPatch>(boundary[patchi]))
1917  {
1918  labelList patchFaceMap(patchSizes[patchi], -1);
1919  labelList patchFaceRotation(patchSizes[patchi], Zero);
1920 
1921  const bool changed = boundary[patchi].order
1922  (
1923  pBufs,
1925  (
1926  SubList<face>
1927  (
1928  faces_,
1929  patchSizes[patchi],
1930  patchStarts[patchi]
1931  ),
1932  points
1933  ),
1934  patchFaceMap,
1935  patchFaceRotation
1936  );
1937 
1938  if (changed)
1939  {
1940  // Merge patch face reordering into mesh face reordering table
1941  const label start = patchStarts[patchi];
1942 
1943  forAll(patchFaceMap, patchFacei)
1944  {
1945  oldToNew[patchFacei + start] =
1946  start + patchFaceMap[patchFacei];
1947  }
1948 
1949  forAll(patchFaceRotation, patchFacei)
1950  {
1951  rotation[patchFacei + start] =
1952  patchFaceRotation[patchFacei];
1953  }
1954 
1955  anyChanged = true;
1956  }
1957  }
1958  }
1959 
1960  if (syncParallel)
1961  {
1962  reduce(anyChanged, orOp<bool>());
1963  }
1964 
1965  if (anyChanged)
1966  {
1967  // Reorder faces according to oldToNew.
1968  reorderCompactFaces(oldToNew.size(), oldToNew);
1969 
1970  // Rotate faces (rotation is already in new face indices).
1971  forAll(rotation, facei)
1972  {
1973  if (rotation[facei] != 0)
1974  {
1975  inplaceRotateList<List, label>(faces_[facei], rotation[facei]);
1976  }
1977  }
1978  }
1979 }
1980 
1981 
1982 void Foam::polyTopoChange::compactAndReorder
1983 (
1984  const polyMesh& mesh,
1985  const bool syncParallel,
1986  const bool orderCells,
1987  const bool orderPoints,
1988 
1989  label& nInternalPoints,
1990  pointField& newPoints,
1991  labelList& patchSizes,
1992  labelList& patchStarts,
1993  List<objectMap>& pointsFromPoints,
1994  List<objectMap>& facesFromPoints,
1995  List<objectMap>& facesFromEdges,
1996  List<objectMap>& facesFromFaces,
1997  List<objectMap>& cellsFromPoints,
1998  List<objectMap>& cellsFromEdges,
1999  List<objectMap>& cellsFromFaces,
2000  List<objectMap>& cellsFromCells,
2001  List<Map<label>>& oldPatchMeshPointMaps,
2002  labelList& oldPatchNMeshPoints,
2003  labelList& oldPatchStarts,
2004  List<Map<label>>& oldFaceZoneMeshPointMaps
2005 )
2006 {
2007  if (mesh.boundaryMesh().size() != nPatches_)
2008  {
2010  << "polyTopoChange was constructed with a mesh with "
2011  << nPatches_ << " patches." << endl
2012  << "The mesh now provided has a different number of patches "
2013  << mesh.boundaryMesh().size()
2014  << " which is illegal" << endl
2015  << abort(FatalError);
2016  }
2017 
2018  // Remove any holes from points/faces/cells and sort faces.
2019  // Sets nActiveFaces_.
2020  compact(orderCells, orderPoints, nInternalPoints, patchSizes, patchStarts);
2021 
2022  // Transfer points to pointField. points_ are now cleared!
2023  // Only done since e.g. reorderCoupledFaces requires pointField.
2024  newPoints.transfer(points_);
2025 
2026  // Reorder any coupled faces
2027  reorderCoupledFaces
2028  (
2029  syncParallel,
2030  mesh.boundaryMesh(),
2031  patchStarts,
2032  patchSizes,
2033  newPoints
2034  );
2035 
2036 
2037  // Calculate inflation/merging maps
2038  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2039  // These are for the new face(/point/cell) the old faces whose value
2040  // needs to be
2041  // averaged/summed to get the new value. These old faces come either from
2042  // merged old faces (face remove into other face),
2043  // the old edgeFaces (inflate from edge) or the old pointFaces (inflate
2044  // from point). As an additional complexity will use only internal faces
2045  // to create new value for internal face and vice versa only patch
2046  // faces to to create patch face value.
2047 
2048  // For point only point merging
2049  getMergeSets
2050  (
2051  reversePointMap_,
2052  pointMap_,
2053  pointsFromPoints
2054  );
2055 
2056  calcFaceInflationMaps
2057  (
2058  mesh,
2059  facesFromPoints,
2060  facesFromEdges,
2061  facesFromFaces
2062  );
2063 
2064  calcCellInflationMaps
2065  (
2066  mesh,
2067  cellsFromPoints,
2068  cellsFromEdges,
2069  cellsFromFaces,
2070  cellsFromCells
2071  );
2072 
2073  // Clear inflation info
2074  {
2075  faceFromPoint_.clearStorage();
2076  faceFromEdge_.clearStorage();
2077 
2078  cellFromPoint_.clearStorage();
2079  cellFromEdge_.clearStorage();
2080  cellFromFace_.clearStorage();
2081  }
2082 
2083 
2084  const polyBoundaryMesh& boundary = mesh.boundaryMesh();
2085 
2086  // Grab patch mesh point maps
2087  oldPatchMeshPointMaps.setSize(boundary.size());
2088  oldPatchNMeshPoints.setSize(boundary.size());
2089  oldPatchStarts.setSize(boundary.size());
2090 
2091  forAll(boundary, patchi)
2092  {
2093  // Copy old face zone mesh point maps
2094  oldPatchMeshPointMaps[patchi] = boundary[patchi].meshPointMap();
2095  oldPatchNMeshPoints[patchi] = boundary[patchi].meshPoints().size();
2096  oldPatchStarts[patchi] = boundary[patchi].start();
2097  }
2098 
2099  // Grab old face zone mesh point maps.
2100  // These need to be saved before resetting the mesh and are used
2101  // later on to calculate the faceZone pointMaps.
2102  oldFaceZoneMeshPointMaps.setSize(mesh.faceZones().size());
2103 
2104  forAll(mesh.faceZones(), zonei)
2105  {
2106  const faceZone& oldZone = mesh.faceZones()[zonei];
2107 
2108  oldFaceZoneMeshPointMaps[zonei] = oldZone().meshPointMap();
2109  }
2110 }
2111 
2112 
2113 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
2114 
2115 // Construct from components
2116 Foam::polyTopoChange::polyTopoChange(const label nPatches, const bool strict)
2117 :
2118  strict_(strict),
2119  nPatches_(nPatches),
2120  points_(0),
2121  pointMap_(0),
2122  reversePointMap_(0),
2123  pointZone_(0),
2124  retiredPoints_(0),
2125  faces_(0),
2126  region_(0),
2127  faceOwner_(0),
2128  faceNeighbour_(0),
2129  faceMap_(0),
2130  reverseFaceMap_(0),
2131  faceFromPoint_(0),
2132  faceFromEdge_(0),
2133  flipFaceFlux_(0),
2134  faceZone_(0),
2135  faceZoneFlip_(0),
2136  nActiveFaces_(0),
2137  cellMap_(0),
2138  reverseCellMap_(0),
2139  cellFromPoint_(0),
2140  cellFromEdge_(0),
2141  cellFromFace_(0),
2142  cellZone_(0)
2143 {}
2144 
2145 
2146 // Construct from components
2149  const polyMesh& mesh,
2150  const bool strict
2151 )
2152 :
2153  strict_(strict),
2154  nPatches_(0),
2155  points_(0),
2156  pointMap_(0),
2157  reversePointMap_(0),
2158  pointZone_(0),
2159  retiredPoints_(0),
2160  faces_(0),
2161  region_(0),
2162  faceOwner_(0),
2163  faceNeighbour_(0),
2164  faceMap_(0),
2165  reverseFaceMap_(0),
2166  faceFromPoint_(0),
2167  faceFromEdge_(0),
2168  flipFaceFlux_(0),
2169  faceZone_(0),
2170  faceZoneFlip_(0),
2171  nActiveFaces_(0),
2172  cellMap_(0),
2173  reverseCellMap_(0),
2174  cellFromPoint_(0),
2175  cellFromEdge_(0),
2176  cellFromFace_(0),
2177  cellZone_(0)
2178 {
2179  addMesh
2180  (
2181  mesh,
2182  identity(mesh.boundaryMesh().size()),
2183  identity(mesh.pointZones().size()),
2184  identity(mesh.faceZones().size()),
2185  identity(mesh.cellZones().size())
2186  );
2187 }
2188 
2189 
2190 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
2191 
2193 {
2194  points_.clearStorage();
2195  pointMap_.clearStorage();
2196  reversePointMap_.clearStorage();
2197  pointZone_.clearStorage();
2198  retiredPoints_.clearStorage();
2199 
2200  faces_.clearStorage();
2201  region_.clearStorage();
2202  faceOwner_.clearStorage();
2203  faceNeighbour_.clearStorage();
2204  faceMap_.clearStorage();
2205  reverseFaceMap_.clearStorage();
2206  faceFromPoint_.clearStorage();
2207  faceFromEdge_.clearStorage();
2208  flipFaceFlux_.clearStorage();
2209  faceZone_.clearStorage();
2210  faceZoneFlip_.clearStorage();
2211  nActiveFaces_ = 0;
2212 
2213  cellMap_.clearStorage();
2214  reverseCellMap_.clearStorage();
2215  cellZone_.clearStorage();
2216  cellFromPoint_.clearStorage();
2217  cellFromEdge_.clearStorage();
2218  cellFromFace_.clearStorage();
2219 }
2220 
2221 
2224  const polyMesh& mesh,
2225  const labelUList& patchMap,
2226  const labelUList& pointZoneMap,
2227  const labelUList& faceZoneMap,
2228  const labelUList& cellZoneMap
2229 )
2230 {
2231  label maxRegion = nPatches_ - 1;
2232  for (const label regioni : patchMap)
2233  {
2234  maxRegion = max(maxRegion, regioni);
2235  }
2236  nPatches_ = maxRegion + 1;
2237 
2238 
2239  // Add points
2240  {
2241  const pointField& points = mesh.points();
2242  const pointZoneMesh& pointZones = mesh.pointZones();
2243 
2244  // Extend
2245  points_.setCapacity(points_.size() + points.size());
2246  pointMap_.setCapacity(pointMap_.size() + points.size());
2247  reversePointMap_.setCapacity(reversePointMap_.size() + points.size());
2248  pointZone_.resize(pointZone_.size() + points.size()/100);
2249 
2250  // Precalc offset zones
2251  labelList newZoneID(points.size(), -1);
2252 
2253  forAll(pointZones, zonei)
2254  {
2255  const labelList& pointLabels = pointZones[zonei];
2256 
2257  for (const label pointi : pointLabels)
2258  {
2259  newZoneID[pointi] = pointZoneMap[zonei];
2260  }
2261  }
2262 
2263  // Add points in mesh order
2264  for (label pointi = 0; pointi < mesh.nPoints(); pointi++)
2265  {
2266  addPoint
2267  (
2268  points[pointi],
2269  pointi,
2270  newZoneID[pointi],
2271  true
2272  );
2273  }
2274  }
2275 
2276  // Add cells
2277  {
2278  const cellZoneMesh& cellZones = mesh.cellZones();
2279 
2280  // Resize
2281 
2282  // Note: polyMesh does not allow retired cells anymore. So allCells
2283  // always equals nCells
2284  label nAllCells = mesh.nCells();
2285 
2286  cellMap_.setCapacity(cellMap_.size() + nAllCells);
2287  reverseCellMap_.setCapacity(reverseCellMap_.size() + nAllCells);
2288  cellFromPoint_.resize(cellFromPoint_.size() + nAllCells/100);
2289  cellFromEdge_.resize(cellFromEdge_.size() + nAllCells/100);
2290  cellFromFace_.resize(cellFromFace_.size() + nAllCells/100);
2291  cellZone_.setCapacity(cellZone_.size() + nAllCells);
2292 
2293 
2294  // Precalc offset zones
2295  labelList newZoneID(nAllCells, -1);
2296 
2297  forAll(cellZones, zonei)
2298  {
2299  const labelList& cellLabels = cellZones[zonei];
2300 
2301  for (const label celli : cellLabels)
2302  {
2303  if (newZoneID[celli] != -1)
2304  {
2306  << "Cell:" << celli
2307  << " centre:" << mesh.cellCentres()[celli]
2308  << " is in two zones:"
2309  << cellZones[newZoneID[celli]].name()
2310  << " and " << cellZones[zonei].name() << endl
2311  << " This is not supported."
2312  << " Continuing with first zone only." << endl;
2313  }
2314  else
2315  {
2316  newZoneID[celli] = cellZoneMap[zonei];
2317  }
2318  }
2319  }
2320 
2321  // Add cells in mesh order
2322  for (label celli = 0; celli < nAllCells; celli++)
2323  {
2324  // Add cell from cell
2325  addCell(-1, -1, -1, celli, newZoneID[celli]);
2326  }
2327  }
2328 
2329  // Add faces
2330  {
2332  const faceList& faces = mesh.faces();
2333  const labelList& faceOwner = mesh.faceOwner();
2334  const labelList& faceNeighbour = mesh.faceNeighbour();
2335  const faceZoneMesh& faceZones = mesh.faceZones();
2336 
2337  // Resize
2338  label nAllFaces = mesh.faces().size();
2339 
2340  faces_.setCapacity(faces_.size() + nAllFaces);
2341  region_.setCapacity(region_.size() + nAllFaces);
2342  faceOwner_.setCapacity(faceOwner_.size() + nAllFaces);
2343  faceNeighbour_.setCapacity(faceNeighbour_.size() + nAllFaces);
2344  faceMap_.setCapacity(faceMap_.size() + nAllFaces);
2345  reverseFaceMap_.setCapacity(reverseFaceMap_.size() + nAllFaces);
2346  faceFromPoint_.resize(faceFromPoint_.size() + nAllFaces/100);
2347  faceFromEdge_.resize(faceFromEdge_.size() + nAllFaces/100);
2348  flipFaceFlux_.setCapacity(faces_.size() + nAllFaces);
2349  faceZone_.resize(faceZone_.size() + nAllFaces/100);
2350  faceZoneFlip_.setCapacity(faces_.size() + nAllFaces);
2351 
2352 
2353  // Precalc offset zones
2354  labelList newZoneID(nAllFaces, -1);
2355  boolList zoneFlip(nAllFaces, false);
2356 
2357  forAll(faceZones, zonei)
2358  {
2359  const labelList& faceLabels = faceZones[zonei];
2360  const boolList& flipMap = faceZones[zonei].flipMap();
2361 
2362  forAll(faceLabels, facei)
2363  {
2364  newZoneID[faceLabels[facei]] = faceZoneMap[zonei];
2365  zoneFlip[faceLabels[facei]] = flipMap[facei];
2366  }
2367  }
2368 
2369  // Add faces in mesh order
2370 
2371  // 1. Internal faces
2372  for (label facei = 0; facei < mesh.nInternalFaces(); facei++)
2373  {
2374  addFace
2375  (
2376  faces[facei],
2377  faceOwner[facei],
2378  faceNeighbour[facei],
2379  -1, // masterPointID
2380  -1, // masterEdgeID
2381  facei, // masterFaceID
2382  false, // flipFaceFlux
2383  -1, // patchID
2384  newZoneID[facei], // zoneID
2385  zoneFlip[facei] // zoneFlip
2386  );
2387  }
2388 
2389  // 2. Patch faces
2390  forAll(patches, patchi)
2391  {
2392  const polyPatch& pp = patches[patchi];
2393 
2394  if (pp.start() != faces_.size())
2395  {
2397  << "Problem : "
2398  << "Patch " << pp.name() << " starts at " << pp.start()
2399  << endl
2400  << "Current face counter at " << faces_.size() << endl
2401  << "Are patches in incremental order?"
2402  << abort(FatalError);
2403  }
2404  forAll(pp, patchFacei)
2405  {
2406  const label facei = pp.start() + patchFacei;
2407 
2408  addFace
2409  (
2410  faces[facei],
2411  faceOwner[facei],
2412  -1, // neighbour
2413  -1, // masterPointID
2414  -1, // masterEdgeID
2415  facei, // masterFaceID
2416  false, // flipFaceFlux
2417  patchMap[patchi], // patchID
2418  newZoneID[facei], // zoneID
2419  zoneFlip[facei] // zoneFlip
2420  );
2421  }
2422  }
2423  }
2424 }
2425 
2426 
2429  const label nPoints,
2430  const label nFaces,
2431  const label nCells
2432 )
2433 {
2434  points_.setCapacity(nPoints);
2435  pointMap_.setCapacity(nPoints);
2436  reversePointMap_.setCapacity(nPoints);
2437  pointZone_.resize(pointZone_.size() + nPoints/100);
2438 
2439  faces_.setCapacity(nFaces);
2440  region_.setCapacity(nFaces);
2441  faceOwner_.setCapacity(nFaces);
2442  faceNeighbour_.setCapacity(nFaces);
2443  faceMap_.setCapacity(nFaces);
2444  reverseFaceMap_.setCapacity(nFaces);
2445  faceFromPoint_.resize(faceFromPoint_.size() + nFaces/100);
2446  faceFromEdge_.resize(faceFromEdge_.size() + nFaces/100);
2447  flipFaceFlux_.setCapacity(nFaces);
2448  faceZone_.resize(faceZone_.size() + nFaces/100);
2449  faceZoneFlip_.setCapacity(nFaces);
2450 
2451  cellMap_.setCapacity(nCells);
2452  reverseCellMap_.setCapacity(nCells);
2453  cellFromPoint_.resize(cellFromPoint_.size() + nCells/100);
2454  cellFromEdge_.resize(cellFromEdge_.size() + nCells/100);
2455  cellFromFace_.resize(cellFromFace_.size() + nCells/100);
2456  cellZone_.setCapacity(nCells);
2457 }
2458 
2459 
2461 {
2462  if (isType<polyAddPoint>(action))
2463  {
2464  const polyAddPoint& pap = refCast<const polyAddPoint>(action);
2465 
2466  return addPoint
2467  (
2468  pap.newPoint(),
2469  pap.masterPointID(),
2470  pap.zoneID(),
2471  pap.inCell()
2472  );
2473  }
2474  else if (isType<polyModifyPoint>(action))
2475  {
2476  const polyModifyPoint& pmp = refCast<const polyModifyPoint>(action);
2477 
2478  modifyPoint
2479  (
2480  pmp.pointID(),
2481  pmp.newPoint(),
2482  pmp.zoneID(),
2483  pmp.inCell()
2484  );
2485 
2486  return -1;
2487  }
2488  else if (isType<polyRemovePoint>(action))
2489  {
2490  const polyRemovePoint& prp = refCast<const polyRemovePoint>(action);
2491 
2492  removePoint(prp.pointID(), prp.mergePointID());
2493 
2494  return -1;
2495  }
2496  else if (isType<polyAddFace>(action))
2497  {
2498  const polyAddFace& paf = refCast<const polyAddFace>(action);
2499 
2500  return addFace
2501  (
2502  paf.newFace(),
2503  paf.owner(),
2504  paf.neighbour(),
2505  paf.masterPointID(),
2506  paf.masterEdgeID(),
2507  paf.masterFaceID(),
2508  paf.flipFaceFlux(),
2509  paf.patchID(),
2510  paf.zoneID(),
2511  paf.zoneFlip()
2512  );
2513  }
2514  else if (isType<polyModifyFace>(action))
2515  {
2516  const polyModifyFace& pmf = refCast<const polyModifyFace>(action);
2517 
2518  modifyFace
2519  (
2520  pmf.newFace(),
2521  pmf.faceID(),
2522  pmf.owner(),
2523  pmf.neighbour(),
2524  pmf.flipFaceFlux(),
2525  pmf.patchID(),
2526  pmf.zoneID(),
2527  pmf.zoneFlip()
2528  );
2529 
2530  return -1;
2531  }
2532  else if (isType<polyRemoveFace>(action))
2533  {
2534  const polyRemoveFace& prf = refCast<const polyRemoveFace>(action);
2535 
2536  removeFace(prf.faceID(), prf.mergeFaceID());
2537 
2538  return -1;
2539  }
2540  else if (isType<polyAddCell>(action))
2541  {
2542  const polyAddCell& pac = refCast<const polyAddCell>(action);
2543 
2544  return addCell
2545  (
2546  pac.masterPointID(),
2547  pac.masterEdgeID(),
2548  pac.masterFaceID(),
2549  pac.masterCellID(),
2550  pac.zoneID()
2551  );
2552  }
2553  else if (isType<polyModifyCell>(action))
2554  {
2555  const polyModifyCell& pmc = refCast<const polyModifyCell>(action);
2556 
2557  if (pmc.removeFromZone())
2558  {
2559  modifyCell(pmc.cellID(), -1);
2560  }
2561  else
2562  {
2563  modifyCell(pmc.cellID(), pmc.zoneID());
2564  }
2565 
2566  return -1;
2567  }
2568  else if (isType<polyRemoveCell>(action))
2569  {
2570  const polyRemoveCell& prc = refCast<const polyRemoveCell>(action);
2571 
2572  removeCell(prc.cellID(), prc.mergeCellID());
2573 
2574  return -1;
2575  }
2576  else
2577  {
2579  << "Unknown type of topoChange: " << action.type()
2580  << abort(FatalError);
2581 
2582  // Dummy return to keep compiler happy
2583  return -1;
2584  }
2585 }
2586 
2587 
2590  const point& pt,
2591  const label masterPointID,
2592  const label zoneID,
2593  const bool inCell
2594 )
2595 {
2596  const label pointi = points_.size();
2597 
2598  points_.append(pt);
2599  pointMap_.append(masterPointID);
2600  reversePointMap_.append(pointi);
2601 
2602  if (zoneID >= 0)
2603  {
2604  pointZone_.insert(pointi, zoneID);
2605  }
2606 
2607  if (!inCell)
2608  {
2609  retiredPoints_.insert(pointi);
2610  }
2611 
2612  return pointi;
2613 }
2614 
2615 
2618  const label pointi,
2619  const point& pt,
2620  const label zoneID,
2621  const bool inCell
2622 )
2623 {
2624  if (pointi < 0 || pointi >= points_.size())
2625  {
2627  << "illegal point label " << pointi << endl
2628  << "Valid point labels are 0 .. " << points_.size()-1
2629  << abort(FatalError);
2630  }
2631  if (pointRemoved(pointi) || pointMap_[pointi] == -1)
2632  {
2634  << "point " << pointi << " already marked for removal"
2635  << abort(FatalError);
2636  }
2637  points_[pointi] = pt;
2638 
2639  if (zoneID >= 0)
2640  {
2641  pointZone_.set(pointi, zoneID);
2642  }
2643  else
2644  {
2645  pointZone_.erase(pointi);
2646  }
2647 
2648  if (inCell)
2649  {
2650  retiredPoints_.erase(pointi);
2651  }
2652  else
2653  {
2654  retiredPoints_.insert(pointi);
2655  }
2656 }
2657 
2658 
2660 {
2661  if (newPoints.size() != points_.size())
2662  {
2664  << "illegal pointField size." << endl
2665  << "Size:" << newPoints.size() << endl
2666  << "Points in mesh:" << points_.size()
2667  << abort(FatalError);
2668  }
2669 
2670  forAll(points_, pointi)
2671  {
2672  points_[pointi] = newPoints[pointi];
2673  }
2674 }
2675 
2676 
2679  const label pointi,
2680  const label mergePointi
2681 )
2682 {
2683  if (pointi < 0 || pointi >= points_.size())
2684  {
2686  << "illegal point label " << pointi << endl
2687  << "Valid point labels are 0 .. " << points_.size()-1
2688  << abort(FatalError);
2689  }
2690 
2691  if
2692  (
2693  strict_
2694  && (pointRemoved(pointi) || pointMap_[pointi] == -1)
2695  )
2696  {
2698  << "point " << pointi << " already marked for removal" << nl
2699  << "Point:" << points_[pointi] << " pointMap:" << pointMap_[pointi]
2700  << abort(FatalError);
2701  }
2702 
2703  if (pointi == mergePointi)
2704  {
2706  << "Cannot remove/merge point " << pointi << " onto itself."
2707  << abort(FatalError);
2708  }
2709 
2710  points_[pointi] = point::max;
2711  pointMap_[pointi] = -1;
2712  if (mergePointi >= 0)
2713  {
2714  reversePointMap_[pointi] = -mergePointi-2;
2715  }
2716  else
2717  {
2718  reversePointMap_[pointi] = -1;
2719  }
2720  pointZone_.erase(pointi);
2721  retiredPoints_.erase(pointi);
2722 }
2723 
2724 
2727  const face& f,
2728  const label own,
2729  const label nei,
2730  const label masterPointID,
2731  const label masterEdgeID,
2732  const label masterFaceID,
2733  const bool flipFaceFlux,
2734  const label patchID,
2735  const label zoneID,
2736  const bool zoneFlip
2737 )
2738 {
2739  // Check validity
2740  if (debug)
2741  {
2742  checkFace(f, -1, own, nei, patchID, zoneID);
2743  }
2744 
2745  label facei = faces_.size();
2746 
2747  faces_.append(f);
2748  region_.append(patchID);
2749  faceOwner_.append(own);
2750  faceNeighbour_.append(nei);
2751 
2752  if (masterPointID >= 0)
2753  {
2754  faceMap_.append(-1);
2755  faceFromPoint_.insert(facei, masterPointID);
2756  }
2757  else if (masterEdgeID >= 0)
2758  {
2759  faceMap_.append(-1);
2760  faceFromEdge_.insert(facei, masterEdgeID);
2761  }
2762  else if (masterFaceID >= 0)
2763  {
2764  faceMap_.append(masterFaceID);
2765  }
2766  else
2767  {
2768  // Allow inflate-from-nothing?
2769  //FatalErrorInFunction
2770  // << "Need to specify a master point, edge or face"
2771  // << "face:" << f << " own:" << own << " nei:" << nei
2772  // << abort(FatalError);
2773  faceMap_.append(-1);
2774  }
2775  reverseFaceMap_.append(facei);
2776 
2777  flipFaceFlux_.set(facei, flipFaceFlux);
2778 
2779  if (zoneID >= 0)
2780  {
2781  faceZone_.insert(facei, zoneID);
2782  }
2783  faceZoneFlip_.set(facei, zoneFlip);
2784 
2785  return facei;
2786 }
2787 
2788 
2791  const face& f,
2792  const label facei,
2793  const label own,
2794  const label nei,
2795  const bool flipFaceFlux,
2796  const label patchID,
2797  const label zoneID,
2798  const bool zoneFlip
2799 )
2800 {
2801  // Check validity
2802  if (debug)
2803  {
2804  checkFace(f, facei, own, nei, patchID, zoneID);
2805  }
2806 
2807  faces_[facei] = f;
2808  faceOwner_[facei] = own;
2809  faceNeighbour_[facei] = nei;
2810  region_[facei] = patchID;
2811 
2812  flipFaceFlux_.set(facei, flipFaceFlux);
2813  faceZoneFlip_.set(facei, zoneFlip);
2814 
2815  if (zoneID >= 0)
2816  {
2817  faceZone_.set(facei, zoneID);
2818  }
2819  else
2820  {
2821  faceZone_.erase(facei);
2822  }
2823 }
2824 
2825 
2828  const label facei,
2829  const label mergeFacei
2830 )
2831 {
2832  if (facei < 0 || facei >= faces_.size())
2833  {
2835  << "illegal face label " << facei << endl
2836  << "Valid face labels are 0 .. " << faces_.size()-1
2837  << abort(FatalError);
2838  }
2839 
2840  if
2841  (
2842  strict_
2843  && (faceRemoved(facei) || faceMap_[facei] == -1)
2844  )
2845  {
2847  << "face " << facei
2848  << " already marked for removal"
2849  << abort(FatalError);
2850  }
2851 
2852  faces_[facei].setSize(0);
2853  region_[facei] = -1;
2854  faceOwner_[facei] = -1;
2855  faceNeighbour_[facei] = -1;
2856  faceMap_[facei] = -1;
2857  if (mergeFacei >= 0)
2858  {
2859  reverseFaceMap_[facei] = -mergeFacei-2;
2860  }
2861  else
2862  {
2863  reverseFaceMap_[facei] = -1;
2864  }
2865  faceFromEdge_.erase(facei);
2866  faceFromPoint_.erase(facei);
2867  flipFaceFlux_.unset(facei);
2868  faceZoneFlip_.unset(facei);
2869  faceZone_.erase(facei);
2870 }
2871 
2872 
2875  const label masterPointID,
2876  const label masterEdgeID,
2877  const label masterFaceID,
2878  const label masterCellID,
2879  const label zoneID
2880 )
2881 {
2882  label celli = cellMap_.size();
2883 
2884  if (masterPointID >= 0)
2885  {
2886  cellMap_.append(-1);
2887  cellFromPoint_.insert(celli, masterPointID);
2888  }
2889  else if (masterEdgeID >= 0)
2890  {
2891  cellMap_.append(-1);
2892  cellFromEdge_.insert(celli, masterEdgeID);
2893  }
2894  else if (masterFaceID >= 0)
2895  {
2896  cellMap_.append(-1);
2897  cellFromFace_.insert(celli, masterFaceID);
2898  }
2899  else
2900  {
2901  cellMap_.append(masterCellID);
2902  }
2903  reverseCellMap_.append(celli);
2904  cellZone_.append(zoneID);
2905 
2906  return celli;
2907 }
2908 
2909 
2912  const label celli,
2913  const label zoneID
2914 )
2915 {
2916  cellZone_[celli] = zoneID;
2917 }
2918 
2919 
2922  const label celli,
2923  const label mergeCelli
2924 )
2925 {
2926  if (celli < 0 || celli >= cellMap_.size())
2927  {
2929  << "illegal cell label " << celli << endl
2930  << "Valid cell labels are 0 .. " << cellMap_.size()-1
2931  << abort(FatalError);
2932  }
2933 
2934  if (strict_ && cellMap_[celli] == -2)
2935  {
2937  << "cell " << celli
2938  << " already marked for removal"
2939  << abort(FatalError);
2940  }
2941 
2942  cellMap_[celli] = -2;
2943  if (mergeCelli >= 0)
2944  {
2945  reverseCellMap_[celli] = -mergeCelli-2;
2946  }
2947  else
2948  {
2949  reverseCellMap_[celli] = -1;
2950  }
2951  cellFromPoint_.erase(celli);
2952  cellFromEdge_.erase(celli);
2953  cellFromFace_.erase(celli);
2954  cellZone_[celli] = -1;
2955 }
2956 
2957 
2960  polyMesh& mesh,
2961  const bool inflate,
2962  const bool syncParallel,
2963  const bool orderCells,
2964  const bool orderPoints
2965 )
2966 {
2967  if (debug)
2968  {
2969  Pout<< "polyTopoChange::changeMesh"
2970  << "(polyMesh&, const bool, const bool, const bool, const bool)"
2971  << endl;
2972  }
2973 
2974  if (debug)
2975  {
2976  Pout<< "Old mesh:" << nl;
2977  writeMeshStats(mesh, Pout);
2978  }
2979 
2980  // new mesh points
2981  pointField newPoints;
2982  // number of internal points
2983  label nInternalPoints;
2984  // patch slicing
2985  labelList patchSizes;
2986  labelList patchStarts;
2987  // inflate maps
2988  List<objectMap> pointsFromPoints;
2989  List<objectMap> facesFromPoints;
2990  List<objectMap> facesFromEdges;
2991  List<objectMap> facesFromFaces;
2992  List<objectMap> cellsFromPoints;
2993  List<objectMap> cellsFromEdges;
2994  List<objectMap> cellsFromFaces;
2995  List<objectMap> cellsFromCells;
2996  // old mesh info
2997  List<Map<label>> oldPatchMeshPointMaps;
2998  labelList oldPatchNMeshPoints;
2999  labelList oldPatchStarts;
3000  List<Map<label>> oldFaceZoneMeshPointMaps;
3001 
3002  // Compact, reorder patch faces and calculate mesh/patch maps.
3003  compactAndReorder
3004  (
3005  mesh,
3006  syncParallel,
3007  orderCells,
3008  orderPoints,
3009 
3010  nInternalPoints,
3011  newPoints,
3012  patchSizes,
3013  patchStarts,
3014  pointsFromPoints,
3015  facesFromPoints,
3016  facesFromEdges,
3017  facesFromFaces,
3018  cellsFromPoints,
3019  cellsFromEdges,
3020  cellsFromFaces,
3021  cellsFromCells,
3022  oldPatchMeshPointMaps,
3023  oldPatchNMeshPoints,
3024  oldPatchStarts,
3025  oldFaceZoneMeshPointMaps
3026  );
3027 
3028  const label nOldPoints(mesh.nPoints());
3029  const label nOldFaces(mesh.nFaces());
3030  const label nOldCells(mesh.nCells());
3031  autoPtr<scalarField> oldCellVolumes(new scalarField(mesh.cellVolumes()));
3032 
3033 
3034  // Change the mesh
3035  // ~~~~~~~~~~~~~~~
3036  // This will invalidate any addressing so better make sure you have
3037  // all the information you need!!!
3038 
3039  if (inflate)
3040  {
3041  // Keep (renumbered) mesh points, store new points in map for inflation
3042  // (appended points (i.e. from nowhere) get value zero)
3043  pointField renumberedMeshPoints(newPoints.size());
3044 
3045  forAll(pointMap_, newPointi)
3046  {
3047  const label oldPointi = pointMap_[newPointi];
3048 
3049  if (oldPointi >= 0)
3050  {
3051  renumberedMeshPoints[newPointi] = mesh.points()[oldPointi];
3052  }
3053  else
3054  {
3055  renumberedMeshPoints[newPointi] = Zero;
3056  }
3057  }
3058 
3060  (
3061  autoPtr<pointField>::New(std::move(renumberedMeshPoints)),
3062  autoPtr<faceList>::New(std::move(faces_)),
3063  autoPtr<labelList>::New(std::move(faceOwner_)),
3064  autoPtr<labelList>::New(std::move(faceNeighbour_)),
3065  patchSizes,
3066  patchStarts,
3067  syncParallel
3068  );
3069 
3070  mesh.topoChanging(true);
3071  // Note: could already set moving flag as well
3072  // mesh.moving(true);
3073  }
3074  else
3075  {
3076  // Set new points.
3078  (
3079  autoPtr<pointField>::New(std::move(newPoints)),
3080  autoPtr<faceList>::New(std::move(faces_)),
3081  autoPtr<labelList>::New(std::move(faceOwner_)),
3082  autoPtr<labelList>::New(std::move(faceNeighbour_)),
3083  patchSizes,
3084  patchStarts,
3085  syncParallel
3086  );
3087  mesh.topoChanging(true);
3088  }
3089 
3090  // Clear out primitives
3091  {
3092  retiredPoints_.clearStorage();
3093  region_.clearStorage();
3094  }
3095 
3096 
3097  if (debug)
3098  {
3099  // Some stats on changes
3100  label nAdd, nInflate, nMerge, nRemove;
3101  countMap(pointMap_, reversePointMap_, nAdd, nInflate, nMerge, nRemove);
3102  Pout<< "Points:"
3103  << " added(from point):" << nAdd
3104  << " added(from nothing):" << nInflate
3105  << " merged(into other point):" << nMerge
3106  << " removed:" << nRemove
3107  << nl;
3108 
3109  countMap(faceMap_, reverseFaceMap_, nAdd, nInflate, nMerge, nRemove);
3110  Pout<< "Faces:"
3111  << " added(from face):" << nAdd
3112  << " added(inflated):" << nInflate
3113  << " merged(into other face):" << nMerge
3114  << " removed:" << nRemove
3115  << nl;
3116 
3117  countMap(cellMap_, reverseCellMap_, nAdd, nInflate, nMerge, nRemove);
3118  Pout<< "Cells:"
3119  << " added(from cell):" << nAdd
3120  << " added(inflated):" << nInflate
3121  << " merged(into other cell):" << nMerge
3122  << " removed:" << nRemove
3123  << nl
3124  << endl;
3125  }
3126 
3127  if (debug)
3128  {
3129  Pout<< "New mesh:" << nl;
3130  writeMeshStats(mesh, Pout);
3131  }
3132 
3133 
3134  // Zones
3135  // ~~~~~
3136 
3137  // Inverse of point/face/cell zone addressing.
3138  // For every preserved point/face/cells in zone give the old position.
3139  // For added points, the index is set to -1
3140  labelListList pointZoneMap(mesh.pointZones().size());
3141  labelListList faceZoneFaceMap(mesh.faceZones().size());
3142  labelListList cellZoneMap(mesh.cellZones().size());
3143 
3144  resetZones(mesh, mesh, pointZoneMap, faceZoneFaceMap, cellZoneMap);
3145 
3146  // Clear zone info
3147  {
3148  pointZone_.clearStorage();
3149  faceZone_.clearStorage();
3150  faceZoneFlip_.clearStorage();
3151  cellZone_.clearStorage();
3152  }
3153 
3154 
3155  // Patch point renumbering
3156  // For every preserved point on a patch give the old position.
3157  // For added points, the index is set to -1
3158  labelListList patchPointMap(mesh.boundaryMesh().size());
3159  calcPatchPointMap
3160  (
3161  oldPatchMeshPointMaps,
3162  mesh.boundaryMesh(),
3163  patchPointMap
3164  );
3165 
3166  // Create the face zone mesh point renumbering
3167  labelListList faceZonePointMap(mesh.faceZones().size());
3168  calcFaceZonePointMap(mesh, oldFaceZoneMeshPointMaps, faceZonePointMap);
3169 
3170  labelHashSet flipFaceFluxSet(HashSetOps::used(flipFaceFlux_));
3171 
3173  (
3174  mesh,
3175  nOldPoints,
3176  nOldFaces,
3177  nOldCells,
3178 
3179  pointMap_,
3180  pointsFromPoints,
3181 
3182  faceMap_,
3183  facesFromPoints,
3184  facesFromEdges,
3185  facesFromFaces,
3186 
3187  cellMap_,
3188  cellsFromPoints,
3189  cellsFromEdges,
3190  cellsFromFaces,
3191  cellsFromCells,
3192 
3193  reversePointMap_,
3194  reverseFaceMap_,
3195  reverseCellMap_,
3196 
3197  flipFaceFluxSet,
3198 
3199  patchPointMap,
3200 
3201  pointZoneMap,
3202 
3203  faceZonePointMap,
3204  faceZoneFaceMap,
3205  cellZoneMap,
3206 
3207  newPoints, // if empty signals no inflation.
3208  oldPatchStarts,
3209  oldPatchNMeshPoints,
3210 
3211  oldCellVolumes,
3212 
3213  true // steal storage.
3214  );
3215 
3216  // At this point all member DynamicList (pointMap_, cellMap_ etc.) will
3217  // be invalid.
3218 }
3219 
3220 
3221 // ************************************************************************* //
Foam::polyModifyCell::zoneID
label zoneID() const
Cell zone ID.
Definition: polyModifyCell.H:124
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::polyModifyPoint::pointID
label pointID() const
Point ID.
Definition: polyModifyPoint.H:120
Foam::polyTopoChange::addCell
label addCell(const label masterPointID, const label masterEdgeID, const label masterFaceID, const label masterCellID, const label zoneID)
Add cell. Return new cell label.
Definition: polyTopoChange.C:2874
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::polyAddPoint::inCell
bool inCell() const
Does the point support a cell.
Definition: polyAddPoint.H:156
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::polyModifyFace::zoneFlip
label zoneFlip() const
Face zone flip.
Definition: polyModifyFace.H:265
Foam::polyModifyFace::flipFaceFlux
bool flipFaceFlux() const
Does the face flux need to be flipped.
Definition: polyModifyFace.H:224
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::polyMesh::topoChanging
bool topoChanging() const
Is mesh topology changing.
Definition: polyMesh.H:536
Foam::polyAddFace::masterFaceID
label masterFaceID() const
Return master face ID.
Definition: polyAddFace.H:294
Foam::UPstream::commsTypes::nonBlocking
Foam::polyModifyCell::cellID
label cellID() const
Cell ID.
Definition: polyModifyCell.H:107
Foam::polyRemoveCell::cellID
label cellID() const
Return cell ID.
Definition: polyRemoveCell.H:97
Foam::boolListList
List< List< bool > > boolListList
A List of boolList.
Definition: boolList.H:48
polyRemovePoint.H
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
Foam::polyAddFace::owner
label owner() const
Return owner cell.
Definition: polyAddFace.H:246
Foam::polyTopoChange::clear
void clear()
Clear all storage.
Definition: polyTopoChange.C:2192
Foam::polyTopoChange::addMesh
void addMesh(const polyMesh &mesh, const labelUList &patchMap, const labelUList &pointZoneMap, const labelUList &faceZoneMap, const labelUList &cellZoneMap)
Definition: polyTopoChange.C:2223
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
Foam::polyRemovePoint
Class containing data for point removal.
Definition: polyRemovePoint.H:48
nPatches
label nPatches
Definition: readKivaGrid.H:396
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::polyAddCell::masterCellID
label masterCellID() const
Return master cell ID.
Definition: polyAddCell.H:170
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Definition: polyTopoChange.C:2959
Foam::polyTopoChange::removePoint
void removePoint(const label pointi, const label mergePointi)
Remove/merge point.
Definition: polyTopoChange.C:2678
Foam::polyTopoChange::removeCell
void removeCell(const label celli, const label mergeCelli)
Remove/merge cell.
Definition: polyTopoChange.C:2921
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::polyRemoveFace::mergeFaceID
label mergeFaceID() const
Return merge face ID.
Definition: polyRemoveFace.H:103
polyAddFace.H
Foam::primitiveMesh::edgeFaces
const labelListList & edgeFaces() const
Definition: primitiveMeshEdgeFaces.C:33
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
polyRemoveFace.H
Foam::polyRemovePoint::mergePointID
label mergePointID() const
Definition: polyRemovePoint.H:103
Foam::polyTopoChange::addFace
label addFace(const face &f, const label own, const label nei, const label masterPointID, const label masterEdgeID, const label masterFaceID, const bool flipFaceFlux, const label patchID, const label zoneID, const bool zoneFlip)
Add face to cells. Return new face label.
Definition: polyTopoChange.C:2726
Foam::polyAddFace::flipFaceFlux
bool flipFaceFlux() const
Does the face flux need to be flipped.
Definition: polyAddFace.H:300
polyTopoChange.H
Foam::primitiveMesh::pointFaces
const labelListList & pointFaces() const
Definition: primitiveMeshPointFaces.C:34
Foam::polyTopoChange::addPoint
label addPoint(const point &pt, const label masterPointID, const label zoneID, const bool inCell)
Add point. Return new point label.
Definition: polyTopoChange.C:2589
Foam::polyAddCell::masterPointID
label masterPointID() const
Return master point ID.
Definition: polyAddCell.H:152
Foam::polyMesh::cellZones
const cellZoneMesh & cellZones() const
Return cell zone mesh.
Definition: polyMesh.H:492
Foam::polyAddCell::masterEdgeID
label masterEdgeID() const
Return master edge ID.
Definition: polyAddCell.H:158
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:69
Foam::polyModifyFace
Class describing modification of a face.
Definition: polyModifyFace.H:50
Foam::polyModifyPoint
Class describing modification of a point.
Definition: polyModifyPoint.H:49
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::polyTopoChange::modifyCell
void modifyCell(const label celli, const label zoneID)
Modify zone of cell.
Definition: polyTopoChange.C:2911
Foam::cellZoneMesh
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
Definition: cellZoneMeshFwd.H:44
Foam::polyAddFace::masterEdgeID
label masterEdgeID() const
Return master edge ID.
Definition: polyAddFace.H:288
polyMesh.H
Foam::HashSet< label, Hash< label > >
Foam::Swap
void Swap(DynamicList< T, SizeMin1 > &a, DynamicList< T, SizeMin2 > &b)
Definition: DynamicListI.H:913
Foam::fieldTypes::internal
const wordList internal
Standard dimensioned field types (scalar, vector, tensor, etc)
Foam::pointZoneMesh
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
Definition: pointZoneMeshFwd.H:44
Foam::polyBoundaryMesh::start
label start() const
The start label of the boundary faces in the polyMesh face list.
Definition: polyBoundaryMesh.C:638
Foam::polyAddFace::patchID
label patchID() const
Boundary patch ID.
Definition: polyAddFace.H:312
Foam::invert
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:36
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::polyAddPoint::newPoint
const point & newPoint() const
Point location.
Definition: polyAddPoint.H:126
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::stableSort
void stableSort(UList< T > &a)
Definition: UList.C:268
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:486
Foam::polyTopoChange::setCapacity
void setCapacity(const label nPoints, const label nFaces, const label nCells)
Definition: polyTopoChange.C:2428
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::faceZoneMesh
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
Definition: faceZoneMeshFwd.H:44
SortableList.H
Foam::polyTopoChange::polyTopoChange
polyTopoChange(const label nPatches, const bool strict=true)
Definition: polyTopoChange.C:2116
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::polyRemoveCell
Class containing data for cell removal.
Definition: polyRemoveCell.H:48
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::polyAddFace::neighbour
label neighbour() const
Return neighbour cell.
Definition: polyAddFace.H:252
polyModifyPoint.H
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::polyMesh::pointZones
const pointZoneMesh & pointZones() const
Return point zone mesh.
Definition: polyMesh.H:480
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:107
patchID
label patchID
Definition: boundaryProcessorFaPatchPoints.H:5
Foam::polyTopoChange::modifyFace
void modifyFace(const face &f, const label facei, const label own, const label nei, const bool flipFaceFlux, const label patchID, const label zoneID, const bool zoneFlip)
Modify vertices or cell of face.
Definition: polyTopoChange.C:2790
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1107
Foam::polyMesh::resetPrimitives
void resetPrimitives(autoPtr< pointField > &&points, autoPtr< faceList > &&faces, autoPtr< labelList > &&owner, autoPtr< labelList > &&neighbour, const labelUList &patchSizes, const labelUList &patchStarts, const bool validBoundary=true)
Reset mesh primitive data. Assumes all patch info correct.
Definition: polyMesh.C:718
Foam::PtrList::setSize
void setSize(const label newLen)
Same as resize()
Definition: PtrListI.H:105
Foam::ZoneMesh< pointZone, polyMesh >
Foam::reorder
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.
Definition: ListOpsTemplates.C:80
polyAddPoint.H
Foam::polyRemoveFace::faceID
label faceID() const
Return face ID.
Definition: polyRemoveFace.H:97
Foam::polyAddFace::zoneID
label zoneID() const
Face zone ID.
Definition: polyAddFace.H:330
Foam::polyModifyPoint::zoneID
label zoneID() const
Point zone ID.
Definition: polyModifyPoint.H:144
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::polyModifyFace::newFace
const face & newFace() const
Return face.
Definition: polyModifyFace.H:200
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::polyModifyFace::neighbour
label neighbour() const
Return owner cell ID.
Definition: polyModifyFace.H:218
newPointi
label newPointi
Definition: readKivaGrid.H:496
Foam::primitiveMesh::edgeCells
const labelListList & edgeCells() const
Definition: primitiveMeshEdgeCells.C:34
Foam::FatalError
error FatalError
processorPolyPatch.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
polyRemoveCell.H
zoneID
const labelIOList & zoneID
Definition: interpolatedFaces.H:22
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::polyModifyFace::faceID
label faceID() const
Return master face ID.
Definition: polyModifyFace.H:206
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::primitiveMesh::cellVolumes
const scalarField & cellVolumes() const
Definition: primitiveMeshCellCentresAndVols.C:96
Foam::polyAddCell
Class containing data for cell addition.
Definition: polyAddCell.H:48
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:313
Foam::polyTopoChange::removeFace
void removeFace(const label facei, const label mergeFacei)
Remove/merge face.
Definition: polyTopoChange.C:2827
polyModifyFace.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::polyRemovePoint::pointID
label pointID() const
Return point ID.
Definition: polyRemovePoint.H:98
polyAddCell.H
Foam::polyModifyFace::owner
label owner() const
Return owner cell ID.
Definition: polyModifyFace.H:212
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::renumber
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:37
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:84
Foam::polyModifyCell
Class describing modification of a cell.
Definition: polyModifyCell.H:48
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::polyTopoChange::setAction
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
Definition: polyTopoChange.C:2460
Foam::polyModifyFace::patchID
label patchID() const
Boundary patch ID.
Definition: polyModifyFace.H:236
Foam::nl
constexpr char nl
Definition: Ostream.H:385
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::VectorSpace< Vector< Cmpt >, Cmpt, 3 >::max
static const Vector< Cmpt > max
Definition: VectorSpace.H:117
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::polyTopoChange::modifyPoint
void modifyPoint(const label pointi, const point &pt, const label zoneID, const bool inCell)
Modify coordinate.
Definition: polyTopoChange.C:2617
Foam::polyRemoveFace
Class containing data for face removal.
Definition: polyRemoveFace.H:48
Foam::polyModifyPoint::inCell
bool inCell() const
Does the point support a cell.
Definition: polyModifyPoint.H:150
Foam::List< label >
Foam::HashSetOps::used
labelHashSet used(const bitSet &select)
Convert a bitset to a labelHashSet of the indices used.
Definition: HashOps.C:35
Foam::primitiveMesh::isInternalFace
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
Definition: primitiveMeshI.H:102
Foam::UList< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::primitiveMesh::nPoints
label nPoints() const
Number of mesh points.
Definition: primitiveMeshI.H:37
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::polyRemoveCell::mergeCellID
label mergeCellID() const
Return cell ID.
Definition: polyRemoveCell.H:103
Foam::polyModifyCell::removeFromZone
bool removeFromZone() const
Definition: polyModifyCell.H:118
Foam::primitiveMesh::pointCells
const labelListList & pointCells() const
Definition: primitiveMeshPointCells.C:110
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:181
Foam::polyAddFace::masterPointID
label masterPointID() const
Return master point ID.
Definition: polyAddFace.H:282
Foam::polyAddPoint::zoneID
label zoneID() const
Point zone ID.
Definition: polyAddPoint.H:150
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::polyAddPoint
Class containing data for point addition.
Definition: polyAddPoint.H:49
Foam::polyModifyFace::zoneID
label zoneID() const
Face zone ID.
Definition: polyModifyFace.H:259
Foam::polyAddFace
A face addition data class. A face can be inflated either from a point or from another face and can e...
Definition: polyAddFace.H:53
Foam::polyAddCell::masterFaceID
label masterFaceID() const
Return master face ID.
Definition: polyAddCell.H:164
Foam::primitivePatch
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
Definition: primitivePatch.H:51
Foam::topoAction
A virtual base class for topological actions.
Definition: topoAction.H:51
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
ListOps.H
Various functions to operate on Lists.
CompactListList.H
Foam::sortedOrder
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:80
Foam::polyAddPoint::masterPointID
label masterPointID() const
Master point label.
Definition: polyAddPoint.H:132
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:409
Foam::polyAddFace::zoneFlip
label zoneFlip() const
Face zone flip.
Definition: polyAddFace.H:336
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::polyModifyPoint::newPoint
const point & newPoint() const
New point location.
Definition: polyModifyPoint.H:126
objectMap.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::polyAddCell::zoneID
label zoneID() const
Cell zone ID.
Definition: polyAddCell.H:182
Foam::patchIdentifier::name
const word & name() const
The patch name.
Definition: patchIdentifier.H:134
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
pointLabels
labelList pointLabels(nPoints, -1)
boundary
faceListList boundary
Definition: createBlockMesh.H:4
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1113
Foam::polyTopoChange::movePoints
void movePoints(const pointField &newPoints)
Move all points. Incompatible with other topology changes.
Definition: polyTopoChange.C:2659
polyModifyCell.H
Foam::polyAddFace::newFace
const face & newFace() const
Return face.
Definition: polyAddFace.H:240