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