snappyHexMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2022 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 Application
28  snappyHexMesh
29 
30 Group
31  grpMeshGenerationUtilities
32 
33 Description
34  Automatic split hex mesher. Refines and snaps to surface.
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #include "argList.H"
39 #include "Time.H"
40 #include "fvMesh.H"
41 #include "snappyRefineDriver.H"
42 #include "snappySnapDriver.H"
43 #include "snappyLayerDriver.H"
44 #include "searchableSurfaces.H"
45 #include "refinementSurfaces.H"
46 #include "refinementFeatures.H"
47 #include "shellSurfaces.H"
48 #include "decompositionMethod.H"
49 #include "fvMeshDistribute.H"
50 #include "wallPolyPatch.H"
51 #include "refinementParameters.H"
52 #include "snapParameters.H"
53 #include "layerParameters.H"
54 #include "vtkCoordSetWriter.H"
55 #include "faceSet.H"
56 #include "motionSmoother.H"
57 #include "polyTopoChange.H"
58 #include "indirectPrimitivePatch.H"
59 #include "surfZoneIdentifierList.H"
60 #include "UnsortedMeshedSurface.H"
61 #include "MeshedSurface.H"
62 #include "globalIndex.H"
63 #include "IOmanip.H"
64 #include "decompositionModel.H"
65 #include "fvMeshTools.H"
66 #include "profiling.H"
67 #include "processorMeshes.H"
68 #include "snappyVoxelMeshDriver.H"
69 
70 using namespace Foam;
71 
72 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
73 
74 // Convert size (as fraction of defaultCellSize) to refinement level
75 label sizeCoeffToRefinement
76 (
77  const scalar level0Coeff, // ratio of hex cell size v.s. defaultCellSize
78  const scalar sizeCoeff
79 )
80 {
81  return round(::log(level0Coeff/sizeCoeff)/::log(2));
82 }
83 
84 
85 autoPtr<refinementSurfaces> createRefinementSurfaces
86 (
87  const searchableSurfaces& allGeometry,
88  const dictionary& surfacesDict,
89  const dictionary& shapeControlDict,
90  const label gapLevelIncrement,
91  const scalar level0Coeff
92 )
93 {
94  autoPtr<refinementSurfaces> surfacePtr;
95 
96  // Count number of surfaces.
97  label surfi = 0;
98  forAll(allGeometry.names(), geomi)
99  {
100  const word& geomName = allGeometry.names()[geomi];
101 
102  if (surfacesDict.found(geomName))
103  {
104  surfi++;
105  }
106  }
107 
108  labelList surfaces(surfi);
109  wordList names(surfi);
110  PtrList<surfaceZonesInfo> surfZones(surfi);
111 
112  labelList regionOffset(surfi);
113 
114  labelList globalMinLevel(surfi, Zero);
115  labelList globalMaxLevel(surfi, Zero);
116  labelList globalLevelIncr(surfi, Zero);
117  PtrList<dictionary> globalPatchInfo(surfi);
118  List<Map<label>> regionMinLevel(surfi);
119  List<Map<label>> regionMaxLevel(surfi);
120  List<Map<label>> regionLevelIncr(surfi);
121  List<Map<scalar>> regionAngle(surfi);
122  List<Map<autoPtr<dictionary>>> regionPatchInfo(surfi);
123 
124  wordHashSet unmatchedKeys(surfacesDict.toc());
125 
126  surfi = 0;
127  forAll(allGeometry.names(), geomi)
128  {
129  const word& geomName = allGeometry.names()[geomi];
130 
131  const entry* ePtr = surfacesDict.findEntry(geomName, keyType::REGEX);
132 
133  if (ePtr)
134  {
135  const dictionary& shapeDict = ePtr->dict();
136  unmatchedKeys.erase(ePtr->keyword());
137 
138  names[surfi] = geomName;
139  surfaces[surfi] = geomi;
140 
141  const searchableSurface& surface = allGeometry[geomi];
142 
143  // Find the index in shapeControlDict
144  // Invert surfaceCellSize to get the refinementLevel
145 
146  const word scsFuncName =
147  shapeDict.get<word>("surfaceCellSizeFunction");
148 
149  const dictionary& scsDict =
150  shapeDict.optionalSubDict(scsFuncName + "Coeffs");
151 
152  const scalar surfaceCellSize =
153  scsDict.get<scalar>("surfaceCellSizeCoeff");
154 
155  const label refLevel = sizeCoeffToRefinement
156  (
157  level0Coeff,
158  surfaceCellSize
159  );
160 
161  globalMinLevel[surfi] = refLevel;
162  globalMaxLevel[surfi] = refLevel;
163  globalLevelIncr[surfi] = gapLevelIncrement;
164 
165  // Surface zones
166  surfZones.set
167  (
168  surfi,
169  new surfaceZonesInfo
170  (
171  surface,
172  shapeDict,
173  allGeometry.regionNames()[surfaces[surfi]]
174  )
175  );
176 
177 
178  // Global perpendicular angle
179  if (shapeDict.found("patchInfo"))
180  {
181  globalPatchInfo.set
182  (
183  surfi,
184  shapeDict.subDict("patchInfo").clone()
185  );
186  }
187 
188 
189  // Per region override of patchInfo
190 
191  if (shapeDict.found("regions"))
192  {
193  const dictionary& regionsDict = shapeDict.subDict("regions");
194  const wordList& regionNames =
195  allGeometry[surfaces[surfi]].regions();
196 
197  forAll(regionNames, regioni)
198  {
199  if (regionsDict.found(regionNames[regioni]))
200  {
201  // Get the dictionary for region
202  const dictionary& regionDict = regionsDict.subDict
203  (
204  regionNames[regioni]
205  );
206 
207  if (regionDict.found("patchInfo"))
208  {
209  regionPatchInfo[surfi].insert
210  (
211  regioni,
212  regionDict.subDict("patchInfo").clone()
213  );
214  }
215  }
216  }
217  }
218 
219  // Per region override of cellSize
220  if (shapeDict.found("regions"))
221  {
222  const dictionary& shapeControlRegionsDict =
223  shapeDict.subDict("regions");
224  const wordList& regionNames =
225  allGeometry[surfaces[surfi]].regions();
226 
227  forAll(regionNames, regioni)
228  {
229  if (shapeControlRegionsDict.found(regionNames[regioni]))
230  {
231  const dictionary& shapeControlRegionDict =
232  shapeControlRegionsDict.subDict
233  (
234  regionNames[regioni]
235  );
236 
237  const word scsFuncName =
238  shapeControlRegionDict.get<word>
239  (
240  "surfaceCellSizeFunction"
241  );
242  const dictionary& scsDict =
243  shapeControlRegionDict.subDict
244  (
245  scsFuncName + "Coeffs"
246  );
247 
248  const scalar surfaceCellSize =
249  scsDict.get<scalar>("surfaceCellSizeCoeff");
250 
251  const label refLevel = sizeCoeffToRefinement
252  (
253  level0Coeff,
254  surfaceCellSize
255  );
256 
257  regionMinLevel[surfi].insert(regioni, refLevel);
258  regionMaxLevel[surfi].insert(regioni, refLevel);
259  regionLevelIncr[surfi].insert(regioni, 0);
260  }
261  }
262  }
263 
264  surfi++;
265  }
266  }
267 
268  // Calculate local to global region offset
269  label nRegions = 0;
270 
271  forAll(surfaces, surfi)
272  {
273  regionOffset[surfi] = nRegions;
274  nRegions += allGeometry[surfaces[surfi]].regions().size();
275  }
276 
277  // Rework surface specific information into information per global region
278  labelList minLevel(nRegions, Zero);
279  labelList maxLevel(nRegions, Zero);
280  labelList gapLevel(nRegions, -1);
281  PtrList<dictionary> patchInfo(nRegions);
282 
283  forAll(globalMinLevel, surfi)
284  {
285  label nRegions = allGeometry[surfaces[surfi]].regions().size();
286 
287  // Initialise to global (i.e. per surface)
288  for (label i = 0; i < nRegions; i++)
289  {
290  label globalRegioni = regionOffset[surfi] + i;
291  minLevel[globalRegioni] = globalMinLevel[surfi];
292  maxLevel[globalRegioni] = globalMaxLevel[surfi];
293  gapLevel[globalRegioni] =
294  maxLevel[globalRegioni]
295  + globalLevelIncr[surfi];
296 
297  if (globalPatchInfo.set(surfi))
298  {
299  patchInfo.set
300  (
301  globalRegioni,
302  globalPatchInfo[surfi].clone()
303  );
304  }
305  }
306 
307  // Overwrite with region specific information
308  forAllConstIters(regionMinLevel[surfi], iter)
309  {
310  label globalRegioni = regionOffset[surfi] + iter.key();
311 
312  minLevel[globalRegioni] = iter();
313  maxLevel[globalRegioni] = regionMaxLevel[surfi][iter.key()];
314  gapLevel[globalRegioni] =
315  maxLevel[globalRegioni]
316  + regionLevelIncr[surfi][iter.key()];
317  }
318 
319  const Map<autoPtr<dictionary>>& localInfo = regionPatchInfo[surfi];
320  forAllConstIters(localInfo, iter)
321  {
322  label globalRegioni = regionOffset[surfi] + iter.key();
323  patchInfo.set(globalRegioni, iter()().clone());
324  }
325  }
326 
327  surfacePtr.reset
328  (
330  (
331  allGeometry,
332  surfaces,
333  names,
334  surfZones,
335  regionOffset,
336  minLevel,
337  maxLevel,
338  gapLevel,
339  scalarField(nRegions, -GREAT), //perpendicularAngle,
340  patchInfo,
341  false //dryRun
342  )
343  );
344 
345 
346  const refinementSurfaces& rf = surfacePtr();
347 
348  // Determine maximum region name length
349  label maxLen = 0;
350  forAll(rf.surfaces(), surfi)
351  {
352  label geomi = rf.surfaces()[surfi];
353  const wordList& regionNames = allGeometry.regionNames()[geomi];
354  forAll(regionNames, regioni)
355  {
356  maxLen = Foam::max(maxLen, label(regionNames[regioni].size()));
357  }
358  }
359 
360 
361  Info<< setw(maxLen) << "Region"
362  << setw(10) << "Min Level"
363  << setw(10) << "Max Level"
364  << setw(10) << "Gap Level" << nl
365  << setw(maxLen) << "------"
366  << setw(10) << "---------"
367  << setw(10) << "---------"
368  << setw(10) << "---------" << endl;
369 
370  forAll(rf.surfaces(), surfi)
371  {
372  label geomi = rf.surfaces()[surfi];
373 
374  Info<< rf.names()[surfi] << ':' << nl;
375 
376  const wordList& regionNames = allGeometry.regionNames()[geomi];
377 
378  forAll(regionNames, regioni)
379  {
380  label globali = rf.globalRegion(surfi, regioni);
381 
382  Info<< setw(maxLen) << regionNames[regioni]
383  << setw(10) << rf.minLevel()[globali]
384  << setw(10) << rf.maxLevel()[globali]
385  << setw(10) << rf.gapLevel()[globali] << endl;
386  }
387  }
388 
389 
390  return surfacePtr;
391 }
392 
393 
394 void extractSurface
395 (
396  const polyMesh& mesh,
397  const Time& runTime,
398  const labelHashSet& includePatches,
399  const fileName& outFileName
400 )
401 {
403 
404  // Collect sizes. Hash on names to handle local-only patches (e.g.
405  // processor patches)
406  HashTable<label> patchSize(1024);
407  label nFaces = 0;
408  for (const label patchi : includePatches)
409  {
410  const polyPatch& pp = bMesh[patchi];
411  patchSize.insert(pp.name(), pp.size());
412  nFaces += pp.size();
413  }
415 
416 
417  // Allocate zone/patch for all patches
418  HashTable<label> compactZoneID(1024);
419  if (Pstream::master())
420  {
421  forAllConstIters(patchSize, iter)
422  {
423  compactZoneID.insert(iter.key(), compactZoneID.size());
424  }
425  }
426  Pstream::broadcast(compactZoneID);
427 
428 
429  // Rework HashTable into labelList just for speed of conversion
430  labelList patchToCompactZone(bMesh.size(), -1);
431  forAllConstIters(compactZoneID, iter)
432  {
433  label patchi = bMesh.findPatchID(iter.key());
434  if (patchi != -1)
435  {
436  patchToCompactZone[patchi] = iter.val();
437  }
438  }
439 
440  // Collect faces on zones
442  DynamicList<label> compactZones(nFaces);
443  for (const label patchi : includePatches)
444  {
445  const polyPatch& pp = bMesh[patchi];
446  forAll(pp, i)
447  {
448  faceLabels.append(pp.start()+i);
449  compactZones.append(patchToCompactZone[pp.index()]);
450  }
451  }
452 
453  // Addressing engine for all faces
454  uindirectPrimitivePatch allBoundary
455  (
457  mesh.points()
458  );
459 
460 
461  // Find correspondence to master points
462  labelList pointToGlobal;
463  labelList uniqueMeshPoints;
465  (
466  allBoundary.meshPoints(),
467  allBoundary.meshPointMap(),
468  pointToGlobal,
469  uniqueMeshPoints
470  );
471 
472  // Gather all unique points on master
473  List<pointField> gatheredPoints(Pstream::nProcs());
474  gatheredPoints[Pstream::myProcNo()] = pointField
475  (
476  mesh.points(),
477  uniqueMeshPoints
478  );
479  Pstream::gatherList(gatheredPoints);
480 
481  // Gather all faces
482  List<faceList> gatheredFaces(Pstream::nProcs());
483  gatheredFaces[Pstream::myProcNo()] = allBoundary.localFaces();
484  forAll(gatheredFaces[Pstream::myProcNo()], i)
485  {
486  inplaceRenumber(pointToGlobal, gatheredFaces[Pstream::myProcNo()][i]);
487  }
488  Pstream::gatherList(gatheredFaces);
489 
490  // Gather all ZoneIDs
491  List<labelList> gatheredZones(Pstream::nProcs());
492  gatheredZones[Pstream::myProcNo()].transfer(compactZones);
493  Pstream::gatherList(gatheredZones);
494 
495  // On master combine all points, faces, zones
496  if (Pstream::master())
497  {
498  pointField allPoints = ListListOps::combine<pointField>
499  (
500  gatheredPoints,
502  );
503  gatheredPoints.clear();
504 
505  faceList allFaces = ListListOps::combine<faceList>
506  (
507  gatheredFaces,
509  );
510  gatheredFaces.clear();
511 
512  labelList allZones = ListListOps::combine<labelList>
513  (
514  gatheredZones,
516  );
517  gatheredZones.clear();
518 
519 
520  // Zones
521  surfZoneIdentifierList surfZones(compactZoneID.size());
522  forAllConstIters(compactZoneID, iter)
523  {
524  surfZones[iter()] = surfZoneIdentifier(iter.key(), iter());
525  Info<< "surfZone " << iter() << " : " << surfZones[iter()].name()
526  << endl;
527  }
528 
529  UnsortedMeshedSurface<face> unsortedFace
530  (
531  std::move(allPoints),
532  std::move(allFaces),
533  std::move(allZones),
534  surfZones
535  );
536 
537 
538  MeshedSurface<face> sortedFace(unsortedFace);
539 
540  fileName globalCasePath
541  (
543  ? runTime.globalPath()/outFileName
544  : runTime.path()/outFileName
545  );
546  globalCasePath.clean(); // Remove unneeded ".."
547 
548  Info<< "Writing merged surface to " << globalCasePath << endl;
549 
550  sortedFace.write(globalCasePath);
551  }
552 }
553 
554 
555 label checkAlignment(const polyMesh& mesh, const scalar tol, Ostream& os)
556 {
557  // Check all edges aligned with one of the coordinate axes
558  const faceList& faces = mesh.faces();
559  const pointField& points = mesh.points();
560 
561  label nUnaligned = 0;
562 
563  forAll(faces, facei)
564  {
565  const face& f = faces[facei];
566  forAll(f, fp)
567  {
568  label fp1 = f.fcIndex(fp);
569  const linePointRef e(edge(f[fp], f[fp1]).line(points));
570  const vector v(e.vec());
571  const scalar magV(mag(v));
572  if (magV > ROOTVSMALL)
573  {
574  for
575  (
576  direction dir = 0;
577  dir < pTraits<vector>::nComponents;
578  ++dir
579  )
580  {
581  const scalar s(mag(v[dir]));
582  if (s > magV*tol && s < magV*(1-tol))
583  {
584  ++nUnaligned;
585  break;
586  }
587  }
588  }
589  }
590  }
591 
592  reduce(nUnaligned, sumOp<label>());
593 
594  if (nUnaligned)
595  {
596  os << "Initial mesh has " << nUnaligned
597  << " edges unaligned with any of the coordinate axes" << nl << endl;
598  }
599  return nUnaligned;
600 }
601 
602 
603 // Check writing tolerance before doing any serious work
604 scalar getMergeDistance
605 (
606  const polyMesh& mesh,
607  const scalar mergeTol,
608  const bool dryRun
609 )
610 {
611  const boundBox& meshBb = mesh.bounds();
612  scalar mergeDist = mergeTol * meshBb.mag();
613 
614  Info<< nl
615  << "Overall mesh bounding box : " << meshBb << nl
616  << "Relative tolerance : " << mergeTol << nl
617  << "Absolute matching distance : " << mergeDist << nl
618  << endl;
619 
620  // check writing tolerance
621  if (mesh.time().writeFormat() == IOstreamOption::ASCII && !dryRun)
622  {
623  const scalar writeTol = std::pow
624  (
625  scalar(10),
626  -scalar(IOstream::defaultPrecision())
627  );
628 
629  if (mergeTol < writeTol)
630  {
632  << "Your current settings specify ASCII writing with "
633  << IOstream::defaultPrecision() << " digits precision." << nl
634  << "Your merging tolerance (" << mergeTol
635  << ") is finer than this." << nl
636  << "Change to binary writeFormat, "
637  << "or increase the writePrecision" << endl
638  << "or adjust the merge tolerance (mergeTol)."
639  << exit(FatalError);
640  }
641  }
642 
643  return mergeDist;
644 }
645 
646 
647 void removeZeroSizedPatches(fvMesh& mesh)
648 {
649  // Remove any zero-sized ones. Assumes
650  // - processor patches are already only there if needed
651  // - all other patches are available on all processors
652  // - but coupled ones might still be needed, even if zero-size
653  // (e.g. processorCyclic)
654  // See also logic in createPatch.
656 
657  labelList oldToNew(pbm.size(), -1);
658  label newPatchi = 0;
659  forAll(pbm, patchi)
660  {
661  const polyPatch& pp = pbm[patchi];
662 
663  if (!isA<processorPolyPatch>(pp))
664  {
665  if
666  (
667  isA<coupledPolyPatch>(pp)
668  || returnReduceOr(pp.size())
669  )
670  {
671  // Coupled (and unknown size) or uncoupled and used
672  oldToNew[patchi] = newPatchi++;
673  }
674  }
675  }
676 
677  forAll(pbm, patchi)
678  {
679  const polyPatch& pp = pbm[patchi];
680 
681  if (isA<processorPolyPatch>(pp))
682  {
683  oldToNew[patchi] = newPatchi++;
684  }
685  }
686 
687 
688  const label nKeepPatches = newPatchi;
689 
690  // Shuffle unused ones to end
691  if (nKeepPatches != pbm.size())
692  {
693  Info<< endl
694  << "Removing zero-sized patches:" << endl << incrIndent;
695 
696  forAll(oldToNew, patchi)
697  {
698  if (oldToNew[patchi] == -1)
699  {
700  Info<< indent << pbm[patchi].name()
701  << " type " << pbm[patchi].type()
702  << " at position " << patchi << endl;
703  oldToNew[patchi] = newPatchi++;
704  }
705  }
706  Info<< decrIndent;
707 
708  fvMeshTools::reorderPatches(mesh, oldToNew, nKeepPatches, true);
709  Info<< endl;
710  }
711 }
712 
713 
714 // Write mesh and additional information
715 void writeMesh
716 (
717  const string& msg,
718  const meshRefinement& meshRefiner,
719  const meshRefinement::debugType debugLevel,
720  const meshRefinement::writeType writeLevel
721 )
722 {
723  const fvMesh& mesh = meshRefiner.mesh();
724 
725  meshRefiner.printMeshInfo(debugLevel, msg);
726  Info<< "Writing mesh to time " << meshRefiner.timeName() << endl;
727 
729  if (!debugLevel && !(writeLevel&meshRefinement::WRITELAYERSETS))
730  {
732  }
734 
735  meshRefiner.write
736  (
737  debugLevel,
739  mesh.time().path()/meshRefiner.timeName()
740  );
741  Info<< "Wrote mesh in = "
742  << mesh.time().cpuTimeIncrement() << " s." << endl;
743 }
744 
745 
746 int main(int argc, char *argv[])
747 {
749  (
750  "Automatic split hex mesher. Refines and snaps to surface"
751  );
752 
753  #include "addRegionOption.H"
754  #include "addOverwriteOption.H"
755  #include "addProfilingOption.H"
757  (
758  "checkGeometry",
759  "Check all surface geometry for quality"
760  );
762  (
763  "Check case set-up only using a single time step"
764  );
766  (
767  "surfaceSimplify",
768  "boundBox",
769  "Simplify the surface using snappyHexMesh starting from a boundBox"
770  );
772  (
773  "patches",
774  "(patch0 .. patchN)",
775  "Only triangulate selected patches (wildcards supported)"
776  );
778  (
779  "outFile",
780  "file",
781  "Name of the file to save the simplified surface to"
782  );
783  argList::addOption("dict", "file", "Alternative snappyHexMeshDict");
784 
785  argList::noFunctionObjects(); // Never use function objects
786 
787  #include "setRootCase.H"
788  #include "createTime.H"
789 
790  const bool overwrite = args.found("overwrite");
791  const bool checkGeometry = args.found("checkGeometry");
792  const bool surfaceSimplify = args.found("surfaceSimplify");
793  const bool dryRun = args.dryRun();
794 
795  if (dryRun)
796  {
797  Info<< "Operating in dry-run mode to detect set-up errors"
798  << nl << endl;
799  }
800 
801 
802  #include "createNamedMesh.H"
803  Info<< "Read mesh in = "
804  << runTime.cpuTimeIncrement() << " s" << endl;
805 
806  // Check patches and faceZones are synchronised
809 
810  if (dryRun)
811  {
812  // Check if mesh aligned with cartesian axes
813  checkAlignment(mesh, 1e-6, Pout); //FatalIOError);
814  }
815 
816 
817 
818  // Read meshing dictionary
819  const word dictName("snappyHexMeshDict");
820  #include "setSystemMeshDictionaryIO.H"
822 
823 
824  // all surface geometry
825  const dictionary& geometryDict =
826  meshRefinement::subDict(meshDict, "geometry", dryRun);
827 
828  // refinement parameters
829  const dictionary& refineDict =
830  meshRefinement::subDict(meshDict, "castellatedMeshControls", dryRun);
831 
832  // mesh motion and mesh quality parameters
833  const dictionary& motionDict =
834  meshRefinement::subDict(meshDict, "meshQualityControls", dryRun);
835 
836  // snap-to-surface parameters
837  const dictionary& snapDict =
838  meshRefinement::subDict(meshDict, "snapControls", dryRun);
839 
840  // layer addition parameters
841  const dictionary& layerDict =
842  meshRefinement::subDict(meshDict, "addLayersControls", dryRun);
843 
844  // absolute merge distance
845  const scalar mergeDist = getMergeDistance
846  (
847  mesh,
848  meshRefinement::get<scalar>
849  (
850  meshDict,
851  "mergeTolerance",
852  dryRun
853  ),
854  dryRun
855  );
856 
857  const bool keepPatches(meshDict.getOrDefault("keepPatches", false));
858 
859  // Writer for writing lines
860  autoPtr<coordSetWriter> setFormatter;
861  {
862  const word setFormat
863  (
865  (
866  "setFormat",
867  coordSetWriters::vtkWriter::typeName // Default: "vtk"
868  )
869  );
870 
871  setFormatter = coordSetWriter::New
872  (
873  setFormat,
875  );
876  }
877 
878 
879  const scalar maxSizeRatio
880  (
881  meshDict.getOrDefault<scalar>("maxSizeRatio", 100)
882  );
883 
884 
885  // Read decomposePar dictionary
886  dictionary decomposeDict;
887  if (Pstream::parRun())
888  {
889  // Ensure demand-driven decompositionMethod finds alternative
890  // decomposeParDict location properly.
891 
892  IOdictionary* dictPtr = new IOdictionary
893  (
895  (
896  IOobject
897  (
899  runTime.system(),
900  runTime,
904  ),
905  args.getOrDefault<fileName>("decomposeParDict", "")
906  )
907  );
908 
909  // Store it on the object registry, but to be found it must also
910  // have the expected "decomposeParDict" name.
911 
913  runTime.store(dictPtr);
914 
915  decomposeDict = *dictPtr;
916  }
917  else
918  {
919  decomposeDict.add("method", "none");
920  decomposeDict.add("numberOfSubdomains", 1);
921  }
922 
923 
924  // Debug
925  // ~~~~~
926 
927  // Set debug level
929  (
930  meshDict.getOrDefault<label>
931  (
932  "debug",
933  0
934  )
935  );
936  {
937  wordList flags;
938  if (meshDict.readIfPresent("debugFlags", flags))
939  {
940  debugLevel = meshRefinement::debugType
941  (
943  (
945  flags
946  )
947  );
948  }
949  }
950  if (debugLevel > 0)
951  {
952  meshRefinement::debug = debugLevel;
953  snappyRefineDriver::debug = debugLevel;
954  snappySnapDriver::debug = debugLevel;
955  snappyLayerDriver::debug = debugLevel;
956  }
957 
958  // Set file writing level
959  {
960  wordList flags;
961  if (meshDict.readIfPresent("writeFlags", flags))
962  {
964  (
966  (
968  (
970  flags
971  )
972  )
973  );
974  }
975  }
976 
978  //{
979  // wordList flags;
980  // if (meshDict.readIfPresent("outputFlags", flags))
981  // {
982  // meshRefinement::outputLevel
983  // (
984  // meshRefinement::outputType
985  // (
986  // meshRefinement::readFlags
987  // (
988  // meshRefinement::outputTypeNames,
989  // flags
990  // )
991  // )
992  // );
993  // }
994  //}
995 
996  // for the impatient who want to see some output files:
998 
999  // Read geometry
1000  // ~~~~~~~~~~~~~
1001 
1002  searchableSurfaces allGeometry
1003  (
1004  IOobject
1005  (
1006  "abc", // dummy name
1007  mesh.time().constant(), // instance
1008  //mesh.time().findInstance("triSurface", word::null),// instance
1009  "triSurface", // local
1010  mesh.time(), // registry
1013  ),
1014  geometryDict,
1015  meshDict.getOrDefault("singleRegionName", true)
1016  );
1017 
1018 
1019  // Read refinement surfaces
1020  // ~~~~~~~~~~~~~~~~~~~~~~~~
1021 
1022  autoPtr<refinementSurfaces> surfacesPtr;
1023 
1024  Info<< "Reading refinement surfaces." << endl;
1025 
1026  if (surfaceSimplify)
1027  {
1028  addProfiling(surfaceSimplify, "snappyHexMesh::surfaceSimplify");
1029  IOdictionary foamyHexMeshDict
1030  (
1031  IOobject
1032  (
1033  "foamyHexMeshDict",
1034  runTime.system(),
1035  runTime,
1038  )
1039  );
1040 
1041  const dictionary& conformationDict =
1042  foamyHexMeshDict.subDict("surfaceConformation").subDict
1043  (
1044  "geometryToConformTo"
1045  );
1046 
1047  const dictionary& motionDict =
1048  foamyHexMeshDict.subDict("motionControl");
1049 
1050  const dictionary& shapeControlDict =
1051  motionDict.subDict("shapeControlFunctions");
1052 
1053  // Calculate current ratio of hex cells v.s. wanted cell size
1054  const scalar defaultCellSize =
1055  motionDict.get<scalar>("defaultCellSize");
1056 
1057  const scalar initialCellSize = ::pow(mesh.V()[0], 1.0/3.0);
1058 
1059  //Info<< "Wanted cell size = " << defaultCellSize << endl;
1060  //Info<< "Current cell size = " << initialCellSize << endl;
1061  //Info<< "Fraction = " << initialCellSize/defaultCellSize
1062  // << endl;
1063 
1064  surfacesPtr =
1065  createRefinementSurfaces
1066  (
1067  allGeometry,
1068  conformationDict,
1069  shapeControlDict,
1070  refineDict.getOrDefault("gapLevelIncrement", 0),
1071  initialCellSize/defaultCellSize
1072  );
1073 
1075  }
1076  else
1077  {
1078  surfacesPtr.reset
1079  (
1080  new refinementSurfaces
1081  (
1082  allGeometry,
1084  (
1085  refineDict,
1086  "refinementSurfaces",
1087  dryRun
1088  ),
1089  refineDict.getOrDefault("gapLevelIncrement", 0),
1090  dryRun
1091  )
1092  );
1093 
1094  Info<< "Read refinement surfaces in = "
1095  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1096  }
1097 
1098  refinementSurfaces& surfaces = surfacesPtr();
1099 
1100 
1101  // Checking only?
1102 
1103  if (checkGeometry)
1104  {
1105  // Check geometry amongst itself (e.g. intersection, size differences)
1106 
1107  // Extract patchInfo
1108  List<wordList> patchTypes(allGeometry.size());
1109 
1110  const PtrList<dictionary>& patchInfo = surfaces.patchInfo();
1111  const labelList& surfaceGeometry = surfaces.surfaces();
1112  forAll(surfaceGeometry, surfi)
1113  {
1114  label geomi = surfaceGeometry[surfi];
1115  const wordList& regNames = allGeometry.regionNames()[geomi];
1116 
1117  patchTypes[geomi].setSize(regNames.size());
1118  forAll(regNames, regioni)
1119  {
1120  label globalRegioni = surfaces.globalRegion(surfi, regioni);
1121 
1122  if (patchInfo.set(globalRegioni))
1123  {
1124  patchTypes[geomi][regioni] =
1125  meshRefinement::get<word>
1126  (
1127  patchInfo[globalRegioni],
1128  "type",
1129  dryRun,
1131  word::null
1132  );
1133  }
1134  else
1135  {
1136  patchTypes[geomi][regioni] = wallPolyPatch::typeName;
1137  }
1138  }
1139  }
1140 
1141  // Write some stats
1142  allGeometry.writeStats(patchTypes, Info);
1143  // Check topology
1144  allGeometry.checkTopology(true);
1145  // Check geometry
1146  allGeometry.checkGeometry
1147  (
1148  maxSizeRatio, // max size ratio
1149  1e-9, // intersection tolerance
1150  setFormatter,
1151  0.01, // min triangle quality
1152  true
1153  );
1154 
1155  if (!dryRun)
1156  {
1157  return 0;
1158  }
1159  }
1160 
1161 
1162  if (dryRun)
1163  {
1164  // Check geometry to mesh bounding box
1165  Info<< "Checking for geometry size relative to mesh." << endl;
1166  const boundBox& meshBb = mesh.bounds();
1167  forAll(allGeometry, geomi)
1168  {
1169  const searchableSurface& s = allGeometry[geomi];
1170  const boundBox& bb = s.bounds();
1171 
1172  scalar ratio = bb.mag() / meshBb.mag();
1173  if (ratio > maxSizeRatio || ratio < 1.0/maxSizeRatio)
1174  {
1175  Warning
1176  << " " << allGeometry.names()[geomi]
1177  << " bounds differ from mesh"
1178  << " by more than a factor " << maxSizeRatio << ":" << nl
1179  << " bounding box : " << bb << nl
1180  << " mesh bounding box : " << meshBb
1181  << endl;
1182  }
1183  if (!meshBb.contains(bb))
1184  {
1185  Warning
1186  << " " << allGeometry.names()[geomi]
1187  << " bounds not fully contained in mesh" << nl
1188  << " bounding box : " << bb << nl
1189  << " mesh bounding box : " << meshBb
1190  << endl;
1191  }
1192  }
1193  Info<< endl;
1194  }
1195 
1196 
1197 
1198 
1199  // Read refinement shells
1200  // ~~~~~~~~~~~~~~~~~~~~~~
1201 
1202  Info<< "Reading refinement shells." << endl;
1203  shellSurfaces shells
1204  (
1205  allGeometry,
1206  meshRefinement::subDict(refineDict, "refinementRegions", dryRun),
1207  dryRun
1208  );
1209  Info<< "Read refinement shells in = "
1210  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1211 
1212 
1213  Info<< "Setting refinement level of surface to be consistent"
1214  << " with shells." << endl;
1215  surfaces.setMinLevelFields(shells);
1216  Info<< "Checked shell refinement in = "
1217  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1218 
1219 
1220  // Optionally read limit shells
1221  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1222 
1223  const dictionary limitDict(refineDict.subOrEmptyDict("limitRegions"));
1224 
1225  if (!limitDict.empty())
1226  {
1227  Info<< "Reading limit shells." << endl;
1228  }
1229 
1230  shellSurfaces limitShells(allGeometry, limitDict, dryRun);
1231 
1232  if (!limitDict.empty())
1233  {
1234  Info<< "Read limit shells in = "
1235  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1236  }
1237 
1238  if (dryRun)
1239  {
1240  // Check for use of all geometry
1241  const wordList& allGeomNames = allGeometry.names();
1242 
1243  labelHashSet unusedGeometries(identity(allGeomNames.size()));
1244  unusedGeometries.erase(surfaces.surfaces());
1245  unusedGeometries.erase(shells.shells());
1246  unusedGeometries.erase(limitShells.shells());
1247 
1248  if (unusedGeometries.size())
1249  {
1250  IOWarningInFunction(geometryDict)
1251  << "The following geometry entries are not used:" << nl;
1252  for (const label geomi : unusedGeometries)
1253  {
1254  Info<< " " << allGeomNames[geomi] << nl;
1255  }
1256  Info<< endl;
1257  }
1258  }
1259 
1260 
1261 
1262 
1263  // Read feature meshes
1264  // ~~~~~~~~~~~~~~~~~~~
1265 
1266  Info<< "Reading features." << endl;
1267  refinementFeatures features
1268  (
1269  mesh,
1271  (
1272  meshRefinement::lookup(refineDict, "features", dryRun)
1273  ),
1274  dryRun
1275  );
1276  Info<< "Read features in = "
1277  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1278 
1279 
1280  if (dryRun)
1281  {
1282  // Check geometry to mesh bounding box
1283  Info<< "Checking for line geometry size relative to surface geometry."
1284  << endl;
1285 
1286  OStringStream os;
1287  bool hasErrors = features.checkSizes
1288  (
1289  maxSizeRatio, //const scalar maxRatio,
1290  mesh.bounds(),
1291  true, //const bool report,
1292  os //FatalIOError
1293  );
1294  if (hasErrors)
1295  {
1296  Warning<< os.str() << endl;
1297  }
1298  }
1299 
1300 
1301  // Refinement engine
1302  // ~~~~~~~~~~~~~~~~~
1303 
1304  Info<< nl
1305  << "Determining initial surface intersections" << nl
1306  << "-----------------------------------------" << nl
1307  << endl;
1308 
1309  // Main refinement engine
1310  meshRefinement meshRefiner
1311  (
1312  mesh,
1313  mergeDist, // tolerance used in sorting coordinates
1314  overwrite, // overwrite mesh files?
1315  surfaces, // for surface intersection refinement
1316  features, // for feature edges/point based refinement
1317  shells, // for volume (inside/outside) refinement
1318  limitShells, // limit of volume refinement
1319  labelList(), // initial faces to test
1320  dryRun
1321  );
1322 
1323  if (!dryRun)
1324  {
1325  meshRefiner.updateIntersections(identity(mesh.nFaces()));
1326  Info<< "Calculated surface intersections in = "
1327  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1328  }
1329 
1330  // Some stats
1331  meshRefiner.printMeshInfo(debugLevel, "Initial mesh");
1332 
1333  meshRefiner.write
1334  (
1337  mesh.time().path()/meshRefiner.timeName()
1338  );
1339 
1340 
1341  // Refinement parameters
1342  const refinementParameters refineParams(refineDict, dryRun);
1343 
1344  // Snap parameters
1345  const snapParameters snapParams(snapDict, dryRun);
1346 
1347 
1348  Info<< "Setting refinement level of surface to be consistent"
1349  << " with curvature." << endl;
1351  (
1352  refineParams.curvature(),
1353  meshRefiner.meshCutter().level0EdgeLength()
1354  );
1355  Info<< "Checked curvature refinement in = "
1356  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1357 
1358 
1359 
1360  // Add all the cellZones and faceZones
1361  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1362 
1363  // 1. cellZones relating to surface (faceZones added later)
1364 
1365  const labelList namedSurfaces
1366  (
1368  );
1369 
1371  (
1372  surfaces.surfZones(),
1373  namedSurfaces,
1374  mesh
1375  );
1376 
1377 
1378  // 2. cellZones relating to locations
1379 
1380  refineParams.addCellZonesToMesh(mesh);
1381 
1382 
1383 
1384  // Add all the surface regions as patches
1385  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1386 
1387  //- Global surface region to patch (non faceZone surface) or patches
1388  // (faceZone surfaces)
1389  labelList globalToMasterPatch;
1390  labelList globalToSlavePatch;
1391 
1392 
1393  {
1394  Info<< nl
1395  << "Adding patches for surface regions" << nl
1396  << "----------------------------------" << nl
1397  << endl;
1398 
1399  // From global region number to mesh patch.
1400  globalToMasterPatch.setSize(surfaces.nRegions(), -1);
1401  globalToSlavePatch.setSize(surfaces.nRegions(), -1);
1402 
1403  if (!dryRun)
1404  {
1405  Info<< setf(ios_base::left)
1406  << setw(6) << "Patch"
1407  << setw(20) << "Type"
1408  << setw(30) << "Region" << nl
1409  << setw(6) << "-----"
1410  << setw(20) << "----"
1411  << setw(30) << "------" << endl;
1412  }
1413 
1414  const labelList& surfaceGeometry = surfaces.surfaces();
1415  const PtrList<dictionary>& surfacePatchInfo = surfaces.patchInfo();
1417 
1418  forAll(surfaceGeometry, surfi)
1419  {
1420  label geomi = surfaceGeometry[surfi];
1421 
1422  const wordList& regNames = allGeometry.regionNames()[geomi];
1423 
1424  if (!dryRun)
1425  {
1426  Info<< surfaces.names()[surfi] << ':' << nl << nl;
1427  }
1428 
1429  const wordList& fzNames =
1430  surfaces.surfZones()[surfi].faceZoneNames();
1431 
1432  if (fzNames.empty())
1433  {
1434  // 'Normal' surface
1435  forAll(regNames, i)
1436  {
1437  label globalRegioni = surfaces.globalRegion(surfi, i);
1438 
1439  label patchi;
1440 
1441  if (surfacePatchInfo.set(globalRegioni))
1442  {
1443  patchi = meshRefiner.addMeshedPatch
1444  (
1445  regNames[i],
1446  surfacePatchInfo[globalRegioni]
1447  );
1448  }
1449  else
1450  {
1451  dictionary patchInfo;
1452  patchInfo.set("type", wallPolyPatch::typeName);
1453 
1454  patchi = meshRefiner.addMeshedPatch
1455  (
1456  regNames[i],
1457  patchInfo
1458  );
1459  }
1460 
1461  if (!dryRun)
1462  {
1463  Info<< setf(ios_base::left)
1464  << setw(6) << patchi
1465  << setw(20) << pbm[patchi].type()
1466  << setw(30) << regNames[i] << nl;
1467  }
1468 
1469  globalToMasterPatch[globalRegioni] = patchi;
1470  globalToSlavePatch[globalRegioni] = patchi;
1471  }
1472  }
1473  else
1474  {
1475  // Zoned surface
1476  forAll(regNames, i)
1477  {
1478  label globalRegioni = surfaces.globalRegion(surfi, i);
1479 
1480  // Add master side patch
1481  {
1482  label patchi;
1483 
1484  if (surfacePatchInfo.set(globalRegioni))
1485  {
1486  patchi = meshRefiner.addMeshedPatch
1487  (
1488  regNames[i],
1489  surfacePatchInfo[globalRegioni]
1490  );
1491  }
1492  else
1493  {
1494  dictionary patchInfo;
1495  patchInfo.set("type", wallPolyPatch::typeName);
1496 
1497  patchi = meshRefiner.addMeshedPatch
1498  (
1499  regNames[i],
1500  patchInfo
1501  );
1502  }
1503 
1504  if (!dryRun)
1505  {
1506  Info<< setf(ios_base::left)
1507  << setw(6) << patchi
1508  << setw(20) << pbm[patchi].type()
1509  << setw(30) << regNames[i] << nl;
1510  }
1511 
1512  globalToMasterPatch[globalRegioni] = patchi;
1513  }
1514  // Add slave side patch
1515  {
1516  const word slaveName = regNames[i] + "_slave";
1517  label patchi;
1518 
1519  if (surfacePatchInfo.set(globalRegioni))
1520  {
1521  patchi = meshRefiner.addMeshedPatch
1522  (
1523  slaveName,
1524  surfacePatchInfo[globalRegioni]
1525  );
1526  }
1527  else
1528  {
1529  dictionary patchInfo;
1530  patchInfo.set("type", wallPolyPatch::typeName);
1531 
1532  patchi = meshRefiner.addMeshedPatch
1533  (
1534  slaveName,
1535  patchInfo
1536  );
1537  }
1538 
1539  if (!dryRun)
1540  {
1541  Info<< setf(ios_base::left)
1542  << setw(6) << patchi
1543  << setw(20) << pbm[patchi].type()
1544  << setw(30) << slaveName << nl;
1545  }
1546 
1547  globalToSlavePatch[globalRegioni] = patchi;
1548  }
1549  }
1550 
1551  // For now: have single faceZone per surface. Use first
1552  // region in surface for patch for zoning
1553  if (regNames.size())
1554  {
1555  forAll(fzNames, fzi)
1556  {
1557  const word& fzName = fzNames[fzi];
1558  label globalRegioni = surfaces.globalRegion(surfi, fzi);
1559 
1560  meshRefiner.addFaceZone
1561  (
1562  fzName,
1563  pbm[globalToMasterPatch[globalRegioni]].name(),
1564  pbm[globalToSlavePatch[globalRegioni]].name(),
1565  surfaces.surfZones()[surfi].faceType()
1566  );
1567  }
1568  }
1569  }
1570 
1571  if (!dryRun)
1572  {
1573  Info<< nl;
1574  }
1575  }
1576  Info<< "Added patches in = "
1577  << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
1578  }
1579 
1580 
1581 
1582  // Add all information for all the remaining faceZones
1583  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1584 
1585  HashTable<Pair<word>> faceZoneToPatches;
1586  forAll(mesh.faceZones(), zonei)
1587  {
1588  const word& fzName = mesh.faceZones()[zonei].name();
1589 
1590  label mpI, spI;
1592  bool hasInfo = meshRefiner.getFaceZoneInfo(fzName, mpI, spI, fzType);
1593 
1594  if (!hasInfo)
1595  {
1596  // faceZone does not originate from a surface but presumably
1597  // from a cellZone pair instead
1598  string::size_type i = fzName.find("_to_");
1599  if (i != string::npos)
1600  {
1601  word cz0 = fzName.substr(0, i);
1602  word cz1 = fzName.substr(i+4, fzName.size()-i+4);
1603  word slaveName(cz1 + "_to_" + cz0);
1604  faceZoneToPatches.insert(fzName, Pair<word>(fzName, slaveName));
1605  }
1606  else
1607  {
1608  // Add as fzName + fzName_slave
1609  const word slaveName = fzName + "_slave";
1610  faceZoneToPatches.insert(fzName, Pair<word>(fzName, slaveName));
1611  }
1612  }
1613  }
1614 
1615  if (faceZoneToPatches.size())
1616  {
1618  (
1619  meshRefiner,
1620  refineParams,
1621  faceZoneToPatches
1622  );
1623  }
1624 
1625 
1626 
1627  // Re-do intersections on meshed boundaries since they use an extrapolated
1628  // other side
1629  {
1630  const labelList adaptPatchIDs(meshRefiner.meshedPatches());
1631 
1633 
1634  label nFaces = 0;
1635  forAll(adaptPatchIDs, i)
1636  {
1637  nFaces += pbm[adaptPatchIDs[i]].size();
1638  }
1639 
1640  labelList faceLabels(nFaces);
1641  nFaces = 0;
1642  forAll(adaptPatchIDs, i)
1643  {
1644  const polyPatch& pp = pbm[adaptPatchIDs[i]];
1645  forAll(pp, i)
1646  {
1647  faceLabels[nFaces++] = pp.start()+i;
1648  }
1649  }
1650  meshRefiner.updateIntersections(faceLabels);
1651  }
1652 
1653 
1654 
1655  // Parallel
1656  // ~~~~~~~~
1657 
1658  // Construct decomposition engine. Note: cannot use decompositionModel
1659  // MeshObject since we're clearing out the mesh inside the mesh generation.
1660  autoPtr<decompositionMethod> decomposerPtr
1661  (
1663  (
1664  decomposeDict
1665  )
1666  );
1667  decompositionMethod& decomposer = *decomposerPtr;
1668 
1669  if (Pstream::parRun() && !decomposer.parallelAware())
1670  {
1672  << "You have selected decomposition method "
1673  << decomposer.typeName
1674  << " which is not parallel aware." << endl
1675  << "Please select one that is (hierarchical, ptscotch)"
1676  << exit(FatalError);
1677  }
1678 
1679  // Mesh distribution engine (uses tolerance to reconstruct meshes)
1680  fvMeshDistribute distributor(mesh);
1681 
1682 
1683 
1684 
1685 
1686  // Now do the real work -refinement -snapping -layers
1687  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1688 
1689  const bool wantRefine
1690  (
1691  meshRefinement::get<bool>(meshDict, "castellatedMesh", dryRun)
1692  );
1693  const bool wantSnap
1694  (
1695  meshRefinement::get<bool>(meshDict, "snap", dryRun)
1696  );
1697  const bool wantLayers
1698  (
1699  meshRefinement::get<bool>(meshDict, "addLayers", dryRun)
1700  );
1701 
1702  if (dryRun)
1703  {
1704  string errorMsg(FatalError.message());
1705  string IOerrorMsg(FatalIOError.message());
1706 
1707  if (errorMsg.size() || IOerrorMsg.size())
1708  {
1709  //errorMsg = "[dryRun] " + errorMsg;
1710  //errorMsg.replaceAll("\n", "\n[dryRun] ");
1711  //IOerrorMsg = "[dryRun] " + IOerrorMsg;
1712  //IOerrorMsg.replaceAll("\n", "\n[dryRun] ");
1713 
1714  Warning
1715  << nl
1716  << "Missing/incorrect required dictionary entries:" << nl
1717  << nl
1718  << IOerrorMsg.c_str() << nl
1719  << errorMsg.c_str() << nl << nl
1720  << "Exiting dry-run" << nl << endl;
1721 
1722  FatalError.clear();
1723  FatalIOError.clear();
1724 
1725  return 0;
1726  }
1727  }
1728 
1729 
1730  // How to treat co-planar faces
1731  meshRefinement::FaceMergeType mergeType =
1732  meshRefinement::FaceMergeType::GEOMETRIC;
1733  {
1734  const bool mergePatchFaces
1735  (
1736  meshDict.getOrDefault("mergePatchFaces", true)
1737  );
1738 
1739  if (!mergePatchFaces)
1740  {
1741  Info<< "Not merging patch-faces of cell to preserve"
1742  << " (split)hex cell shape."
1743  << nl << endl;
1744  mergeType = meshRefinement::FaceMergeType::NONE;
1745  }
1746  else
1747  {
1748  const bool mergeAcrossPatches
1749  (
1750  meshDict.getOrDefault("mergeAcrossPatches", false)
1751  );
1752 
1753  if (mergeAcrossPatches)
1754  {
1755  Info<< "Merging co-planar patch-faces of cells"
1756  << ", regardless of patch assignment"
1757  << nl << endl;
1758  mergeType = meshRefinement::FaceMergeType::IGNOREPATCH;
1759  }
1760  }
1761  }
1762 
1763 
1764 
1765  if (wantRefine)
1766  {
1767  cpuTime timer;
1768 
1769  snappyRefineDriver refineDriver
1770  (
1771  meshRefiner,
1772  decomposer,
1773  distributor,
1774  globalToMasterPatch,
1775  globalToSlavePatch,
1776  setFormatter(),
1777  dryRun
1778  );
1779 
1780 
1781  if (!overwrite && !debugLevel)
1782  {
1783  const_cast<Time&>(mesh.time())++;
1784  }
1785 
1786 
1787  refineDriver.doRefine
1788  (
1789  refineDict,
1790  refineParams,
1791  snapParams,
1792  refineParams.handleSnapProblems(),
1793  mergeType,
1794  motionDict
1795  );
1796 
1797  // Remove zero sized patches originating from faceZones
1798  if (!keepPatches && !wantSnap && !wantLayers)
1799  {
1801  }
1802 
1803  if (!dryRun)
1804  {
1805  writeMesh
1806  (
1807  "Refined mesh",
1808  meshRefiner,
1809  debugLevel,
1811  );
1812  }
1813 
1814  Info<< "Mesh refined in = "
1815  << timer.cpuTimeIncrement() << " s." << endl;
1816 
1818  }
1819 
1820  if (wantSnap)
1821  {
1822  cpuTime timer;
1823 
1824  snappySnapDriver snapDriver
1825  (
1826  meshRefiner,
1827  globalToMasterPatch,
1828  globalToSlavePatch,
1829  dryRun
1830  );
1831 
1832  if (!overwrite && !debugLevel)
1833  {
1834  const_cast<Time&>(mesh.time())++;
1835  }
1836 
1837  // Use the resolveFeatureAngle from the refinement parameters
1838  scalar curvature = refineParams.curvature();
1839  scalar planarAngle = refineParams.planarAngle();
1840 
1841  snapDriver.doSnap
1842  (
1843  snapDict,
1844  motionDict,
1845  mergeType,
1846  curvature,
1847  planarAngle,
1848  snapParams
1849  );
1850 
1851  // Remove zero sized patches originating from faceZones
1852  if (!keepPatches && !wantLayers)
1853  {
1855  }
1856 
1857  if (!dryRun)
1858  {
1859  writeMesh
1860  (
1861  "Snapped mesh",
1862  meshRefiner,
1863  debugLevel,
1865  );
1866  }
1867 
1868  Info<< "Mesh snapped in = "
1869  << timer.cpuTimeIncrement() << " s." << endl;
1870 
1872  }
1873 
1874  if (wantLayers)
1875  {
1876  cpuTime timer;
1877 
1878  // Layer addition parameters
1879  const layerParameters layerParams
1880  (
1881  layerDict,
1882  mesh.boundaryMesh(),
1883  dryRun
1884  );
1885 
1886  snappyLayerDriver layerDriver
1887  (
1888  meshRefiner,
1889  globalToMasterPatch,
1890  globalToSlavePatch,
1891  dryRun
1892  );
1893 
1894  // Use the maxLocalCells from the refinement parameters
1895  const bool preBalance =
1896  returnReduceOr(mesh.nCells() >= refineParams.maxLocalCells());
1897 
1898 
1899  if (!overwrite && !debugLevel)
1900  {
1901  const_cast<Time&>(mesh.time())++;
1902  }
1903 
1904  layerDriver.doLayers
1905  (
1906  layerDict,
1907  motionDict,
1908  layerParams,
1909  mergeType,
1910  preBalance,
1911  decomposer,
1912  distributor
1913  );
1914 
1915  // Remove zero sized patches originating from faceZones
1916  if (!keepPatches)
1917  {
1919  }
1920 
1921  if (!dryRun)
1922  {
1923  writeMesh
1924  (
1925  "Layer mesh",
1926  meshRefiner,
1927  debugLevel,
1929  );
1930  }
1931 
1932  Info<< "Layers added in = "
1933  << timer.cpuTimeIncrement() << " s." << endl;
1934 
1936  }
1937 
1938 
1939  {
1940  addProfiling(checkMesh, "snappyHexMesh::checkMesh");
1941 
1942  // Check final mesh
1943  Info<< "Checking final mesh ..." << endl;
1944  faceSet wrongFaces(mesh, "wrongFaces", mesh.nFaces()/100);
1945  motionSmoother::checkMesh(false, mesh, motionDict, wrongFaces, dryRun);
1946  const label nErrors = returnReduce
1947  (
1948  wrongFaces.size(),
1949  sumOp<label>()
1950  );
1951 
1952  if (nErrors > 0)
1953  {
1954  Info<< "Finished meshing with " << nErrors << " illegal faces"
1955  << " (concave, zero area or negative cell pyramid volume)"
1956  << endl;
1957  wrongFaces.write();
1958  }
1959  else
1960  {
1961  Info<< "Finished meshing without any errors" << endl;
1962  }
1963 
1965  }
1966 
1967 
1968  if (surfaceSimplify)
1969  {
1970  addProfiling(surfaceSimplify, "snappyHexMesh::surfaceSimplify");
1971 
1973 
1974  labelHashSet includePatches(bMesh.size());
1975 
1976  if (args.found("patches"))
1977  {
1978  includePatches = bMesh.patchSet
1979  (
1980  args.getList<wordRe>("patches")
1981  );
1982  }
1983  else
1984  {
1985  forAll(bMesh, patchi)
1986  {
1987  const polyPatch& patch = bMesh[patchi];
1988 
1989  if (!isA<processorPolyPatch>(patch))
1990  {
1991  includePatches.insert(patchi);
1992  }
1993  }
1994  }
1995 
1996  fileName outFileName
1997  (
1999  (
2000  "outFile",
2001  "constant/triSurface/simplifiedSurface.stl"
2002  )
2003  );
2004 
2005  extractSurface
2006  (
2007  mesh,
2008  runTime,
2009  includePatches,
2010  outFileName
2011  );
2012 
2013  pointIOField cellCentres
2014  (
2015  IOobject
2016  (
2017  "internalCellCentres",
2018  runTime.timeName(),
2019  mesh,
2022  ),
2023  mesh.cellCentres()
2024  );
2025 
2026  cellCentres.write();
2027  }
2028 
2030 
2031  Info<< "Finished meshing in = "
2032  << runTime.elapsedCpuTime() << " s." << endl;
2033 
2034 
2035  if (dryRun)
2036  {
2037  string errorMsg(FatalError.message());
2038  string IOerrorMsg(FatalIOError.message());
2039 
2040  if (errorMsg.size() || IOerrorMsg.size())
2041  {
2042  //errorMsg = "[dryRun] " + errorMsg;
2043  //errorMsg.replaceAll("\n", "\n[dryRun] ");
2044  //IOerrorMsg = "[dryRun] " + IOerrorMsg;
2045  //IOerrorMsg.replaceAll("\n", "\n[dryRun] ");
2046 
2047  Perr<< nl
2048  << "Missing/incorrect required dictionary entries:" << nl
2049  << nl
2050  << IOerrorMsg.c_str() << nl
2051  << errorMsg.c_str() << nl << nl
2052  << "Exiting dry-run" << nl << endl;
2053 
2054  FatalError.clear();
2055  FatalIOError.clear();
2056 
2057  return 0;
2058  }
2059  }
2060 
2061 
2062  Info<< "End\n" << endl;
2063 
2064  return 0;
2065 }
2066 
2067 
2068 // ************************************************************************* //
const IOdictionary & meshDict
bool contains(const T &val, label pos=0) const
Is the value contained in the list?
Definition: UListI.H:257
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:76
static bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, labelHashSet &wrongFaces, const bool dryRun=false)
Check mesh with mesh settings in dict. Collects incorrect faces.
static void mapCombineGather(const List< commsStruct > &comms, Container &values, const CombineOp &cop, const int tag, const label comm)
const polyBoundaryMesh & pbm
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
void printMeshInfo(const bool, const string &) const
Print some mesh stats.
label addFaceZone(const word &fzName, const word &masterPatch, const word &slavePatch, const surfaceZonesInfo::faceZoneType &fzType)
Add/lookup faceZone and update information. Return index of.
static void noFunctionObjects(bool addWithOption=false)
Remove &#39;-noFunctionObjects&#39; option and ignore any occurrences.
Definition: argList.C:547
static void reorderPatches(fvMesh &, const labelList &oldToNew, const label nPatches, const bool validBoundary)
Reorder and remove trailing patches.
Definition: fvMeshTools.C:317
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:462
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
static void removeFiles(const polyMesh &mesh)
Helper: remove all procAddressing files from mesh instance.
static const dictionary & subDict(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX)
Wrapper around dictionary::subDict which does not exit.
#define addProfiling(name, descr)
Define profiling trigger with specified name and description string.
fileName path() const
Return path.
Definition: Time.H:454
Simple container to keep together layer specific information.
uint8_t direction
Definition: direction.H:48
A line primitive.
Definition: line.H:52
void clear() const
Clear any messages.
Definition: error.C:321
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
A class for handling file names.
Definition: fileName.H:71
const labelList & surfaces() const
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:449
A list of face labels.
Definition: faceSet.H:47
virtual bool parallelAware() const =0
Is method parallel aware?
Identifies a surface patch/zone by name and index, with optional geometric type.
label checkTopology(const bool report) const
All topological checks. Return number of failed checks.
dimensionedScalar log(const dimensionedScalar &ds)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:500
bool getFaceZoneInfo(const word &fzName, label &masterPatchID, label &slavePatchID, surfaceZonesInfo::faceZoneType &fzType) const
Lookup faceZone information. Return false if no information.
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:162
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:472
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
static ITstream & lookup(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX)
Wrapper around dictionary::lookup which does not exit.
Implements a timeout mechanism via sigalarm.
Definition: timer.H:82
"ascii" (normal default)
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:632
wordList patchTypes(nPatches)
const word dictName("faMeshDefinition")
engineTime & runTime
Object access operator or list access operator.
Definition: UList.H:969
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
List< T > getList(const label index) const
Get a List of values from the argument at index.
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1004
Required Variables.
static writeType writeLevel()
Get/set write level.
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary.
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:423
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:374
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
static bool writeNow()
Write profiling information now.
Definition: profiling.C:129
static labelList addCellZonesToMesh(const PtrList< surfaceZonesInfo > &surfList, const labelList &namedSurfaces, polyMesh &mesh)
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:637
Base class of (analytical or triangulated) surface. Encapsulates all the search routines. WIP.
autoPtr< globalIndex > mergePoints(labelList &pointToGlobal, labelList &uniquePoints) const
Helper for merging (collocated!) mesh point data.
wordList regionNames
const labelList & minLevel() const
From global region number to refinement level.
Ignore writing from objectRegistry::writeObject()
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1029
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:300
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:362
label nFaces() const noexcept
Number of mesh faces.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
Simple container to keep together refinement specific information.
labelList faceLabels(nFaceLabels)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:453
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
autoPtr< dictionary > clone() const
Construct and return clone.
Definition: dictionary.C:165
bool processorCase() const noexcept
Return true if this is a processor case.
Definition: TimePathsI.H:29
scalar level0EdgeLength() const
Typical edge length between unrefined points.
Definition: hexRef8.H:499
wordList toc() const
Return the table of contents.
Definition: dictionary.C:599
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all processes in communicator.
const fvMesh & mesh() const
Reference to mesh.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:100
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
Container for data on surfaces used for surface-driven refinement. Contains all the data about the le...
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1073
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
Definition: UListI.H:52
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:37
static const Enum< writeType > writeTypeNames
Encapsulates queries for features.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:331
const dictionary & optionalSubDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary, otherwise return this dictionary.
Definition: dictionary.C:572
static autoPtr< coordSetWriter > New(const word &writeFormat)
Return a reference to the selected writer.
A list of faces which address into the list of points.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1020
Sends/receives parts of mesh+fvfields to neighbouring processors. Used in load balancing.
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
Definition: topoSet.C:618
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
static void gatherList(const List< commsStruct > &comms, List< T > &values, const int tag, const label comm)
Gather data, but keep individual values separate. Uses the specified communication schedule...
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
void setSize(const label n)
Alias for resize()
Definition: List.H:289
const keyType & keyword() const noexcept
Return keyword.
Definition: entry.H:231
FaceMergeType
Enumeration for what to do with co-planar patch faces on a single.
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
const pointField & points
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Definition: edge.H:59
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:31
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:584
A class for handling words, derived from Foam::string.
Definition: word.H:63
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a &#39;dry-run&#39; bool option, with usage information.
Definition: argList.C:504
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Simple container to keep together snap specific information.
int dryRun() const noexcept
Return the dry-run flag.
Definition: argListI.H:109
const labelList & gapLevel() const
From global region number to small gap refinement level.
const List< wordList > & regionNames() const
Region names per surface.
scalar mag() const
The magnitude/length of the bounding box diagonal.
Definition: boundBoxI.H:198
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:113
string message() const
The accumulated error message.
Definition: error.C:315
const word & system() const noexcept
Return system name.
Definition: TimePathsI.H:95
static void checkCoupledFaceZones(const polyMesh &)
Helper function: check that face zones are synced.
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
static const word null
An empty word.
Definition: word.H:84
Container for searchableSurfaces. The collection is specified as a dictionary. For example...
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:385
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Smanip< ios_base::fmtflags > setf(const ios_base::fmtflags flags)
Definition: IOmanip.H:169
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1300
Abstract base class for domain decomposition.
Encapsulates queries for volume refinement (&#39;refine all cells within shell&#39;).
Definition: shellSurfaces.H:53
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1098
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:68
const PtrList< surfaceZonesInfo > & surfZones() const
const vectorField & cellCentres() const
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: PtrList.H:159
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
Definition: wordRe.H:78
word timeName() const
Replacement for Time::timeName() that returns oldInstance (if overwrite_)
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
const hexRef8 & meshCutter() const
Reference to meshcutting engine.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
Istream and Ostream manipulators taking arguments.
static int readFlags(const EnumContainer &namedEnum, const wordList &words)
Helper: convert wordList into bit pattern using provided Enum.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
static word timeName(const scalar t, const int precision=precision_)
Return time name of given scalar time formatted with the given precision.
Definition: Time.C:770
const word & constant() const noexcept
Return constant name.
Definition: TimePathsI.H:89
int debug
Static debugging option.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
OBJstream os(runTime.globalPath()/outputName)
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:646
static bool clean(std::string &str)
Cleanup filename string, possibly applies other transformations such as changing the path separator e...
Definition: fileName.C:192
label addMeshedPatch(const word &name, const dictionary &)
Add patch originating from meshing. Update meshedPatches_.
labelList meshedPatches() const
Get patchIDs for patches added in addMeshedPatch.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:467
static const word canonicalName
The canonical name ("decomposeParDict") under which the MeshObject is registered. ...
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:416
labelList f(nPoints)
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Find and return a sub-dictionary as a copy, otherwise return an empty dictionary. ...
Definition: dictionary.C:533
All to do with adding layers.
double cpuTimeIncrement() const
Return CPU time (in seconds) since last call to cpuTimeIncrement()
Definition: cpuTimePosix.C:80
static void addFaceZones(meshRefinement &meshRefiner, const refinementParameters &refineParams, const HashTable< Pair< word >> &faceZoneToPatches)
Helper: add faceZones and patches.
IOstreamOption::streamFormat writeFormat() const noexcept
The write stream format.
Definition: Time.H:491
void updateIntersections(const labelList &changedFaces)
Find any intersection of surface. Store in surfaceIndex_.
messageStream Warning
Warning stream (stdout output on master, null elsewhere), with additional &#39;FOAM Warning&#39; header text...
void setCurvatureMinLevelFields(const scalar cosAngle, const scalar level0EdgeLength)
Update minLevelFields according to (triSurface-only) curvature.
Helper class which maintains intersections of (changing) mesh with (static) surfaces.
bool erase(T *item)
Remove the specified element from the list and delete it.
Definition: ILList.C:101
All to do with snapping to surface.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
static autoPtr< decompositionMethod > New(const dictionary &decompDict, const word &regionName="")
Return a reference to the selected decomposition method, optionally region-specific.
const wordList & names() const
Names of surfaces.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
label checkGeometry(const scalar maxRatio, const scalar tolerance, autoPtr< coordSetWriter > &setWriter, const scalar minQuality, const bool report) const
All geometric checks. Return number of failed checks.
label nCells() const noexcept
Number of mesh cells.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
const wordList & names() const
Surface names, not region names.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:79
A List with indirect addressing. Like IndirectList but does not store addressing. ...
Definition: faMatrix.H:56
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1037
Nothing to be read.
Automatically write from objectRegistry::writeObject()
const std::string patch
OpenFOAM patch number as a std::string.
label globalRegion(const label surfI, const label regionI) const
From surface and region on surface to global region.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
const entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:80
static const Enum< debugType > debugTypeNames
static labelList getNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces (surfaces with faceZoneName)
messageStream Info
Information stream (stdout output on master, null elsewhere)
const PtrList< dictionary > & patchInfo() const
From global region number to patch type.
writeType
Enumeration for what to write. Used as a bit-pattern.
const boundBox & bounds() const noexcept
Return mesh bounding box.
Definition: polyMesh.H:592
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
IOobject dictIO
faceZoneType
What to do with faceZone faces.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
debugType
Enumeration for what to debug. Used as a bit-pattern.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:777
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
word setFormat(propsDict.getOrDefault< word >("setFormat", "vtk"))
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
bool write() const
Write mesh and all data.
double elapsedCpuTime() const
Return CPU time (in seconds) from the start.
Definition: cpuTimePosix.C:73
List< label > labelList
A List of labels.
Definition: List.H:62
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void setMinLevelFields(const shellSurfaces &shells)
Calculate minLevelFields according to both surface- and.
Foam::argList args(argc, argv)
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
void writeStats(const List< wordList > &, Ostream &) const
Write some stats.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:458
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:171
Request registration (bool: true)
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:256
A primitive field of type <T> with automated input and output.
Regular expression.
Definition: keyType.H:83
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
List< treeBoundBox > meshBb(1, treeBoundBox(coarseMesh.points()).extend(rndGen, 1e-3))
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
static labelList removeEmptyPatches(fvMesh &, const bool validBoundary)
Remove zero sized patches. All but processor patches are.
Definition: fvMeshTools.C:363
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
Definition: IOobject.C:231
fileName globalPath() const
Return global path for the case.
Definition: TimePathsI.H:73
A HashTable to objects of type <T> with a label key.
const labelList & maxLevel() const
From global region number to refinement level.
label checkGeometry(const polyMesh &mesh, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:133
Starts timing CPU usage and return elapsed time from start.
Definition: cpuTimePosix.H:52