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