polyMeshFilter.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 | Copyright (C) 2012-2013 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "polyMeshFilter.H"
27 #include "polyMesh.H"
28 #include "fvMesh.H"
29 #include "unitConversion.H"
30 #include "edgeCollapser.H"
31 #include "syncTools.H"
32 #include "polyTopoChange.H"
33 #include "globalIndex.H"
34 #include "PackedBoolList.H"
35 #include "pointSet.H"
36 #include "faceSet.H"
37 #include "cellSet.H"
38 
39 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43 defineTypeNameAndDebug(polyMeshFilter, 0);
44 }
45 
46 
48 {
49  updateSets<pointSet>(map);
50  updateSets<faceSet>(map);
51  updateSets<cellSet>(map);
52 }
53 
54 
56 (
57  const polyMesh& oldMesh,
58  const polyMesh& newMesh
59 )
60 {
61  copySets<pointSet>(oldMesh, newMesh);
62  copySets<faceSet>(oldMesh, newMesh);
63  copySets<cellSet>(oldMesh, newMesh);
64 }
65 
66 
68 {
69  polyTopoChange originalMeshToNewMesh(mesh);
70 
71  autoPtr<fvMesh> meshCopy;
72  autoPtr<mapPolyMesh> mapPtr = originalMeshToNewMesh.makeMesh
73  (
74  meshCopy,
75  IOobject
76  (
77  mesh.name(),
78  mesh.polyMesh::instance(),
79  mesh.time(),
82  false
83  ),
84  mesh,
85  true // parallel sync
86  );
87 
88  const mapPolyMesh& map = mapPtr();
89 
90  // Update fields
91  meshCopy().updateMesh(map);
92  if (map.hasMotionPoints())
93  {
94  meshCopy().movePoints(map.preMotionPoints());
95  }
96 
97  copySets(mesh, meshCopy());
98 
99  return meshCopy;
100 }
101 
102 
103 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
104 
106 {
107  label nBadFaces = labelMax;
108  label nOuterIterations = 0;
109 
110  // Maintain the number of times a point has been part of a bad face
111  labelList pointErrorCount(mesh_.nPoints(), 0);
112 
113  PackedBoolList newErrorPoint(mesh_.nPoints());
115  (
116  mesh_,
117  meshQualityCoeffDict(),
118  newErrorPoint
119  );
120 
121  bool newBadFaces = true;
122 
123  // Main loop
124  // ~~~~~~~~~
125  // It tries and do some collapses, checks the resulting mesh and
126  // 'freezes' some edges (by marking in minEdgeLen) and tries again.
127  // This will iterate ultimately to the situation where every edge is
128  // frozen and nothing gets collapsed.
129  while
130  (
131  nOuterIterations < maxIterations()
132  //&& nBadFaces > nOriginalBadFaces
133  && newBadFaces
134  )
135  {
136  Info<< nl << "Outer Iteration = " << nOuterIterations++ << nl
137  << endl;
138 
139  printScalarFieldStats("Edge Filter Factor", minEdgeLen_);
140  printScalarFieldStats("Face Filter Factor", faceFilterFactor_);
141 
142  // Reset the new mesh to the old mesh
143  newMeshPtr_ = copyMesh(mesh_);
144  fvMesh& newMesh = newMeshPtr_();
145 
146  scalarField newMeshFaceFilterFactor = faceFilterFactor_;
147  pointPriority_.reset(new labelList(originalPointPriority_));
148 
149  labelList origToCurrentPointMap(identity(newMesh.nPoints()));
150 
151  {
152  label nInnerIterations = 0;
153  label nPrevLocalCollapse = labelMax;
154 
155  Info<< incrIndent;
156 
157  while (true)
158  {
159  Info<< nl << indent << "Inner iteration = "
160  << nInnerIterations++ << nl << incrIndent << endl;
161 
162  label nLocalCollapse = filterFaces
163  (
164  newMesh,
165  newMeshFaceFilterFactor,
166  origToCurrentPointMap
167  );
168  Info<< decrIndent;
169 
170  if
171  (
172  nLocalCollapse >= nPrevLocalCollapse
173  || nLocalCollapse == 0
174  )
175  {
176  Info<< decrIndent;
177  break;
178  }
179  else
180  {
181  nPrevLocalCollapse = nLocalCollapse;
182  }
183  }
184  }
185 
186  scalarField newMeshMinEdgeLen = minEdgeLen_;
187 
188  {
189  label nInnerIterations = 0;
190  label nPrevLocalCollapse = labelMax;
191 
192  Info<< incrIndent;
193 
194  while (true)
195  {
196  Info<< nl << indent << "Inner iteration = "
197  << nInnerIterations++ << nl << incrIndent << endl;
198 
199  label nLocalCollapse = filterEdges
200  (
201  newMesh,
202  newMeshMinEdgeLen,
203  origToCurrentPointMap
204  );
205  Info<< decrIndent;
206 
207  if
208  (
209  nLocalCollapse >= nPrevLocalCollapse
210  || nLocalCollapse == 0
211  )
212  {
213  Info<< decrIndent;
214  break;
215  }
216  else
217  {
218  nPrevLocalCollapse = nLocalCollapse;
219  }
220  }
221  }
222 
223 
224  // Mesh check
225  // ~~~~~~~~~~~~~~~~~~
226  // Do not allow collapses in regions of error.
227  // Updates minEdgeLen, nRelaxedEdges
228 
229  if (controlMeshQuality())
230  {
231  PackedBoolList isErrorPoint(newMesh.nPoints());
233  (
234  newMesh,
235  meshQualityCoeffDict(),
236  isErrorPoint
237  );
238 
239  Info<< nl << " Number of bad faces : " << nBadFaces << nl
240  << " Number of marked points : "
241  << returnReduce(isErrorPoint.count(), sumOp<unsigned int>())
242  << endl;
243 
244  updatePointErrorCount
245  (
246  isErrorPoint,
247  origToCurrentPointMap,
248  pointErrorCount
249  );
250 
251  checkMeshEdgesAndRelaxEdges
252  (
253  newMesh,
254  origToCurrentPointMap,
255  isErrorPoint,
256  pointErrorCount
257  );
258 
259  checkMeshFacesAndRelaxEdges
260  (
261  newMesh,
262  origToCurrentPointMap,
263  isErrorPoint,
264  pointErrorCount
265  );
266 
267  newBadFaces = false;
268  forAll(mesh_.points(), pI)
269  {
270  if
271  (
272  origToCurrentPointMap[pI] >= 0
273  && isErrorPoint[origToCurrentPointMap[pI]]
274  )
275  {
276  if (!newErrorPoint[pI])
277  {
278  newBadFaces = true;
279  break;
280  }
281  }
282  }
283 
284  reduce(newBadFaces, orOp<bool>());
285  }
286  else
287  {
288  return -1;
289  }
290  }
291 
292  return nBadFaces;
293 }
294 
295 
297 (
298  polyMesh& newMesh,
299  scalarField& newMeshFaceFilterFactor,
300  labelList& origToCurrentPointMap
301 )
302 {
303  // Per edge collapse status
305 
306  Map<point> collapsePointToLocation(newMesh.nPoints());
307 
308  edgeCollapser collapser(newMesh, collapseFacesCoeffDict());
309 
310  {
311  // Collapse faces
312  labelPair nCollapsedPtEdge = collapser.markSmallSliverFaces
313  (
314  newMeshFaceFilterFactor,
315  pointPriority_(),
316  collapseEdge,
317  collapsePointToLocation
318  );
319 
320  label nCollapsed = 0;
321  forAll(nCollapsedPtEdge, collapseTypeI)
322  {
323  nCollapsed += nCollapsedPtEdge[collapseTypeI];
324  }
325 
326  reduce(nCollapsed, sumOp<label>());
327 
328  label nToPoint = returnReduce(nCollapsedPtEdge.first(), sumOp<label>());
329  label nToEdge = returnReduce(nCollapsedPtEdge.second(), sumOp<label>());
330 
331  Info<< indent
332  << "Collapsing " << nCollapsed << " faces "
333  << "(to point = " << nToPoint << ", to edge = " << nToEdge << ")"
334  << endl;
335 
336  if (nCollapsed == 0)
337  {
338  return 0;
339  }
340  }
341 
342  // Merge edge collapses into consistent collapse-network.
343  // Make sure no cells get collapsed.
344  List<pointEdgeCollapse> allPointInfo;
345  const globalIndex globalPoints(newMesh.nPoints());
346 
347  collapser.consistentCollapse
348  (
349  globalPoints,
350  pointPriority_(),
351  collapsePointToLocation,
352  collapseEdge,
353  allPointInfo
354  );
355 
356  label nLocalCollapse = collapseEdge.count();
357 
358  reduce(nLocalCollapse, sumOp<label>());
359  Info<< nl << indent << "Collapsing " << nLocalCollapse
360  << " edges after synchronisation and PointEdgeWave" << endl;
361 
362  if (nLocalCollapse == 0)
363  {
364  return 0;
365  }
366 
367  {
368  // Apply collapses to current mesh
369  polyTopoChange newMeshMod(newMesh);
370 
371  // Insert mesh refinement into polyTopoChange.
372  collapser.setRefinement(allPointInfo, newMeshMod);
373 
374  Info<< indent << "Apply changes to the current mesh" << endl;
375 
376  // Apply changes to current mesh
377  autoPtr<mapPolyMesh> newMapPtr = newMeshMod.changeMesh
378  (
379  newMesh,
380  false
381  );
382  const mapPolyMesh& newMap = newMapPtr();
383 
384  // Update fields
385  newMesh.updateMesh(newMap);
386  if (newMap.hasMotionPoints())
387  {
388  newMesh.movePoints(newMap.preMotionPoints());
389  }
390  updateSets(newMap);
391 
392  updatePointPriorities(newMesh, newMap.pointMap());
393 
394  mapOldMeshFaceFieldToNewMesh
395  (
396  newMesh,
397  newMap.faceMap(),
398  newMeshFaceFilterFactor
399  );
400 
401  updateOldToNewPointMap
402  (
403  newMap.reversePointMap(),
404  origToCurrentPointMap
405  );
406  }
407 
408  return nLocalCollapse;
409 }
410 
411 
413 (
414  polyMesh& newMesh,
415  scalarField& newMeshMinEdgeLen,
416  labelList& origToCurrentPointMap
417 )
418 {
419  // Per edge collapse status
421 
422  Map<point> collapsePointToLocation(newMesh.nPoints());
423 
424  edgeCollapser collapser(newMesh, collapseFacesCoeffDict());
425 
426  // Work out which edges to collapse
427  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
428  // This is by looking at minEdgeLen (to avoid frozen edges)
429  // and marking in collapseEdge.
430  label nSmallCollapsed = collapser.markSmallEdges
431  (
432  newMeshMinEdgeLen,
433  pointPriority_(),
434  collapseEdge,
435  collapsePointToLocation
436  );
437 
438  reduce(nSmallCollapsed, sumOp<label>());
439  Info<< indent << "Collapsing " << nSmallCollapsed
440  << " small edges" << endl;
441 
442  // Merge inline edges
443  label nMerged = collapser.markMergeEdges
444  (
445  maxCos(),
446  pointPriority_(),
447  collapseEdge,
448  collapsePointToLocation
449  );
450 
451  reduce(nMerged, sumOp<label>());
452  Info<< indent << "Collapsing " << nMerged << " in line edges"
453  << endl;
454 
455  if (nMerged + nSmallCollapsed == 0)
456  {
457  return 0;
458  }
459 
460  // Merge edge collapses into consistent collapse-network.
461  // Make sure no cells get collapsed.
462  List<pointEdgeCollapse> allPointInfo;
463  const globalIndex globalPoints(newMesh.nPoints());
464 
465  collapser.consistentCollapse
466  (
467  globalPoints,
468  pointPriority_(),
469  collapsePointToLocation,
470  collapseEdge,
471  allPointInfo
472  );
473 
474  label nLocalCollapse = collapseEdge.count();
475 
476  reduce(nLocalCollapse, sumOp<label>());
477  Info<< nl << indent << "Collapsing " << nLocalCollapse
478  << " edges after synchronisation and PointEdgeWave" << endl;
479 
480  if (nLocalCollapse == 0)
481  {
482  return 0;
483  }
484 
485  // Apply collapses to current mesh
486  polyTopoChange newMeshMod(newMesh);
487 
488  // Insert mesh refinement into polyTopoChange.
489  collapser.setRefinement(allPointInfo, newMeshMod);
490 
491  Info<< indent << "Apply changes to the current mesh" << endl;
492 
493  // Apply changes to current mesh
494  autoPtr<mapPolyMesh> newMapPtr = newMeshMod.changeMesh
495  (
496  newMesh,
497  false
498  );
499  const mapPolyMesh& newMap = newMapPtr();
500 
501  // Update fields
502  newMesh.updateMesh(newMap);
503  if (newMap.hasMotionPoints())
504  {
505  newMesh.movePoints(newMap.preMotionPoints());
506  }
507  updateSets(newMap);
508 
509  // Synchronise the factors
510  mapOldMeshEdgeFieldToNewMesh
511  (
512  newMesh,
513  newMap.pointMap(),
514  newMeshMinEdgeLen
515  );
516 
517  updateOldToNewPointMap
518  (
519  newMap.reversePointMap(),
520  origToCurrentPointMap
521  );
522 
523  updatePointPriorities(newMesh, newMap.pointMap());
524 
525  return nLocalCollapse;
526 }
527 
528 
530 (
531  const PackedBoolList& isErrorPoint,
532  const labelList& oldToNewMesh,
533  labelList& pointErrorCount
534 ) const
535 {
536  forAll(mesh_.points(), pI)
537  {
538  if (isErrorPoint[oldToNewMesh[pI]])
539  {
540  pointErrorCount[pI]++;
541  }
542  }
543 }
544 
545 
547 (
548  const polyMesh& newMesh,
549  const labelList& oldToNewMesh,
550  const PackedBoolList& isErrorPoint,
551  const labelList& pointErrorCount
552 )
553 {
554  const edgeList& edges = mesh_.edges();
555 
556  forAll(edges, edgeI)
557  {
558  const edge& e = edges[edgeI];
559  label newStart = oldToNewMesh[e[0]];
560  label newEnd = oldToNewMesh[e[1]];
561 
562  if
563  (
564  pointErrorCount[e[0]] >= maxPointErrorCount()
565  || pointErrorCount[e[1]] >= maxPointErrorCount()
566  )
567  {
568  minEdgeLen_[edgeI] = -1;
569  }
570 
571  if
572  (
573  (newStart >= 0 && isErrorPoint[newStart])
574  || (newEnd >= 0 && isErrorPoint[newEnd])
575  )
576  {
577  minEdgeLen_[edgeI] *= edgeReductionFactor();
578  }
579  }
580 
581  syncTools::syncEdgeList(mesh_, minEdgeLen_, minEqOp<scalar>(), scalar(0.0));
582 
583  for (label smoothIter = 0; smoothIter < maxSmoothIters(); ++smoothIter)
584  {
585  // Smooth minEdgeLen
586  forAll(mesh_.edges(), edgeI)
587  {
588  const edge& e = mesh_.edges()[edgeI];
589 
590  scalar sumMinEdgeLen = 0;
591  label nEdges = 0;
592 
593  forAll(e, pointI)
594  {
595  const labelList& pEdges = mesh_.pointEdges()[e[pointI]];
596 
597  forAll(pEdges, pEdgeI)
598  {
599  const label pEdge = pEdges[pEdgeI];
600  sumMinEdgeLen += minEdgeLen_[pEdge];
601  nEdges++;
602  }
603  }
604 
605  minEdgeLen_[edgeI] = min
606  (
607  minEdgeLen_[edgeI],
608  sumMinEdgeLen/nEdges
609  );
610  }
611 
613  (
614  mesh_,
615  minEdgeLen_,
616  minEqOp<scalar>(),
617  scalar(0.0)
618  );
619  }
620 }
621 
622 
624 (
625  const polyMesh& newMesh,
626  const labelList& oldToNewMesh,
627  const PackedBoolList& isErrorPoint,
628  const labelList& pointErrorCount
629 )
630 {
631  const faceList& faces = mesh_.faces();
632 
633  forAll(faces, faceI)
634  {
635  const face& f = faces[faceI];
636 
637  forAll(f, fpI)
638  {
639  const label ptIndex = oldToNewMesh[f[fpI]];
640 
641  if (pointErrorCount[f[fpI]] >= maxPointErrorCount())
642  {
643  faceFilterFactor_[faceI] = -1;
644  }
645 
646  if (isErrorPoint[ptIndex])
647  {
648  faceFilterFactor_[faceI] *= faceReductionFactor();
649 
650  break;
651  }
652  }
653  }
654 
655  syncTools::syncFaceList(mesh_, faceFilterFactor_, minEqOp<scalar>());
656 
657  for (label smoothIter = 0; smoothIter < maxSmoothIters(); ++smoothIter)
658  {
659  // Smooth faceFilterFactor
660  forAll(faces, faceI)
661  {
662  const labelList& fEdges = mesh_.faceEdges()[faceI];
663 
664  scalar sumFaceFilterFactors = 0;
665  label nFaces = 0;
666 
667  // This is important: Only smooth around faces that share an
668  // edge with a bad face
669  bool skipFace = true;
670 
671  forAll(fEdges, fEdgeI)
672  {
673  const labelList& eFaces = mesh_.edgeFaces()[fEdges[fEdgeI]];
674 
675  forAll(eFaces, eFaceI)
676  {
677  const label eFace = eFaces[eFaceI];
678 
679  const face& f = faces[eFace];
680 
681  forAll(f, fpI)
682  {
683  const label ptIndex = oldToNewMesh[f[fpI]];
684 
685  if (isErrorPoint[ptIndex])
686  {
687  skipFace = false;
688  break;
689  }
690  }
691 
692  if (eFace != faceI)
693  {
694  sumFaceFilterFactors += faceFilterFactor_[eFace];
695  nFaces++;
696  }
697  }
698  }
699 
700  if (skipFace)
701  {
702  continue;
703  }
704 
705  faceFilterFactor_[faceI] = min
706  (
707  faceFilterFactor_[faceI],
708  sumFaceFilterFactors/nFaces
709  );
710  }
711 
712  // Face filter factor needs to be synchronised!
713  syncTools::syncFaceList(mesh_, faceFilterFactor_, minEqOp<scalar>());
714  }
715 }
716 
717 
719 (
720  const polyMesh& newMesh,
721  const labelList& pointMap
722 )
723 {
724  labelList newPointPriority(newMesh.nPoints(), labelMin);
725  const labelList& currPointPriority = pointPriority_();
726 
727  forAll(newPointPriority, ptI)
728  {
729  const label newPointToOldPoint = pointMap[ptI];
730  const label origPointPriority = currPointPriority[newPointToOldPoint];
731 
732  newPointPriority[ptI] = max(origPointPriority, newPointPriority[ptI]);
733  }
734 
736  (
737  newMesh,
738  newPointPriority,
739  maxEqOp<label>(),
740  labelMin
741  );
742 
743  pointPriority_.reset(new labelList(newPointPriority));
744 }
745 
746 
748 (
749  const string desc,
750  const scalarField& fld
751 ) const
752 {
753  scalar sum = 0;
754  scalar validElements = 0;
755  scalar min = GREAT;
756  scalar max = -GREAT;
757 
758  forAll(fld, i)
759  {
760  const scalar fldElement = fld[i];
761 
762  if (fldElement >= 0)
763  {
764  sum += fldElement;
765 
766  if (fldElement < min)
767  {
768  min = fldElement;
769  }
770 
771  if (fldElement > max)
772  {
773  max = fldElement;
774  }
775 
776  validElements++;
777  }
778  }
779 
783  reduce(validElements, sumOp<label>());
784  const label totFieldSize = returnReduce(fld.size(), sumOp<label>());
785 
786  Info<< incrIndent << indent << desc
787  << ": min = " << min
788  << " av = " << sum/(validElements + SMALL)
789  << " max = " << max << nl
790  << indent
791  << " " << validElements << " / " << totFieldSize << " elements used"
792  << decrIndent << endl;
793 }
794 
795 
797 (
798  const polyMesh& newMesh,
799  const labelList& pointMap,
800  scalarField& newMeshMinEdgeLen
801 ) const
802 {
803  scalarField tmp(newMesh.nEdges());
804 
805  const edgeList& newEdges = newMesh.edges();
806 
807  forAll(newEdges, newEdgeI)
808  {
809  const edge& newEdge = newEdges[newEdgeI];
810  const label pStart = newEdge.start();
811  const label pEnd = newEdge.end();
812 
813  tmp[newEdgeI] = min
814  (
815  newMeshMinEdgeLen[pointMap[pStart]],
816  newMeshMinEdgeLen[pointMap[pEnd]]
817  );
818  }
819 
820  newMeshMinEdgeLen.transfer(tmp);
821 
823  (
824  newMesh,
825  newMeshMinEdgeLen,
826  maxEqOp<scalar>(),
827  scalar(0.0)
828  );
829 }
830 
831 
833 (
834  const polyMesh& newMesh,
835  const labelList& faceMap,
836  scalarField& newMeshFaceFilterFactor
837 ) const
838 {
839  scalarField tmp(newMesh.nFaces());
840 
841  forAll(faceMap, newFaceI)
842  {
843  const label oldFaceI = faceMap[newFaceI];
844 
845  tmp[newFaceI] = newMeshFaceFilterFactor[oldFaceI];
846  }
847 
848  newMeshFaceFilterFactor.transfer(tmp);
849 
851  (
852  newMesh,
853  newMeshFaceFilterFactor,
855  );
856 }
857 
858 
860 (
861  const labelList& currToNew,
862  labelList& origToCurrentPointMap
863 ) const
864 {
865  forAll(origToCurrentPointMap, origPointI)
866  {
867  label oldPointI = origToCurrentPointMap[origPointI];
868 
869  if (oldPointI != -1)
870  {
871  label newPointI = currToNew[oldPointI];
872 
873  if (newPointI >= 0)
874  {
875  origToCurrentPointMap[origPointI] = newPointI;
876  }
877  else if (newPointI == -1)
878  {
879  origToCurrentPointMap[origPointI] = -1;
880  }
881  else
882  {
883  origToCurrentPointMap[origPointI] = -newPointI-2;
884  }
885  }
886  }
887 }
888 
889 
890 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
891 
893 :
895  (
897  (
898  IOobject
899  (
900  "collapseDict",
901  mesh.time().system(),
902  mesh.time(),
903  IOobject::MUST_READ,
904  IOobject::NO_WRITE
905  )
906  )
907  ),
908  mesh_(mesh),
909  newMeshPtr_(),
910  originalPointPriority_(mesh.nPoints(), labelMin),
911  pointPriority_(),
912  minEdgeLen_(),
913  faceFilterFactor_()
914 {
916 }
917 
918 
920 (
921  const fvMesh& mesh,
922  const labelList& pointPriority
923 )
924 :
926  (
928  (
929  IOobject
930  (
931  "collapseDict",
932  mesh.time().system(),
933  mesh.time(),
936  )
937  )
938  ),
939  mesh_(mesh),
940  newMeshPtr_(),
941  originalPointPriority_(pointPriority),
942  pointPriority_(),
943  minEdgeLen_(),
944  faceFilterFactor_()
945 {
946  writeSettings(Info);
947 }
948 
949 
950 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
951 
953 {}
954 
955 
956 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
957 
959 {
960  minEdgeLen_.resize(mesh_.nEdges(), minLen());
961  faceFilterFactor_.resize(mesh_.nFaces(), initialFaceLengthFactor());
962 
963  return filterFacesLoop(nOriginalBadFaces);
964 }
965 
966 
968 {
969  minEdgeLen_.resize(mesh_.nEdges(), minLen());
970  faceFilterFactor_.resize(mesh_.nFaces(), initialFaceLengthFactor());
971 
972  forAll(faceFilterFactor_, fI)
973  {
974  if (!fSet.found(fI))
975  {
976  faceFilterFactor_[fI] = -1;
977  }
978  }
979 
980  return filterFacesLoop(0);
981 }
982 
983 
985 (
986  const label nOriginalBadFaces
987 )
988 {
989  label nBadFaces = labelMax/2;
990  label nPreviousBadFaces = labelMax;
991  label nOuterIterations = 0;
992 
993  minEdgeLen_.resize(mesh_.nEdges(), minLen());
994  faceFilterFactor_.resize(0);
995 
996  labelList pointErrorCount(mesh_.nPoints(), 0);
997 
998  // Main loop
999  // ~~~~~~~~~
1000  // It tries and do some collapses, checks the resulting mesh and
1001  // 'freezes' some edges (by marking in minEdgeLen) and tries again.
1002  // This will iterate ultimately to the situation where every edge is
1003  // frozen and nothing gets collapsed.
1004  while
1005  (
1006  nOuterIterations < maxIterations()
1007  && nBadFaces > nOriginalBadFaces
1008  && nBadFaces < nPreviousBadFaces
1009  )
1010  {
1011  Info<< nl << "Outer Iteration = " << nOuterIterations++ << nl
1012  << endl;
1013 
1014  printScalarFieldStats("Edge Filter Factor", minEdgeLen_);
1015 
1016  nPreviousBadFaces = nBadFaces;
1017 
1018  // Reset the new mesh to the old mesh
1019  newMeshPtr_ = copyMesh(mesh_);
1020  fvMesh& newMesh = newMeshPtr_();
1021 
1022  scalarField newMeshMinEdgeLen = minEdgeLen_;
1023  pointPriority_.reset(new labelList(originalPointPriority_));
1024 
1025  labelList origToCurrentPointMap(identity(newMesh.nPoints()));
1026 
1027  Info<< incrIndent;
1028 
1029  label nInnerIterations = 0;
1030  label nPrevLocalCollapse = labelMax;
1031 
1032  while (true)
1033  {
1034  Info<< nl
1035  << indent << "Inner iteration = " << nInnerIterations++ << nl
1036  << incrIndent << endl;
1037 
1038  label nLocalCollapse = filterEdges
1039  (
1040  newMesh,
1041  newMeshMinEdgeLen,
1042  origToCurrentPointMap
1043  );
1044 
1045  Info<< decrIndent;
1046 
1047  if
1048  (
1049  nLocalCollapse >= nPrevLocalCollapse
1050  || nLocalCollapse == 0
1051  )
1052  {
1053  Info<< decrIndent;
1054  break;
1055  }
1056  else
1057  {
1058  nPrevLocalCollapse = nLocalCollapse;
1059  }
1060  }
1061 
1062  // Mesh check
1063  // ~~~~~~~~~~~~~~~~~~
1064  // Do not allow collapses in regions of error.
1065  // Updates minEdgeLen, nRelaxedEdges
1066 
1067  if (controlMeshQuality())
1068  {
1069  PackedBoolList isErrorPoint(newMesh.nPoints());
1071  (
1072  newMesh,
1073  meshQualityCoeffDict(),
1074  isErrorPoint
1075  );
1076 
1077  Info<< nl << " Number of bad faces : " << nBadFaces << nl
1078  << " Number of marked points : "
1079  << returnReduce(isErrorPoint.count(), sumOp<unsigned int>())
1080  << endl;
1081 
1082  updatePointErrorCount
1083  (
1084  isErrorPoint,
1085  origToCurrentPointMap,
1086  pointErrorCount
1087  );
1088 
1089  checkMeshEdgesAndRelaxEdges
1090  (
1091  newMesh,
1092  origToCurrentPointMap,
1093  isErrorPoint,
1094  pointErrorCount
1095  );
1096  }
1097  else
1098  {
1099  return -1;
1100  }
1101  }
1102 
1103  return nBadFaces;
1104 }
1105 
1106 
1108 {
1109  return newMeshPtr_;
1110 }
1111 
1112 
1115 {
1116  return pointPriority_;
1117 }
1118 
1119 
1120 // ************************************************************************* //
Foam::polyMeshFilter::checkMeshFacesAndRelaxEdges
void checkMeshFacesAndRelaxEdges(const polyMesh &newMesh, const labelList &oldToNewMesh, const PackedBoolList &isErrorPoint, const labelList &pointErrorCount)
Given the new points that are part of bad faces, and a map from the.
Definition: polyMeshFilter.C:624
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:53
Foam::maxOp
Definition: ops.H:172
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
Foam::PackedBoolList
A bit-packed bool list.
Definition: PackedBoolList.H:63
Foam::globalPoints
Calculates points shared by more than two processor patches or cyclic patches.
Definition: globalPoints.H:100
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:90
Foam::polyMeshFilterSettings::writeSettings
void writeSettings(Ostream &os) const
Write the settings to a stream.
Definition: polyMeshFilterSettings.C:93
Foam::edgeCollapser::markMergeEdges
label markMergeEdges(const scalar maxCos, const labelList &pointPriority, PackedBoolList &collapseEdge, Map< point > &collapsePointToLocation) const
Mark (in collapseEdge) any edges to merge.
Definition: edgeCollapser.C:1880
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::polyMeshFilter::checkMeshEdgesAndRelaxEdges
void checkMeshEdgesAndRelaxEdges(const polyMesh &newMesh, const labelList &oldToNewMesh, const PackedBoolList &isErrorPoint, const labelList &pointErrorCount)
Given the new points that are part of bad faces, and a map from the.
Definition: polyMeshFilter.C:547
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::polyMeshFilter::updateOldToNewPointMap
void updateOldToNewPointMap(const labelList &currToNew, labelList &origToCurrentPointMap) const
Maintain a map of the original mesh points to the latest version of.
Definition: polyMeshFilter.C:860
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Definition: polyTopoChange.C:3039
Foam::polyMesh::movePoints
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition: polyMesh.C:1048
globalIndex.H
Foam::labelMax
static const label labelMax
Definition: label.H:62
Foam::minOp
Definition: ops.H:173
polyTopoChange.H
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:97
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::maxEqOp
Definition: ops.H:77
Foam::Pair::first
const Type & first() const
Return first.
Definition: Pair.H:87
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: PrimitivePatchTemplate.H:68
unitConversion.H
Unit conversion functions.
Foam::faceSet
A list of face labels.
Definition: faceSet.H:48
Foam::IOobject::MUST_READ
@ MUST_READ
Definition: IOobject.H:108
Foam::polyMeshFilter::mapOldMeshFaceFieldToNewMesh
void mapOldMeshFaceFieldToNewMesh(const polyMesh &newMesh, const labelList &faceMap, scalarField &newMeshFaceFilterFactor) const
Update faceFilterFactor_ for the new mesh based upon the movement.
Definition: polyMeshFilter.C:833
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::mapPolyMesh::preMotionPoints
const pointField & preMotionPoints() const
Pre-motion point positions.
Definition: mapPolyMesh.H:609
Foam::polyMeshFilter::~polyMeshFilter
~polyMeshFilter()
Destructor.
Definition: polyMeshFilter.C:952
Foam::primitiveMesh::edges
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
Definition: primitiveMeshEdges.C:353
Foam::edgeCollapser::markSmallEdges
label markSmallEdges(const scalarField &minEdgeLen, const labelList &pointPriority, PackedBoolList &collapseEdge, Map< point > &collapsePointToLocation) const
Mark (in collapseEdge) any edges to collapse.
Definition: edgeCollapser.C:1828
polyMesh.H
Foam::primitiveMesh::nEdges
label nEdges() const
Definition: primitiveMeshI.H:41
Foam::incrIndent
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:228
syncTools.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
Foam::polyMeshFilter::filterFacesLoop
label filterFacesLoop(const label nOriginalBadFaces)
Definition: polyMeshFilter.C:105
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::edgeCollapser
Does polyTopoChanges to remove edges. Can remove faces due to edge collapse but can not remove cells ...
Definition: edgeCollapser.H:66
Foam::edge::end
label end() const
Return end vertex label.
Definition: edgeI.H:92
Foam::polyMeshFilter::filterEdges
label filterEdges(polyMesh &newMesh, scalarField &newMeshMinEdgeLen, labelList &origToCurrentPointMap)
Definition: polyMeshFilter.C:413
Foam::primitiveMesh::nPoints
label nPoints() const
Definition: primitiveMeshI.H:35
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::labelMin
static const label labelMin
Definition: label.H:61
Foam::polyMeshFilter::printScalarFieldStats
void printScalarFieldStats(const string desc, const scalarField &fld) const
Print min/mean/max data for a field.
Definition: polyMeshFilter.C:748
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::polyMeshFilter::polyMeshFilter
polyMeshFilter(const polyMeshFilter &)
Disallow default bitwise copy construct.
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::polyMeshFilter::updatePointErrorCount
void updatePointErrorCount(const PackedBoolList &isErrorPoint, const labelList &oldToNewMesh, labelList &pointErrorCount) const
Increment pointErrorCount for points attached to a bad face.
Definition: polyMeshFilter.C:530
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePaths.H:120
edgeCollapser.H
Foam::orOp
Definition: ops.H:178
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::minEqOp
Definition: ops.H:78
PackedBoolList.H
Foam::polyMeshFilter::filteredMesh
const autoPtr< fvMesh > & filteredMesh() const
Return reference to the filtered mesh. Does not check if the.
Definition: polyMeshFilter.C:1107
Foam::polyTopoChange::makeMesh
autoPtr< mapPolyMesh > makeMesh(autoPtr< fvMesh > &newMesh, const IOobject &io, const polyMesh &mesh, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Create new mesh with old mesh patches.
Definition: polyTopoChange.C:3305
Foam::polyMesh::updateMesh
virtual void updateMesh(const mapPolyMesh &mpm)
Update the mesh corresponding to given map.
Definition: polyMeshUpdate.C:39
Foam::polyMeshFilter::filter
label filter(const label nOriginalBadFaces)
Filter edges and faces.
Definition: polyMeshFilter.C:958
faceSet.H
Foam::polyMeshFilter::updateSets
static void updateSets(const mapPolyMesh &map)
Definition: polyMeshFilterTemplates.C:34
Foam::Pair::second
const Type & second() const
Return second.
Definition: Pair.H:99
Foam::PackedList::count
unsigned int count() const
Count number of bits set, O(log(n))
Definition: PackedList.C:55
Foam::edgeCollapser::consistentCollapse
void consistentCollapse(const globalIndex &globalPoints, const labelList &pointPriority, const Map< point > &collapsePointToLocation, PackedBoolList &collapseEdge, List< pointEdgeCollapse > &allPointInfo, const bool allowCellCollapse=false) const
Ensure that the collapse is parallel consistent and update.
Definition: edgeCollapser.C:1637
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Foam::edgeCollapser::markSmallSliverFaces
labelPair markSmallSliverFaces(const scalarField &faceFilterFactor, const labelList &pointPriority, PackedBoolList &collapseEdge, Map< point > &collapsePointToLocation) const
Find small faces and sliver faces in the mesh and mark the.
Definition: edgeCollapser.C:1967
Foam::polyMeshFilterSettings
Class to store the settings for the polyMeshFilter class.
Definition: polyMeshFilterSettings.H:52
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
fld
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
polyMeshFilter.H
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
fvMesh.H
Foam::edgeCollapser::setRefinement
bool setRefinement(const List< pointEdgeCollapse > &allPointInfo, polyTopoChange &meshMod) const
Play commands into polyTopoChange to create mesh.
Definition: edgeCollapser.C:1265
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::polyMeshFilter::pointPriority
const autoPtr< labelList > & pointPriority() const
Return the new pointPriority list.
Definition: polyMeshFilter.C:1114
Foam::decrIndent
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:235
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:221
Foam::polyMeshFilter::mapOldMeshEdgeFieldToNewMesh
void mapOldMeshEdgeFieldToNewMesh(const polyMesh &newMesh, const labelList &pointMap, scalarField &newMeshMinEdgeLen) const
Update minEdgeLen_ for the new mesh based upon the movement of the.
Definition: polyMeshFilter.C:797
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::autoPtr< Foam::fvMesh >
Foam::syncTools::syncEdgeList
static void syncEdgeList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh edges.
Definition: syncToolsTemplates.C:1141
Foam::primitiveMesh::nFaces
label nFaces() const
Definition: primitiveMeshI.H:58
Foam::edge::start
label start() const
Return start vertex label.
Definition: edgeI.H:81
Foam::sumOp
Definition: ops.H:162
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: contiguous.H:49
f
labelList f(nPoints)
Foam::mapPolyMesh::reversePointMap
const labelList & reversePointMap() const
Reverse point map.
Definition: mapPolyMesh.H:465
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::mapPolyMesh::pointMap
const labelList & pointMap() const
Old point map.
Definition: mapPolyMesh.H:392
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:333
Foam::polyMeshFilter::copySets
static void copySets(const polyMesh &oldMesh, const polyMesh &newMesh)
Definition: polyMeshFilterTemplates.C:71
Foam::mapPolyMesh::faceMap
const labelList & faceMap() const
Old face map.
Definition: mapPolyMesh.H:406
Foam::mapPolyMesh
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
Foam::mapPolyMesh::hasMotionPoints
bool hasMotionPoints() const
Has valid preMotionPoints?
Definition: mapPolyMesh.H:615
Foam::edgeCollapser::checkMeshQuality
static label checkMeshQuality(const polyMesh &mesh, const dictionary &meshQualityDict, PackedBoolList &isErrorPoint)
Check mesh and mark points on faces in error.
Definition: edgeCollapser.C:82
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:243
Foam::polyMeshFilter::copyMesh
static autoPtr< fvMesh > copyMesh(const fvMesh &mesh)
Return a copy of an fvMesh.
Definition: polyMeshFilter.C:67
Foam::polyMeshFilter::updatePointPriorities
void updatePointPriorities(const polyMesh &newMesh, const labelList &pointMap)
Definition: polyMeshFilter.C:719
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
cellSet.H
Foam::syncTools::syncFaceList
static void syncFaceList(const polyMesh &mesh, UList< T > &l, const CombineOp &cop)
Synchronize values on all mesh faces.
Definition: syncTools.H:381
collapseEdge
label collapseEdge(triSurface &surf, const scalar minLen)
Keep collapsing all edges < minLen.
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::system
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1155
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:984
Foam::fvMesh::name
const word & name() const
Return reference to name.
Definition: fvMesh.H:257
Foam::polyMeshFilter::filterFaces
label filterFaces(polyMesh &newMesh, scalarField &newMeshFaceFilterFactor, labelList &origToCurrentPointMap)
Definition: polyMeshFilter.C:297
pointSet.H