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-2024 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 "globalIndex.H"
32 #include "processorFaPatch.H"
33 #include "wordRes.H"
34 #include "PtrListOps.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(faBoundaryMesh, 0);
41 }
42 
43 
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 
46 bool Foam::faBoundaryMesh::hasGroupIDs() const
47 {
48  if (groupIDsPtr_)
49  {
50  // Use existing cache
51  return !groupIDsPtr_->empty();
52  }
53 
54  const faPatchList& patches = *this;
55 
56  for (const faPatch& p : patches)
57  {
58  if (!p.inGroups().empty())
59  {
60  return true;
61  }
62  }
63 
64  return false;
65 }
66 
67 
68 void Foam::faBoundaryMesh::calcGroupIDs() const
69 {
70  if (groupIDsPtr_)
71  {
72  return; // Or FatalError
73  }
74 
75  groupIDsPtr_.emplace(16);
76  auto& groupLookup = *groupIDsPtr_;
77 
78  const faPatchList& patches = *this;
79 
80  forAll(patches, patchi)
81  {
82  for (const word& groupName : patches[patchi].inGroups())
83  {
84  groupLookup(groupName).push_back(patchi);
85  }
86  }
87 
88  // Remove groups that clash with patch names
89  forAll(patches, patchi)
90  {
91  if (groupLookup.erase(patches[patchi].name()))
92  {
94  << "Removed group '" << patches[patchi].name()
95  << "' which clashes with patch " << patchi
96  << " of the same name."
97  << endl;
98  }
99  }
100 }
101 
102 
103 void Foam::faBoundaryMesh::populate(PtrList<entry>&& entries)
104 {
105  clearLocalAddressing();
106 
107  faPatchList& patches = *this;
108 
109  patches.resize_null(entries.size());
110 
111  // Transcribe.
112  // Does not handle nullptr at all (what could possibly be done?)
113  forAll(patches, patchi)
114  {
115  patches.set
116  (
117  patchi,
119  (
120  entries[patchi].keyword(),
121  entries[patchi].dict(),
122  patchi,
123  *this
124  )
125  );
126  }
127 
128  entries.clear();
129 }
130 
131 
132 bool Foam::faBoundaryMesh::readIOcontents(const bool allowOptionalRead)
133 {
134  bool updated = false;
135  PtrList<entry> entries;
136 
137  if
138  (
139  this->isReadRequired()
140  || (allowOptionalRead && this->isReadOptional() && this->headerOk())
141  )
142  {
143  // Warn for MUST_READ_IF_MODIFIED
144  warnNoRereading<faBoundaryMesh>();
145 
146  // Read entries
147  Istream& is = readStream(typeName);
148 
149  is >> entries;
150 
151  is.check(FUNCTION_NAME);
152  close();
153  updated = true;
154  }
155  // Future: support master-only and broadcast?
156 
157  if (updated)
158  {
159  populate(std::move(entries));
160  }
161 
162  return updated;
163 }
164 
165 
166 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
167 
169 (
170  const IOobject& io,
171  const faMesh& mesh
172 )
173 :
174  faPatchList(),
175  regIOobject(io),
176  mesh_(mesh)
177 {
178  readIOcontents(false); // allowOptionalRead = false
179 }
180 
181 
183 (
184  const IOobject& io,
185  const faMesh& pm,
186  Foam::zero
187 )
188 :
190  regIOobject(io),
191  mesh_(pm)
192 {}
193 
194 
196 (
197  const IOobject& io,
198  const faMesh& pm,
199  const label size
200 )
201 :
202  faPatchList(size),
203  regIOobject(io),
204  mesh_(pm)
205 {}
206 
207 
209 (
210  const IOobject& io,
211  const faMesh& fam,
212  const faPatchList& list
213 )
214 :
215  faPatchList(),
216  regIOobject(io),
217  mesh_(fam)
218 {
219  if (!readIOcontents(true)) // allowOptionalRead = true
220  {
221  // Nothing read. Use supplied patches
222  faPatchList& patches = *this;
223  patches.resize(list.size());
224 
225  forAll(patches, patchi)
226  {
227  patches.set(patchi, list[patchi].clone(*this));
228  }
229  }
230 }
231 
232 
234 (
235  const IOobject& io,
236  const faMesh& fam,
237  PtrList<entry>&& entries
238 )
239 :
240  faPatchList(),
241  regIOobject(io),
242  mesh_(fam)
243 {
244  if (!readIOcontents(true)) // allowOptionalRead = true
245  {
246  populate(std::move(entries));
247  }
248  entries.clear();
249 }
250 
251 
252 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
253 
255 {
256  clearLocalAddressing();
258 }
259 
260 
261 void Foam::faBoundaryMesh::clearLocalAddressing()
262 {
263  groupIDsPtr_.reset(nullptr);
264 }
265 
266 
267 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
268 
270 {
271  // processor initGeometry send/recv the following:
272  // - edgeCentres() : faMesh::edgeCentres()
273  // - edgeLengths() : faMesh::Le()
274  // - edgeFaceCentres() : faMesh::areaCentres()
275  //
276  // faMesh::Le() has its own point-to-point communication (OK) but
277  // triggers either/or edgeAreaNormals(), pointAreaNormals()
278  // with their own communication that can block.
279 
280  // This uses parallel comms and hence will not be trigggered
281  // on processors that do not have a processorFaPatch so instead
282  // force construction.
283 
284  (void)mesh_.edgeAreaNormals();
285  (void)mesh_.pointAreaNormals();
286 
287  (void)mesh_.areaCentres();
288  (void)mesh_.faceAreaNormals();
289 
290 
292 
293  if
294  (
295  pBufs.commsType() == Pstream::commsTypes::buffered
296  || pBufs.commsType() == Pstream::commsTypes::nonBlocking
297  )
298  {
299  forAll(*this, patchi)
300  {
301  operator[](patchi).initGeometry(pBufs);
302  }
303 
304  pBufs.finishedSends();
305 
306  forAll(*this, patchi)
307  {
308  operator[](patchi).calcGeometry(pBufs);
309  }
310  }
311  else if (pBufs.commsType() == Pstream::commsTypes::scheduled)
312  {
313  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
314 
315  // Dummy.
316  pBufs.finishedSends();
317 
318  for (const auto& patchEval : patchSchedule)
319  {
320  const label patchi = patchEval.patch;
321 
322  if (patchEval.init)
323  {
324  operator[](patchi).initGeometry(pBufs);
325  }
326  else
327  {
328  operator[](patchi).calcGeometry(pBufs);
329  }
330  }
331  }
332 }
333 
334 
337 {
338  const faPatchList& patches = *this;
339 
340  UPtrList<const labelUList> list(patches.size());
341 
342  forAll(list, patchi)
343  {
344  list.set(patchi, &patches[patchi].edgeLabels());
345  }
346 
347  return list;
348 }
349 
350 
353 {
354  const faPatchList& patches = *this;
355 
356  UPtrList<const labelUList> list(patches.size());
357 
358  forAll(list, patchi)
359  {
360  list.set(patchi, &patches[patchi].edgeFaces());
361  }
362 
363  return list;
364 }
365 
366 
368 {
369  const faPatchList& patches = *this;
370 
372 
373  forAll(list, patchi)
374  {
375  const lduInterface* lduPtr = isA<lduInterface>(patches[patchi]);
376 
377  if (lduPtr)
378  {
379  list.set(patchi, lduPtr);
380  }
381  }
382 
383  return list;
384 }
385 
386 
387 Foam::label Foam::faBoundaryMesh::nNonProcessor() const
388 {
389  const faPatchList& patches = *this;
390 
391  label count = 0;
392 
393  for (const faPatch& p : patches)
394  {
395  if (isA<processorFaPatch>(p))
396  {
397  break;
398  }
399 
400  ++count;
401  }
402 
403  return count;
404 }
405 
406 
407 Foam::label Foam::faBoundaryMesh::nProcessorPatches() const
408 {
409  const faPatchList& patches = *this;
410 
411  label count = 0;
412 
413  for (const faPatch& p : patches)
414  {
415  if (isA<processorFaPatch>(p))
416  {
417  ++count;
418  }
419  }
420 
421  return count;
422 }
423 
424 
427 {
428  if (!groupIDsPtr_)
429  {
430  calcGroupIDs();
431  }
432 
433  return *groupIDsPtr_;
434 }
435 
436 
438 (
439  const word& groupName,
440  const labelUList& patchIDs
441 )
442 {
443  groupIDsPtr_.reset(nullptr);
444 
445  faPatchList& patches = *this;
446 
447  boolList pending(patches.size(), true);
448 
449  // Add to specified patches
450  for (const label patchi : patchIDs)
451  {
452  if (pending.test(patchi))
453  {
454  pending.unset(patchi);
455  patches[patchi].addGroup(groupName);
456  }
457  }
458 
459  // Remove from other patches
460  forAll(patches, patchi)
461  {
462  if (pending.test(patchi))
463  {
464  patches[patchi].removeGroup(groupName);
465  }
466  }
467 }
468 
471 {
472  return PtrListOps::get<word>(*this, nameOp<faPatch>());
473 }
474 
477 {
478  return PtrListOps::get<word>(*this, typeOp<faPatch>());
479 }
480 
481 
483 {
484  // Manually: faPatch does not have independent start() information
485 
486  const faPatchList& patches = *this;
487 
488  labelList list(patches.size());
489 
490  label beg = mesh_.nInternalEdges();
491  forAll(patches, patchi)
492  {
493  const label len = patches[patchi].nEdges();
494  list[patchi] = beg;
495  beg += len;
496  }
497  return list;
498 }
499 
500 
502 {
503  return
504  PtrListOps::get<label>
505  (
506  *this,
507  [](const faPatch& p) { return p.nEdges(); } // avoid virtual
508  );
509 }
510 
511 
513 {
514  const faPatchList& patches = *this;
515 
516  List<labelRange> list(patches.size());
517 
518  label beg = mesh_.nInternalEdges();
519  forAll(patches, patchi)
520  {
521  const label len = patches[patchi].nEdges();
522  list[patchi].reset(beg, len);
523  beg += len;
524  }
525  return list;
526 }
527 
530 {
531  return this->groupPatchIDs().sortedToc();
532 }
533 
535 Foam::label Foam::faBoundaryMesh::start() const
536 {
537  return mesh_.nInternalEdges();
538 }
539 
541 Foam::label Foam::faBoundaryMesh::nEdges() const
542 {
543  return mesh_.nBoundaryEdges();
544 }
545 
546 
548 {
549  return labelRange(mesh_.nInternalEdges(), mesh_.nBoundaryEdges());
550 }
551 
552 
554 (
555  const wordRe& matcher,
556  const bool useGroups
557 ) const
558 {
559  if (matcher.empty())
560  {
561  return labelList();
562  }
563 
564  // Only check groups if requested and they exist
565  const bool checkGroups = (useGroups && this->hasGroupIDs());
566 
567  labelHashSet ids(0);
568 
569  if (matcher.isPattern())
570  {
571  if (checkGroups)
572  {
573  ids.reserve(this->size());
574 
575  const auto& groupLookup = groupPatchIDs();
576  forAllConstIters(groupLookup, iter)
577  {
578  if (matcher(iter.key()))
579  {
580  // Add patch ids associated with the group
581  ids.insert(iter.val());
582  }
583  }
584  }
585 
586  if (ids.empty())
587  {
588  return PtrListOps::findMatching(*this, matcher);
589  }
590  else
591  {
592  ids.insert(PtrListOps::findMatching(*this, matcher));
593  }
594  }
595  else
596  {
597  // Literal string.
598  // Special version of above for reduced memory footprint
599 
600  const label patchId = PtrListOps::firstMatching(*this, matcher);
601 
602  if (patchId >= 0)
603  {
604  return labelList(one{}, patchId);
605  }
606  else if (checkGroups)
607  {
608  const auto iter = groupPatchIDs().cfind(matcher);
609 
610  if (iter.good())
611  {
612  // Add patch ids associated with the group
613  ids.insert(iter.val());
614  }
615  }
616  }
617 
618  return ids.sortedToc();
619 }
620 
621 
623 (
624  const wordRes& matcher,
625  const bool useGroups
626 ) const
627 {
628  if (matcher.empty())
629  {
630  return labelList();
631  }
632  else if (matcher.size() == 1)
633  {
634  return this->indices(matcher.front(), useGroups);
635  }
636 
637  labelHashSet ids(0);
638 
639  // Only check groups if requested and they exist
640  if (useGroups && this->hasGroupIDs())
641  {
642  ids.reserve(this->size());
643 
644  const auto& groupLookup = groupPatchIDs();
645  forAllConstIters(groupLookup, iter)
646  {
647  if (matcher(iter.key()))
648  {
649  // Add patch ids associated with the group
650  ids.insert(iter.val());
651  }
652  }
653  }
654 
655  if (ids.empty())
656  {
657  return PtrListOps::findMatching(*this, matcher);
658  }
659  else
660  {
661  ids.insert(PtrListOps::findMatching(*this, matcher));
662  }
663 
664  return ids.sortedToc();
665 }
666 
667 
669 (
670  const wordRes& select,
671  const wordRes& ignore,
672  const bool useGroups
673 ) const
674 {
675  if (ignore.empty())
676  {
677  return this->indices(select, useGroups);
678  }
679 
680  const wordRes::filter matcher(select, ignore);
681 
682  labelHashSet ids(0);
683 
684  // Only check groups if requested and they exist
685  if (useGroups && this->hasGroupIDs())
686  {
687  ids.reserve(this->size());
688 
689  const auto& groupLookup = groupPatchIDs();
690  forAllConstIters(groupLookup, iter)
691  {
692  if (matcher(iter.key()))
693  {
694  // Add patch ids associated with the group
695  ids.insert(iter.val());
696  }
697  }
698  }
699 
700  if (ids.empty())
701  {
702  return PtrListOps::findMatching(*this, matcher);
703  }
704  else
705  {
706  ids.insert(PtrListOps::findMatching(*this, matcher));
707  }
708 
709  return ids.sortedToc();
710 }
711 
712 
713 Foam::label Foam::faBoundaryMesh::findIndex(const wordRe& key) const
714 {
715  if (key.empty())
716  {
717  return -1;
718  }
719  return PtrListOps::firstMatching(*this, key);
720 }
721 
722 
724 (
725  const word& patchName,
726  bool allowNotFound
727 ) const
728 {
729  if (patchName.empty())
730  {
731  return -1;
732  }
733 
734  const label patchId = PtrListOps::firstMatching(*this, patchName);
735 
736  if (patchId >= 0)
737  {
738  return patchId;
739  }
740 
741  if (!allowNotFound)
742  {
744  << "Patch '" << patchName << "' not found. "
745  << "Available patch names: " << names() << endl
746  << exit(FatalError);
747  }
748 
749  // Patch not found
750  if (debug)
751  {
752  Pout<< "label faBoundaryMesh::findPatchID(const word&) const"
753  << "Patch named " << patchName << " not found. "
754  << "Available patch names: " << names() << endl;
755  }
756 
757  // Not found, return -1
758  return -1;
759 }
760 
761 
762 Foam::label Foam::faBoundaryMesh::whichPatch(const label edgeIndex) const
763 {
764  if (edgeIndex < mesh().nInternalEdges())
765  {
766  // Internal edge
767  return -1;
768  }
769  else if (edgeIndex >= mesh().nEdges())
770  {
771  // Bounds error: abort
773  << "Edge " << edgeIndex
774  << " out of bounds. Number of geometric edges " << mesh().nEdges()
775  << abort(FatalError);
776 
777  return -1;
778  }
779 
780  // Find patch that the edgeIndex belongs to.
781 
782  forAll(*this, patchi)
783  {
784  label start = mesh_.patchStarts()[patchi];
785  label size = operator[](patchi).faPatch::size();
786 
787  if (edgeIndex >= start && edgeIndex < start + size)
788  {
789  return patchi;
790  }
791  }
792 
793  // If not in any of above, it's trouble!
795  << "Error in patch search algorithm"
796  << abort(FatalError);
797 
798  return -1;
799 }
800 
801 
802 bool Foam::faBoundaryMesh::checkParallelSync(const bool report) const
803 {
804  if (!Pstream::parRun())
805  {
806  return false;
807  }
808 
809  const faBoundaryMesh& bm = *this;
810 
811  bool hasError = false;
812 
813  // Collect non-proc patches and check proc patches are last.
814  wordList localNames(bm.size());
815  wordList localTypes(bm.size());
816 
817  label nonProci = 0;
818 
819  forAll(bm, patchi)
820  {
821  if (!isA<processorFaPatch>(bm[patchi]))
822  {
823  if (nonProci != patchi)
824  {
825  // A processor patch in between normal patches!
826  hasError = true;
827 
828  if (debug || report)
829  {
830  Pout<< " ***Problem with boundary patch " << patchi
831  << " name:" << bm[patchi].name()
832  << " type:" << bm[patchi].type()
833  << " - seems to be preceeded by processor patches."
834  << " This is usually a problem." << endl;
835  }
836  }
837  else
838  {
839  localNames[nonProci] = bm[patchi].name();
840  localTypes[nonProci] = bm[patchi].type();
841  ++nonProci;
842  }
843  }
844  }
845  localNames.resize(nonProci);
846  localTypes.resize(nonProci);
847 
848  // Check and report error(s) on master
849  // - don't need indexing on master itself
850 
851  const globalIndex procAddr(globalIndex::gatherNonLocal{}, nonProci);
852 
853  const wordList allNames(procAddr.gather(localNames));
854  const wordList allTypes(procAddr.gather(localTypes));
855 
856  // Automatically restricted to master
857  for (const int proci : procAddr.subProcs())
858  {
859  const auto procNames(allNames.slice(procAddr.range(proci)));
860  const auto procTypes(allTypes.slice(procAddr.range(proci)));
861 
862  if (procNames != localNames || procTypes != localTypes)
863  {
864  hasError = true;
865 
866  if (debug || report)
867  {
868  Info<< " ***Inconsistent patches across processors, "
869  "processor0 has patch names:" << localNames
870  << " patch types:" << localTypes
871  << " processor" << proci
872  << " has patch names:" << procNames
873  << " patch types:" << procTypes
874  << endl;
875  }
876  }
877  }
878 
879  // Reduce (not broadcast) to respect local out-of-order errors (first loop)
880  return returnReduceOr(hasError);
881 }
882 
883 
884 bool Foam::faBoundaryMesh::checkDefinition(const bool report) const
885 {
886  label nextPatchStart = mesh().nInternalEdges();
887  const faBoundaryMesh& bm = *this;
888 
889  bool hasError = false;
890 
891  forAll(bm, patchi)
892  {
893  if (bm[patchi].start() != nextPatchStart && !hasError)
894  {
895  hasError = true;
896 
898  << " ****Problem with boundary patch " << patchi
899  << " named " << bm[patchi].name()
900  << " of type " << bm[patchi].type()
901  << ". The patch should start on face no " << nextPatchStart
902  << " and the patch specifies " << bm[patchi].start()
903  << "." << endl
904  << "Possibly consecutive patches have this same problem."
905  << " Suppressing future warnings." << endl;
906  }
907 
908  // Warn about duplicate boundary patches?
909 
910  nextPatchStart += bm[patchi].faPatch::size();
911  }
912 
913  if (hasError)
914  {
916  << "This mesh is not valid: boundary definition is in error."
917  << endl;
918  }
919  else
920  {
921  if (debug || report)
922  {
923  Info << "Boundary definition OK." << endl;
924  }
925  }
926 
927  return hasError;
928 }
929 
930 
932 {
933  // See comments in calcGeometry()
934 
935  (void)mesh_.edgeAreaNormals();
936  (void)mesh_.pointAreaNormals();
937 
938  (void)mesh_.areaCentres();
939  (void)mesh_.faceAreaNormals();
940 
941 
942  PstreamBuffers pBufs(Pstream::defaultCommsType);
943 
944  if
945  (
946  pBufs.commsType() == Pstream::commsTypes::buffered
947  || pBufs.commsType() == Pstream::commsTypes::nonBlocking
948  )
949  {
950  forAll(*this, patchi)
951  {
952  operator[](patchi).initMovePoints(pBufs, p);
953  }
954 
955  pBufs.finishedSends();
956 
957  forAll(*this, patchi)
958  {
959  operator[](patchi).movePoints(pBufs, p);
960  }
961  }
962  else if (pBufs.commsType() == Pstream::commsTypes::scheduled)
963  {
964  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
965 
966  // Dummy.
967  pBufs.finishedSends();
968 
969  for (const auto& schedEval : patchSchedule)
970  {
971  const label patchi = schedEval.patch;
972 
973  if (schedEval.init)
974  {
975  operator[](patchi).initMovePoints(pBufs, p);
976  }
977  else
978  {
979  operator[](patchi).movePoints(pBufs, p);
980  }
981  }
982  }
983 }
984 
985 
987 {
988  PstreamBuffers pBufs(Pstream::defaultCommsType);
989 
990  if
991  (
992  pBufs.commsType() == Pstream::commsTypes::buffered
993  || pBufs.commsType() == Pstream::commsTypes::nonBlocking
994  )
995  {
996  forAll(*this, patchi)
997  {
998  operator[](patchi).initUpdateMesh(pBufs);
999  }
1000 
1001  pBufs.finishedSends();
1002 
1003  forAll(*this, patchi)
1004  {
1005  operator[](patchi).updateMesh(pBufs);
1006  }
1007  }
1008  else if (pBufs.commsType() == Pstream::commsTypes::scheduled)
1009  {
1010  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
1011 
1012  // Dummy.
1013  pBufs.finishedSends();
1014 
1015  for (const auto& schedEval : patchSchedule)
1016  {
1017  const label patchi = schedEval.patch;
1018 
1019  if (schedEval.init)
1020  {
1021  operator[](patchi).initUpdateMesh(pBufs);
1022  }
1023  else
1024  {
1025  operator[](patchi).updateMesh(pBufs);
1026  }
1027  }
1028  }
1029 }
1030 
1031 
1032 void Foam::faBoundaryMesh::writeEntry(Ostream& os) const
1033 {
1034  const faPatchList& entries = *this;
1035 
1036  os << entries.size();
1037 
1038  if (entries.empty())
1039  {
1040  // 0-sized : can write with less vertical space
1042  }
1043  else
1044  {
1045  os << nl << token::BEGIN_LIST << incrIndent << nl;
1046 
1047  for (const auto& pp : entries)
1048  {
1049  os.beginBlock(pp.name());
1050  os << pp;
1051  os.endBlock();
1052  }
1054  }
1056 }
1057 
1058 
1060 (
1061  const word& keyword,
1062  Ostream& os
1063 ) const
1064 {
1065  const faPatchList& entries = *this;
1066 
1067  if (!keyword.empty())
1068  {
1069  os.write(keyword);
1070  os << (entries.empty() ? token::SPACE : token::NL);
1071  }
1073  writeEntry(os);
1074 
1075  if (!keyword.empty()) os.endEntry();
1076 }
1077 
1078 
1081  writeEntry(os);
1082  return os.good();
1083 }
1084 
1085 
1087 (
1088  IOstreamOption streamOpt,
1089  const bool writeOnProc
1090 ) const
1091 {
1093  return regIOobject::writeObject(streamOpt, writeOnProc);
1094 }
1095 
1096 
1097 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1098 
1099 Foam::Ostream& Foam::operator<<(Ostream& os, const faBoundaryMesh& bm)
1100 {
1101  bm.writeData(os);
1102  return os;
1103 }
1104 
1105 
1106 // ************************************************************************* //
wordList groupNames() const
A list of the group names (if any)
label whichPatch(const label edgeIndex) const
Return patch index for a given edge label.
PtrList< faPatch > faPatchList
Store lists of faPatch as a PtrList.
Definition: faPatch.H:59
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:133
labelRange range(const label proci) const
Return start/size range of proci data.
Definition: globalIndexI.H:282
label patchId(-1)
List< labelRange > patchRanges() const
Return a list of patch ranges.
const labelList patchIDs(pbm.indices(polyPatchNames, true))
static autoPtr< faPatch > New(const word &name, const dictionary &dict, const label index, const faBoundaryMesh &bm)
Return pointer to a new patch created on freestore from dictionary.
Definition: faPatchNew.C:28
dictionary dict
autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:629
labelList indices(const wordRe &matcher, const bool useGroups=true) const
Return (sorted) patch indices for all matches.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access. ...
Definition: UList.H:805
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with &#39;name()&#39; that matches.
bool checkDefinition(const bool report=false) const
Check boundary definition.
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
void clear()
Clear the patch list and all demand-driven data.
virtual const fileName & name() const
The name of the stream.
Definition: IOstream.C:33
virtual bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
virtual Ostream & write(const char c) override
Write character.
Definition: OBJstream.C:69
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
lduInterfacePtrsList interfaces() const
Return a list of pointers for each patch with only those pointing to interfaces being set...
void calcGeometry()
Calculate the geometry for the patches.
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
labelList patchSizes() const
Return a list of patch sizes (number of edges in each patch)
UPtrList< const labelUList > edgeFaces() const
Return a list of edgeFaces for each patch.
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
Definition: BitOps.C:134
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Type type(bool followLink=true, bool checkGzip=false) const
Return the directory entry type: UNDEFINED, FILE, DIRECTORY (or SYMLINK).
Definition: fileName.C:353
Newline [isspace].
Definition: token.H:130
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
void updateMesh()
Correct faBoundaryMesh after topology update.
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1061
Begin list [isseparator].
Definition: token.H:161
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
Definition: lduSchedule.H:46
Functions to operate on Pointer Lists.
A simple container for options an IOstream can normally have.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
const HashTable< labelList > & groupPatchIDs() const
The patch indices per patch group.
label findIndex(const wordRe &key) const
Return patch index for the first match, return -1 if not found.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
Definition: OSstream.H:134
void writeEntry(Ostream &os) const
Write as a plain list of entries.
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
Extract name (as a word) from an object, typically using its name() method.
Definition: word.H:340
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
void resize_null(const label newLen)
Set the addressed list to the given size, deleting all existing entries. Afterwards the list contains...
Definition: PtrListI.H:96
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
void movePoints(const pointField &)
Correct faBoundaryMesh after moving points.
dynamicFvMesh & mesh
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
wordList names() const
Return a list of patch names.
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:108
Space [isspace].
Definition: token.H:131
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
const globalMeshData & globalData() const
Return parallel info (demand-driven)
Definition: polyMesh.C:1311
End list [isseparator].
Definition: token.H:162
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
errorManip< error > abort(error &err)
Definition: errorManip.H:139
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: PtrList.H:159
label nEdges() const
Number of mesh edges.
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
Definition: wordRe.H:78
label nInternalEdges() const
Internal edges using 0,1 or 2 boundary points.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
int debug
Static debugging option.
wordList types() const
Return a list of patch types.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
faBoundaryMesh(const faBoundaryMesh &)=delete
No copy construct.
defineTypeNameAndDebug(combustionModel, 0)
Finite area patch class. Used for 2-D non-Euclidian finite area method.
Definition: faPatch.H:72
compressionType compression() const noexcept
Get the stream compression.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:511
Buffers for inter-processor communications streams (UOPstream, UIPstream).
label start() const
The start label of the edges in the faMesh edges list.
UPtrList< const labelUList > edgeLabels() const
Return a list of edgeLabels for each patch.
label nEdges() const
The number of boundary edges for the underlying mesh.
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
Definition: globalIndexI.H:197
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
List< word > wordList
List of word.
Definition: fileName.H:59
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:397
#define WarningInFunction
Report a warning using Foam::Warning.
globalIndex procAddr(aMesh.nFaces())
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
label nNonProcessor() const
The number of patches before the first processor patch.
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
const lduSchedule & patchSchedule() const noexcept
Order in which the patches should be initialised/evaluated corresponding to the schedule.
const polyBoundaryMesh & patches
void setGroup(const word &groupName, const labelUList &patchIDs)
Set/add group with patches.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:68
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition: PtrListI.H:81
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:90
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
labelRange range() const
The edge range for all boundary edges.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
virtual Ostream & endEntry()
Write end entry (&#39;;&#39;) followed by newline.
Definition: Ostream.C:117
"buffered" : (MPI_Bsend, MPI_Recv)
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:502
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc=true) const
Write using stream options, but always UNCOMPRESSED.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
Calculate the matrix for the second temporal derivative.
labelList patchStarts() const
Return a list of patch start indices.
List< bool > boolList
A List of bools.
Definition: List.H:60
label nProcessorPatches() const
The number of processorFaPatch patches.
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
Definition: wordReI.H:104
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Extract type (as a word) from an object, typically using its type() method.
Definition: word.H:361
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with &#39;name()&#39; that matches, -1 on failure.
#define InfoInFunction
Report an information message using Foam::Info.