snappyHexMeshConfiguration.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2023-2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "Tuple3.H"
28 
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
32 {
33  dictionary dict("switches");
34 
35  dict.add("castellatedMesh", "on", true);
36  dict.add("snap", "on", true);
37  dict.add
38  (
39  "addLayers",
40  layers_.empty() ? "off" : "on",
41  true
42  );
43 
44  dict.write(os_, false);
45  os_ << endl;
46 }
47 
48 
50 {
51  beginDict(os_, surfaces_[surfID].name());
52 
53  os_ << indent << "type triSurface;" << nl
54  << indent << "file " << surfaces_[surfID].file() << ";" << endl;
55 
56  const wordList& inletRegions = surfaces_[surfID].inletRegions();
57  const wordList& outletRegions = surfaces_[surfID].outletRegions();
58 
59  if (!inletRegions.empty() || !outletRegions.empty())
60  {
61  beginDict(os_, "regions");
62 
63  forAll(inletRegions, i)
64  {
65  const word& region = inletRegions[i];
66  const word patch =
67  (
68  region == "<inletRegion>" || inletRegions.size() == 1
69  ? "inlet"
70  : region
71  );
72 
73  os_ << indent << region << " { name " << patch << "; }" << endl;
74  }
75 
76  forAll(outletRegions, i)
77  {
78  const word& region = outletRegions[i];
79  const word patch =
80  (
81  region == "<outletRegion>" || outletRegions.size() == 1
82  ? "outlet"
83  : region
84  );
85 
86  os_ << indent << region << " { name " << patch << "; }" << endl;
87  }
88 
89  endDict(os_, false);
90  }
91 
92  endDict(os_, false);
93 }
94 
95 
97 {
98  beginDict(os_, "box" + std::to_string(i));
99 
100  os_ << indent << "type box;" << nl
101  << indent << "min " << refinementBoxes_[i].first() << ";" << nl
102  << indent << "max " << refinementBoxes_[i].second() << ";" << endl;
103 
104  endDict(os_);
105 }
106 
107 
109 {
110  beginDict(os_, "geometry");
111 
112  forAll(surfaces_, i)
113  {
114  if (i != 0)
115  {
116  os_ << endl;
117  }
118 
119  writeGeometrySurface(i);
120  }
121 
122  forAll(refinementBoxes_, i)
123  {
124  os_ << endl;
125  writeSearchableBox(i);
126  }
127 
128  endDict(os_);
129 }
130 
131 
133 {
134  beginList(os_, "features");
135 
136  if (explicitFeatures_)
137  {
138  forAll(surfaces_, i)
139  {
140  fileName eMeshFile(surfaces_[i].name() + ".eMesh");
141  os_ << indent << "{ file " << eMeshFile
142  << "; level 1; }" << endl;
143  }
144  }
145 
146  endList(os_);
147 }
148 
149 
151 (
152  const label rl
153 )
154 {
155  os_ << indent << "level (" << rl << " " << rl << ");" << endl;
156 }
157 
158 
160 {
161  writeRefinementSurfacesLevel(refinementLevel_);
162 }
163 
164 
166 (
167  const word& name
168 )
169 {
170  label rl(refinementLevel_);
171 
172  forAll(surfaceLevels_, i)
173  {
174  if (surfaceLevels_[i].first() == name)
175  {
176  rl = surfaceLevels_[i].second();
177  break;
178  }
179  }
180 
181  writeRefinementSurfacesLevel(rl);
182 }
183 
184 
186 (
187  const word& type,
188  const word& group
189 )
190 {
191  if (group.empty())
192  {
193  os_ << indent << "patchInfo { type " << type << "; }" << endl;
194  }
195  else
196  {
197  beginDict(os_, "patchInfo");
198  os_ << indent << "type "<< type << ";" << endl;
199  os_ << indent << "inGroups (" << group << ");" << endl;
200  endDict(os_, false);
201  }
202 }
203 
204 
206 (
207  const word regionName,
208  const List<word>& regions
209 )
210 {
211  switch (regions.size())
212  {
213  case 0:
214  {
215  return;
216  }
217  case 1:
218  {
219  os_ << indent << regions[0] << endl;
220  break;
221  }
222  default:
223  {
224  os_ << indent << "\"" << regionName << ".*\"" << endl;
225  }
226  }
227 
228  beginDict(os_);
229  writeRefinementSurfacesLevel();
230 
231  word group(regionName);
232  if (regions.size() == 1 && regions[0] == regionName)
233  {
234  group = "";
235  }
236 
237  writePatchInfo("patch", group);
238 
239  endDict(os_, false);
240 }
241 
242 
244 (
245  const wordList& inletRegions,
246  const wordList& outletRegions
247 )
248 {
249  if (inletRegions.empty() && outletRegions.empty())
250  {
251  return;
252  }
253 
254  os_ << endl;
255  beginDict(os_, "regions");
256  writeRefinementSurfacesRegion("inlet", inletRegions);
257  writeRefinementSurfacesRegion("outlet", outletRegions);
258  endDict(os_, false);
259 }
260 
261 
263 {
264  beginDict(os_, "refinementSurfaces");
265 
266  forAll(surfaces_, i)
267  {
268  if (i != 0)
269  {
270  os_ << endl;
271  }
272 
273  const word& name = surfaces_[i].name();
274 
275  beginDict(os_, name);
276 
277  writeRefinementSurfacesLevel(name);
278 
279  const wordList& inletRegions = surfaces_[i].inletRegions();
280  const wordList& outletRegions = surfaces_[i].outletRegions();
281 
282  switch (surfaces_[i].type())
283  {
284  case surfaceType::wall:
285  {
286  writePatchInfo("wall");
287  writeRefinementSurfacesRegions(inletRegions, outletRegions);
288  break;
289  }
290 
291  case surfaceType::external:
292  {
293  writePatchInfo("wall", "externalWall");
294  writeRefinementSurfacesRegions(inletRegions, outletRegions);
295  break;
296  }
297 
298  case surfaceType::cellZone:
299  case surfaceType::rotatingZone:
300  {
301  os_ << indent << "faceZone "
302  << surfaces_[i].name() << ";" << nl
303  << indent << "cellZone "
304  << surfaces_[i].name() << ";" << nl
305  << indent << "mode inside;" << endl;
306 
307  break;
308  }
309 
310  case surfaceType::baffle:
311  {
312  writePatchInfo("wall");
313 
314  os_ << indent << "faceZone "
315  << surfaces_[i].name() << ";" << nl
316  << indent << "faceType boundary;" << endl;
317 
318  break;
319  }
320  }
321 
322  endDict(os_, false);
323  }
324 
325  endDict(os_);
326 }
327 
328 
330 (
331  const word& name,
332  const label level
333 )
334 {
335  beginDict(os_, name);
336 
337  os_ << indent << "mode inside;" << nl
338  << indent << "level " << level << ";" << endl;
339 
340  endDict(os_, false);
341 }
342 
343 
345 {
346  if
347  (
348  refinementRegions_.empty()
349  && refinementBoxes_.empty()
350  && refinementDists_.empty()
351  )
352  {
353  os_ << indent
354  << "// delete \"-disabled\" below to enable refinementRegions"
355  << endl;
356 
357  beginDict(os_, "refinementRegions-disabled");
358  writeRefinementRegion("<surface>", refinementLevel_);
359  endDict(os_);
360  }
361  else
362  {
363  beginDict(os_, "refinementRegions");
364 
365  forAll(refinementRegions_, i)
366  {
367  writeRefinementRegion
368  (
369  refinementRegions_[i].first(),
370  refinementRegions_[i].second()
371  );
372  }
373 
374  forAll(refinementBoxes_, i)
375  {
376  writeRefinementRegion
377  (
378  "box" + std::to_string(i),
379  refinementBoxes_[i].third()
380  );
381  }
382 
383  forAll(refinementDists_, i)
384  {
385  beginDict(os_, refinementDists_[i].first());
386 
387  os_ << indent << "mode distance;" << nl
388  << indent << "levels (("
389  << refinementDists_[i].second() << " "
390  << refinementDists_[i].third() << "));" << endl;
391 
392  endDict(os_, false);
393  }
394 
395  endDict(os_);
396  }
397 }
398 
399 
401 {
402  beginDict(os_, "castellatedMeshControls");
403 
404  writeFeatures();
405  writeRefinementSurfaces();
406  writeRefinementRegions();
407 
408  // Needs customising
409  if (insidePointsOpt_)
410  {
411  beginList(os_, "insidePoints");
412 
413  forAll(insidePoints_, i)
414  {
415  os_ << indent << insidePoints_[i] << endl;
416  }
417 
418  endList(os_);
419  }
420  else
421  {
422  os_ << indent << "insidePoint "
423  << insidePoints_[0] << ";" << endl;
424  }
425 
426  os_ << indent << "nCellsBetweenLevels "
427  << nCellsBetweenLevels_
428  << ";" << endl;
429 
430  endDict(os_);
431 }
432 
433 
435 {
436  beginDict(os_, "snapControls");
437 
438  os_ << indent << "explicitFeatureSnap "
439  << (explicitFeatures_ ? "on" : "off") << ";" << endl;
440  os_ << indent << "implicitFeatureSnap "
441  << (explicitFeatures_ ? "off" : "on") << ";" << endl;
442 
443  endDict(os_);
444 }
445 
446 
448 {
449  // Include addLayersControls sub-dict with zero layers when layers are
450  // switched off, so they can be conveniently switched on later.
451 
452  beginDict(os_, "addLayersControls");
453 
454  beginDict(os_, "layers");
455 
456  if (layers_.empty())
457  {
458  // Add convenient entries with zero layers if layers are switched off.
459  forAll(surfaces_, i)
460  {
461  switch (surfaces_[i].type())
462  {
463  case surfaceType::wall:
464  case surfaceType::external:
465  case surfaceType::baffle:
466  {
467  os_ << indent << "\"" << surfaces_[i].name()
468  << ".*\" { nSurfaceLayers 0; }" << endl;
469  break;
470  }
471  default: break;
472  }
473  }
474  }
475  else
476  {
477  // Add entries for specified surfaces.
478  forAll(layers_, i)
479  {
480  os_ << indent << "\"" << layers_[i].first()
481  << ".*\" { nSurfaceLayers "
482  << layers_[i].second() << "; }" << endl;
483  }
484  }
485 
486  endDict(os_);
487 
488  bool relativeSizes(firstLayerThickness_ == 0);
489 
490  // relativeSizes
491  os_ << indent << "relativeSizes "
492  << (
493  relativeSizes
494  ? "on; // off, usually with firstLayerThickness"
495  : "off; // on, usually with finalLayerThickness"
496  ) << endl;
497 
498  // expansionRatio
499  os_ << indent << "expansionRatio "<< layerExpansionRatio_
500  << ";" << endl;
501 
502  // finalLayerThickness
503  os_ << indent << "finalLayerThickness"
504  << (relativeSizes ? " " : "-disabled ") << "0.5;" << endl;
505 
506  // minimumThickness
507  os_ << indent << "minThickness "
508  << (relativeSizes ? scalar(0.001) : 0.5*firstLayerThickness_)
509  << ";" << endl;
510 
511  // firstLayerThickness
512  os_ << indent << "firstLayerThickness"
513  << (relativeSizes ? "-disabled " : " ")
514  << firstLayerThickness_ << ";" << endl;
515 
516  // maxThicknessToMedialRatio
517  os_ << indent << "maxThicknessToMedialRatio-disabled 0.3;" << endl;
518 
519  endDict(os_);
520 }
521 
522 
524 {
525  os_ << "// delete \"-disabled\" to output mesh data, e.g. for layers"
526  << endl;
527 
528  beginList(os_, "writeFlags-disabled");
529  os_ << indent << "scalarLevels" << endl;
530  os_ << indent << "layerSets" << endl;
531  os_ << indent << "layerFields" << endl;
532  endList(os_);
533 }
534 
535 
536 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
537 
539 (
540  const fileName& name,
541  const fileName& dir,
542  const Time& time,
543  const meshingSurfaceList& surfaces,
544  const label refinementLevel,
545  const List<Tuple2<word, label>>& surfaceLevels,
546  const List<Tuple2<word, label>>& refinementRegions,
547  const List<Tuple3<vector, vector, label>>& refinementBoxes,
548  const List<Tuple3<word, scalar, label>>& refinementDists,
549  const bool explicitFeatures,
550  const List<Tuple2<word, label>>& layers,
551  const scalar firstLayerThickness,
552  const scalar layerExpansionRatio,
553  const bool insidePointsOpt,
554  const List<point>& insidePoints,
555  const label nCellsBetweenLevels
556 )
557 :
558  caseFileConfiguration(name, dir, time),
559  surfaces_(surfaces),
560  refinementLevel_(refinementLevel),
561  surfaceLevels_(surfaceLevels),
562  refinementRegions_(refinementRegions),
563  refinementBoxes_(refinementBoxes),
564  refinementDists_(refinementDists),
565  explicitFeatures_(explicitFeatures),
566  layers_(layers),
567  firstLayerThickness_(firstLayerThickness),
568  layerExpansionRatio_(layerExpansionRatio),
569  insidePointsOpt_(insidePointsOpt),
570  insidePoints_(insidePoints),
571  nCellsBetweenLevels_(nCellsBetweenLevels)
572 {}
573 
574 
575 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
576 
578 {}
579 
580 
581 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
582 
584 {
585  dict_.writeHeader(os_, word("dictionary"));
586  os_ << "#includeEtc \"caseDicts/mesh/generation/snappyHexMeshDict.cfg\""
587  << nl << endl;
588  writeSnappySwitches();
589  writeSnappyGeometry();
590  writeCastellatedMeshControls();
591  writeSnapControls();
592  writeAddLayersControls();
593  writeWriteFlags();
594 
595  os_ << "mergeTolerance 1e-6;";
596 
597  dict_.writeEndDivider(os_);
598 }
599 
600 
601 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
OFstream os_
Output file stream to write file content.
void writeFeatures()
Write features list in castellatedMeshControls.
void writePatchInfo(const word &type, const word &group="")
Write refinementSurfaces wall patchInfo entry.
void writeRefinementSurfacesLevel()
Write refinementSurfaces level entry using refinementLevel_.
void writeSnappySwitches()
Write switches.
void writeRefinementSurfacesRegion(const word regionName, const List< word > &regions)
Write a refinement surface region.
void writeRefinementRegions()
Write refinementRegions.
void writeSearchableBox(const label i)
Write searchableBox entry for geometry sub-dictionary.
void writeRefinementSurfaces()
Write refinementSurfaces.
const List< Tuple2< word, label > > layers_
Number of layers on specified surfaces.
void writeRefinementSurfacesRegions(const wordList &inletRegions, const wordList &outletRegions)
Write refinement surface region information.
void writeSnapControls()
Write snapControls.
void writeSnappyGeometry()
Write geometry sub-dictionary.
snappyHexMeshConfiguration(const fileName &name, const fileName &dir, const Time &time, const meshingSurfaceList &surfaces, const label refinementLevel, const List< Tuple2< word, label >> &surfaceLevels, const List< Tuple2< word, label >> &refinementRegions, const List< Tuple3< vector, vector, label >> &refinementBoxes, const List< Tuple3< word, scalar, label >> &refinementDists, const bool explicitFeatures, const List< Tuple2< word, label >> &layers, const scalar firstLayerThickness, const scalar layerExpansionRatio, const bool insidePointsOpt, const List< point > &insidePoints, const label nCellsBetweenLevels)
Construct from components.
void writeRefinementRegion(const word &name, const label level)
Write a refinement region.
void writeWriteFlags()
Write writeFlags.
void writeAddLayersControls()
Write addLayersControls.
void writeGeometrySurface(const label surfID)
Write surface entry for geometry sub-dictionary.
void writeCastellatedMeshControls()
Write castellatedMeshControls.
const char *const group
Group name for atomic constants.
List< word > wordList
A List of words.
Definition: fileName.H:54
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
const word & regionName(const solver &region)
Definition: solver.H:218
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:228
static const char nl
Definition: Ostream.H:267
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
insidePoints((1 2 3))
dictionary dict