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-2023 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 "primitiveMesh.H"
33 #include "processorFaPatch.H"
34 #include "wordRes.H"
35 #include "PtrListOps.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41  defineTypeNameAndDebug(faBoundaryMesh, 0);
42 }
43 
44 
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 
47 bool Foam::faBoundaryMesh::hasGroupIDs() const
48 {
49  if (groupIDsPtr_)
50  {
51  // Use existing cache
52  return !groupIDsPtr_->empty();
53  }
54 
55  const faPatchList& patches = *this;
56 
57  for (const faPatch& p : patches)
58  {
59  if (!p.inGroups().empty())
60  {
61  return true;
62  }
63  }
64 
65  return false;
66 }
67 
68 
69 void Foam::faBoundaryMesh::calcGroupIDs() const
70 {
71  if (groupIDsPtr_)
72  {
73  return; // Or FatalError
74  }
75 
76  groupIDsPtr_.emplace(16);
77  auto& groupLookup = *groupIDsPtr_;
78 
79  const faPatchList& patches = *this;
80 
81  forAll(patches, patchi)
82  {
83  for (const word& groupName : patches[patchi].inGroups())
84  {
85  groupLookup(groupName).push_back(patchi);
86  }
87  }
88 
89  // Remove groups that clash with patch names
90  forAll(patches, patchi)
91  {
92  if (groupLookup.erase(patches[patchi].name()))
93  {
95  << "Removed group '" << patches[patchi].name()
96  << "' which clashes with patch " << patchi
97  << " of the same name."
98  << endl;
99  }
100  }
101 }
102 
103 
104 void Foam::faBoundaryMesh::populate(PtrList<entry>&& entries)
105 {
106  clearLocalAddressing();
107 
108  faPatchList& patches = *this;
109 
110  patches.resize_null(entries.size());
111 
112  // Transcribe.
113  // Does not handle nullptr at all (what could possibly be done?)
114  forAll(patches, patchi)
115  {
116  patches.set
117  (
118  patchi,
120  (
121  entries[patchi].keyword(),
122  entries[patchi].dict(),
123  patchi,
124  *this
125  )
126  );
127  }
128 
129  entries.clear();
130 }
131 
132 
133 bool Foam::faBoundaryMesh::readContents(const bool allowOptionalRead)
134 {
135  bool updated = false;
136  PtrList<entry> entries;
137 
138  if
139  (
140  isReadRequired()
141  || (allowOptionalRead && this->isReadOptional() && this->headerOk())
142  )
143  {
144  // Warn for MUST_READ_IF_MODIFIED
145  warnNoRereading<faBoundaryMesh>();
146 
147  // Read entries
148  Istream& is = readStream(typeName);
149 
150  is >> entries;
151 
152  is.check(FUNCTION_NAME);
153  close();
154  updated = true;
155  }
156  // Future: support master-only and broadcast?
157 
158  if (updated)
159  {
160  populate(std::move(entries));
161  }
162 
163  return updated;
164 }
165 
166 
167 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
168 
170 (
171  const IOobject& io,
172  const faMesh& mesh
173 )
174 :
175  faPatchList(),
176  regIOobject(io),
177  mesh_(mesh)
178 {
179  readContents(false); // allowOptionalRead = false
180 }
181 
182 
184 (
185  const IOobject& io,
186  const faMesh& pm,
187  Foam::zero
188 )
189 :
191  regIOobject(io),
192  mesh_(pm)
193 {}
194 
195 
197 (
198  const IOobject& io,
199  const faMesh& pm,
200  const label size
201 )
202 :
203  faPatchList(size),
204  regIOobject(io),
205  mesh_(pm)
206 {}
207 
208 
210 (
211  const IOobject& io,
212  const faMesh& fam,
213  const faPatchList& list
214 )
215 :
216  faPatchList(),
217  regIOobject(io),
218  mesh_(fam)
219 {
220  if (!readContents(true)) // allowOptionalRead = true
221  {
222  // Nothing read. Use supplied patches
223  faPatchList& patches = *this;
224  patches.resize(list.size());
225 
226  forAll(patches, patchi)
227  {
228  patches.set(patchi, list[patchi].clone(*this));
229  }
230  }
231 }
232 
233 
235 (
236  const IOobject& io,
237  const faMesh& fam,
238  PtrList<entry>&& entries
239 )
240 :
241  faPatchList(),
242  regIOobject(io),
243  mesh_(fam)
244 {
245  if (!readContents(true)) // allowOptionalRead = true
246  {
247  populate(std::move(entries));
248  }
249  entries.clear();
250 }
251 
252 
253 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
254 
256 {
257  clearLocalAddressing();
259 }
260 
261 
262 void Foam::faBoundaryMesh::clearLocalAddressing()
263 {
264  groupIDsPtr_.reset(nullptr);
265 }
266 
267 
268 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
269 
271 {
272  // processor initGeometry send/recv the following:
273  // - edgeCentres() : faMesh::edgeCentres()
274  // - edgeLengths() : faMesh::Le()
275  // - edgeFaceCentres() : faMesh::areaCentres()
276  //
277  // faMesh::Le() has its own point-to-point communication (OK) but
278  // triggers either/or edgeAreaNormals(), pointAreaNormals()
279  // with their own communication that can block.
280 
281  // This uses parallel comms and hence will not be trigggered
282  // on processors that do not have a processorFaPatch so instead
283  // force construction.
284 
285  (void)mesh_.edgeAreaNormals();
286  (void)mesh_.pointAreaNormals();
287 
288  (void)mesh_.areaCentres();
289  (void)mesh_.faceAreaNormals();
290 
291 
293 
294  if
295  (
296  pBufs.commsType() == Pstream::commsTypes::blocking
297  || pBufs.commsType() == Pstream::commsTypes::nonBlocking
298  )
299  {
300  forAll(*this, patchi)
301  {
302  operator[](patchi).initGeometry(pBufs);
303  }
304 
305  pBufs.finishedSends();
306 
307  forAll(*this, patchi)
308  {
309  operator[](patchi).calcGeometry(pBufs);
310  }
311  }
312  else if (pBufs.commsType() == Pstream::commsTypes::scheduled)
313  {
314  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
315 
316  // Dummy.
317  pBufs.finishedSends();
318 
319  for (const auto& patchEval : patchSchedule)
320  {
321  const label patchi = patchEval.patch;
322 
323  if (patchEval.init)
324  {
325  operator[](patchi).initGeometry(pBufs);
326  }
327  else
328  {
329  operator[](patchi).calcGeometry(pBufs);
330  }
331  }
332  }
333 }
334 
335 
338 {
339  const faPatchList& patches = *this;
340 
341  UPtrList<const labelUList> list(patches.size());
342 
343  forAll(list, patchi)
344  {
345  list.set(patchi, &patches[patchi].edgeLabels());
346  }
347 
348  return list;
349 }
350 
351 
354 {
355  const faPatchList& patches = *this;
356 
357  UPtrList<const labelUList> list(patches.size());
358 
359  forAll(list, patchi)
360  {
361  list.set(patchi, &patches[patchi].edgeFaces());
362  }
363 
364  return list;
365 }
366 
367 
369 {
370  const faPatchList& patches = *this;
371 
373 
374  forAll(list, patchi)
375  {
376  const lduInterface* lduPtr = isA<lduInterface>(patches[patchi]);
377 
378  if (lduPtr)
379  {
380  list.set(patchi, lduPtr);
381  }
382  }
383 
384  return list;
385 }
386 
387 
388 Foam::label Foam::faBoundaryMesh::nNonProcessor() const
389 {
390  const faPatchList& patches = *this;
391 
392  label count = 0;
393 
394  for (const faPatch& p : patches)
395  {
396  if (isA<processorFaPatch>(p))
397  {
398  break;
399  }
400 
401  ++count;
402  }
403 
404  return count;
405 }
406 
407 
408 Foam::label Foam::faBoundaryMesh::nProcessorPatches() const
409 {
410  const faPatchList& patches = *this;
411 
412  label count = 0;
413 
414  for (const faPatch& p : patches)
415  {
416  if (isA<processorFaPatch>(p))
417  {
418  ++count;
419  }
420  }
421 
422  return count;
423 }
424 
425 
428 {
429  if (!groupIDsPtr_)
430  {
431  calcGroupIDs();
432  }
433 
434  return *groupIDsPtr_;
435 }
436 
437 
439 (
440  const word& groupName,
441  const labelUList& patchIDs
442 )
443 {
444  groupIDsPtr_.reset(nullptr);
445 
446  faPatchList& patches = *this;
447 
448  boolList pending(patches.size(), true);
449 
450  // Add to specified patches
451  for (const label patchi : patchIDs)
452  {
453  if (pending.test(patchi))
454  {
455  pending.unset(patchi);
456  patches[patchi].addGroup(groupName);
457  }
458  }
459 
460  // Remove from other patches
461  forAll(patches, patchi)
462  {
463  if (pending.test(patchi))
464  {
465  patches[patchi].removeGroup(groupName);
466  }
467  }
468 }
469 
472 {
473  return PtrListOps::get<word>(*this, nameOp<faPatch>());
474 }
475 
478 {
479  return PtrListOps::get<word>(*this, typeOp<faPatch>());
480 }
481 
482 
484 {
485  // Manually: faPatch does not have independent start() information
486 
487  const faPatchList& patches = *this;
488 
489  labelList list(patches.size());
490 
491  label beg = mesh_.nInternalEdges();
492  forAll(patches, patchi)
493  {
494  const label len = patches[patchi].nEdges();
495  list[patchi] = beg;
496  beg += len;
497  }
498  return list;
499 }
500 
501 
503 {
504  return
505  PtrListOps::get<label>
506  (
507  *this,
508  [](const faPatch& p) { return p.nEdges(); } // avoid virtual
509  );
510 }
511 
512 
514 {
515  const faPatchList& patches = *this;
516 
517  List<labelRange> list(patches.size());
518 
519  label beg = mesh_.nInternalEdges();
520  forAll(patches, patchi)
521  {
522  const label len = patches[patchi].nEdges();
523  list[patchi].reset(beg, len);
524  beg += len;
525  }
526  return list;
527 }
528 
531 {
532  return this->groupPatchIDs().sortedToc();
533 }
534 
536 Foam::label Foam::faBoundaryMesh::start() const
537 {
538  return mesh_.nInternalEdges();
539 }
540 
542 Foam::label Foam::faBoundaryMesh::nEdges() const
543 {
544  return mesh_.nBoundaryEdges();
545 }
546 
547 
549 {
550  return labelRange(mesh_.nInternalEdges(), mesh_.nBoundaryEdges());
551 }
552 
553 
555 (
556  const wordRe& matcher,
557  const bool useGroups
558 ) const
559 {
560  if (matcher.empty())
561  {
562  return labelList();
563  }
564 
565  // Only check groups if requested and they exist
566  const bool checkGroups = (useGroups && this->hasGroupIDs());
567 
568  labelHashSet ids(0);
569 
570  if (matcher.isPattern())
571  {
572  if (checkGroups)
573  {
574  ids.reserve(this->size());
575 
576  const auto& groupLookup = groupPatchIDs();
577  forAllConstIters(groupLookup, iter)
578  {
579  if (matcher(iter.key()))
580  {
581  // Add patch ids associated with the group
582  ids.insert(iter.val());
583  }
584  }
585  }
586 
587  if (ids.empty())
588  {
589  return PtrListOps::findMatching(*this, matcher);
590  }
591  else
592  {
593  ids.insert(PtrListOps::findMatching(*this, matcher));
594  }
595  }
596  else
597  {
598  // Literal string.
599  // Special version of above for reduced memory footprint
600 
601  const label patchId = PtrListOps::firstMatching(*this, matcher);
602 
603  if (patchId >= 0)
604  {
605  return labelList(one{}, patchId);
606  }
607  else if (checkGroups)
608  {
609  const auto iter = groupPatchIDs().cfind(matcher);
610 
611  if (iter.good())
612  {
613  // Add patch ids associated with the group
614  ids.insert(iter.val());
615  }
616  }
617  }
618 
619  return ids.sortedToc();
620 }
621 
622 
624 (
625  const wordRes& matcher,
626  const bool useGroups
627 ) const
628 {
629  if (matcher.empty())
630  {
631  return labelList();
632  }
633  else if (matcher.size() == 1)
634  {
635  return this->indices(matcher.front(), useGroups);
636  }
637 
638  labelHashSet ids(0);
639 
640  // Only check groups if requested and they exist
641  if (useGroups && this->hasGroupIDs())
642  {
643  ids.reserve(this->size());
644 
645  const auto& groupLookup = groupPatchIDs();
646  forAllConstIters(groupLookup, iter)
647  {
648  if (matcher(iter.key()))
649  {
650  // Add patch ids associated with the group
651  ids.insert(iter.val());
652  }
653  }
654  }
655 
656  if (ids.empty())
657  {
658  return PtrListOps::findMatching(*this, matcher);
659  }
660  else
661  {
662  ids.insert(PtrListOps::findMatching(*this, matcher));
663  }
664 
665  return ids.sortedToc();
666 }
667 
668 
670 (
671  const wordRes& select,
672  const wordRes& ignore,
673  const bool useGroups
674 ) const
675 {
676  if (ignore.empty())
677  {
678  return this->indices(select, useGroups);
679  }
680 
681  const wordRes::filter matcher(select, ignore);
682 
683  labelHashSet ids(0);
684 
685  // Only check groups if requested and they exist
686  if (useGroups && this->hasGroupIDs())
687  {
688  ids.reserve(this->size());
689 
690  const auto& groupLookup = groupPatchIDs();
691  forAllConstIters(groupLookup, iter)
692  {
693  if (matcher(iter.key()))
694  {
695  // Add patch ids associated with the group
696  ids.insert(iter.val());
697  }
698  }
699  }
700 
701  if (ids.empty())
702  {
703  return PtrListOps::findMatching(*this, matcher);
704  }
705  else
706  {
707  ids.insert(PtrListOps::findMatching(*this, matcher));
708  }
709 
710  return ids.sortedToc();
711 }
712 
713 
714 Foam::label Foam::faBoundaryMesh::findIndex(const wordRe& key) const
715 {
716  if (key.empty())
717  {
718  return -1;
719  }
720  return PtrListOps::firstMatching(*this, key);
721 }
722 
723 
725 (
726  const word& patchName,
727  bool allowNotFound
728 ) const
729 {
730  if (patchName.empty())
731  {
732  return -1;
733  }
734 
735  const label patchId = PtrListOps::firstMatching(*this, patchName);
736 
737  if (patchId >= 0)
738  {
739  return patchId;
740  }
741 
742  if (!allowNotFound)
743  {
745  << "Patch '" << patchName << "' not found. "
746  << "Available patch names: " << names() << endl
747  << exit(FatalError);
748  }
749 
750  // Patch not found
751  if (debug)
752  {
753  Pout<< "label faBoundaryMesh::findPatchID(const word&) const"
754  << "Patch named " << patchName << " not found. "
755  << "Available patch names: " << names() << endl;
756  }
757 
758  // Not found, return -1
759  return -1;
760 }
761 
762 
763 Foam::label Foam::faBoundaryMesh::whichPatch(const label edgeIndex) const
764 {
765  if (edgeIndex < mesh().nInternalEdges())
766  {
767  // Internal edge
768  return -1;
769  }
770  else if (edgeIndex >= mesh().nEdges())
771  {
772  // Bounds error: abort
774  << "Edge " << edgeIndex
775  << " out of bounds. Number of geometric edges " << mesh().nEdges()
776  << abort(FatalError);
777 
778  return -1;
779  }
780 
781  // Find patch that the edgeIndex belongs to.
782 
783  forAll(*this, patchi)
784  {
785  label start = mesh_.patchStarts()[patchi];
786  label size = operator[](patchi).faPatch::size();
787 
788  if (edgeIndex >= start && edgeIndex < start + size)
789  {
790  return patchi;
791  }
792  }
793 
794  // If not in any of above, it's trouble!
796  << "Error in patch search algorithm"
797  << abort(FatalError);
798 
799  return -1;
800 }
801 
802 
803 bool Foam::faBoundaryMesh::checkParallelSync(const bool report) const
804 {
805  if (!Pstream::parRun())
806  {
807  return false;
808  }
809 
810  const faBoundaryMesh& bm = *this;
811 
812  bool hasError = false;
813 
814  // Collect non-proc patches and check proc patches are last.
815  wordList localNames(bm.size());
816  wordList localTypes(bm.size());
817 
818  label nonProci = 0;
819 
820  forAll(bm, patchi)
821  {
822  if (!isA<processorFaPatch>(bm[patchi]))
823  {
824  if (nonProci != patchi)
825  {
826  // A processor patch in between normal patches!
827  hasError = true;
828 
829  if (debug || report)
830  {
831  Pout<< " ***Problem with boundary patch " << patchi
832  << " name:" << bm[patchi].name()
833  << " type:" << bm[patchi].type()
834  << " - seems to be preceeded by processor patches."
835  << " This is usually a problem." << endl;
836  }
837  }
838  else
839  {
840  localNames[nonProci] = bm[patchi].name();
841  localTypes[nonProci] = bm[patchi].type();
842  ++nonProci;
843  }
844  }
845  }
846  localNames.resize(nonProci);
847  localTypes.resize(nonProci);
848 
849  // Check and report error(s) on master
850  // - don't need indexing on master itself
851 
852  const globalIndex procAddr(globalIndex::gatherNonLocal{}, nonProci);
853 
854  const wordList allNames(procAddr.gather(localNames));
855  const wordList allTypes(procAddr.gather(localTypes));
856 
857  // Automatically restricted to master
858  for (const int proci : procAddr.subProcs())
859  {
860  const auto procNames(allNames.slice(procAddr.range(proci)));
861  const auto procTypes(allTypes.slice(procAddr.range(proci)));
862 
863  if (procNames != localNames || procTypes != localTypes)
864  {
865  hasError = true;
866 
867  if (debug || report)
868  {
869  Info<< " ***Inconsistent patches across processors, "
870  "processor0 has patch names:" << localNames
871  << " patch types:" << localTypes
872  << " processor" << proci
873  << " has patch names:" << procNames
874  << " patch types:" << procTypes
875  << endl;
876  }
877  }
878  }
879 
880  // Reduce (not broadcast) to respect local out-of-order errors (first loop)
881  return returnReduceOr(hasError);
882 }
883 
884 
885 bool Foam::faBoundaryMesh::checkDefinition(const bool report) const
886 {
887  label nextPatchStart = mesh().nInternalEdges();
888  const faBoundaryMesh& bm = *this;
889 
890  bool hasError = false;
891 
892  forAll(bm, patchi)
893  {
894  if (bm[patchi].start() != nextPatchStart && !hasError)
895  {
896  hasError = true;
897 
899  << " ****Problem with boundary patch " << patchi
900  << " named " << bm[patchi].name()
901  << " of type " << bm[patchi].type()
902  << ". The patch should start on face no " << nextPatchStart
903  << " and the patch specifies " << bm[patchi].start()
904  << "." << endl
905  << "Possibly consecutive patches have this same problem."
906  << " Suppressing future warnings." << endl;
907  }
908 
909  // Warn about duplicate boundary patches?
910 
911  nextPatchStart += bm[patchi].faPatch::size();
912  }
913 
914  if (hasError)
915  {
917  << "This mesh is not valid: boundary definition is in error."
918  << endl;
919  }
920  else
921  {
922  if (debug || report)
923  {
924  Info << "Boundary definition OK." << endl;
925  }
926  }
927 
928  return hasError;
929 }
930 
931 
933 {
934  // See comments in calcGeometry()
935 
936  (void)mesh_.edgeAreaNormals();
937  (void)mesh_.pointAreaNormals();
938 
939  (void)mesh_.areaCentres();
940  (void)mesh_.faceAreaNormals();
941 
942 
943  PstreamBuffers pBufs(Pstream::defaultCommsType);
944 
945  if
946  (
947  pBufs.commsType() == Pstream::commsTypes::blocking
948  || pBufs.commsType() == Pstream::commsTypes::nonBlocking
949  )
950  {
951  forAll(*this, patchi)
952  {
953  operator[](patchi).initMovePoints(pBufs, p);
954  }
955 
956  pBufs.finishedSends();
957 
958  forAll(*this, patchi)
959  {
960  operator[](patchi).movePoints(pBufs, p);
961  }
962  }
963  else if (pBufs.commsType() == Pstream::commsTypes::scheduled)
964  {
965  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
966 
967  // Dummy.
968  pBufs.finishedSends();
969 
970  for (const auto& schedEval : patchSchedule)
971  {
972  const label patchi = schedEval.patch;
973 
974  if (schedEval.init)
975  {
976  operator[](patchi).initMovePoints(pBufs, p);
977  }
978  else
979  {
980  operator[](patchi).movePoints(pBufs, p);
981  }
982  }
983  }
984 }
985 
986 
988 {
989  PstreamBuffers pBufs(Pstream::defaultCommsType);
990 
991  if
992  (
993  pBufs.commsType() == Pstream::commsTypes::blocking
994  || pBufs.commsType() == Pstream::commsTypes::nonBlocking
995  )
996  {
997  forAll(*this, patchi)
998  {
999  operator[](patchi).initUpdateMesh(pBufs);
1000  }
1001 
1002  pBufs.finishedSends();
1003 
1004  forAll(*this, patchi)
1005  {
1006  operator[](patchi).updateMesh(pBufs);
1007  }
1008  }
1009  else if (pBufs.commsType() == Pstream::commsTypes::scheduled)
1010  {
1011  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
1012 
1013  // Dummy.
1014  pBufs.finishedSends();
1015 
1016  for (const auto& schedEval : patchSchedule)
1017  {
1018  const label patchi = schedEval.patch;
1019 
1020  if (schedEval.init)
1021  {
1022  operator[](patchi).initUpdateMesh(pBufs);
1023  }
1024  else
1025  {
1026  operator[](patchi).updateMesh(pBufs);
1027  }
1028  }
1029  }
1030 }
1031 
1032 
1033 void Foam::faBoundaryMesh::writeEntry(Ostream& os) const
1034 {
1035  const faPatchList& entries = *this;
1036 
1037  os << entries.size();
1038 
1039  if (entries.empty())
1040  {
1041  // 0-sized : can write with less vertical space
1043  }
1044  else
1045  {
1046  os << nl << token::BEGIN_LIST << incrIndent << nl;
1047 
1048  for (const auto& pp : entries)
1049  {
1050  os.beginBlock(pp.name());
1051  os << pp;
1052  os.endBlock();
1053  }
1055  }
1057 }
1058 
1059 
1061 (
1062  const keyType& keyword,
1063  Ostream& os
1064 ) const
1065 {
1066  const faPatchList& entries = *this;
1067 
1068  if (!keyword.empty())
1069  {
1070  os.write(keyword);
1071  os << (entries.empty() ? token::SPACE : token::NL);
1072  }
1074  writeEntry(os);
1075 
1076  if (!keyword.empty()) os.endEntry();
1077 }
1078 
1079 
1082  writeEntry(os);
1083  return os.good();
1084 }
1085 
1086 
1088 (
1089  IOstreamOption streamOpt,
1090  const bool writeOnProc
1091 ) const
1092 {
1094  return regIOobject::writeObject(streamOpt, writeOnProc);
1095 }
1096 
1097 
1098 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1099 
1100 Foam::Ostream& Foam::operator<<(Ostream& os, const faBoundaryMesh& bm)
1101 {
1102  bm.writeData(os);
1103  return os;
1104 }
1105 
1106 
1107 // ************************************************************************* //
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:87
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:621
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:796
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with &#39;name()&#39; that matches.
"blocking" : (MPI_Bsend, MPI_Recv)
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:598
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:1049
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:128
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_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:385
#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:66
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition: PtrListI.H:81
"nonBlocking" : (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
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:172
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.