GeometricBoundaryField.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017,2022 OpenFOAM Foundation
9  Copyright (C) 2016-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 "GeometricBoundaryField.H"
30 #include "globalMeshData.H"
31 #include "cyclicPolyPatch.H"
32 #include "emptyPolyPatch.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 template<class Type, template<class> class PatchField, class GeoMesh>
37 template<class CheckPatchFieldType>
39 (
40  const scalar tol,
41  const bool doExit
42 ) const
43 {
44  if (!this->size())
45  {
46  return true;
47  }
48 
49  if (debug&2)
50  {
51  const auto& pfld0 = this->operator[](0);
53  << " Checking boundary consistency for field "
54  << pfld0.internalField().name()
55  << endl;
56  }
57 
58  auto& bfld = const_cast<GeometricBoundaryField<Type, PatchField, GeoMesh>&>
59  (
60  *this
61  );
62 
63 
64  // Store old value
65  List<Field<Type>> oldBfld(this->size());
66  boolList oldUpdated(this->size());
67  //Note: areaFields (finiteArea) do not have manipulatedMatrix() flag. TBD.
68  //boolList oldManipulated(this->size());
69 
70  for (auto& pfld : bfld)
71  {
72  if (isA<CheckPatchFieldType>(pfld))
73  {
74  const label patchi = pfld.patch().index();
75  oldUpdated[patchi] = pfld.updated();
76  oldBfld[patchi] = pfld;
77  //oldManipulated[patchi] = pfld.manipulatedMatrix();
78  }
79  }
80 
81 
82  // Re-evaluate
83  {
84  const label startOfRequests = UPstream::nRequests();
85 
86  for (auto& pfld : bfld)
87  {
88  if (isA<CheckPatchFieldType>(pfld))
89  {
90  pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
91  }
92  }
93 
94  // Wait for outstanding requests (non-blocking)
95  UPstream::waitRequests(startOfRequests);
96 
97  for (auto& pfld : bfld)
98  {
99  if (isA<CheckPatchFieldType>(pfld))
100  {
101  pfld.evaluate(UPstream::commsTypes::nonBlocking);
102  }
103  }
104  }
105 
106 
107  // Check
108  bool ok = true;
109  for (auto& pfld : bfld)
110  {
111  if (isA<CheckPatchFieldType>(pfld))
112  {
113  const label patchi = pfld.patch().index();
114  const auto& oldPfld = oldBfld[patchi];
115 
116  forAll(pfld, facei)
117  {
118  if (mag(pfld[facei]-oldPfld[facei]) > tol)
119  {
120  ok = false;
121  break;
122  }
123  }
124 
125  if (!ok)
126  {
127  if (doExit)
128  {
129  FatalErrorInFunction << "Field "
130  << pfld.internalField().name()
131  << " is not evaluated?"
132  << " On patch " << pfld.patch().name()
133  << " type " << pfld.type()
134  << " : average of field = "
135  << average(oldPfld)
136  << ". Average of evaluated field = "
137  << average(pfld)
138  << ". Difference:" << average(pfld-oldPfld)
139  << ". Tolerance:" << tol
140  << exit(FatalError);
141  }
142  else
143  {
144  WarningInFunction << "Field "
145  << pfld.internalField().name()
146  << " is not evaluated?"
147  << " On patch " << pfld.patch().name()
148  << " type " << pfld.type()
149  << " : average of field = "
150  << average(oldPfld)
151  << ". Average of evaluated field = "
152  << average(pfld)
153  << ". Difference:" << average(pfld-oldPfld)
154  << ". Tolerance:" << tol
155  << endl;
156 
157  // Skip other patches
158  break;
159  }
160  }
161  }
162  }
163 
164  // Restore bfld, updated
165  for (auto& pfld : bfld)
166  {
167  if (isA<CheckPatchFieldType>(pfld))
168  {
169  const label patchi = pfld.patch().index();
170  pfld.setUpdated(oldUpdated[patchi]);
171  Field<Type>& vals = pfld;
172  vals = std::move(oldBfld[patchi]);
173  //pfld.setManipulated(oldManipulated[patchi]);
174  }
175  }
176 
177  if (debug&2)
178  {
179  const auto& pfld0 = this->operator[](0);
181  << " Result of checking for field "
182  << pfld0.internalField().name() << " : " << ok << endl;
183  }
185  return ok;
186 }
187 
188 
189 template<class Type, template<class> class PatchField, class GeoMesh>
191 (
192  const Internal& iField,
193  const dictionary& dict
194 )
195 {
196  // DebugInFunction << nl;
197 
198  // Clear the boundary field if already initialised
199  this->clear();
200 
201  this->resize(bmesh_.size());
202 
203  label nUnset = this->size();
204 
205  // 1. Handle explicit patch names. Note that there can be only one explicit
206  // patch name since is key of dictionary.
207 
208  for (const entry& dEntry : dict)
209  {
210  const auto* subdict = dEntry.dictPtr();
211 
212  if (subdict && dEntry.keyword().isLiteral())
213  {
214  const label patchi = bmesh_.findPatchID(dEntry.keyword());
215 
216  if (patchi != -1)
217  {
218  this->set
219  (
220  patchi,
222  (
223  bmesh_[patchi],
224  iField,
225  *subdict
226  )
227  );
228  --nUnset;
229  }
230  }
231  }
232 
233  if (nUnset == 0)
234  {
235  return;
236  }
237 
238 
239  // 2. Patch-groups. (using non-wild card entries of dictionaries)
240  // (patchnames already matched above)
241  // Note: in reverse order of entries in the dictionary (last
242  // patchGroups wins). This is so it is consistent with dictionary wildcard
243  // behaviour
244  for (auto iter = dict.crbegin(); iter != dict.crend(); ++iter)
245  {
246  const entry& dEntry = *iter;
247  const auto* subdict = dEntry.dictPtr();
248 
249  if (subdict && dEntry.keyword().isLiteral())
250  {
251  const labelList patchIds =
252  bmesh_.indices(dEntry.keyword(), true); // use patchGroups
253 
254  for (const label patchi : patchIds)
255  {
256  if (!this->set(patchi))
257  {
258  this->set
259  (
260  patchi,
262  (
263  bmesh_[patchi],
264  iField,
265  *subdict
266  )
267  );
268  }
269  }
270  }
271  }
272 
273 
274  // 3. Wildcard patch overrides
275  forAll(bmesh_, patchi)
276  {
277  if (!this->set(patchi))
278  {
279  if (bmesh_[patchi].type() == emptyPolyPatch::typeName)
280  {
281  this->set
282  (
283  patchi,
285  (
286  emptyPolyPatch::typeName,
287  bmesh_[patchi],
288  iField
289  )
290  );
291  }
292  else
293  {
294  const auto* subdict = dict.findDict(bmesh_[patchi].name());
295 
296  if (subdict)
297  {
298  this->set
299  (
300  patchi,
302  (
303  bmesh_[patchi],
304  iField,
305  *subdict
306  )
307  );
308  }
309  }
310  }
311  }
312 
313 
314  // Check for any unset patches
315  forAll(bmesh_, patchi)
316  {
317  if (!this->set(patchi))
318  {
319  if (bmesh_[patchi].type() == cyclicPolyPatch::typeName)
320  {
322  << "Cannot find patchField entry for cyclic "
323  << bmesh_[patchi].name() << endl
324  << "Is your field uptodate with split cyclics?" << endl
325  << "Run foamUpgradeCyclics to convert mesh and fields"
326  << " to split cyclics." << exit(FatalIOError);
327  }
328  else
329  {
331  << "Cannot find patchField entry for "
332  << bmesh_[patchi].name() << exit(FatalIOError);
333  }
334  }
335  }
336 }
337 
338 
339 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
340 
341 template<class Type, template<class> class PatchField, class GeoMesh>
343 (
344  const BoundaryMesh& bmesh
345 )
346 :
347  FieldField<PatchField, Type>(bmesh.size()),
348  bmesh_(bmesh)
349 {}
350 
351 
352 template<class Type, template<class> class PatchField, class GeoMesh>
354 (
355  const BoundaryMesh& bmesh,
356  const Internal& iField,
357  const word& patchFieldType
358 )
359 :
360  FieldField<PatchField, Type>(bmesh.size()),
361  bmesh_(bmesh)
362 {
363  // DebugInFunction << nl;
364 
365  forAll(bmesh_, patchi)
366  {
367  this->set
368  (
369  patchi,
371  (
372  patchFieldType,
373  bmesh_[patchi],
374  iField
375  )
376  );
377  }
378 }
379 
380 
381 template<class Type, template<class> class PatchField, class GeoMesh>
383 (
384  const BoundaryMesh& bmesh,
385  const Internal& iField,
386  const wordList& patchFieldTypes,
387  const wordList& constraintTypes
388 )
389 :
390  FieldField<PatchField, Type>(bmesh.size()),
391  bmesh_(bmesh)
392 {
393  // DebugInFunction << nl;
394 
395  if
396  (
397  patchFieldTypes.size() != this->size()
398  || (constraintTypes.size() && (constraintTypes.size() != this->size()))
399  )
400  {
402  << "Incorrect number of patch type specifications given" << nl
403  << " Number of patches in mesh = " << bmesh.size()
404  << " number of patch type specifications = "
405  << patchFieldTypes.size()
406  << abort(FatalError);
407  }
408 
409  if (constraintTypes.size())
410  {
411  forAll(bmesh_, patchi)
412  {
413  this->set
414  (
415  patchi,
417  (
418  patchFieldTypes[patchi],
419  constraintTypes[patchi],
420  bmesh_[patchi],
421  iField
422  )
423  );
424  }
425  }
426  else
427  {
428  forAll(bmesh_, patchi)
429  {
430  this->set
431  (
432  patchi,
434  (
435  patchFieldTypes[patchi],
436  bmesh_[patchi],
437  iField
438  )
439  );
440  }
441  }
442 }
443 
444 
445 template<class Type, template<class> class PatchField, class GeoMesh>
447 (
448  const BoundaryMesh& bmesh,
449  const Internal& iField,
450  const PtrList<PatchField<Type>>& ptfl
451 )
452 :
453  FieldField<PatchField, Type>(bmesh.size()),
454  bmesh_(bmesh)
455 {
456  // DebugInFunction << nl;
457 
458  forAll(bmesh_, patchi)
459  {
460  this->set(patchi, ptfl[patchi].clone(iField));
461  }
462 }
463 
464 
465 template<class Type, template<class> class PatchField, class GeoMesh>
467 (
468  const Internal& iField,
469  const GeometricBoundaryField<Type, PatchField, GeoMesh>& btf
470 )
471 :
472  FieldField<PatchField, Type>(btf.size()),
473  bmesh_(btf.bmesh_)
474 {
475  // DebugInFunction << nl;
476 
477  forAll(bmesh_, patchi)
478  {
479  this->set(patchi, btf[patchi].clone(iField));
480  }
481 }
482 
483 
484 template<class Type, template<class> class PatchField, class GeoMesh>
486 (
487  const Internal& iField,
488  const GeometricBoundaryField<Type, PatchField, GeoMesh>& btf,
489  const labelList& patchIDs,
490  const word& patchFieldType
491 )
492 :
493  FieldField<PatchField, Type>(btf.size()),
494  bmesh_(btf.bmesh_)
495 {
496  // DebugInFunction << nl;
497 
498  for (const label patchi : patchIDs)
499  {
500  this->set
501  (
502  patchi,
504  (
505  patchFieldType,
506  bmesh_[patchi],
507  iField
508  )
509  );
510  }
511 
512  forAll(bmesh_, patchi)
513  {
514  if (!this->set(patchi))
515  {
516  this->set(patchi, btf[patchi].clone(iField));
517  }
518  }
519 }
520 
521 
522 template<class Type, template<class> class PatchField, class GeoMesh>
524 (
525  const GeometricBoundaryField<Type, PatchField, GeoMesh>& btf
526 )
527 :
528  FieldField<PatchField, Type>(btf),
529  bmesh_(btf.bmesh_)
530 {}
531 
532 
533 template<class Type, template<class> class PatchField, class GeoMesh>
535 (
536  const BoundaryMesh& bmesh,
537  const Internal& iField,
538  const dictionary& dict
539 )
540 :
541  FieldField<PatchField, Type>(bmesh.size()),
542  bmesh_(bmesh)
543 {
544  readField(iField, dict);
545 }
546 
547 
548 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
549 
550 template<class Type, template<class> class PatchField, class GeoMesh>
552 {
553  // DebugInFunction << nl;
554 
555  for (auto& pfld : *this)
556  {
557  pfld.updateCoeffs();
558  }
559 }
560 
561 
562 template<class Type, template<class> class PatchField, class GeoMesh>
564 (
565  const UPstream::commsTypes commsType
566 )
567 {
568  if
569  (
570  commsType == UPstream::commsTypes::buffered
571  || commsType == UPstream::commsTypes::nonBlocking
572  )
573  {
574  const label startOfRequests = UPstream::nRequests();
575 
576  for (auto& pfld : *this)
577  {
578  pfld.initEvaluate(commsType);
579  }
580 
581  // Wait for outstanding requests (non-blocking)
582  UPstream::waitRequests(startOfRequests);
583 
584  for (auto& pfld : *this)
585  {
586  pfld.evaluate(commsType);
587  }
588  }
589  else if (commsType == UPstream::commsTypes::scheduled)
590  {
591  const lduSchedule& patchSchedule =
592  bmesh_.mesh().globalData().patchSchedule();
593 
594  for (const auto& schedEval : patchSchedule)
595  {
596  const label patchi = schedEval.patch;
597  auto& pfld = (*this)[patchi];
598 
599  if (schedEval.init)
600  {
601  pfld.initEvaluate(commsType);
602  }
603  else
604  {
605  pfld.evaluate(commsType);
606  }
607  }
608  }
609  else
610  {
612  << "Unsupported communications type " << int(commsType) << nl
613  << exit(FatalError);
614  }
615 }
616 
617 
618 template<class Type, template<class> class PatchField, class GeoMesh>
619 template<class UnaryPredicate>
621 (
622  const UnaryPredicate& pred,
623  const UPstream::commsTypes commsType
624 )
625 {
626  if
627  (
628  commsType == UPstream::commsTypes::buffered
629  || commsType == UPstream::commsTypes::nonBlocking
630  )
631  {
632  const label startOfRequests = UPstream::nRequests();
633 
634  for (auto& pfld : *this)
635  {
636  if (pred(pfld))
637  {
638  pfld.initEvaluate(commsType);
639  }
640  }
641 
642  // Wait for outstanding requests (non-blocking)
643  UPstream::waitRequests(startOfRequests);
644 
645  for (auto& pfld : *this)
646  {
647  if (pred(pfld))
648  {
649  pfld.evaluate(commsType);
650  }
651  }
652  }
653  else if (commsType == UPstream::commsTypes::scheduled)
654  {
655  const lduSchedule& patchSchedule =
656  bmesh_.mesh().globalData().patchSchedule();
657 
658  for (const auto& schedEval : patchSchedule)
659  {
660  const label patchi = schedEval.patch;
661  auto& pfld = (*this)[patchi];
662 
663  if (pred(pfld))
664  {
665  if (schedEval.init)
666  {
667  pfld.initEvaluate(commsType);
668  }
669  else
670  {
671  pfld.evaluate(commsType);
672  }
673  }
674  }
675  }
676  else
677  {
679  << "Unsupported communications type " << int(commsType) << nl
681  }
682 }
683 
684 
685 template<class Type, template<class> class PatchField, class GeoMesh>
687 (
688  const labelUList& patchIDs
689 )
690 {
691  const label startOfRequests = UPstream::nRequests();
692 
693  for (const label patchi : patchIDs)
694  {
695  auto& pfld = (*this)[patchi];
696 
697  DebugInfo<< "Updating " << pfld.patch().name() << endl;
698 
699  pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
700  }
701 
702  // Wait for outstanding requests (non-blocking)
703  UPstream::waitRequests(startOfRequests);
704 
705  for (const label patchi : patchIDs)
706  {
707  auto& pfld = (*this)[patchi];
708 
709  pfld.evaluate(UPstream::commsTypes::nonBlocking);
710  }
711 }
712 
713 
714 template<class Type, template<class> class PatchField, class GeoMesh>
716 (
717  const UPstream::commsTypes commsType
718 )
719 {
720  // DebugInFunction << nl;
721 
722  if (!localConsistency)
723  {
724  return;
725  }
726 
727  if
728  (
729  commsType == UPstream::commsTypes::buffered
730  || commsType == UPstream::commsTypes::nonBlocking
731  )
732  {
733  const label startOfRequests = UPstream::nRequests();
734 
735  for (auto& pfld : *this)
736  {
737  pfld.initEvaluateLocal(commsType);
738  }
739 
740  // Wait for outstanding requests (non-blocking)
741  UPstream::waitRequests(startOfRequests);
742 
743  for (auto& pfld : *this)
744  {
745  pfld.evaluateLocal(commsType);
746  }
747  }
748  else if (commsType == UPstream::commsTypes::scheduled)
749  {
750  const lduSchedule& patchSchedule =
751  bmesh_.mesh().globalData().patchSchedule();
752 
753  for (const auto& schedEval : patchSchedule)
754  {
755  const label patchi = schedEval.patch;
756  auto& pfld = (*this)[patchi];
757 
758  if (schedEval.init)
759  {
760  pfld.initEvaluateLocal(commsType);
761  }
762  else
763  {
764  pfld.evaluateLocal(commsType);
765  }
766  }
767  }
768  else
769  {
771  << "Unsupported communications type " << int(commsType) << nl
772  << exit(FatalError);
773  }
774 }
775 
776 
777 template<class Type, template<class> class PatchField, class GeoMesh>
778 template<class CoupledPatchType>
780 (
781  const UPstream::commsTypes commsType
782 )
783 {
784  // Alternative (C++14)
785  //
786  // this->evaluate_if
787  // (
788  // [](const auto& pfld) -> bool
789  // {
790  // const auto* cpp = isA<CoupledPatchType>(pfld.patch());
791  // return (cpp && cpp->coupled());
792  // },
793  // commsType
794  // );
795 
796  // DebugInFunction << nl;
797 
798  if
799  (
800  commsType == UPstream::commsTypes::buffered
801  || commsType == UPstream::commsTypes::nonBlocking
802  )
803  {
804  const label startOfRequests = UPstream::nRequests();
805 
806  for (auto& pfld : *this)
807  {
808  const auto* cpp = isA<CoupledPatchType>(pfld.patch());
809 
810  if (cpp && cpp->coupled())
811  {
812  pfld.initEvaluate(commsType);
813  }
814  }
815 
816  // Wait for outstanding requests (non-blocking)
817  UPstream::waitRequests(startOfRequests);
818 
819  for (auto& pfld : *this)
820  {
821  const auto* cpp = isA<CoupledPatchType>(pfld.patch());
822 
823  if (cpp && cpp->coupled())
824  {
825  pfld.evaluate(commsType);
826  }
827  }
828  }
829  else if (commsType == UPstream::commsTypes::scheduled)
830  {
831  const lduSchedule& patchSchedule =
832  bmesh_.mesh().globalData().patchSchedule();
833 
834  for (const auto& schedEval : patchSchedule)
835  {
836  const label patchi = schedEval.patch;
837  auto& pfld = (*this)[patchi];
838 
839  const auto* cpp = isA<CoupledPatchType>(pfld.patch());
840 
841  if (cpp && cpp->coupled())
842  {
843  if (schedEval.init)
844  {
845  pfld.initEvaluate(commsType);
846  }
847  else
848  {
849  pfld.evaluate(commsType);
850  }
851  }
852  }
853  }
854  else
855  {
857  << "Unsupported communications type " << int(commsType) << nl
859  }
860 }
861 
862 
863 template<class Type, template<class> class PatchField, class GeoMesh>
866 {
867  const FieldField<PatchField, Type>& pff = *this;
868 
869  wordList list(pff.size());
870 
871  forAll(pff, patchi)
872  {
873  list[patchi] = pff[patchi].type();
874  }
875 
876  return list;
877 }
878 
879 
880 template<class Type, template<class> class PatchField, class GeoMesh>
883 boundaryInternalField() const
884 {
886  (
888  *this
889  );
890 
891  auto& result = tresult;
892 
893  forAll(result, patchi)
894  {
895  result[patchi] == this->operator[](patchi).patchInternalField();
896  }
898  return tresult;
899 }
900 
901 
902 template<class Type, template<class> class PatchField, class GeoMesh>
905 {
906  LduInterfaceFieldPtrsList<Type> list(this->size());
907 
908  forAll(list, patchi)
909  {
910  list.set
911  (
912  patchi,
913  isA<LduInterfaceField<Type>>(this->operator[](patchi))
914  );
915  }
916 
917  return list;
918 }
919 
920 
921 template<class Type, template<class> class PatchField, class GeoMesh>
924 scalarInterfaces() const
925 {
926  lduInterfaceFieldPtrsList list(this->size());
927 
928  forAll(list, patchi)
929  {
930  list.set
931  (
932  patchi,
933  isA<lduInterfaceField>(this->operator[](patchi))
934  );
935  }
937  return list;
938 }
939 
940 
941 template<class Type, template<class> class PatchField, class GeoMesh>
943 (
944  const word& keyword,
945  Ostream& os
946 ) const
947 {
948  os.beginBlock(keyword);
949  this->writeEntries(os);
950  os.endBlock();
952  os.check(FUNCTION_NAME);
953 }
954 
955 
956 template<class Type, template<class> class PatchField, class GeoMesh>
958 (
959  Ostream& os
960 ) const
961 {
962  for (const auto& pfld : *this)
963  {
964  os.beginBlock(pfld.patch().name());
965  os << pfld;
966  os.endBlock();
967  }
968 }
969 
970 
971 template<class Type, template<class> class PatchField, class GeoMesh>
973 (
974 ) const
975 {
976  // Dummy op - template specialisations provide logic (usually call
977  // to checkConsistency)
978  return true;
979 }
980 
981 
982 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
983 
984 template<class Type, template<class> class PatchField, class GeoMesh>
986 (
987  const GeometricBoundaryField<Type, PatchField, GeoMesh>& bf
988 )
989 {
991 }
992 
993 
994 template<class Type, template<class> class PatchField, class GeoMesh>
996 (
998 )
999 {
1001 }
1002 
1003 
1004 template<class Type, template<class> class PatchField, class GeoMesh>
1006 (
1007  const Type& val
1008 )
1009 {
1011 }
1012 
1013 
1014 template<class Type, template<class> class PatchField, class GeoMesh>
1016 (
1017  const GeometricBoundaryField<Type, PatchField, GeoMesh>& bf
1018 )
1019 {
1020  forAll(*this, patchi)
1021  {
1022  this->operator[](patchi) == bf[patchi];
1023  }
1024 }
1025 
1026 
1027 template<class Type, template<class> class PatchField, class GeoMesh>
1029 (
1030  const FieldField<PatchField, Type>& bf
1031 )
1032 {
1033  forAll(*this, patchi)
1034  {
1035  this->operator[](patchi) == bf[patchi];
1036  }
1037 }
1038 
1039 
1040 template<class Type, template<class> class PatchField, class GeoMesh>
1042 (
1043  const Type& val
1044 )
1045 {
1046  forAll(*this, patchi)
1047  {
1048  this->operator[](patchi) == val;
1049  }
1050 }
1051 
1052 
1053 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
1054 
1055 template<class Type, template<class> class PatchField, class GeoMesh>
1056 Foam::Ostream& Foam::operator<<
1057 (
1058  Ostream& os,
1059  const GeometricBoundaryField<Type, PatchField, GeoMesh>& bf
1060 )
1061 {
1062  os << static_cast<const FieldField<PatchField, Type>&>(bf);
1063  return os;
1064 }
1065 
1066 
1067 // ************************************************************************* //
const labelList patchIDs(pbm.indices(polyPatchNames, true))
labelList patchIds
dictionary dict
type
Types of root.
Definition: Roots.H:52
GeometricBoundaryField(const BoundaryMesh &bmesh)
Construct from a BoundaryMesh, setting patches later.
tmp< GeometricBoundaryField > boundaryInternalField() const
Return boundary field of values neighbouring the boundary.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
patchWriters resize(patchIds.size())
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
void evaluate(const UPstream::commsTypes commsType=UPstream::defaultCommsType)
Evaluate boundary conditions for each patch field. Uses specified or default comms.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
lduInterfaceFieldPtrsList scalarInterfaces() const
Return a list of pointers for each patch field with only those pointing to interfaces being set...
wordList types() const
Return a list of the patch types.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
tmp< GeometricField< Type, faPatchField, areaMesh > > average(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Area-weighted average a edgeField creating a areaField.
Definition: facAverage.C:40
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
An abstract base class for implicitly-coupled interface fields e.g. processor and cyclic patch fields...
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
Definition: lduSchedule.H:46
void evaluateCoupled(const UPstream::commsTypes commsType=UPstream::defaultCommsType)
Evaluate boundary conditions on coupled patches of given type. Uses specified or default comms...
void evaluateLocal(const UPstream::commsTypes commsType=UPstream::defaultCommsType)
Evaluate boundary conditions after change in local values. Uses specified or default comms...
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:51
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
void evaluate_if(const UnaryPredicate &pred, const UPstream::commsTypes commsType=UPstream::defaultCommsType)
Evaluate boundary conditions for patch fields matching the given predicate. Uses specified or default...
void evaluateSelected(const labelUList &patchIDs)
Evaluate boundary conditions for selected patches. Uses non-blocking comms.
void readField(const Internal &iField, const dictionary &dict)
Read the boundary field.
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
bool check() const
Helper: check if field has been evaluated. See instantiations.
void updateCoeffs()
Update the boundary condition coefficients.
#define DebugInfo
Report an information message using Foam::Info.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
Generic GeometricBoundaryField class.
List< word > wordList
List of word.
Definition: fileName.H:59
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:637
void writeEntry(const word &keyword, Ostream &os) const
Write boundary field as dictionary entry.
surface1 clear()
#define PoutInFunction
Report using Foam::Pout with FUNCTION_NAME prefix.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
LduInterfaceFieldPtrsList< Type > interfaces() const
Return a list of pointers for each patch field with only those pointing to interfaces being set...
void writeEntries(Ostream &os) const
Write dictionary entries of the individual boundary fields.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition: typeInfo.H:87
Generic mesh wrapper used by volMesh, surfaceMesh, pointMesh etc.
Definition: GeoMesh.H:42
List< label > labelList
A List of labels.
Definition: List.H:62
A class for managing temporary objects.
Definition: HashPtrTable.H:50
List< bool > boolList
A List of bools.
Definition: List.H:60
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrList.H:366
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...