36 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
37 template<
class CheckPatchFieldType>
44 auto& bfld = this->constCast();
54 <<
" Checking boundary consistency for field " 55 << bfld[0].internalField().name() <<
endl;
59 List<Field<Type>> oldFields(bfld.size());
61 boolList oldManipulated(bfld.size());
65 for (
auto& pfld : bfld)
67 if (isA<CheckPatchFieldType>(pfld))
69 const label patchi = pfld.patch().index();
70 oldFields[patchi] = pfld;
71 oldUpdated[patchi] = pfld.updated();
72 oldManipulated[patchi] = pfld.manipulatedMatrix();
77 if (!nEvaluated)
return true;
81 const label startOfRequests = UPstream::nRequests();
85 for (
auto& pfld : bfld)
87 if (isA<CheckPatchFieldType>(pfld))
89 pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
95 UPstream::waitRequests(startOfRequests);
97 for (
auto& pfld : bfld)
99 if (isA<CheckPatchFieldType>(pfld))
101 pfld.evaluate(UPstream::commsTypes::nonBlocking);
102 if (--nEvaluated == 0)
break;
111 for (
auto& pfld : bfld)
113 if (isA<CheckPatchFieldType>(pfld))
115 const label patchi = pfld.patch().index();
116 auto& oldPfld = oldFields[patchi];
125 if (tol <
Foam::mag(pfld[facei]-oldPfld[facei]))
145 << pfld.internalField().name()
146 <<
" is not evaluated?" 147 <<
" On patch " << pfld.patch().name()
148 <<
" type " << pfld.type()
149 <<
" : average of field = " 151 <<
". Average of evaluated field = " 153 <<
". Difference:" <<
average(pfld-oldPfld)
154 <<
". Tolerance:" << tol <<
endl;
163 static_cast<Field<Type>&
>(pfld) = std::move(oldPfld);
164 pfld.setUpdated(oldUpdated[patchi]);
165 pfld.setManipulated(oldManipulated[patchi]);
172 <<
" Result of checking for field " 173 << bfld[0].internalField().name() <<
" : " << allOk <<
endl;
180 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
183 const Internal& iField,
192 this->
resize(bmesh_.size());
194 label nUnset = this->size();
201 const auto* subdict = dEntry.dictPtr();
203 if (subdict && dEntry.keyword().isLiteral())
205 const label patchi = bmesh_.findPatchID(dEntry.keyword());
235 for (
auto iter =
dict.crbegin(); iter !=
dict.crend(); ++iter)
237 const entry& dEntry = *iter;
238 const auto* subdict = dEntry.dictPtr();
240 if (subdict && dEntry.keyword().isLiteral())
243 bmesh_.indices(dEntry.keyword(),
true);
247 if (!this->
set(patchi))
268 if (!this->
set(patchi))
270 if (bmesh_[patchi].
type() == emptyPolyPatch::typeName)
277 emptyPolyPatch::typeName,
285 const auto* subdict =
dict.findDict(bmesh_[patchi].
name());
308 if (!this->
set(patchi))
310 if (bmesh_[patchi].
type() == cyclicPolyPatch::typeName)
313 <<
"Cannot find patchField entry for cyclic " 314 << bmesh_[patchi].name() <<
endl 315 <<
"Is your field uptodate with split cyclics?" <<
endl 316 <<
"Run foamUpgradeCyclics to convert mesh and fields" 322 <<
"Cannot find patchField entry for " 332 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
335 const BoundaryMesh& bmesh
343 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
346 const BoundaryMesh& bmesh,
347 const Internal& iField,
348 const word& patchFieldType
372 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
375 const BoundaryMesh& bmesh,
376 const Internal& iField,
381 FieldField<PatchField, Type>(bmesh.size()),
388 patchFieldTypes.size() != this->size()
389 || (constraintTypes.size() && (constraintTypes.size() != this->size()))
393 <<
"Incorrect number of patch type specifications given" <<
nl 394 <<
" Number of patches in mesh = " << bmesh.size()
395 <<
" number of patch type specifications = " 396 << patchFieldTypes.size()
400 if (constraintTypes.size())
409 patchFieldTypes[patchi],
410 constraintTypes[patchi],
426 patchFieldTypes[patchi],
436 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
439 const BoundaryMesh& bmesh,
440 const Internal& iField,
441 const PtrList<PatchField<Type>>& ptfl
444 FieldField<PatchField, Type>(bmesh.size()),
451 this->
set(patchi, ptfl[patchi].clone(iField));
456 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
459 const Internal& iField,
460 const GeometricBoundaryField<Type, PatchField, GeoMesh>& btf
463 FieldField<PatchField, Type>(btf.size()),
470 this->
set(patchi, btf[patchi].clone(iField));
475 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
478 const Internal& iField,
479 const GeometricBoundaryField<Type, PatchField, GeoMesh>& btf,
481 const word& patchFieldType
484 FieldField<PatchField, Type>(btf.size()),
505 if (!this->
set(patchi))
507 this->
set(patchi, btf[patchi].clone(iField));
513 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
516 const GeometricBoundaryField<Type, PatchField, GeoMesh>& btf
524 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
527 const BoundaryMesh& bmesh,
528 const Internal& iField,
541 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
546 for (
auto& pfld : *
this)
553 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
556 const UPstream::commsTypes commsType
561 commsType == UPstream::commsTypes::buffered
562 || commsType == UPstream::commsTypes::nonBlocking
565 const label startOfRequests = UPstream::nRequests();
567 for (
auto& pfld : *
this)
569 pfld.initEvaluate(commsType);
573 UPstream::waitRequests(startOfRequests);
575 for (
auto& pfld : *
this)
577 pfld.evaluate(commsType);
580 else if (commsType == UPstream::commsTypes::scheduled)
583 bmesh_.mesh().globalData().patchSchedule();
585 for (
const auto& schedEval : patchSchedule)
587 const label patchi = schedEval.patch;
588 auto& pfld = (*this)[patchi];
592 pfld.initEvaluate(commsType);
596 pfld.evaluate(commsType);
603 <<
"Unsupported communications type " << int(commsType) <<
nl 609 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
610 template<
class UnaryPredicate>
613 const UnaryPredicate& pred,
614 const UPstream::commsTypes commsType
619 commsType == UPstream::commsTypes::buffered
620 || commsType == UPstream::commsTypes::nonBlocking
624 const label startOfRequests = UPstream::nRequests();
626 for (
auto& pfld : *
this)
630 pfld.initEvaluate(commsType);
636 UPstream::waitRequests(startOfRequests);
638 if (!nEvaluated)
return;
640 for (
auto& pfld : *
this)
644 pfld.evaluate(commsType);
645 if (--nEvaluated == 0)
break;
649 else if (commsType == UPstream::commsTypes::scheduled)
652 bmesh_.mesh().globalData().patchSchedule();
654 for (
const auto& schedEval : patchSchedule)
656 const label patchi = schedEval.patch;
657 auto& pfld = (*this)[patchi];
663 pfld.initEvaluate(commsType);
667 pfld.evaluate(commsType);
675 <<
"Unsupported communications type " << int(commsType) <<
nl 681 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
687 const label startOfRequests = UPstream::nRequests();
691 auto& pfld = (*this)[patchi];
695 pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
699 UPstream::waitRequests(startOfRequests);
703 auto& pfld = (*this)[patchi];
705 pfld.evaluate(UPstream::commsTypes::nonBlocking);
710 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
713 const UPstream::commsTypes commsType
718 if (!FieldBase::localBoundaryConsistency())
725 commsType == UPstream::commsTypes::buffered
726 || commsType == UPstream::commsTypes::nonBlocking
729 const label startOfRequests = UPstream::nRequests();
731 for (
auto& pfld : *
this)
733 pfld.initEvaluateLocal(commsType);
737 UPstream::waitRequests(startOfRequests);
739 for (
auto& pfld : *
this)
741 pfld.evaluateLocal(commsType);
744 else if (commsType == UPstream::commsTypes::scheduled)
747 bmesh_.mesh().globalData().patchSchedule();
749 for (
const auto& schedEval : patchSchedule)
751 const label patchi = schedEval.patch;
752 auto& pfld = (*this)[patchi];
756 pfld.initEvaluateLocal(commsType);
760 pfld.evaluateLocal(commsType);
767 <<
"Unsupported communications type " << int(commsType) <<
nl 773 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
774 template<
class CoupledPatchType>
777 const UPstream::commsTypes commsType
780 if constexpr (std::is_void_v<CoupledPatchType>)
784 [](
const auto& pfld) {
return pfld.coupled(); },
792 [](
const auto& pfld) ->
bool 794 const auto* cpp = isA<CoupledPatchType>(pfld.patch());
795 return (cpp && cpp->coupled());
803 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
807 const FieldField<PatchField, Type>& pff = *
this;
813 list[patchi] = pff[patchi].type();
820 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
831 auto& result = tresult.ref();
835 result[patchi] == this->operator[](patchi).patchInternalField();
842 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
861 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
873 isA<lduInterfaceField>(this->
operator[](patchi))
881 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
888 os.beginBlock(keyword);
889 this->writeEntries(
os);
896 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
902 for (
const auto& pfld : *
this)
904 os.beginBlock(pfld.patch().name());
911 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
924 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
927 const GeometricBoundaryField<Type, PatchField, GeoMesh>& bf
934 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
944 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
954 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
957 const GeometricBoundaryField<Type, PatchField, GeoMesh>& bf
962 this->operator[](patchi) == bf[patchi];
967 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
970 const FieldField<PatchField, Type>& bf
975 this->operator[](patchi) == bf[patchi];
980 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
988 this->operator[](patchi) == val;
995 template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
999 const GeometricBoundaryField<Type, PatchField, GeoMesh>& bf
1002 os << static_cast<const FieldField<PatchField, Type>&>(bf);
const labelList patchIDs(pbm.indices(polyPatchNames, true))
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)
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 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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 '\n' character (0x0a)
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.
tmp< GeometricField< Type, faPatchField, areaMesh > > average(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Area-weighted average a edgeField creating a areaField.
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.
void evaluateCoupled(const UPstream::commsTypes commsType=UPstream::defaultCommsType)
Evaluate boundary conditions on coupled patches of the given type, using 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.
A field of fields is a PtrList of fields with reference counting.
#define forAll(list, i)
Loop across all elements in list.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
A class for handling words, derived from Foam::string.
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...
errorManip< error > abort(error &err)
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...
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
Generic GeometricBoundaryField class.
List< word > wordList
List of word.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
void writeEntry(const word &keyword, Ostream &os) const
Write boundary field as dictionary entry.
#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.
Generic mesh wrapper used by volMesh, surfaceMesh, pointMesh etc.
List< label > labelList
A List of labels.
A class for managing temporary objects.
List< bool > boolList
A List of bools.
A keyword and a list of tokens is an 'entry'.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...