faBoundaryMesh.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) 2016-2017 Wikki Ltd
9  Copyright (C) 2018-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 "faBoundaryMesh.H"
30 #include "faMesh.H"
31 #include "primitiveMesh.H"
32 #include "PtrListOps.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(faBoundaryMesh, 0);
39 }
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
44 // bool Foam::faBoundaryMesh::hasGroupIDs() const
45 // {
46 // /// if (groupIDsPtr_)
47 // /// {
48 // /// // Use existing cache
49 // /// return !groupIDsPtr_->empty();
50 // /// }
51 //
52 // const faPatchList& patches = *this;
53 //
54 // for (const faPatch& p : patches)
55 // {
56 // if (!p.inGroups().empty())
57 // {
58 // return true;
59 // }
60 // }
61 //
62 // return false;
63 // }
64 
65 
66 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
67 
68 Foam::faBoundaryMesh::faBoundaryMesh
69 (
70  const IOobject& io,
71  const faMesh& mesh
72 )
73 :
74  faPatchList(),
75  regIOobject(io),
76  mesh_(mesh)
77 {
78  if
79  (
80  readOpt() == IOobject::MUST_READ
81  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
82  )
83  {
84  // Warn for MUST_READ_IF_MODIFIED
85  warnNoRereading<faBoundaryMesh>();
86 
87  faPatchList& patches = *this;
88 
89  // Read faPatch list
90  Istream& is = readStream(typeName);
91 
92  PtrList<entry> patchEntries(is);
93  patches.setSize(patchEntries.size());
94 
95  forAll(patches, patchi)
96  {
97  patches.set
98  (
99  patchi,
101  (
102  patchEntries[patchi].keyword(),
103  patchEntries[patchi].dict(),
104  patchi,
105  *this
106  )
107  );
108  }
109 
110  is.check(FUNCTION_NAME);
111 
112  close();
113  }
114 }
115 
116 
117 Foam::faBoundaryMesh::faBoundaryMesh
118 (
119  const IOobject& io,
120  const faMesh& pm,
121  const label size
122 )
123 :
124  faPatchList(size),
125  regIOobject(io),
126  mesh_(pm)
127 {}
128 
129 
130 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
131 
133 {
134  // processorFaPatch geometry triggers calculation of pointNormals.
135  // This uses parallel comms and hence will not be trigggered
136  // on processors that do not have a processorFaPatch so instead
137  // force construction.
138  (void)mesh_.pointAreaNormals();
139 
140  forAll(*this, patchi)
141  {
142  operator[](patchi).initGeometry();
143  }
144 
145  forAll(*this, patchi)
146  {
147  operator[](patchi).calcGeometry();
148  }
149 }
150 
151 
154 {
155  const faPatchList& patches = *this;
156 
157  UPtrList<const labelUList> list(patches.size());
158 
159  forAll(list, patchi)
160  {
161  list.set(patchi, &patches[patchi].edgeFaces());
162  }
163 
164  return list;
165 }
166 
167 
169 {
170  const faPatchList& patches = *this;
171 
172  lduInterfacePtrsList list(patches.size());
173 
174  forAll(list, patchi)
175  {
176  const lduInterface* lduPtr = isA<lduInterface>(patches[patchi]);
177 
178  if (lduPtr)
179  {
180  list.set(patchi, lduPtr);
181  }
182  }
183 
184  return list;
185 }
186 
187 
189 {
190  const faPatchList& patches = *this;
191 
192  label nonProc = 0;
193 
194  for (const faPatch& p : patches)
195  {
196  if (isA<processorFaPatch>(p))
197  {
198  break;
199  }
200 
201  ++nonProc;
202  }
203 
204  return nonProc;
205 }
206 
207 
209 {
210  return PtrListOps::get<word>(*this, nameOp<faPatch>());
211 }
212 
213 
215 {
216  return PtrListOps::get<word>(*this, typeOp<faPatch>());
217 }
218 
219 
221 {
222  // Manually: faPatch does not have independent start() information
223 
224  const faPatchList& patches = *this;
225 
226  labelList list(patches.size());
227 
228  label beg = mesh_.nInternalEdges();
229  forAll(patches, patchi)
230  {
231  const label len = patches[patchi].nEdges();
232  list[patchi] = beg;
233  beg += len;
234  }
235  return list;
236 }
237 
238 
240 {
241  return
242  PtrListOps::get<label>
243  (
244  *this,
245  [](const faPatch& p) { return p.nEdges(); } // avoid virtual
246  );
247 }
248 
249 
251 {
252  const faPatchList& patches = *this;
253 
254  List<labelRange> list(patches.size());
255 
256  label beg = mesh_.nInternalEdges();
257  forAll(patches, patchi)
258  {
259  const label len = patches[patchi].nEdges();
260  list[patchi].reset(beg, len);
261  beg += len;
262  }
263  return list;
264 }
265 
266 
267 Foam::label Foam::faBoundaryMesh::start() const
268 {
269  return mesh_.nInternalEdges();
270 }
271 
272 
273 Foam::label Foam::faBoundaryMesh::nEdges() const
274 {
275  return mesh_.nBoundaryEdges();
276 }
277 
278 
280 {
281  return labelRange(mesh_.nInternalEdges(), mesh_.nBoundaryEdges());
282 }
283 
284 
286 (
287  const wordRe& matcher,
288  const bool useGroups /* ignored */
289 ) const
290 {
291  if (matcher.empty())
292  {
293  return labelList();
294  }
295 
296  if (matcher.isPattern())
297  {
298  return PtrListOps::findMatching(*this, matcher);
299  }
300  else
301  {
302  // Literal string.
303  // Special version of above for reduced memory footprint
304 
305  const label patchId = PtrListOps::firstMatching(*this, matcher);
306 
307  if (patchId >= 0)
308  {
309  return labelList(one{}, patchId);
310  }
311  }
312 
313  return labelList();
314 }
315 
316 
318 (
319  const wordRes& matcher,
320  const bool useGroups /* ignored */
321 ) const
322 {
323  if (matcher.empty())
324  {
325  return labelList();
326  }
327  else if (matcher.size() == 1)
328  {
329  return this->indices(matcher.first(), useGroups);
330  }
331 
332  return PtrListOps::findMatching(*this, matcher);
333 }
334 
335 
336 Foam::label Foam::faBoundaryMesh::findIndex(const wordRe& key) const
337 {
338  if (key.empty())
339  {
340  return -1;
341  }
342  return PtrListOps::firstMatching(*this, key);
343 }
344 
345 
346 Foam::label Foam::faBoundaryMesh::findPatchID(const word& patchName) const
347 {
348  if (patchName.empty())
349  {
350  return -1;
351  }
352 
353  return PtrListOps::firstMatching(*this, patchName);
354 }
355 
356 
357 Foam::label Foam::faBoundaryMesh::whichPatch(const label edgeIndex) const
358 {
359  // Find out which patch the current face belongs to by comparing label
360  // with patch start labels.
361  // If the face is internal, return -1;
362  // if it is off the end of the list, abort
363  if (edgeIndex < mesh().nInternalEdges())
364  {
365  return -1;
366  }
367  else if (edgeIndex >= mesh().nEdges())
368  {
370  << "Edge " << edgeIndex
371  << " out of bounds. Number of geometric edges " << mesh().nEdges()
372  << abort(FatalError);
373  }
374 
375  forAll(*this, patchi)
376  {
377  label start = mesh_.patchStarts()[patchi];
378  label size = operator[](patchi).faPatch::size();
379 
380  if
381  (
382  edgeIndex >= start
383  && edgeIndex < start + size
384  )
385  {
386  return patchi;
387  }
388  }
389 
390  // If not in any of above, it's trouble!
392  << "error in patch search algorithm"
393  << abort(FatalError);
394 
395  return -1;
396 }
397 
398 
399 bool Foam::faBoundaryMesh::checkDefinition(const bool report) const
400 {
401  label nextPatchStart = mesh().nInternalEdges();
402  const faBoundaryMesh& bm = *this;
403 
404  bool hasError = false;
405 
406  forAll(bm, patchi)
407  {
408  if (bm[patchi].start() != nextPatchStart && !hasError)
409  {
410  hasError = true;
411 
413  << " ****Problem with boundary patch " << patchi
414  << " named " << bm[patchi].name()
415  << " of type " << bm[patchi].type()
416  << ". The patch should start on face no " << nextPatchStart
417  << " and the patch specifies " << bm[patchi].start()
418  << "." << endl
419  << "Possibly consecutive patches have this same problem."
420  << " Suppressing future warnings." << endl;
421  }
422 
423  // Warn about duplicate boundary patches?
424 
425  nextPatchStart += bm[patchi].faPatch::size();
426  }
427 
428  if (hasError)
429  {
431  << "This mesh is not valid: boundary definition is in error."
432  << endl;
433  }
434  else
435  {
436  if (debug || report)
437  {
438  Info << "Boundary definition OK." << endl;
439  }
440  }
441 
442  return hasError;
443 }
444 
445 
447 {
448  // processorFaPatch geometry triggers calculation of pointNormals.
449  // This uses parallel comms and hence will not be trigggered
450  // on processors that do not have a processorFaPatch so instead
451  // force construction.
452  (void)mesh_.pointAreaNormals();
453 
454  faPatchList& patches = *this;
455 
456  forAll(patches, patchi)
457  {
458  patches[patchi].initMovePoints(p);
459  }
460 
461  forAll(patches, patchi)
462  {
463  patches[patchi].movePoints(p);
464  }
465 }
466 
467 
469 {
470  faPatchList& patches = *this;
471 
472  forAll(patches, patchi)
473  {
474  patches[patchi].initUpdateMesh();
475  }
476 
477  forAll(patches, patchi)
478  {
479  patches[patchi].updateMesh();
480  }
481 }
482 
483 
485 {
486  const faPatchList& patches = *this;
487 
488  os << patches.size() << nl << token::BEGIN_LIST << incrIndent << nl;
489 
490  for (const faPatch& p : patches)
491  {
492  os.beginBlock(p.name());
493  os << p;
494  os.endBlock();
495  }
496 
498 
500  return os.good();
501 }
502 
503 
505 (
506  IOstreamOption streamOpt,
507  const bool valid
508 ) const
509 {
510  // Allow/disallow compression?
511  // 1. keep readable
512  // 2. save some space
513  // ??? streamOpt.compression(IOstreamOption::UNCOMPRESSED);
514  return regIOobject::writeObject(streamOpt, valid);
515 }
516 
517 
518 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
519 
521 {
522  bm.writeData(os);
523  return os;
524 }
525 
526 
527 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::faBoundaryMesh::whichPatch
label whichPatch(const label edgeIndex) const
Return patch index for a given edge label.
Definition: faBoundaryMesh.C:357
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::wordRe::isPattern
bool isPattern() const noexcept
The wordRe is treated as a pattern, not as literal string.
Definition: wordReI.H:107
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:350
Foam::faBoundaryMesh::updateMesh
void updateMesh()
Correct faBoundaryMesh after topology update.
Definition: faBoundaryMesh.C:468
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::faBoundaryMesh::indices
labelList indices(const wordRe &matcher, const bool useGroups=true) const
Return (sorted) patch indices for all matches.
Definition: faBoundaryMesh.C:286
Foam::faBoundaryMesh::writeData
bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
Definition: faBoundaryMesh.C:484
Foam::faBoundaryMesh::checkDefinition
bool checkDefinition(const bool report=false) const
Check boundary definition.
Definition: faBoundaryMesh.C:399
Foam::faBoundaryMesh::patchSizes
labelList patchSizes() const
Return a list of patch sizes (number of edges in each patch)
Definition: faBoundaryMesh.C:239
Foam::lduInterface
An abstract base class for implicitly-coupled interfaces e.g. processor and cyclic patches.
Definition: lduInterface.H:54
Foam::faBoundaryMesh::patchRanges
List< labelRange > patchRanges() const
Return a list of patch ranges.
Definition: faBoundaryMesh.C:250
Foam::faBoundaryMesh::calcGeometry
void calcGeometry()
Calculate the geometry for the patches.
Definition: faBoundaryMesh.C:132
Foam::glTF::key
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:108
Foam::primitiveMesh::nEdges
label nEdges() const
Number of mesh edges.
Definition: primitiveMeshI.H:67
Foam::PtrListOps::findMatching
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with 'name()' that matches.
Foam::one
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:61
PtrListOps.H
Functions to operate on Pointer Lists.
Foam::faBoundaryMesh::edgeFaces
UPtrList< const labelUList > edgeFaces() const
Return a list of edgeFaces for each patch.
Definition: faBoundaryMesh.C:153
primitiveMesh.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::faBoundaryMesh::movePoints
void movePoints(const pointField &)
Correct faBoundaryMesh after moving points.
Definition: faBoundaryMesh.C:446
faMesh.H
Foam::faMesh::pointAreaNormals
const vectorField & pointAreaNormals() const
Return point area normals.
Definition: faMesh.C:704
Foam::Ostream::beginBlock
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:91
Foam::incrIndent
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:346
Foam::wordRe
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:80
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::faBoundaryMesh::findIndex
label findIndex(const wordRe &key) const
Return patch index for the first match, return -1 if not found.
Definition: faBoundaryMesh.C:336
Foam::faBoundaryMesh
Finite area boundary mesh.
Definition: faBoundaryMesh.H:65
Foam::Field< vector >
Foam::faBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: faBoundaryMesh.C:208
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::primitiveMesh::nInternalEdges
label nInternalEdges() const
Internal edges using 0,1 or 2 boundary points.
Definition: primitiveMeshI.H:59
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
SeriousErrorInFunction
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Definition: messageStream.H:306
Foam::UPtrList
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: UPtrList.H:62
Foam::labelRange
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:55
Foam::nameOp
Extract name (as a word) from an object, typically using its name() method.
Definition: word.H:237
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::Ostream::endBlock
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:109
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
Foam::FatalError
error FatalError
Foam::faBoundaryMesh::findPatchID
label findPatchID(const word &patchName) const
Find patch index given a name, return -1 if not found.
Definition: faBoundaryMesh.C:346
faBoundaryMesh.H
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::regIOobject::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: regIOobjectWrite.C:36
Foam::faBoundaryMesh::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: faBoundaryMesh.C:505
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::decrIndent
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:353
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::faBoundaryMesh::nEdges
label nEdges() const
The number of boundary edges for the underlying mesh.
Definition: faBoundaryMesh.C:273
Foam::polyBoundaryMesh::movePoints
void movePoints(const pointField &p)
Correct polyBoundaryMesh after moving points.
Definition: polyBoundaryMesh.C:1117
Foam::faBoundaryMesh::start
label start() const
The start label of the edges in the faMesh edges list.
Definition: faBoundaryMesh.C:267
Foam::polyBoundaryMesh::updateMesh
void updateMesh()
Correct polyBoundaryMesh after topology update.
Definition: polyBoundaryMesh.C:1163
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
Foam::faBoundaryMesh::types
wordList types() const
Return a list of patch types.
Definition: faBoundaryMesh.C:214
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:73
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::faBoundaryMesh::nNonProcessor
label nNonProcessor() const
The number of patches before the first processor patch.
Definition: faBoundaryMesh.C:188
Foam::List< word >
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::faBoundaryMesh::range
labelRange range() const
The edge range for all boundary edges.
Definition: faBoundaryMesh.C:279
Foam::PtrListOps::firstMatching
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with 'name()' that matches, -1 on failure.
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:156
Foam::faMesh
Finite area mesh. Used for 2-D non-Euclidian finite area method.
Definition: faMesh.H:82
patchId
label patchId(-1)
Foam::faPatchList
PtrList< faPatch > faPatchList
Definition: faPatchList.H:47
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
Foam::faPatch
Finite area patch class. Used for 2-D non-Euclidian finite area method.
Definition: faPatch.H:69
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::typeOp
Extract type (as a word) from an object, typically using its type() method.
Definition: word.H:248
Foam::faBoundaryMesh::patchStarts
labelList patchStarts() const
Return a list of patch start indices.
Definition: faBoundaryMesh.C:220
Foam::faBoundaryMesh::interfaces
lduInterfacePtrsList interfaces() const
Definition: faBoundaryMesh.C:168