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 -------------------------------------------------------------------------------
11 License
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 
34 bool 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 
95 void 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 
164 void 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,
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 
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 
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 
493 Foam::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 // ************************************************************************* //
Foam::ijkMesh::nFaces
label nFaces() const
The total number of mesh faces in the i-j-k mesh.
Definition: ijkMeshI.H:74
Foam::dictionary::findDict
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionaryI.H:127
Foam::blockMeshTools::write
void write(Ostream &, const label val, const dictionary &)
Write with dictionary lookup.
Definition: blockMeshTools.C:112
Foam::Vector::x
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::InfoProxy
A helper class for outputting values to Ostream.
Definition: InfoProxy.H:47
Foam::blockDescriptor::grading
const List< gradingDescriptors > & grading() const noexcept
Expansion ratios in all directions.
Definition: blockDescriptorI.H:60
Foam::blockDescriptor::zoneName
const word & zoneName() const noexcept
Return the (optional) zone name.
Definition: blockDescriptorI.H:66
Foam::blockDescriptor::write
static void write(Ostream &, const label blocki, const dictionary &)
Write block index with dictionary lookup.
Definition: blockDescriptor.C:402
Foam::ijkAddressing::sizes
const labelVector & sizes() const
The (i,j,k) addressing dimensions.
Definition: ijkAddressingI.H:69
Foam::face::sameVertices
static bool sameVertices(const face &a, const face &b)
Return true if the faces have the same vertices.
Definition: face.C:382
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:65
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
blockDescriptor.H
Foam::Vector::z
const Cmpt & z() const
Access to the vector z component.
Definition: VectorI.H:85
Foam::token::pToken
punctuationToken pToken() const
Return punctuation character.
Definition: tokenI.H:485
Foam::token::isWord
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE)
Definition: tokenI.H:609
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::check
static void check(const int retVal, const char *what)
Definition: ptscotchDecomp.C:80
Foam::ijkMesh
A simple i-j-k (row-major order) to linear addressing for a rectilinear mesh. Since the underlying me...
Definition: ijkMesh.H:57
Foam::Field< vector >
Foam::token::info
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::blockDescriptor::density
const labelVector & density() const noexcept
The mesh density (number of cells) in the i,j,k directions.
Definition: blockDescriptorI.H:53
Foam::token::isPunctuation
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:459
Foam::PtrList< blockEdge >
Foam::blockDescriptor::facePoints
FixedList< pointField, 6 > facePoints(const pointField &points) const
Return the list of face-points for all of the faces of the block.
Definition: blockDescriptor.C:326
Foam::blockDescriptor::correctFacePoints
void correctFacePoints(FixedList< pointField, 6 > &) const
Correct the location of the given face-points.
Definition: blockDescriptor.C:382
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::vertices
pointField vertices(const blockVertexList &bvl)
Definition: blockVertexList.H:49
os
OBJstream os(runTime.globalPath()/outputName)
Foam::ijkMesh::nInternalFaces
label nInternalFaces() const
The number of internal faces in the i-j-k mesh.
Definition: ijkMeshI.H:92
Foam::FixedList::setSize
void setSize(const label n)
Dummy function, to make FixedList consistent with List.
Definition: FixedList.H:304
Foam::cellShape
An analytical geometric cellShape.
Definition: cellShape.H:69
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::token::wordToken
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:631
Foam::dictionary::subOrEmptyDict
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Definition: dictionary.C:540
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::cellModel::name
const word & name() const noexcept
Return model name.
Definition: cellModelI.H:31
Foam::Vector::y
const Cmpt & y() const
Access to the vector y component.
Definition: VectorI.H:79
blockMeshTools.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::ijkMesh::nCells
label nCells() const
The number of mesh cells (nx*ny*nz) in the i-j-k mesh.
Definition: ijkMeshI.H:68
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::Vector< label >
Foam::ijkMesh::nPoints
label nPoints() const
The number of mesh points (nx+1)*(ny+1)*(nz+1) in the i-j-k mesh.
Definition: ijkMeshI.H:55
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::Istream::putBack
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::FixedList
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:104
Foam::token::SPACE
Space [isspace].
Definition: token.H:125
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
points
const pointField & points
Definition: gmvOutputHeader.H:1
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::blockDescriptor::blockDescriptor
blockDescriptor(const blockDescriptor &)=default
Copy construct.
Foam::blockDescriptor::blockShape
const cellShape & blockShape() const noexcept
Return the block shape.
Definition: blockDescriptorI.H:46
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:340
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::stringOps::expand
string expand(const std::string &s, const HashTable< string > &mapping, const char sigil='$')
Definition: stringOps.C:718
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
Foam::blockDescriptor
Takes the description of the block and the list of curved edges and creates a list of points on edges...
Definition: blockDescriptor.H:78
Foam::cellShape::model
const cellModel & model() const
Model reference.
Definition: cellShapeI.H:126