blockDescriptor.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2019-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "blockDescriptor.H"
30#include "blockMeshTools.H"
31
32// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33
34bool Foam::blockDescriptor::assignGradings
35(
36 const UList<gradingDescriptors>& ratios
37)
38{
39 bool ok = true;
40
41 switch (ratios.size())
42 {
43 case 0:
44 {
45 expand_.resize(12);
46 expand_ = gradingDescriptors();
47 break;
48 }
49 case 1:
50 {
51 // Identical in x/y/z-directions
52 expand_.resize(12);
53 expand_ = ratios[0];
54 break;
55 }
56 case 3:
57 {
58 expand_.resize(12);
59
60 // x-direction
61 expand_[0] = ratios[0];
62 expand_[1] = ratios[0];
63 expand_[2] = ratios[0];
64 expand_[3] = ratios[0];
65
66 // y-direction
67 expand_[4] = ratios[1];
68 expand_[5] = ratios[1];
69 expand_[6] = ratios[1];
70 expand_[7] = ratios[1];
71
72 // z-direction
73 expand_[8] = ratios[2];
74 expand_[9] = ratios[2];
75 expand_[10] = ratios[2];
76 expand_[11] = ratios[2];
77 break;
78 }
79 case 12:
80 {
81 expand_ = ratios;
82 break;
83 }
84 default:
85 {
86 ok = false;
87 break;
88 }
89 }
90
91 return ok;
92}
93
94
95void Foam::blockDescriptor::check(const Istream& is)
96{
97 for (const label pointi : blockShape_)
98 {
99 if (pointi < 0 || pointi >= vertices_.size())
100 {
102 << "Point label (" << pointi
103 << ") out of range 0.." << vertices_.size() - 1
104 << " in block " << *this
105 << exit(FatalIOError);
106 }
107 }
108
109 const point blockCentre(blockShape_.centre(vertices_));
110 const faceList faces(blockShape_.faces());
111
112 // Check each face is outward-pointing with respect to the block centre
113 label outwardFaceCount = 0;
114 boolList correctFaces(faces.size(), true);
115
116 forAll(faces, i)
117 {
118 point faceCentre(faces[i].centre(vertices_));
119 vector faceNormal(faces[i].areaNormal(vertices_));
120
121 if (mag(faceNormal) > SMALL)
122 {
123 if (((faceCentre - blockCentre) & faceNormal) > 0)
124 {
125 outwardFaceCount++;
126 }
127 else
128 {
129 correctFaces[i] = false;
130 }
131 }
132 else
133 {
134 outwardFaceCount++;
135 }
136 }
137
138 // If all faces are inward-pointing the block is inside-out
139 if (outwardFaceCount == 0)
140 {
142 << "Block " << *this << " is inside-out"
143 << exit(FatalIOError);
144 }
145 else if (outwardFaceCount != faces.size())
146 {
148 << "Block " << *this << " has inward-pointing faces"
149 << nl << " ";
150
151 forAll(correctFaces, i)
152 {
153 if (!correctFaces[i])
154 {
155 FatalIOError<< faces[i] << token::SPACE;
156 }
157 }
158
160 }
161}
162
163
164void Foam::blockDescriptor::findCurvedFaces(const label blockIndex)
165{
166 const faceList shapeFaces(blockShape().faces());
167
168 forAll(shapeFaces, shapeFacei)
169 {
170 forAll(blockFaces_, facei)
171 {
172 const face& f = blockFaces_[facei].vertices();
173
174 // Accept (<block> <face>) face description
175 if
176 (
177 (
178 f.size() == 2
179 && f[0] == blockIndex
180 && f[1] == shapeFacei
181 )
182 || face::sameVertices(f, shapeFaces[shapeFacei])
183 )
184 {
185 curvedFaces_[shapeFacei] = facei;
186 ++nCurvedFaces_;
187 break;
188 }
189 }
190 }
191}
192
193
194// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
195
197(
198 const cellShape& bshape,
199 const pointField& vertices,
200 const blockEdgeList& edges,
201 const blockFaceList& faces,
202 const labelVector& density,
203 const UList<gradingDescriptors>& expand,
204 const word& zoneName
205)
206:
207 ijkMesh(density),
208 vertices_(vertices),
209 blockEdges_(edges),
210 blockFaces_(faces),
211 blockShape_(bshape),
212 expand_(),
213 index_(-1),
214 zoneName_(zoneName),
215 curvedFaces_(-1),
216 nCurvedFaces_(0)
217{
218 if (!assignGradings(expand))
219 {
221 << "Unknown definition of expansion ratios: " << expand
222 << exit(FatalError);
223 }
224
225 findCurvedFaces();
226}
227
228
230(
231 const dictionary& dict,
232 const label blockIndex,
233 const pointField& vertices,
234 const blockEdgeList& edges,
235 const blockFaceList& faces,
236 Istream& is
237)
238:
239 ijkMesh(),
240 vertices_(vertices),
241 blockEdges_(edges),
242 blockFaces_(faces),
243 blockShape_(),
244 expand_(),
245 index_(blockIndex),
246 zoneName_(),
247 curvedFaces_(-1),
248 nCurvedFaces_(0)
249{
250 // Read cell model and list of vertices (potentially with variables)
251 word model(is);
252 blockShape_ = cellShape
253 (
254 model,
255 blockMeshTools::read<label>
256 (
257 is,
258 dict.subOrEmptyDict("namedVertices")
259 )
260 );
261
262 // Examine next token
263 token t(is);
264
265 // Optional zone name
266 if (t.isWord())
267 {
268 zoneName_ = t.wordToken();
269
270 // Examine next token
271 is >> t;
272 }
273 is.putBack(t);
274
275 if (t.isPunctuation())
276 {
277 // New-style: read a list of 3 values
278 if (t.pToken() == token::BEGIN_LIST)
279 {
280 is >> ijkMesh::sizes();
281 }
282 else
283 {
285 << "Incorrect token while reading n, expected '(', found "
286 << t.info()
287 << exit(FatalIOError);
288 }
289 }
290 else
291 {
292 // Old-style: read three labels
294 << "Encountered old-style specification of mesh divisions"
295 << endl;
296
297 is >> ijkMesh::sizes().x()
298 >> ijkMesh::sizes().y()
299 >> ijkMesh::sizes().z();
300 }
301
302 is >> t;
303 if (!t.isWord())
304 {
305 is.putBack(t);
306 }
307
308 List<gradingDescriptors> expand(is);
309
310 if (!assignGradings(expand))
311 {
313 << "Unknown definition of expansion ratios: " << expand
314 << exit(FatalError);
315 }
316
317 check(is);
318
319 findCurvedFaces(blockIndex);
320}
321
322
323// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
324
327{
328 const label ni = sizes().x();
329 const label nj = sizes().y();
330 const label nk = sizes().z();
331
332 // Caches points for curvature correction
333 FixedList<pointField, 6> facePoints;
334
335 facePoints[0].setSize((nj + 1)*(nk + 1));
336 facePoints[1].setSize((nj + 1)*(nk + 1));
337
338 for (label j=0; j<=nj; j++)
339 {
340 for (label k=0; k<=nk; k++)
341 {
342 facePoints[0][facePointLabel(0, j, k)] =
343 points[pointLabel(0, j, k)];
344 facePoints[1][facePointLabel(1, j, k)] =
345 points[pointLabel(ni, j, k)];
346 }
347 }
348
349 facePoints[2].setSize((ni + 1)*(nk + 1));
350 facePoints[3].setSize((ni + 1)*(nk + 1));
351
352 for (label i=0; i<=ni; i++)
353 {
354 for (label k=0; k<=nk; k++)
355 {
356 facePoints[2][facePointLabel(2, i, k)] =
357 points[pointLabel(i, 0, k)];
358 facePoints[3][facePointLabel(3, i, k)] =
359 points[pointLabel(i, nj, k)];
360 }
361 }
362
363 facePoints[4].setSize((ni + 1)*(nj + 1));
364 facePoints[5].setSize((ni + 1)*(nj + 1));
365
366 for (label i=0; i<=ni; i++)
367 {
368 for (label j=0; j<=nj; j++)
369 {
370 facePoints[4][facePointLabel(4, i, j)] =
371 points[pointLabel(i, j, 0)];
372 facePoints[5][facePointLabel(5, i, j)] =
373 points[pointLabel(i, j, nk)];
374 }
375 }
376
377 return facePoints;
378}
379
380
382(
383 FixedList<pointField, 6>& facePoints
384) const
385{
386 forAll(curvedFaces_, blockFacei)
387 {
388 if (curvedFaces_[blockFacei] >= 0)
389 {
390 blockFaces_[curvedFaces_[blockFacei]].project
391 (
392 *this,
393 blockFacei,
394 facePoints[blockFacei]
395 );
396 }
397 }
398}
399
400
402(
403 Ostream& os,
404 const label val,
405 const dictionary& d
406)
407{
408 const dictionary* varDictPtr = d.findDict("namedBlocks");
409 if (varDictPtr)
410 {
411 blockMeshTools::write(os, val, *varDictPtr);
412 }
413 else
414 {
415 os << val;
416 }
417}
418
419
420// * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * * //
421
423{
424 const cellShape& bshape = bd.blockShape();
425 const labelList& blockLabels = bshape;
426
427 os << bshape.model().name() << " (";
428
429 forAll(blockLabels, labeli)
430 {
431 if (labeli)
432 {
433 os << ' ';
434 }
435 os << blockLabels[labeli];
436 }
437 os << ')';
438
439 if (bd.zoneName().size())
440 {
441 os << ' ' << bd.zoneName();
442 }
443
444 os << ' ' << bd.density()
445 << " grading (";
446
447
448 const List<gradingDescriptors>& expand = bd.grading();
449
450 // Can we use a compact notation?
451 if
452 (
453 // x-direction
454 (
455 expand[0] == expand[1]
456 && expand[0] == expand[2]
457 && expand[0] == expand[3]
458 )
459 && // y-direction
460 (
461 expand[4] == expand[5]
462 && expand[4] == expand[6]
463 && expand[4] == expand[7]
464 )
465 && // z-direction
466 (
467 expand[8] == expand[9]
468 && expand[8] == expand[10]
469 && expand[8] == expand[11]
470 )
471 )
472 {
473 os << expand[0] << ' ' << expand[4] << ' ' << expand[8];
474 }
475 else
476 {
477 forAll(expand, edgei)
478 {
479 if (edgei)
480 {
481 os << ' ';
482 }
483 os << expand[edgei];
484 }
485 }
486
487 os << ')';
488
489 return os;
490}
491
492
493Foam::Ostream& Foam::operator<<
494(
495 Ostream& os,
496 const InfoProxy<blockDescriptor>& iproxy
497)
498{
499 const blockDescriptor& bd = iproxy.t_;
500
501 os << "Dimensions:" << bd.density()
502 << " nPoints:" << bd.nPoints()
503 << " nCells:" << bd.nCells()
504 << " nFaces:" << bd.nFaces()
505 << " nInternalFaces:" << bd.nInternalFaces()
506 << nl;
507
508 return os;
509}
510
511
512// ************************************************************************* //
label k
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: FixedList.H:81
void setSize(const label n)
Dummy function, to make FixedList consistent with List.
Definition: FixedList.H:304
A helper class for outputting values to Ostream.
Definition: InfoProxy.H:52
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Takes the description of the block and the list of curved edges and creates a list of points on edges...
const List< gradingDescriptors > & grading() const noexcept
Expansion ratios in all directions.
const cellShape & blockShape() const noexcept
Return the block shape.
const labelVector & density() const noexcept
The mesh density (number of cells) in the i,j,k directions.
const word & zoneName() const noexcept
Return the (optional) zone name.
void correctFacePoints(FixedList< pointField, 6 > &) const
Correct the location of the given face-points.
const word & name() const noexcept
Return model name.
Definition: cellModelI.H:31
An analytical geometric cellShape.
Definition: cellShape.H:72
const cellModel & model() const
Model reference.
Definition: cellShapeI.H:126
const DynamicList< point > & facePoints()
Returns the points of the cutting PLICface.
Definition: cutCellIso.C:173
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Definition: dictionary.C:540
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionaryI.H:127
FixedList< label, nTypes > sizes() const
Processor-local sizes per element type.
Definition: ensightCells.C:98
static bool sameVertices(const face &a, const face &b)
Return true if the faces have the same vertices.
Definition: face.C:382
virtual bool write()
Write the output fields.
A simple i-j-k (row-major order) to linear addressing for a rectilinear mesh. Since the underlying me...
Definition: ijkMesh.H:60
label nInternalFaces() const
The number of internal faces in the i-j-k mesh.
Definition: ijkMeshI.H:92
label nCells() const
The number of mesh cells (nx*ny*nz) in the i-j-k mesh.
Definition: ijkMeshI.H:68
label nPoints() const
The number of mesh points (nx+1)*(ny+1)*(nz+1) in the i-j-k mesh.
Definition: ijkMeshI.H:55
label nFaces() const
The total number of mesh faces in the i-j-k mesh.
Definition: ijkMeshI.H:74
A token holds an item read from Istream.
Definition: token.H:69
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:459
@ BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
@ SPACE
Space [isspace].
Definition: token.H:125
punctuationToken pToken() const
Return punctuation character.
Definition: tokenI.H:485
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:631
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE)
Definition: tokenI.H:609
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
void write(Ostream &, const label val, const dictionary &)
Write with dictionary lookup.
vector point
Point is a vector.
Definition: point.H:43
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
pointField vertices(const blockVertexList &bvl)
IOerror FatalIOError
List< bool > boolList
A List of bools.
Definition: List.H:64
error FatalError
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333