polyBoundaryMesh.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 | Copyright (C) 2011-2016 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "polyBoundaryMesh.H"
27 #include "polyMesh.H"
28 #include "primitiveMesh.H"
29 #include "processorPolyPatch.H"
30 #include "stringListOps.H"
31 #include "PstreamBuffers.H"
32 #include "lduSchedule.H"
33 #include "globalMeshData.H"
34 #include "stringListOps.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 defineTypeNameAndDebug(polyBoundaryMesh, 0);
41 }
42 
43 
44 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
45 
46 Foam::polyBoundaryMesh::polyBoundaryMesh
47 (
48  const IOobject& io,
49  const polyMesh& mesh
50 )
51 :
52  polyPatchList(),
53  regIOobject(io),
54  mesh_(mesh)
55 {
56  if
57  (
58  readOpt() == IOobject::MUST_READ
59  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
60  )
61  {
62  if (readOpt() == IOobject::MUST_READ_IF_MODIFIED)
63  {
65  << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
66  << " does not support automatic rereading."
67  << endl;
68  }
69 
70 
71  polyPatchList& patches = *this;
72 
73  // Read polyPatchList
74  Istream& is = readStream(typeName);
75 
76  PtrList<entry> patchEntries(is);
77  patches.setSize(patchEntries.size());
78 
79  forAll(patches, patchi)
80  {
81  patches.set
82  (
83  patchi,
85  (
86  patchEntries[patchi].keyword(),
87  patchEntries[patchi].dict(),
88  patchi,
89  *this
90  )
91  );
92  }
93 
94  // Check state of IOstream
95  is.check
96  (
97  "polyBoundaryMesh::polyBoundaryMesh"
98  "(const IOobject&, const polyMesh&)"
99  );
100 
101  close();
102  }
103 }
104 
105 
106 Foam::polyBoundaryMesh::polyBoundaryMesh
107 (
108  const IOobject& io,
109  const polyMesh& pm,
110  const label size
111 )
112 :
113  polyPatchList(size),
114  regIOobject(io),
115  mesh_(pm)
116 {}
117 
118 
119 Foam::polyBoundaryMesh::polyBoundaryMesh
120 (
121  const IOobject& io,
122  const polyMesh& pm,
123  const polyPatchList& ppl
124 )
125 :
126  polyPatchList(),
127  regIOobject(io),
128  mesh_(pm)
129 {
130  if
131  (
132  (this->readOpt() == IOobject::READ_IF_PRESENT && this->headerOk())
133  || this->readOpt() == IOobject::MUST_READ
134  || this->readOpt() == IOobject::MUST_READ_IF_MODIFIED
135  )
136  {
137 
138  if (readOpt() == IOobject::MUST_READ_IF_MODIFIED)
139  {
141  << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
142  << " does not support automatic rereading."
143  << endl;
144  }
145 
146  polyPatchList& patches = *this;
147 
148  // Read polyPatchList
149  Istream& is = readStream(typeName);
150 
151  PtrList<entry> patchEntries(is);
152  patches.setSize(patchEntries.size());
153 
154  forAll(patches, patchi)
155  {
156  patches.set
157  (
158  patchi,
160  (
161  patchEntries[patchi].keyword(),
162  patchEntries[patchi].dict(),
163  patchi,
164  *this
165  )
166  );
167  }
168 
169  // Check state of IOstream
170  is.check
171  (
172  "polyBoundaryMesh::polyBoundaryMesh"
173  "(const IOobject&, const polyMesh&, const polyPatchList&)"
174  );
175 
176  close();
177  }
178  else
179  {
180  polyPatchList& patches = *this;
181  patches.setSize(ppl.size());
182  forAll(patches, patchi)
183  {
184  patches.set(patchi, ppl[patchi].clone(*this).ptr());
185  }
186  }
187 }
188 
189 
190 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
191 
193 {}
194 
195 
197 {
198  forAll(*this, patchi)
199  {
200  operator[](patchi).clearGeom();
201  }
202 }
203 
204 
206 {
207  neighbourEdgesPtr_.clear();
208  patchIDPtr_.clear();
209  groupPatchIDsPtr_.clear();
210 
211  forAll(*this, patchi)
212  {
213  operator[](patchi).clearAddressing();
214  }
215 }
216 
217 
218 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
219 
220 void Foam::polyBoundaryMesh::calcGeometry()
221 {
223 
224  if
225  (
228  )
229  {
230  forAll(*this, patchi)
231  {
232  operator[](patchi).initGeometry(pBufs);
233  }
234 
235  pBufs.finishedSends();
236 
237  forAll(*this, patchi)
238  {
239  operator[](patchi).calcGeometry(pBufs);
240  }
241  }
243  {
244  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
245 
246  // Dummy.
247  pBufs.finishedSends();
248 
249  forAll(patchSchedule, patchEvali)
250  {
251  const label patchi = patchSchedule[patchEvali].patch;
252 
253  if (patchSchedule[patchEvali].init)
254  {
255  operator[](patchi).initGeometry(pBufs);
256  }
257  else
258  {
259  operator[](patchi).calcGeometry(pBufs);
260  }
261  }
262  }
263 }
264 
265 
268 {
269  if (Pstream::parRun())
270  {
272  << "Neighbour edge addressing not correct across parallel"
273  << " boundaries." << endl;
274  }
275 
276  if (!neighbourEdgesPtr_.valid())
277  {
278  neighbourEdgesPtr_.reset(new List<labelPairList>(size()));
279  List<labelPairList>& neighbourEdges = neighbourEdgesPtr_();
280 
281  // Initialize.
282  label nEdgePairs = 0;
283  forAll(*this, patchi)
284  {
285  const polyPatch& pp = operator[](patchi);
286 
287  neighbourEdges[patchi].setSize(pp.nEdges() - pp.nInternalEdges());
288 
289  forAll(neighbourEdges[patchi], i)
290  {
291  labelPair& edgeInfo = neighbourEdges[patchi][i];
292 
293  edgeInfo[0] = -1;
294  edgeInfo[1] = -1;
295  }
296 
297  nEdgePairs += pp.nEdges() - pp.nInternalEdges();
298  }
299 
300  // From mesh edge (expressed as a point pair so as not to construct
301  // point addressing) to patch + relative edge index.
302  HashTable<labelPair, edge, Hash<edge>> pointsToEdge(nEdgePairs);
303 
304  forAll(*this, patchi)
305  {
306  const polyPatch& pp = operator[](patchi);
307 
308  const edgeList& edges = pp.edges();
309 
310  for
311  (
312  label edgei = pp.nInternalEdges();
313  edgei < edges.size();
314  edgei++
315  )
316  {
317  // Edge in patch local points
318  const edge& e = edges[edgei];
319 
320  // Edge in mesh points.
321  edge meshEdge(pp.meshPoints()[e[0]], pp.meshPoints()[e[1]]);
322 
324  pointsToEdge.find(meshEdge);
325 
326  if (fnd == pointsToEdge.end())
327  {
328  // First occurrence of mesh edge. Store patch and my
329  // local index.
330  pointsToEdge.insert
331  (
332  meshEdge,
333  labelPair
334  (
335  patchi,
336  edgei - pp.nInternalEdges()
337  )
338  );
339  }
340  else
341  {
342  // Second occurrence. Store.
343  const labelPair& edgeInfo = fnd();
344 
345  neighbourEdges[patchi][edgei - pp.nInternalEdges()] =
346  edgeInfo;
347 
348  neighbourEdges[edgeInfo[0]][edgeInfo[1]]
349  = labelPair(patchi, edgei - pp.nInternalEdges());
350 
351  // Found all two occurrences of this edge so remove from
352  // hash to save space. Note that this will give lots of
353  // problems if the polyBoundaryMesh is multiply connected.
354  pointsToEdge.erase(meshEdge);
355  }
356  }
357  }
358 
359  if (pointsToEdge.size())
360  {
362  << "Not all boundary edges of patches match up." << nl
363  << "Is the outside of your mesh multiply connected?"
364  << abort(FatalError);
365  }
366 
367  forAll(*this, patchi)
368  {
369  const polyPatch& pp = operator[](patchi);
370 
371  const labelPairList& nbrEdges = neighbourEdges[patchi];
372 
373  forAll(nbrEdges, i)
374  {
375  const labelPair& edgeInfo = nbrEdges[i];
376 
377  if (edgeInfo[0] == -1 || edgeInfo[1] == -1)
378  {
379  label edgeI = pp.nInternalEdges() + i;
380  const edge& e = pp.edges()[edgeI];
381 
383  << "Not all boundary edges of patches match up." << nl
384  << "Edge " << edgeI << " on patch " << pp.name()
385  << " end points " << pp.localPoints()[e[0]] << ' '
386  << pp.localPoints()[e[1]] << " is not matched to an"
387  << " edge on any other patch." << nl
388  << "Is the outside of your mesh multiply connected?"
389  << abort(FatalError);
390  }
391  }
392  }
393  }
394 
395  return neighbourEdgesPtr_();
396 }
397 
398 
400 {
401  if (!patchIDPtr_.valid())
402  {
403  patchIDPtr_.reset
404  (
405  new labelList
406  (
407  mesh_.nFaces()
408  - mesh_.nInternalFaces()
409  )
410  );
411  labelList& patchID = patchIDPtr_();
412 
413  const polyBoundaryMesh& bm = *this;
414 
415  forAll(bm, patchi)
416  {
417  label bFacei = bm[patchi].start() - mesh_.nInternalFaces();
418  forAll(bm[patchi], i)
419  {
420  patchID[bFacei++] = patchi;
421  }
422  }
423  }
424  return patchIDPtr_();
425 }
426 
427 
430 {
431  if (!groupPatchIDsPtr_.valid())
432  {
433  groupPatchIDsPtr_.reset(new HashTable<labelList, word>(10));
434  HashTable<labelList, word>& groupPatchIDs = groupPatchIDsPtr_();
435 
436  const polyBoundaryMesh& bm = *this;
437 
438  forAll(bm, patchi)
439  {
440  const wordList& groups = bm[patchi].inGroups();
441 
442  forAll(groups, i)
443  {
444  const word& name = groups[i];
445 
446  if (findPatchID(name) != -1)
447  {
449  << "Patch " << bm[patchi].name()
450  << " specifies a group " << name
451  << " which is also a patch name."
452  << " This might give problems later on." << endl;
453  }
454 
455 
456  HashTable<labelList, word>::iterator iter = groupPatchIDs.find
457  (
458  name
459  );
460 
461  if (iter != groupPatchIDs.end())
462  {
463  iter().append(patchi);
464  }
465  else
466  {
467  groupPatchIDs.insert(name, labelList(1, patchi));
468  }
469  }
470  }
471  }
472  return groupPatchIDsPtr_();
473 }
474 
475 
477 (
478  const word& groupName,
479  const labelList& patchIDs
480 )
481 {
482  groupPatchIDsPtr_.clear();
483 
484  polyPatchList& patches = *this;
485 
486  boolList donePatch(patches.size(), false);
487 
488  // Add to specified patches
489  forAll(patchIDs, i)
490  {
491  label patchi = patchIDs[i];
492  polyPatch& pp = patches[patchi];
493 
494  if (!pp.inGroup(groupName))
495  {
496  pp.inGroups().append(groupName);
497  }
498  donePatch[patchi] = true;
499  }
500 
501  // Remove from other patches
502  forAll(patches, patchi)
503  {
504  if (!donePatch[patchi])
505  {
506  polyPatch& pp = patches[patchi];
507 
508  label newI = 0;
509  if (pp.inGroup(groupName))
510  {
511  wordList& groups = pp.inGroups();
512 
513  forAll(groups, i)
514  {
515  if (groups[i] != groupName)
516  {
517  groups[newI++] = groups[i];
518  }
519  }
520  groups.setSize(newI);
521  }
522  }
523  }
524 }
525 
526 
528 {
529  const polyPatchList& patches = *this;
530 
531  wordList t(patches.size());
532 
533  forAll(patches, patchi)
534  {
535  t[patchi] = patches[patchi].name();
536  }
537 
538  return t;
539 }
540 
541 
543 {
544  const polyPatchList& patches = *this;
545 
546  wordList t(patches.size());
547 
548  forAll(patches, patchi)
549  {
550  t[patchi] = patches[patchi].type();
551  }
552 
553  return t;
554 }
555 
556 
558 {
559  const polyPatchList& patches = *this;
560 
561  wordList t(patches.size());
562 
563  forAll(patches, patchi)
564  {
565  t[patchi] = patches[patchi].physicalType();
566  }
567 
568  return t;
569 }
570 
571 
573 (
574  const keyType& key,
575  const bool usePatchGroups
576 ) const
577 {
578  DynamicList<label> indices;
579 
580  if (!key.empty())
581  {
582  if (key.isPattern())
583  {
584  indices = findStrings(key, this->names());
585 
586  if (usePatchGroups && groupPatchIDs().size())
587  {
588  labelHashSet indexSet(indices);
589 
590  const wordList allGroupNames = groupPatchIDs().toc();
591  labelList groupIDs = findStrings(key, allGroupNames);
592  forAll(groupIDs, i)
593  {
594  const word& grpName = allGroupNames[groupIDs[i]];
595  const labelList& patchIDs = groupPatchIDs()[grpName];
596  forAll(patchIDs, j)
597  {
598  if (indexSet.insert(patchIDs[j]))
599  {
600  indices.append(patchIDs[j]);
601  }
602  }
603  }
604  }
605  }
606  else
607  {
608  // Literal string. Special version of above to avoid
609  // unnecessary memory allocations
610 
611  indices.setCapacity(1);
612  forAll(*this, i)
613  {
614  if (key == operator[](i).name())
615  {
616  indices.append(i);
617  break;
618  }
619  }
620 
621  if (usePatchGroups && groupPatchIDs().size())
622  {
624  groupPatchIDs().find(key);
625 
626  if (iter != groupPatchIDs().end())
627  {
628  labelHashSet indexSet(indices);
629 
630  const labelList& patchIDs = iter();
631  forAll(patchIDs, j)
632  {
633  if (indexSet.insert(patchIDs[j]))
634  {
635  indices.append(patchIDs[j]);
636  }
637  }
638  }
639  }
640  }
641  }
642 
643  return indices;
644 }
645 
646 
648 {
649  if (!key.empty())
650  {
651  if (key.isPattern())
652  {
653  labelList indices = this->findIndices(key);
654 
655  // return first element
656  if (!indices.empty())
657  {
658  return indices[0];
659  }
660  }
661  else
662  {
663  forAll(*this, i)
664  {
665  if (key == operator[](i).name())
666  {
667  return i;
668  }
669  }
670  }
671  }
672 
673  // not found
674  return -1;
675 }
676 
677 
679 {
680  const polyPatchList& patches = *this;
681 
682  forAll(patches, patchi)
683  {
684  if (patches[patchi].name() == patchName)
685  {
686  return patchi;
687  }
688  }
689 
690  // Patch not found
691  if (debug)
692  {
693  Pout<< "label polyBoundaryMesh::findPatchID(const word&) const"
694  << "Patch named " << patchName << " not found. "
695  << "List of available patch names: " << names() << endl;
696  }
697 
698  // Not found, return -1
699  return -1;
700 }
701 
702 
704 {
705  // Find out which patch the current face belongs to by comparing label
706  // with patch start labels.
707  // If the face is internal, return -1;
708  // if it is off the end of the list, abort
709  if (faceIndex < mesh().nInternalFaces())
710  {
711  return -1;
712  }
713  else if (faceIndex >= mesh().nFaces())
714  {
716  << "given label " << faceIndex
717  << " greater than the number of geometric faces " << mesh().nFaces()
718  << abort(FatalError);
719  }
720 
721 
722  forAll(*this, patchi)
723  {
724  const polyPatch& bp = operator[](patchi);
725 
726  if
727  (
728  faceIndex >= bp.start()
729  && faceIndex < bp.start() + bp.size()
730  )
731  {
732  return patchi;
733  }
734  }
735 
736  // If not in any of above, it is trouble!
738  << "Cannot find face " << faceIndex << " in any of the patches "
739  << names() << nl
740  << "It seems your patches are not consistent with the mesh :"
741  << " internalFaces:" << mesh().nInternalFaces()
742  << " total number of faces:" << mesh().nFaces()
743  << abort(FatalError);
744 
745  return -1;
746 }
747 
748 
750 (
751  const UList<wordRe>& patchNames,
752  const bool warnNotFound,
753  const bool usePatchGroups
754 ) const
755 {
756  const wordList allPatchNames(this->names());
757  labelHashSet ids(size());
758 
759  forAll(patchNames, i)
760  {
761  const wordRe& patchName = patchNames[i];
762 
763  // Treat the given patch names as wild-cards and search the set
764  // of all patch names for matches
765  labelList patchIDs = findStrings(patchName, allPatchNames);
766 
767  forAll(patchIDs, j)
768  {
769  ids.insert(patchIDs[j]);
770  }
771 
772  if (patchIDs.empty())
773  {
774  if (usePatchGroups)
775  {
776  const wordList allGroupNames = groupPatchIDs().toc();
777 
778  // Regard as group name
779  labelList groupIDs = findStrings(patchName, allGroupNames);
780 
781  forAll(groupIDs, i)
782  {
783  const word& name = allGroupNames[groupIDs[i]];
784  const labelList& extraPatchIDs = groupPatchIDs()[name];
785 
786  forAll(extraPatchIDs, extraI)
787  {
788  ids.insert(extraPatchIDs[extraI]);
789  }
790  }
791 
792  if (groupIDs.empty() && warnNotFound)
793  {
795  << "Cannot find any patch or group names matching "
796  << patchName
797  << endl;
798  }
799  }
800  else if (warnNotFound)
801  {
803  << "Cannot find any patch names matching " << patchName
804  << endl;
805  }
806  }
807  }
808 
809  return ids;
810 }
811 
812 
814 (
815  const labelUList& patchIDs,
816  wordList& groups,
817  labelHashSet& nonGroupPatches
818 ) const
819 {
820  // Current matched groups
821  DynamicList<word> matchedGroups(1);
822 
823  // Current set of unmatched patches
824  nonGroupPatches = labelHashSet(patchIDs);
825 
826  const HashTable<labelList, word>& groupPatchIDs = this->groupPatchIDs();
827  for
828  (
830  groupPatchIDs.begin();
831  iter != groupPatchIDs.end();
832  ++iter
833  )
834  {
835  // Store currently unmatched patches so we can restore
836  labelHashSet oldNonGroupPatches(nonGroupPatches);
837 
838  // Match by deleting patches in group from the current set and seeing
839  // if all have been deleted.
840  labelHashSet groupPatchSet(iter());
841 
842  label nMatch = nonGroupPatches.erase(groupPatchSet);
843 
844  if (nMatch == groupPatchSet.size())
845  {
846  matchedGroups.append(iter.key());
847  }
848  else if (nMatch != 0)
849  {
850  // No full match. Undo.
851  nonGroupPatches.transfer(oldNonGroupPatches);
852  }
853  }
854 
855  groups.transfer(matchedGroups);
856 }
857 
858 
859 bool Foam::polyBoundaryMesh::checkParallelSync(const bool report) const
860 {
861  if (!Pstream::parRun())
862  {
863  return false;
864  }
865 
866 
867  const polyBoundaryMesh& bm = *this;
868 
869  bool hasError = false;
870 
871  // Collect non-proc patches and check proc patches are last.
872  wordList names(bm.size());
873  wordList types(bm.size());
874 
875  label nonProci = 0;
876 
877  forAll(bm, patchi)
878  {
879  if (!isA<processorPolyPatch>(bm[patchi]))
880  {
881  if (nonProci != patchi)
882  {
883  // There is processor patch in between normal patches.
884  hasError = true;
885 
886  if (debug || report)
887  {
888  Pout<< " ***Problem with boundary patch " << patchi
889  << " named " << bm[patchi].name()
890  << " of type " << bm[patchi].type()
891  << ". The patch seems to be preceeded by processor"
892  << " patches. This is can give problems."
893  << endl;
894  }
895  }
896  else
897  {
898  names[nonProci] = bm[patchi].name();
899  types[nonProci] = bm[patchi].type();
900  nonProci++;
901  }
902  }
903  }
904  names.setSize(nonProci);
905  types.setSize(nonProci);
906 
907  List<wordList> allNames(Pstream::nProcs());
908  allNames[Pstream::myProcNo()] = names;
909  Pstream::gatherList(allNames);
910  Pstream::scatterList(allNames);
911 
912  List<wordList> allTypes(Pstream::nProcs());
913  allTypes[Pstream::myProcNo()] = types;
914  Pstream::gatherList(allTypes);
915  Pstream::scatterList(allTypes);
916 
917  // Have every processor check but only master print error.
918 
919  for (label proci = 1; proci < allNames.size(); ++proci)
920  {
921  if
922  (
923  (allNames[proci] != allNames[0])
924  || (allTypes[proci] != allTypes[0])
925  )
926  {
927  hasError = true;
928 
929  if (debug || (report && Pstream::master()))
930  {
931  Info<< " ***Inconsistent patches across processors, "
932  "processor 0 has patch names:" << allNames[0]
933  << " patch types:" << allTypes[0]
934  << " processor " << proci << " has patch names:"
935  << allNames[proci]
936  << " patch types:" << allTypes[proci]
937  << endl;
938  }
939  }
940  }
941 
942  return hasError;
943 }
944 
945 
946 bool Foam::polyBoundaryMesh::checkDefinition(const bool report) const
947 {
948  label nextPatchStart = mesh().nInternalFaces();
949  const polyBoundaryMesh& bm = *this;
950 
951  bool hasError = false;
952 
953  HashSet<word> patchNames(2*size());
954 
955  forAll(bm, patchi)
956  {
957  if (bm[patchi].start() != nextPatchStart && !hasError)
958  {
959  hasError = true;
960 
961  Info<< " ****Problem with boundary patch " << patchi
962  << " named " << bm[patchi].name()
963  << " of type " << bm[patchi].type()
964  << ". The patch should start on face no " << nextPatchStart
965  << " and the patch specifies " << bm[patchi].start()
966  << "." << endl
967  << "Possibly consecutive patches have this same problem."
968  << " Suppressing future warnings." << endl;
969  }
970 
971  if (!patchNames.insert(bm[patchi].name()) && !hasError)
972  {
973  hasError = true;
974 
975  Info<< " ****Duplicate boundary patch " << patchi
976  << " named " << bm[patchi].name()
977  << " of type " << bm[patchi].type()
978  << "." << endl
979  << "Suppressing future warnings." << endl;
980  }
981 
982  nextPatchStart += bm[patchi].size();
983  }
984 
985  reduce(hasError, orOp<bool>());
986 
987  if (debug || report)
988  {
989  if (hasError)
990  {
991  Pout<< " ***Boundary definition is in error." << endl;
992  }
993  else
994  {
995  Info<< " Boundary definition OK." << endl;
996  }
997  }
998 
999  return hasError;
1000 }
1001 
1002 
1004 {
1006 
1007  if
1008  (
1011  )
1012  {
1013  forAll(*this, patchi)
1014  {
1015  operator[](patchi).initMovePoints(pBufs, p);
1016  }
1017 
1018  pBufs.finishedSends();
1019 
1020  forAll(*this, patchi)
1021  {
1022  operator[](patchi).movePoints(pBufs, p);
1023  }
1024  }
1026  {
1027  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
1028 
1029  // Dummy.
1030  pBufs.finishedSends();
1031 
1032  forAll(patchSchedule, patchEvali)
1033  {
1034  const label patchi = patchSchedule[patchEvali].patch;
1035 
1036  if (patchSchedule[patchEvali].init)
1037  {
1038  operator[](patchi).initMovePoints(pBufs, p);
1039  }
1040  else
1041  {
1042  operator[](patchi).movePoints(pBufs, p);
1043  }
1044  }
1045  }
1046 }
1047 
1048 
1050 {
1051  neighbourEdgesPtr_.clear();
1052  patchIDPtr_.clear();
1053  groupPatchIDsPtr_.clear();
1054 
1056 
1057  if
1058  (
1061  )
1062  {
1063  forAll(*this, patchi)
1064  {
1065  operator[](patchi).initUpdateMesh(pBufs);
1066  }
1067 
1068  pBufs.finishedSends();
1069 
1070  forAll(*this, patchi)
1071  {
1072  operator[](patchi).updateMesh(pBufs);
1073  }
1074  }
1076  {
1077  const lduSchedule& patchSchedule = mesh().globalData().patchSchedule();
1078 
1079  // Dummy.
1080  pBufs.finishedSends();
1081 
1082  forAll(patchSchedule, patchEvali)
1083  {
1084  const label patchi = patchSchedule[patchEvali].patch;
1085 
1086  if (patchSchedule[patchEvali].init)
1087  {
1088  operator[](patchi).initUpdateMesh(pBufs);
1089  }
1090  else
1091  {
1092  operator[](patchi).updateMesh(pBufs);
1093  }
1094  }
1095  }
1096 }
1097 
1098 
1101  const labelUList& oldToNew,
1102  const bool validBoundary
1103 )
1104 {
1105  // Change order of patches
1106  polyPatchList::reorder(oldToNew);
1107 
1108  // Adapt indices
1109  polyPatchList& patches = *this;
1110 
1111  forAll(patches, patchi)
1112  {
1113  patches[patchi].index() = patchi;
1114  }
1115 
1116  if (validBoundary)
1117  {
1118  updateMesh();
1119  }
1120 }
1121 
1122 
1124 {
1125  const polyPatchList& patches = *this;
1126 
1127  os << patches.size() << nl << token::BEGIN_LIST << incrIndent << nl;
1128 
1129  forAll(patches, patchi)
1130  {
1131  os << indent << patches[patchi].name() << nl
1132  << indent << token::BEGIN_BLOCK << nl
1133  << incrIndent << patches[patchi] << decrIndent
1134  << indent << token::END_BLOCK << endl;
1135  }
1136 
1137  os << decrIndent << token::END_LIST;
1138 
1139  // Check state of IOstream
1140  os.check("polyBoundaryMesh::writeData(Ostream& os) const");
1141 
1142  return os.good();
1143 }
1144 
1145 
1151 ) const
1152 {
1154 }
1155 
1156 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
1157 
1160  const word& patchName
1161 ) const
1162 {
1163  const label patchi = findPatchID(patchName);
1164 
1165  if (patchi < 0)
1166  {
1168  << "Patch named " << patchName << " not found." << nl
1169  << "Available patch names: " << names() << endl
1170  << abort(FatalError);
1171  }
1172 
1173  return operator[](patchi);
1174 }
1175 
1176 
1179  const word& patchName
1180 )
1181 {
1182  const label patchi = findPatchID(patchName);
1183 
1184  if (patchi < 0)
1185  {
1187  << "Patch named " << patchName << " not found." << nl
1188  << "Available patch names: " << names() << endl
1189  << abort(FatalError);
1190  }
1191 
1192  return operator[](patchi);
1193 }
1194 
1195 
1196 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1197 
1199 {
1200  pbm.writeData(os);
1201  return os;
1202 }
1203 
1204 
1205 // ************************************************************************* //
void matchGroups(const labelUList &patchIDs, wordList &groups, labelHashSet &nonGroupPatches) const
Match the patches to groups. Returns all the (fully matched) groups.
PtrList< polyPatch > polyPatchList
container classes for polyPatch
Definition: polyPatchList.H:45
const labelList & patchID() const
Per boundary face label the patch index.
A class for handling keywords in dictionaries.
Definition: keyType.H:64
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:223
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
An STL-conforming const_iterator.
Definition: HashTable.H:470
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order. Return.
wordList names() const
Return a list of patch names.
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
const double e
Elementary charge.
Definition: doubleFloat.H:78
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
bool checkDefinition(const bool report=false) const
Check boundary definition. Return true if in error.
error FatalError
void reorder(const labelUList &)
Reorders elements. Ordering does not have to be done in.
Definition: PtrList.C:197
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:313
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:417
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:411
void clearGeom()
Clear geometry at this level and at patches.
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Operations on lists of strings.
void transfer(HashTable< T, Key, Hash > &)
Transfer the contents of the argument table into this table.
Definition: HashTable.C:509
patches[0]
labelList findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurences of given element. Linear search.
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
const lduSchedule & patchSchedule() const
Order in which the patches should be initialised/evaluated.
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
Definition: HashTable.C:367
bool inGroup(const word &) const
Test if in group.
bool findStrings(const wordReListMatcher &matcher, const std::string &str)
Return true if string matches one of the regular expressions.
Definition: stringListOps.H:52
An STL iterator.
Definition: UPtrList.H:244
friend Ostream & operator(Ostream &, const UPtrList< T > &)
Write UPtrList to Ostream.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:138
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Definition: HashSet.H:210
An STL-conforming iterator.
Definition: HashTable.H:415
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: contiguous.H:49
dynamicFvMesh & mesh
~polyBoundaryMesh()
Destructor.
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:300
void movePoints(const pointField &)
Correct polyBoundaryMesh after moving points.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
A class for handling words, derived from string.
Definition: word.H:59
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:97
label findIndex(const keyType &) const
Return patch index for the first match, return -1 if not found.
void setCapacity(const label)
Alter the size of the underlying storage.
Definition: DynamicListI.H:118
wordList patchNames(nPatches)
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
bool set(const label) const
Is element set.
Definition: PtrListI.H:65
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:86
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:292
labelHashSet patchSet(const UList< wordRe > &patchNames, const bool warnNotFound=true, const bool usePatchGroups=true) const
Return the set of patch IDs corresponding to the given names.
Pair< label > labelPair
Label pair.
Definition: labelPair.H:48
List< label > labelList
A List of labels.
Definition: labelList.H:56
wordList physicalTypes() const
Return a list of physical types.
iterator begin()
Iterator set to the beginning of the HashTable.
Definition: HashTableI.H:419
const word & name() const
Return name.
An STL-conforming hash table.
Definition: HashTable.H:61
const List< labelPairList > & neighbourEdges() const
Per patch the edges on the neighbouring patch. Is for every external.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
A wordRe is a word, but can also have a regular expression for matching words.
Definition: wordRe.H:74
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType) const
Write using given format, version and compression.
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:60
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:131
labelList findIndices(const keyType &, const bool usePatchGroups=true) const
Return patch indices for all matches. Optionally matches patchGroups.
Foam::polyBoundaryMesh.
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1140
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:193
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
static const char nl
Definition: Ostream.H:262
void updateMesh()
Correct polyBoundaryMesh after topology update.
defineTypeNameAndDebug(combustionModel, 0)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:237
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
const HashTable< labelList, word > & groupPatchIDs() const
Per patch group the patch indices.
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp) const
Write using given format, version and form uncompression.
label nEdges() const
Return number of edges in patch.
label nFaces() const
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:268
void setSize(const label)
Reset size of List.
Definition: List.C:295
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:393
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:399
wordList types() const
Return a list of patch types.
label patchi
#define WarningInFunction
Report a warning using Foam::Warning.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:62
void clearAddressing()
Clear addressing at this level and at patches.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
label nInternalEdges() const
Number of internal edges.
Ostream & operator<<(Ostream &, const ensightPart &)
Version number type.
Definition: IOstream.H:96
bool writeData(Ostream &) const
writeData member function required by regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:60
messageStream Info
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return a pointer to a new patch created on freestore from.
Definition: polyPatchNew.C:32
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
const wordList & inGroups() const
Return the optional groups patch belongs to.
volScalarField & p
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:230
label findPatchID(const word &patchName) const
Find patch index given a name.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
label nInternalFaces() const
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:365
void reorder(const labelUList &, const bool validBoundary)
Reorders patches. Ordering does not have to be done in.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
void setGroup(const word &groupName, const labelList &patchIDs)
Set/add group with patches.
const word & name() const
Return name.
Definition: IOobject.H:260
bool isPattern() const
Should be treated as a match rather than a literal string.
Definition: keyTypeI.H:76
Namespace for OpenFOAM.
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29