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-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 "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  os_ << "convertToMeters 1;" << nl << endl;
136 }
137 
138 
139 void Foam::blockMeshCylindricalConfiguration::writeDefaultPatch()
140 {
141  Pair<word> defaultPatch;
142 
143  word opt = "defaultPatch";
144  if (patchOpts_.found(opt))
145  {
146  defaultPatch = readPatchOption(opt);
147  }
148  else
149  {
150  defaultPatch = {"background", "internal"};
151  }
152 
153  beginDict(os_, "defaultPatch");
154 
155  os_ << indent << "name " << defaultPatch.first() << ";" << nl
156  << indent << "type " << defaultPatch.second() << ";" << endl;
157 
158  endDict(os_);
159 
160  Info<< "\nAdding defaultPatch '" << defaultPatch.first()
161  << "' of type '" << defaultPatch.second() << "'" << endl;
162 }
163 
164 
165 void Foam::blockMeshCylindricalConfiguration::writePatch
166 (
167  const word& name,
168  const word& type,
169  const string& face
170 )
171 {
172  os_ << indent << name
173  << " { type " << type
174  << "; faces ( " << face.c_str()
175  << " ); }" << endl;
176 
177  Info<< "Adding patch '" << name
178  << "' of type '" << type << "'" << endl;
179 }
180 
181 
182 void Foam::blockMeshCylindricalConfiguration::writeBoundary()
183 {
184  // Enable boundary section if a patch option or clearBoundary is selected
185  bool enableBoundary = clearBoundary_;
186  forAll(patches, i)
187  {
188  if (enableBoundary)
189  {
190  break;
191  }
192 
193  enableBoundary = patchOpts_.found(patches[i] + "Patch");
194  }
195 
196  if (!enableBoundary)
197  {
198  os_ << "// delete \"-disabled\" to enable boundary settings" << endl;
199 
200  Info<< "\nNote: The boundary list in blockMeshDict is disabled" << nl
201  << "To enable, open the file and edit line number "
202  << os_.lineNumber() << nl << endl;
203  }
204 
205  beginList
206  (
207  os_,
208  enableBoundary ? "boundary" : "boundary-disabled"
209  );
210 
211  forAll(patches, i)
212  {
213  const bool optFound(patchOpts_.found(patches[i] + "Patch"));
214 
215  // Do not write patch entry if clearBoundary option is selected
216  // and the respective patch option is not selected
217  if (clearBoundary_ && !optFound)
218  {
219  continue;
220  }
221 
222  Pair<word> patch(patches[i], "patch");
223 
224  if (optFound)
225  {
226  patch = readPatchOption(patch.first() + "Patch");
227  }
228 
229  beginDict(os_, patch.first());
230  os_ << indent << "type " << patch.second() << ";" << endl;
231  beginList(os_, "faces");
232 
233  switch (i)
234  {
235  case 0:
236  {
237  os_ << indent << "(0 1 2 3)" << nl
238  << indent << "(0 4 5 1)" << nl
239  << indent << "(1 5 6 2)" << nl
240  << indent << "(2 6 7 3)" << nl
241  << indent << "(3 7 4 0)" << nl
242  << indent << "(4 8 9 5)" << nl
243  << indent << "(5 9 10 6)" << nl
244  << indent << "(6 10 11 7)" << nl
245  << indent << "(7 11 8 4)" << endl;
246  break;
247  }
248 
249  case 1:
250  {
251  os_ << indent << "(12 13 14 15)" << nl
252  << indent << "(12 16 17 13)" << nl
253  << indent << "(13 17 18 14)" << nl
254  << indent << "(14 18 19 15)" << nl
255  << indent << "(15 19 16 12)" << nl
256  << indent << "(16 20 21 17)" << nl
257  << indent << "(17 21 22 18)" << nl
258  << indent << "(18 22 23 19)" << nl
259  << indent << "(19 23 20 16)" << endl;
260  break;
261  }
262  }
263 
264  endList(os_, false);
265  endDict(os_, i != 1);
266  }
267 
268  endList(os_);
269 }
270 
271 
272 void Foam::blockMeshCylindricalConfiguration::writeGeometry()
273 {
274  beginDict(os_, "geometry");
275 
276  List<word> geometries {"rotatingZone", "outer"};
277  List<word> dims {"radIn", "radOut"};
278 
279  scalar zMin = roundDown(bb_.min().z(), 10);
280  scalar zMax = roundUp(bb_.max().z(), 10);
281 
282  // Extend the bounds to avoid bad projections
283  const scalar span = zMax - zMin;
284  zMax += span;
285  zMin -= span;
286 
287  forAll(geometries, i)
288  {
289  beginDict(os_, geometries[i]);
290 
291  os_ << indent << "type cylinder;" << nl
292  << indent << "point1 (0 0 " << zMin << ");" << nl
293  << indent << "point2 (0 0 " << zMax << ");" << nl
294  << indent << "radius $!backgroundMesh/" << dims[i] << ";" << endl;
295 
296  endDict(os_);
297  }
298 
299  endDict(os_);
300 }
301 
302 
303 void Foam::blockMeshCylindricalConfiguration::writeProjectedVertex
304 (
305  const word& x,
306  const word& y,
307  const word& z,
308  const word& surface
309 )
310 {
311  os_ << indent << "project" << endl;
312  writeVertex(x, y, z);
313  os_ << indent << "(" << surface << ")" << nl << endl;
314 }
315 
316 
317 void Foam::blockMeshCylindricalConfiguration::writeVertices()
318 {
319  beginList(os_, "vertices");
320 
321  forAll(patches, i)
322  {
323  const word& dir = patches[i];
324 
325  writeVertex("radBoxN", "radBoxN", dir);
326  writeVertex("radBox", "radBoxN", dir);
327  writeVertex("radBox", "radBox", dir);
328  writeVertex("radBoxN", "radBox", dir);
329 
330  os_ << endl;
331 
332  writeProjectedVertex("radInN", "radInN", dir, "rotatingZone");
333  writeProjectedVertex("radIn", "radInN", dir, "rotatingZone");
334  writeProjectedVertex("radIn", "radIn", dir, "rotatingZone");
335  writeProjectedVertex("radInN", "radIn", dir, "rotatingZone");
336 
337  writeProjectedVertex("radOutN", "radOutN", dir, "outer");
338  writeProjectedVertex("radOut", "radOutN", dir, "outer");
339  writeProjectedVertex("radOut", "radOut", dir, "outer");
340  writeProjectedVertex("radOutN", "radOut", dir, "outer");
341  }
342 
343  endList(os_);
344 }
345 
346 
347 void Foam::blockMeshCylindricalConfiguration::writeBlocks()
348 {
349  os_ << "boxMesh" << endl;
350  writeVertex("boxCells", "boxCells", "zCells");
351  os_ << "simpleGrading (1 1 1);" << nl << endl;
352 
353  os_ << "inMesh" << endl;
354  writeVertex("boxCells", "inCells", "zCells");
355  os_ << "simpleGrading (1 1 1);" << nl << endl;
356 
357  os_ << "outMesh" << endl;
358  writeVertex("boxCells", "outCells", "zCells");
359  os_ << "simpleGrading (1 $!backgroundMesh/outGrading 1);" << nl << endl;
360 
361  beginList(os_, "blocks");
362 
363  os_ << indent << "hex (0 1 2 3 12 13 14 15) $boxMesh" << nl << nl
364  << indent << "hex (1 0 4 5 13 12 16 17) $inMesh" << nl
365  << indent << "hex (0 3 7 4 12 15 19 16) $inMesh" << nl
366  << indent << "hex (2 1 5 6 14 13 17 18) $inMesh" << nl
367  << indent << "hex (3 2 6 7 15 14 18 19) $inMesh" << nl << nl
368  << indent << "hex (5 4 8 9 17 16 20 21) $outMesh" << nl
369  << indent << "hex (4 7 11 8 16 19 23 20) $outMesh" << nl
370  << indent << "hex (6 5 9 10 18 17 21 22) $outMesh" << nl
371  << indent << "hex (7 6 10 11 19 18 22 23) $outMesh" << endl;
372 
373  endList(os_);
374 }
375 
376 
377 void Foam::blockMeshCylindricalConfiguration::writeEdges()
378 {
379  beginList(os_, "edges");
380 
381  os_ << indent << "project 4 5 (rotatingZone)" << nl
382  << indent << "project 5 6 (rotatingZone)" << nl
383  << indent << "project 6 7 (rotatingZone)" << nl
384  << indent << "project 7 4 (rotatingZone)" << nl
385  << indent << "project 16 17 (rotatingZone)" << nl
386  << indent << "project 17 18 (rotatingZone)" << nl
387  << indent << "project 18 19 (rotatingZone)" << nl
388  << indent << "project 19 16 (rotatingZone)" << nl << nl
389  << indent << "project 8 9 (outer)" << nl
390  << indent << "project 9 10 (outer)" << nl
391  << indent << "project 10 11 (outer)" << nl
392  << indent << "project 11 8 (outer)" << nl
393  << indent << "project 20 21 (outer)" << nl
394  << indent << "project 21 22 (outer)" << nl
395  << indent << "project 22 23 (outer)" << nl
396  << indent << "project 23 20 (outer)" << endl;
397 
398  endList(os_);
399 }
400 
401 
402 void Foam::blockMeshCylindricalConfiguration::writeMergePatchPairs()
403 {
404  os_ << "mergePatchPairs" << nl
405  << "(" << nl
406  << ");" << endl;
407 }
408 
409 
410 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
411 
413 (
414  const fileName& name,
415  const fileName& dir,
416  const Time& time,
417  const meshingSurfaceList& surfaces,
418  const bool& boundsOpt,
419  const Vector<label>& nCells,
420  const label refineFactor,
421  const HashTable<Pair<word>>& patchOpts,
422  const bool clearBoundary
423 )
424 :
425  blockMeshConfigurationBase(name, dir, time, surfaces, patchOpts),
426  rzbb_(surfaces.rzbb()),
427  nCells_(nCells),
428  refineFactor_(refineFactor),
429  clearBoundary_(clearBoundary)
430 {
431  if (!isBoundBoxOnZaxis())
432  {
434  << "Attempting to create a cylindrical background mesh"
435  << nl << "but the geometry bounds are not aligned with the z-axis."
436  << exit(FatalError);
437  }
438 
439  bool rotatingZonesOpt(true);
440 
441  if (rzbb_.volume() == 0)
442  {
443  rotatingZonesOpt = false;
444 
446  << "Creating a cylindrical background mesh without a "
447  << "rotatingZone specified by the '-rotatingZones' option."
448  << nl <<endl;
449 
450  // Create the intermediate interface at 40% of domain size if no
451  // rotating zone is specified
452  scalar factor = 0.4;
453 
454  rzbb_.min() = factor*bb_.min();
455  rzbb_.max() = factor*bb_.max();
456  }
457 
458  calcBlockMeshDict(boundsOpt, rotatingZonesOpt);
459 }
460 
461 
462 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
463 
465 {}
466 
467 
468 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
469 
471 {
472  dict_.writeHeader(os_, word("dictionary"));
473 
474  writeBackgroundMesh();
475  writeDefaultPatch();
476  writeBoundary();
477  writeGeometry();
478  writeVertices();
479  writeBlocks();
480  writeEdges();
481  writeMergePatchPairs();
482 
483  dict_.writeEndDivider(os_);
484 }
485 
486 
487 // ************************************************************************* //
scalar y
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
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.
#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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
void cmptMultiply(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1, const LagrangianPatchField< Type > &f2)
scalar degToRad(const scalar deg)
Convert degrees to radians.
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:258
messageStream Info
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
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.
error FatalError
scalar roundingScale(const scalar s)
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:228
static const char nl
Definition: Ostream.H:267
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