blockMeshCylindricalConfiguration.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-2026 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 "dictionary.H"
28 #include "polyPatch.H"
29 #include "wallPolyPatch.H"
30 #include "blockMeshFunctions.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
35  {"zMin", "zMax"};
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 void Foam::blockMeshCylindricalConfiguration::bbInflate
41 (
42  boundBox& bb,
43  const vector& s
44 )
45 {
46  bb.min() = cmptMultiply(s, bb.min());
47  bb.max() = cmptMultiply(s, bb.max());
48 }
49 
50 bool Foam::blockMeshCylindricalConfiguration::isBoundBoxOnZaxis()
51 {
52  const vector bbMidNorm = bb_.midpoint()/bb_.mag();
53  return mag(bbMidNorm.x()) < rootSmall && mag(bbMidNorm.y()) < rootSmall;
54 }
55 
56 void Foam::blockMeshCylindricalConfiguration::calcBlockMeshDict
57 (
58  const bool& boundsOpt,
59  const bool& rotatingZonesOpt
60 )
61 {
62  // Set nCells as a vector: (boxCells radialCells zCells)
63  label boxCells = nCells_.x();
64  label radialCells = nCells_.y();
65 
66  if (nCells_ == Vector<label>::zero)
67  {
68  boxCells = 5;
69  radialCells = 15;
70 
71  nCells_ = Vector<label>
72  (
73  boxCells,
74  radialCells,
75  2.0*radialCells*bb_.span().z()/bb_.span().x()
76  );
77  }
78 
79  // Size the bounding box
80  const scalar roundFactor = roundingScale(0.01*bb_.minDim());
81 
82  // If '-bounds' is not specified, or '-rotatingZones' is specified
83  // inflate the respective bounding box(es) in radial direction,
84  // followed by rounding
85  if(!boundsOpt || rotatingZonesOpt)
86  {
87  const scalar expansion = 1.0/(Foam::cos(degToRad(45.0/nCells_.x())));
88  const vector scaling(expansion, expansion, 1);
89 
90  if(!boundsOpt)
91  {
92  bbInflate(bb_, scaling);
93  roundBoundingBox(bb_, roundFactor);
94  }
95  if(rotatingZonesOpt)
96  {
97  bbInflate(rzbb_, scaling);
98  roundBoundingBox(rzbb_, roundFactor);
99  }
100  }
101 
102  radBox_ = ceil(0.3*rzbb_.max().x()/roundFactor)*roundFactor;
103  nCells_ *= refineFactor_;
104 }
105 
106 
107 void Foam::blockMeshCylindricalConfiguration::writeBackgroundMesh()
108 {
109  const scalar radOut = bb_.max().x();
110  const scalar radIn = rzbb_.max().x();
111  const scalar boxToRadOut = radOut - radBox_;
112  const scalar boxToRadIn = radIn - radBox_;
113 
114  const label inCells = ceil(boxToRadIn*nCells_.y()/boxToRadOut);
115  const label outCells = nCells_.y() - inCells;
116 
117  beginDict(os_, "backgroundMesh");
118 
119  os_ << indent << "radOut " << radOut << ";" << endl;
120  os_ << indent << "radIn " << radIn << ";" << endl;
121  os_ << indent << "radBox " << radBox_ << ";" << nl << endl;
122  os_ << indent << "zMin " << bb_.min().z() << ";" << endl;
123  os_ << indent << "zMax " << bb_.max().z() << ";" << nl << endl;
124  os_ << indent << "boxCells " << nCells_.x() << ";" << endl;
125  os_ << indent << "inCells " << inCells << ";" << endl;
126  os_ << indent << "outCells " << outCells << ";" << endl;
127  os_ << indent << "zCells " << nCells_.z() << ";" << nl << endl;
128  os_ << indent << "outGrading 2.0;" << nl << endl;
129  os_ << indent << "radOutN #neg $radOut;" << endl;
130  os_ << indent << "radInN #neg $radIn;" << endl;
131  os_ << indent << "radBoxN #neg $radBox;" << endl;
132 
133  endDict(os_);
134 }
135 
136 
137 void Foam::blockMeshCylindricalConfiguration::writeDefaultPatch()
138 {
139  Pair<word> defaultPatch;
140 
141  word opt = "defaultPatch";
142  if (patchOpts_.found(opt))
143  {
144  defaultPatch = readPatchOption(opt);
145  }
146  else
147  {
148  defaultPatch = {"background", "internal"};
149  }
150 
151  beginDict(os_, "defaultPatch");
152 
153  os_ << indent << "name " << defaultPatch.first() << ";" << nl
154  << indent << "type " << defaultPatch.second() << ";" << endl;
155 
156  endDict(os_);
157 
158  Info<< "\nAdding defaultPatch '" << defaultPatch.first()
159  << "' of type '" << defaultPatch.second() << "'" << endl;
160 }
161 
162 
163 void Foam::blockMeshCylindricalConfiguration::writePatch
164 (
165  const word& name,
166  const word& type,
167  const string& face
168 )
169 {
170  os_ << indent << name
171  << " { type " << type
172  << "; faces ( " << face.c_str()
173  << " ); }" << endl;
174 
175  Info<< "Adding patch '" << name
176  << "' of type '" << type << "'" << endl;
177 }
178 
179 
180 void Foam::blockMeshCylindricalConfiguration::writeBoundary()
181 {
182  // Enable boundary section if a patch option or clearBoundary is selected
183  bool enableBoundary = clearBoundary_;
184  forAll(patches, i)
185  {
186  if (enableBoundary)
187  {
188  break;
189  }
190 
191  enableBoundary = patchOpts_.found(patches[i] + "Patch");
192  }
193 
194  if (!enableBoundary)
195  {
196  os_ << "// delete \"-disabled\" to enable boundary settings" << endl;
197 
198  Info<< "\nNote: The boundary list in blockMeshDict is disabled" << nl
199  << "To enable, open the file and edit line number "
200  << os_.lineNumber() << nl << endl;
201  }
202 
203  beginList
204  (
205  os_,
206  enableBoundary ? "boundary" : "boundary-disabled"
207  );
208 
209  forAll(patches, i)
210  {
211  const bool optFound(patchOpts_.found(patches[i] + "Patch"));
212 
213  // Do not write patch entry if clearBoundary option is selected
214  // and the respective patch option is not selected
215  if (clearBoundary_ && !optFound)
216  {
217  continue;
218  }
219 
220  Pair<word> patch(patches[i], "patch");
221 
222  if (optFound)
223  {
224  patch = readPatchOption(patch.first() + "Patch");
225  }
226 
227  beginDict(os_, patch.first());
228  os_ << indent << "type " << patch.second() << ";" << endl;
229  beginList(os_, "faces");
230 
231  switch (i)
232  {
233  case 0:
234  {
235  os_ << indent << "(0 1 2 3)" << nl
236  << indent << "(0 4 5 1)" << nl
237  << indent << "(1 5 6 2)" << nl
238  << indent << "(2 6 7 3)" << nl
239  << indent << "(3 7 4 0)" << nl
240  << indent << "(4 8 9 5)" << nl
241  << indent << "(5 9 10 6)" << nl
242  << indent << "(6 10 11 7)" << nl
243  << indent << "(7 11 8 4)" << endl;
244  break;
245  }
246 
247  case 1:
248  {
249  os_ << indent << "(12 13 14 15)" << nl
250  << indent << "(12 16 17 13)" << nl
251  << indent << "(13 17 18 14)" << nl
252  << indent << "(14 18 19 15)" << nl
253  << indent << "(15 19 16 12)" << nl
254  << indent << "(16 20 21 17)" << nl
255  << indent << "(17 21 22 18)" << nl
256  << indent << "(18 22 23 19)" << nl
257  << indent << "(19 23 20 16)" << endl;
258  break;
259  }
260  }
261 
262  endList(os_, false);
263  endDict(os_, i != 1);
264  }
265 
266  endList(os_);
267 }
268 
269 
270 void Foam::blockMeshCylindricalConfiguration::writeGeometry()
271 {
272  beginDict(os_, "geometry");
273 
274  List<word> geometries {"rotatingZone", "outer"};
275  List<word> dims {"radIn", "radOut"};
276 
277  scalar zMin = roundDown(bb_.min().z(), 10);
278  scalar zMax = roundUp(bb_.max().z(), 10);
279 
280  // Extend the bounds to avoid bad projections
281  const scalar span = zMax - zMin;
282  zMax += span;
283  zMin -= span;
284 
285  forAll(geometries, i)
286  {
287  beginDict(os_, geometries[i]);
288 
289  os_ << indent << "type cylinder;" << nl
290  << indent << "point1 (0 0 " << zMin << ");" << nl
291  << indent << "point2 (0 0 " << zMax << ");" << nl
292  << indent << "radius $!backgroundMesh/" << dims[i] << ";" << endl;
293 
294  endDict(os_);
295  }
296 
297  endDict(os_);
298 }
299 
300 
301 void Foam::blockMeshCylindricalConfiguration::writeProjectedVertex
302 (
303  const word& x,
304  const word& y,
305  const word& z,
306  const word& surface
307 )
308 {
309  os_ << indent << "project" << endl;
310  writeVertex(x, y, z);
311  os_ << indent << "(" << surface << ")" << nl << endl;
312 }
313 
314 
315 void Foam::blockMeshCylindricalConfiguration::writeVertices()
316 {
317  beginList(os_, "vertices");
318 
319  forAll(patches, i)
320  {
321  const word& dir = patches[i];
322 
323  writeVertex("radBoxN", "radBoxN", dir);
324  writeVertex("radBox", "radBoxN", dir);
325  writeVertex("radBox", "radBox", dir);
326  writeVertex("radBoxN", "radBox", dir);
327 
328  os_ << endl;
329 
330  writeProjectedVertex("radInN", "radInN", dir, "rotatingZone");
331  writeProjectedVertex("radIn", "radInN", dir, "rotatingZone");
332  writeProjectedVertex("radIn", "radIn", dir, "rotatingZone");
333  writeProjectedVertex("radInN", "radIn", dir, "rotatingZone");
334 
335  writeProjectedVertex("radOutN", "radOutN", dir, "outer");
336  writeProjectedVertex("radOut", "radOutN", dir, "outer");
337  writeProjectedVertex("radOut", "radOut", dir, "outer");
338  writeProjectedVertex("radOutN", "radOut", dir, "outer");
339  }
340 
341  endList(os_);
342 }
343 
344 
345 void Foam::blockMeshCylindricalConfiguration::writeBlocks()
346 {
347  os_ << "boxMesh" << endl;
348  writeVertex("boxCells", "boxCells", "zCells");
349  os_ << "simpleGrading (1 1 1);" << nl << endl;
350 
351  os_ << "inMesh" << endl;
352  writeVertex("boxCells", "inCells", "zCells");
353  os_ << "simpleGrading (1 1 1);" << nl << endl;
354 
355  os_ << "outMesh" << endl;
356  writeVertex("boxCells", "outCells", "zCells");
357  os_ << "simpleGrading (1 $!backgroundMesh/outGrading 1);" << nl << endl;
358 
359  beginList(os_, "blocks");
360 
361  os_ << indent << "hex (0 1 2 3 12 13 14 15) $boxMesh" << nl << nl
362  << indent << "hex (1 0 4 5 13 12 16 17) $inMesh" << nl
363  << indent << "hex (0 3 7 4 12 15 19 16) $inMesh" << nl
364  << indent << "hex (2 1 5 6 14 13 17 18) $inMesh" << nl
365  << indent << "hex (3 2 6 7 15 14 18 19) $inMesh" << nl << nl
366  << indent << "hex (5 4 8 9 17 16 20 21) $outMesh" << nl
367  << indent << "hex (4 7 11 8 16 19 23 20) $outMesh" << nl
368  << indent << "hex (6 5 9 10 18 17 21 22) $outMesh" << nl
369  << indent << "hex (7 6 10 11 19 18 22 23) $outMesh" << endl;
370 
371  endList(os_);
372 }
373 
374 
375 void Foam::blockMeshCylindricalConfiguration::writeEdges()
376 {
377  beginList(os_, "edges");
378 
379  os_ << indent << "project 4 5 (rotatingZone)" << nl
380  << indent << "project 5 6 (rotatingZone)" << nl
381  << indent << "project 6 7 (rotatingZone)" << nl
382  << indent << "project 7 4 (rotatingZone)" << nl
383  << indent << "project 16 17 (rotatingZone)" << nl
384  << indent << "project 17 18 (rotatingZone)" << nl
385  << indent << "project 18 19 (rotatingZone)" << nl
386  << indent << "project 19 16 (rotatingZone)" << nl << nl
387  << indent << "project 8 9 (outer)" << nl
388  << indent << "project 9 10 (outer)" << nl
389  << indent << "project 10 11 (outer)" << nl
390  << indent << "project 11 8 (outer)" << nl
391  << indent << "project 20 21 (outer)" << nl
392  << indent << "project 21 22 (outer)" << nl
393  << indent << "project 22 23 (outer)" << nl
394  << indent << "project 23 20 (outer)" << endl;
395 
396  endList(os_);
397 }
398 
399 
400 void Foam::blockMeshCylindricalConfiguration::writeMergePatchPairs()
401 {
402  os_ << "mergePatchPairs" << nl
403  << "(" << nl
404  << ");" << endl;
405 }
406 
407 
408 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
409 
411 (
412  const fileName& name,
413  const fileName& dir,
414  const Time& time,
415  const meshingSurfaceList& surfaces,
416  const bool& boundsOpt,
417  const Vector<label>& nCells,
418  const label refineFactor,
419  const HashTable<Pair<word>>& patchOpts,
420  const bool clearBoundary
421 )
422 :
423  blockMeshConfigurationBase(name, dir, time, surfaces, patchOpts),
424  rzbb_(surfaces.rzbb()),
425  nCells_(nCells),
426  refineFactor_(refineFactor),
427  clearBoundary_(clearBoundary)
428 {
429  if (!isBoundBoxOnZaxis())
430  {
432  << "Attempting to create a cylindrical background mesh"
433  << nl << "but the geometry bounds are not aligned with the z-axis."
434  << exit(FatalError);
435  }
436 
437  bool rotatingZonesOpt(true);
438 
439  if (rzbb_.volume() == 0)
440  {
441  rotatingZonesOpt = false;
442 
444  << "Creating a cylindrical background mesh without a "
445  << "rotatingZone specified by the '-rotatingZones' option."
446  << nl <<endl;
447 
448  // Create the intermediate interface at 40% of domain size if no
449  // rotating zone is specified
450  scalar factor = 0.4;
451 
452  rzbb_.min() = factor*bb_.min();
453  rzbb_.max() = factor*bb_.max();
454  }
455 
456  calcBlockMeshDict(boundsOpt, rotatingZonesOpt);
457 }
458 
459 
460 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
461 
463 {}
464 
465 
466 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
467 
469 {
470  dict_.writeHeader(os_, word("dictionary"));
471 
472  writeBackgroundMesh();
473  writeDefaultPatch();
474  writeBoundary();
475  writeGeometry();
476  writeVertices();
477  writeBlocks();
478  writeEdges();
479  writeMergePatchPairs();
480 
481  dict_.writeEndDivider(os_);
482 }
483 
484 
485 // ************************************************************************* //
scalar y
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Functions for calculating the bounds and number of cells of a background mesh configured within a blo...
static const Form zero
Definition: VectorSpace.H:118
static const List< word > patches
Default patch names for the background mesh.
blockMeshCylindricalConfiguration(const fileName &name, const fileName &dir, const Time &time, const meshingSurfaceList &surfaces, const bool &boundsOpt, const Vector< label > &nCells, const label refineFactor, const HashTable< Pair< word >> &patchOpts, const bool clearBoundary)
Construct from components.
Motion of the mesh specified as a list of pointMeshMovers.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const fvPatchList & patches
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionSet time
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
scalar degToRad(const scalar deg)
Convert degrees to radians.
Definition: units.C:364
scalar roundDown(const scalar x, const scalar s)
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:288
tmp< DimensionedField< Type, GeoMesh, Field > > cmptMultiply(const DimensionedField< Type, GeoMesh, PrimitiveField1 > &df1, const DimensionedField< Type, GeoMesh, PrimitiveField2 > &df2)
messageStream Info
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
scalar roundUp(const scalar x, const scalar s)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
error FatalError
scalar roundingScale(const scalar s)
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:243
static const char nl
Definition: Ostream.H:297
dimensionedScalar cos(const dimensionedScalar &ds)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488