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