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