ENH: add missing construct GeometricField from primitive field (tmp)

ENH: improvements for GeometricBoundaryField evaluation

- early termination from evaluate_if() and evaluateCoupled().

- evaluateCoupled() now forwards to evaluate_if() and receives
  additional handling for a 'void' parameter type.

BREAKING: extra template parameter for overset correctBoundaryCondition

- the true/false flag as a template parameter instead of as an
  argument to use 'if constexpr' code
This commit is contained in:
Mark Olesen
2025-05-28 09:22:05 +02:00
parent 1d6c77f8f4
commit d6e6450834
18 changed files with 362 additions and 470 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -39,74 +39,23 @@ namespace Foam
{ {
template<class Type> template<class Type>
void evaluateConstraintTypes(GeometricField<Type, fvPatchField, volMesh>& fld) void evaluateConstraintTypes
(
GeometricField<Type, fvPatchField, volMesh>& fld
)
{ {
auto& bfld = fld.boundaryFieldRef(); fld.boundaryFieldRef().evaluate_if
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
if
( (
commsType == UPstream::commsTypes::buffered [](const auto& pfld) -> bool
|| commsType == UPstream::commsTypes::nonBlocking
)
{
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
{ {
if return
( (
pfld.type() == pfld.patch().patch().type() pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type()) && polyPatch::constraintType(pfld.patch().patch().type())
) );
{ },
pfld.initEvaluate(commsType); UPstream::defaultCommsType
} );
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = bfld[patchi];
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
}
} }

View File

@ -373,6 +373,33 @@ public:
Field<Type>&& iField Field<Type>&& iField
); );
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE) //- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions. //- from name, mesh, dimensions.
//- [Takes current timeName from the mesh registry]. //- [Takes current timeName from the mesh registry].

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2024 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -163,6 +163,49 @@ Foam::DimensionedField<Type, GeoMesh>::New
} }
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
)
{
return DimensionedField<Type, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield
);
}
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
)
{
return DimensionedField<Type, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield
);
}
template<class Type, class GeoMesh> template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>> Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New Foam::DimensionedField<Type, GeoMesh>::New

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017,2022 OpenFOAM Foundation Copyright (C) 2011-2017,2022 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -64,6 +64,8 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
//Note: areaFields (finiteArea) do not have manipulatedMatrix() flag. TBD. //Note: areaFields (finiteArea) do not have manipulatedMatrix() flag. TBD.
//boolList oldManipulated(this->size()); //boolList oldManipulated(this->size());
label nEvaluated(0);
for (auto& pfld : bfld) for (auto& pfld : bfld)
{ {
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
@ -72,19 +74,24 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
oldUpdated[patchi] = pfld.updated(); oldUpdated[patchi] = pfld.updated();
oldBfld[patchi] = pfld; oldBfld[patchi] = pfld;
//oldManipulated[patchi] = pfld.manipulatedMatrix(); //oldManipulated[patchi] = pfld.manipulatedMatrix();
++nEvaluated;
} }
} }
if (!nEvaluated) return true; // Early termination
// Re-evaluate // Re-evaluate
{ {
const label startOfRequests = UPstream::nRequests(); const label startOfRequests = UPstream::nRequests();
nEvaluated = 0;
for (auto& pfld : bfld) for (auto& pfld : bfld)
{ {
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
{ {
pfld.initEvaluate(UPstream::commsTypes::nonBlocking); pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
++nEvaluated;
} }
} }
@ -96,13 +103,15 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
{ {
pfld.evaluate(UPstream::commsTypes::nonBlocking); pfld.evaluate(UPstream::commsTypes::nonBlocking);
if (--nEvaluated == 0) break; // Early termination
} }
} }
} }
// Check // Check
bool ok = true; bool allOk(true);
for (auto& pfld : bfld) for (auto& pfld : bfld)
{ {
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
@ -110,16 +119,23 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
const label patchi = pfld.patch().index(); const label patchi = pfld.patch().index();
const auto& oldPfld = oldBfld[patchi]; const auto& oldPfld = oldBfld[patchi];
forAll(pfld, facei) bool localOk(true);
if (allOk)
{ {
if (mag(pfld[facei]-oldPfld[facei]) > tol) // Only check once
forAll(pfld, facei)
{ {
ok = false; if (mag(pfld[facei]-oldPfld[facei]) > tol)
break; {
allOk = false;
localOk = false;
break;
}
} }
} }
if (!ok) if (!localOk)
{ {
if (doExit) if (doExit)
{ {
@ -133,7 +149,7 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
<< ". Average of evaluated field = " << ". Average of evaluated field = "
<< average(pfld) << average(pfld)
<< ". Difference:" << average(pfld-oldPfld) << ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << ". Tolerance:" << tol << endl
<< exit(FatalError); << exit(FatalError);
} }
else else
@ -148,25 +164,13 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
<< ". Average of evaluated field = " << ". Average of evaluated field = "
<< average(pfld) << average(pfld)
<< ". Difference:" << average(pfld-oldPfld) << ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << ". Tolerance:" << tol << endl;
<< endl;
// Skip other patches
break;
} }
} }
}
}
// Restore bfld, updated // Restore bfld, updated
for (auto& pfld : bfld)
{
if (isA<CheckPatchFieldType>(pfld))
{
const label patchi = pfld.patch().index();
pfld.setUpdated(oldUpdated[patchi]); pfld.setUpdated(oldUpdated[patchi]);
Field<Type>& vals = pfld; static_cast<Field<Type>&>(pfld) = std::move(oldBfld[patchi]);
vals = std::move(oldBfld[patchi]);
//pfld.setManipulated(oldManipulated[patchi]); //pfld.setManipulated(oldManipulated[patchi]);
} }
} }
@ -176,10 +180,10 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
const auto& pfld0 = this->operator[](0); const auto& pfld0 = this->operator[](0);
PoutInFunction PoutInFunction
<< " Result of checking for field " << " Result of checking for field "
<< pfld0.internalField().name() << " : " << ok << endl; << pfld0.internalField().name() << " : " << allOk << endl;
} }
return ok; return allOk;
} }
@ -626,6 +630,7 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluate_if
|| commsType == UPstream::commsTypes::nonBlocking || commsType == UPstream::commsTypes::nonBlocking
) )
{ {
label nEvaluated(0);
const label startOfRequests = UPstream::nRequests(); const label startOfRequests = UPstream::nRequests();
for (auto& pfld : *this) for (auto& pfld : *this)
@ -633,17 +638,21 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluate_if
if (pred(pfld)) if (pred(pfld))
{ {
pfld.initEvaluate(commsType); pfld.initEvaluate(commsType);
++nEvaluated;
} }
} }
// Wait for outstanding requests (non-blocking) // Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests); UPstream::waitRequests(startOfRequests);
if (!nEvaluated) return; // Early termination
for (auto& pfld : *this) for (auto& pfld : *this)
{ {
if (pred(pfld)) if (pred(pfld))
{ {
pfld.evaluate(commsType); pfld.evaluate(commsType);
if (--nEvaluated == 0) break; // Early termination
} }
} }
} }
@ -778,81 +787,25 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluateCoupled
const UPstream::commsTypes commsType const UPstream::commsTypes commsType
) )
{ {
// Alternative (C++14) if constexpr (std::is_void_v<CoupledPatchType>)
//
// this->evaluate_if
// (
// [](const auto& pfld) -> bool
// {
// const auto* cpp = isA<CoupledPatchType>(pfld.patch());
// return (cpp && cpp->coupled());
// },
// commsType
// );
// DebugInFunction << nl;
if
(
commsType == UPstream::commsTypes::buffered
|| commsType == UPstream::commsTypes::nonBlocking
)
{ {
const label startOfRequests = UPstream::nRequests(); this->evaluate_if
(
for (auto& pfld : *this) [](const auto& pfld) { return pfld.coupled(); },
{ commsType
const auto* cpp = isA<CoupledPatchType>(pfld.patch()); );
if (cpp && cpp->coupled())
{
pfld.initEvaluate(commsType);
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : *this)
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
bmesh_.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = (*this)[patchi];
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
} }
else else
{ {
FatalErrorInFunction this->evaluate_if
<< "Unsupported communications type " << int(commsType) << nl (
<< exit(FatalError); [](const auto& pfld) -> bool
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
return (cpp && cpp->coupled());
},
commsType
);
} }
} }

View File

@ -205,8 +205,12 @@ public:
const UPstream::commsTypes commsType = UPstream::defaultCommsType const UPstream::commsTypes commsType = UPstream::defaultCommsType
); );
//- Evaluate boundary conditions on coupled patches of given type. //- Evaluate boundary conditions on coupled patches of the given type,
//- Uses specified or default comms. //- using specified or default comms.
//
// \tparam CoupledPatchType The coupled \b patch type that should
// be evaluated. For a \c void type,
// all coupled patch fields will be evaluated.
template<class CoupledPatchType> template<class CoupledPatchType>
void evaluateCoupled void evaluateCoupled
( (

View File

@ -63,8 +63,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::readFields
if (dict.readIfPresent("referenceLevel", refLevel)) if (dict.readIfPresent("referenceLevel", refLevel))
{ {
Field<Type>::operator+=(refLevel); // Add to internal (primitive) field
this->field() += refLevel;
// Add to boundary fields
forAll(boundaryField_, patchi) forAll(boundaryField_, patchi)
{ {
boundaryField_[patchi] == boundaryField_[patchi] + refLevel; boundaryField_[patchi] == boundaryField_[patchi] + refLevel;
@ -409,7 +411,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
boundaryField_(mesh.boundary(), *this, patchFieldType) boundaryField_(mesh.boundary(), *this, patchFieldType)
{ {
DebugInFunction DebugInFunction
<< "Copy construct from internal field" << nl << this->info() << endl; << "Copy construct from primitive field" << nl << this->info() << endl;
readIfPresent(); readIfPresent();
} }
@ -430,7 +432,28 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
boundaryField_(mesh.boundary(), *this, patchFieldType) boundaryField_(mesh.boundary(), *this, patchFieldType)
{ {
DebugInFunction DebugInFunction
<< "Move construct from internal field" << nl << this->info() << endl; << "Move construct from primitive field" << nl << this->info() << endl;
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
:
Internal(io, mesh, dims, tfield),
timeIndex_(this->time().timeIndex()),
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
DebugInFunction
<< "Construct from tmp primitive field" << nl << this->info() << endl;
readIfPresent(); readIfPresent();
} }
@ -1391,10 +1414,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) -> bool [](const auto& pfld) { return pfld.constraintOverride(); }
{
return pfld.constraintOverride();
}
); );
} }
@ -1436,10 +1456,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) -> bool [](const auto& pfld) { return pfld.constraintOverride(); }
{
return pfld.constraintOverride();
}
); );
} }
@ -1456,10 +1473,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) -> bool [](const auto& pfld) { return pfld.constraintOverride(); }
{
return pfld.constraintOverride();
}
); );
} }
@ -1484,10 +1498,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) -> bool [](const auto& pfld) { return pfld.constraintOverride(); }
{
return pfld.constraintOverride();
}
); );
} }
@ -1504,10 +1515,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) -> bool [](const auto& pfld) { return pfld.constraintOverride(); }
{
return pfld.constraintOverride();
}
); );
} }
@ -1527,10 +1535,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\ \
boundaryFieldRef().evaluate_if \ boundaryFieldRef().evaluate_if \
( \ ( \
[](const auto& pfld) -> bool \ [](const auto& pfld) { return pfld.constraintOverride(); } \
{ \
return pfld.constraintOverride(); \
} \
); \ ); \
} \ } \
\ \
@ -1545,10 +1550,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\ \
boundaryFieldRef().evaluate_if \ boundaryFieldRef().evaluate_if \
( \ ( \
[](const auto& pfld) -> bool \ [](const auto& pfld) { return pfld.constraintOverride(); } \
{ \
return pfld.constraintOverride(); \
} \
); \ ); \
} \ } \
\ \
@ -1563,10 +1565,7 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\ \
boundaryFieldRef().evaluate_if \ boundaryFieldRef().evaluate_if \
( \ ( \
[](const auto& pfld) -> bool \ [](const auto& pfld) { return pfld.constraintOverride(); } \
{ \
return pfld.constraintOverride(); \
} \
); \ ); \
} }

View File

@ -251,7 +251,7 @@ public:
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
//- Move construct from internal field and a patch list to clone //- Construct from internal field (tmp) and a patch list to clone
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -273,7 +273,7 @@ public:
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
//- Copy construct from internal field, with specified patch type //- Copy construct from primitive field, with specified patch type
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -283,7 +283,7 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType() const word& patchFieldType = PatchField<Type>::calculatedType()
); );
//- Move construct from internal field, with specified patch type //- Move construct from primitive field, with specified patch type
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -293,7 +293,17 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType() const word& patchFieldType = PatchField<Type>::calculatedType()
); );
//- Copy construct from components //- Construct from primitive field (tmp), with specified patch type
GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Copy construct from primitive field and a patch list to clone
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -303,7 +313,7 @@ public:
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
//- Move construct from internal field and a patch list to clone //- Move construct from primitive field and a patch list to clone
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -319,7 +329,7 @@ public:
const IOobject& io, const IOobject& io,
const Mesh& mesh, const Mesh& mesh,
const dimensionSet& dims, const dimensionSet& dims,
const tmp<Field<Type>>& tiField, const tmp<Field<Type>>& tfield,
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
@ -508,6 +518,37 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType() const word& patchFieldType = PatchField<Type>::calculatedType()
); );
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, tmp of primitive field
//- and patch type.
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<GeometricField<Type, PatchField, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, tmp of primitive field
//- and patch type.
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<GeometricField<Type, PatchField, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE) //- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, copy of internal field contents //- from name, mesh, dimensions, copy of internal field contents
//- and patch list to clone. //- and patch list to clone.

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -215,6 +215,53 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::New
} }
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>> Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New Foam::GeometricField<Type, PatchField, GeoMesh>::New

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2023 OpenCFD Ltd. Copyright (C) 2023-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -88,12 +88,14 @@ bool Foam::patchDistMethods::meshWaveAddressing::correct
// since the supplied options (wall patchIDs and correctWalls) // since the supplied options (wall patchIDs and correctWalls)
// are not assumed to be different from the defaults of other usage. // are not assumed to be different from the defaults of other usage.
const labelList patchIds(patchIDs_.sortedToc());
// Calculate distance and addressing // Calculate distance and addressing
const auto& wDist = wallDistAddressing::New const auto& wDist = wallDistAddressing::New
( (
"wall", "wall",
mesh_, mesh_,
patchIDs_.sortedToc(), patchIds,
correctWalls_ correctWalls_
); );
@ -102,31 +104,18 @@ bool Foam::patchDistMethods::meshWaveAddressing::correct
// Note: copying value only so might not be consistent with supplied // Note: copying value only so might not be consistent with supplied
// patch types (e.g. zeroGradient when called from wallDist). Assume // patch types (e.g. zeroGradient when called from wallDist). Assume
// only affected ones are the supplied patches ... // only affected ones are the supplied patches ...
{
auto& bfld = y.boundaryFieldRef();
const label startOfRequests = UPstream::nRequests();
for (const label patchi : patchIDs_)
{
bfld[patchi].initEvaluate(UPstream::commsTypes::nonBlocking);
}
// Wait for outstanding requests y.boundaryFieldRef().evaluateSelected(patchIds);
UPstream::waitRequests(startOfRequests);
for (const label patchi : patchIDs_)
{
bfld[patchi].evaluate(UPstream::commsTypes::nonBlocking);
}
}
// Only calculate n if the field is defined // Only calculate n if the field is defined
if (notNull(n)) if (notNull(n))
{ {
for (const label patchi : patchIDs_) auto& bfld = n.boundaryFieldRef();
for (const label patchi : patchIds)
{ {
auto& pnf = n.boundaryFieldRef()[patchi]; bfld[patchi] == bfld[patchi].patch().nf();
pnf == pnf.patch().nf();
} }
// No problem with inconsistency as for y (see above) since doing // No problem with inconsistency as for y (see above) since doing

View File

@ -39,79 +39,17 @@ License
// GeometricField<Type, fvPatchField, volMesh>& fld // GeometricField<Type, fvPatchField, volMesh>& fld
//) const //) const
//{ //{
// auto& fldBf = fld.boundaryFieldRef(); // fld.boundaryFieldRef().evaluate_if
//
// const UPstream::commsTypes commsType = UPstream::defaultCommsType;
// const label startOfRequests = UPstream::nRequests();
//
// if
// ( // (
// commsType == UPstream::commsTypes::blocking // [](const auto& pfld) -> bool
// || commsType == UPstream::commsTypes::nonBlocking
// )
// {
// forAll(fldBf, patchi)
// { // {
// fvPatchField<Type>& tgtField = fldBf[patchi]; // return
//
// if
// ( // (
// tgtField.type() == tgtField.patch().patch().type() // pfld.type() == pfld.patch().patch().type()
// && polyPatch::constraintType(tgtField.patch().patch().type()) // && polyPatch::constraintType(pfld.patch().patch().type())
// ) // );
// {
// tgtField.initEvaluate(commsType);
// }
// } // }
// // );
// // Wait for outstanding requests
// if (commsType == UPstream::commsTypes::nonBlocking)
// {
// UPstream::waitRequests(startOfRequests);
// }
//
// forAll(fldBf, patchi)
// {
// fvPatchField<Type>& tgtField = fldBf[patchi];
//
// if
// (
// tgtField.type() == tgtField.patch().patch().type()
// && polyPatch::constraintType(tgtField.patch().patch().type())
// )
// {
// tgtField.evaluate(commsType);
// }
// }
// }
// else if (commsType == UPstream::commsTypes::scheduled)
// {
// const lduSchedule& patchSchedule =
// fld.mesh().globalData().patchSchedule();
//
// for (const auto& schedEval : patchSchedule)
// {
// const label patchi = schedEval.patch;
//
// fvPatchField<Type>& tgtField = fldBf[patchi];
//
// if
// (
// tgtField.type() == tgtField.patch().patch().type()
// && polyPatch::constraintType(tgtField.patch().patch().type())
// )
// {
// if (schedEval.init)
// {
// tgtField.initEvaluate(commsType);
// }
// else
// {
// tgtField.evaluate(commsType);
// }
// }
// }
// }
//} //}
template<class Type> template<class Type>

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2022 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,72 +36,18 @@ void Foam::functionObjects::mapFields::evaluateConstraintTypes
GeometricField<Type, fvPatchField, volMesh>& fld GeometricField<Type, fvPatchField, volMesh>& fld
) const ) const
{ {
auto& bfld = fld.boundaryFieldRef(); fld.boundaryFieldRef().evaluate_if
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
if
( (
commsType == UPstream::commsTypes::buffered [](const auto& pfld) -> bool
|| commsType == UPstream::commsTypes::nonBlocking
)
{
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
{ {
if return
( (
pfld.type() == pfld.patch().patch().type() pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type()) && polyPatch::constraintType(pfld.patch().patch().type())
) );
{ },
pfld.initEvaluate(commsType); UPstream::defaultCommsType
} );
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = bfld[patchi];
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
}
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -182,31 +182,16 @@ void Foam::cellCellStencil::correctBoundaryConditions
GeoField& psi GeoField& psi
) )
{ {
// Version of GeoField::correctBoundaryConditions that exclude evaluation // correctBoundaryConditions excluding oversetFvPatchFields
// of oversetFvPatchFields
auto& bfld = psi.boundaryFieldRef(); psi.boundaryFieldRef().evaluate_if
(
const label startOfRequests = UPstream::nRequests(); [](const auto& pfld)
for (auto& pfld : bfld)
{
if (!isA<SuppressBC>(pfld))
{ {
pfld.initEvaluate(UPstream::commsTypes::nonBlocking); return (!isA<SuppressBC>(pfld));
} },
} UPstream::commsTypes::nonBlocking
);
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if (!isA<SuppressBC>(pfld))
{
pfld.evaluate(UPstream::commsTypes::nonBlocking);
}
}
} }

View File

@ -1033,8 +1033,9 @@ bool Foam::cellCellStencils::cellVolumeWeight::update()
oversetFvMeshBase::correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(cellInterpolationWeight_.boundaryFieldRef(), false); false
>(cellInterpolationWeight_.boundaryFieldRef());
DynamicList<label> interpolationCells; DynamicList<label> interpolationCells;
forAll(cellStencil_, cellI) forAll(cellStencil_, cellI)

View File

@ -2351,8 +2351,9 @@ bool Foam::cellCellStencils::inverseDistance::update()
oversetFvMeshBase::correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(cellInterpolationWeight_.boundaryFieldRef(), false); false
>(cellInterpolationWeight_.boundaryFieldRef());
if ((debug & 2) && mesh_.time().writeTime()) if ((debug & 2) && mesh_.time().writeTime())
@ -2435,8 +2436,9 @@ bool Foam::cellCellStencils::inverseDistance::update()
oversetFvMeshBase::correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(tfld.ref().boundaryFieldRef(), false); false
>(tfld.ref().boundaryFieldRef());
tfld().write(); tfld().write();
} }
@ -2450,8 +2452,9 @@ bool Foam::cellCellStencils::inverseDistance::update()
oversetFvMeshBase::correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(tfld.ref().boundaryFieldRef(), false); false
>(tfld.ref().boundaryFieldRef());
tfld().write(); tfld().write();
} }

View File

@ -1059,8 +1059,9 @@ bool Foam::cellCellStencils::trackingInverseDistance::update()
oversetFvMeshBase::correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(cellInterpolationWeight_.boundaryFieldRef(), false); false
>(cellInterpolationWeight_.boundaryFieldRef());
if ((debug & 2) && mesh_.time().writeTime()) if ((debug & 2) && mesh_.time().writeTime())

View File

@ -445,11 +445,12 @@ void Foam::oversetFvMeshBase::writeAgglomeration
fld[celli] = cellToCoarse[celli]; fld[celli] = cellToCoarse[celli];
} }
fld /= max(fld); fld /= max(fld);
correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(scalarAgglomeration.boundaryFieldRef(), false); false
>(scalarAgglomeration.boundaryFieldRef());
scalarAgglomeration.write(); scalarAgglomeration.write();
Info<< "Writing initial cell distribution to " Info<< "Writing initial cell distribution to "
@ -503,11 +504,12 @@ void Foam::oversetFvMeshBase::writeAgglomeration
//{ //{
// fld /= max(fld); // fld /= max(fld);
//} //}
correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(scalarAgglomeration.boundaryFieldRef(), false); false
>(scalarAgglomeration.boundaryFieldRef());
scalarAgglomeration.write(); scalarAgglomeration.write();
} }
} }

View File

@ -257,13 +257,12 @@ public:
template<class GeoField> template<class GeoField>
static void checkCoupledBC(const GeoField& fld); static void checkCoupledBC(const GeoField& fld);
//- Correct boundary conditions of certain type (typeOnly = true) //- Correct boundary conditions of certain type (TypeOnly = true)
//- or explicitly not of the type (typeOnly = false) //- or explicitly not of the type (TypeOnly = false)
template<class GeoField, class PatchType> template<class GeoField, class PatchType, bool TypeOnly>
static void correctBoundaryConditions static void correctBoundaryConditions
( (
typename GeoField::Boundary& bfld, typename GeoField::Boundary& bfld
const bool typeOnly
); );
//- Determine normalisation for interpolation. This equals the //- Determine normalisation for interpolation. This equals the

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2014-2022 OpenCFD Ltd. Copyright (C) 2014-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -73,44 +73,31 @@ void Foam::oversetFvMeshBase::scaleConnection
} }
} }
template<class GeoField, class PatchType> template<class GeoField, class PatchType, bool TypeOnly>
void Foam::oversetFvMeshBase::correctBoundaryConditions void Foam::oversetFvMeshBase::correctBoundaryConditions
( (
typename GeoField::Boundary& bfld, typename GeoField::Boundary& bfld
const bool typeOnly
) )
{ {
// Alternative (C++14) if constexpr (TypeOnly)
//
// bfld.evaluate_if
// (
// [typeOnly](const auto& pfld) -> bool
// {
// return (typeOnly == bool(isA<PatchType>(pfld)));
// },
// UPstream::defaultCommsType
// );
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
{ {
if (typeOnly == bool(isA<PatchType>(pfld))) bfld.evaluate_if
{ (
pfld.initEvaluate(commsType); [](const auto& pfld)
} {
} return (bool(isA<PatchType>(pfld)));
}
// Wait for outstanding requests (non-blocking) );
UPstream::waitRequests(startOfRequests); }
else
for (auto& pfld : bfld)
{ {
if (typeOnly == bool(isA<PatchType>(pfld))) bfld.evaluate_if
{ (
pfld.evaluate(commsType); [](const auto& pfld)
} {
return (!bool(isA<PatchType>(pfld)));
}
);
} }
} }
@ -766,11 +753,12 @@ Foam::SolverPerformance<Type> Foam::oversetFvMeshBase::solveOverset
dimensionedScalar(dimless, Zero) dimensionedScalar(dimless, Zero)
); );
scale.ref().field() = norm; scale.ref().field() = norm;
correctBoundaryConditions oversetFvMeshBase::correctBoundaryConditions
< <
volScalarField, volScalarField,
oversetFvPatchField<scalar> oversetFvPatchField<scalar>,
>(scale.boundaryFieldRef(), false); false
>(scale.boundaryFieldRef());
scale.write(); scale.write();
if (debug) if (debug)
@ -802,11 +790,12 @@ Foam::SolverPerformance<Type> Foam::oversetFvMeshBase::solveOverset
m.boundaryManipulate(bpsi); m.boundaryManipulate(bpsi);
// Swap psi values so added patches have patchNeighbourField // Swap psi values so added patches have patchNeighbourField
correctBoundaryConditions<GeoField, calculatedProcessorFvPatchField<Type>> oversetFvMeshBase::correctBoundaryConditions
( <
bpsi, GeoField,
calculatedProcessorFvPatchField<Type>,
true true
); >(bpsi);
// Use lower level solver // Use lower level solver
//SolverPerformance<Type> s(dynamicMotionSolverFvMesh::solve(m, dict)); //SolverPerformance<Type> s(dynamicMotionSolverFvMesh::solve(m, dict));
@ -993,32 +982,8 @@ void Foam::oversetFvMeshBase::write
template<class GeoField> template<class GeoField>
void Foam::oversetFvMeshBase::correctCoupledBoundaryConditions(GeoField& fld) void Foam::oversetFvMeshBase::correctCoupledBoundaryConditions(GeoField& fld)
{ {
auto& bfld = fld.boundaryFieldRef(); // Evaluate all coupled fields
fld.boundaryFieldRef().template evaluateCoupled<void>();
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
{
if (pfld.coupled())
{
//Pout<< "initEval of " << pfld.patch().name() << endl;
pfld.initEvaluate(commsType);
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if (pfld.coupled())
{
//Pout<< "eval of " << pfld.patch().name() << endl;
pfld.evaluate(commsType);
}
}
} }
@ -1030,13 +995,13 @@ void Foam::oversetFvMeshBase::checkCoupledBC(const GeoField& fld)
GeoField fldCorr(fld.name()+"_correct", fld); GeoField fldCorr(fld.name()+"_correct", fld);
correctCoupledBoundaryConditions(fldCorr); correctCoupledBoundaryConditions(fldCorr);
const typename GeoField::Boundary& bfld = fld.boundaryField(); const auto& bfld = fld.boundaryField();
const typename GeoField::Boundary& bfldCorr = fldCorr.boundaryField(); const auto& bfldCorr = fldCorr.boundaryField();
forAll(bfld, patchi) forAll(bfld, patchi)
{ {
const typename GeoField::Patch& pfld = bfld[patchi]; const auto& pfld = bfld[patchi];
const typename GeoField::Patch& pfldCorr = bfldCorr[patchi]; const auto& pfldCorr = bfldCorr[patchi];
Pout<< "Patch:" << pfld.patch().name() << endl; Pout<< "Patch:" << pfld.patch().name() << endl;