From 9335b641f1d38bfa56a22c844ad64810b0bb1a8a Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 13 May 2024 12:31:57 +0200 Subject: [PATCH] ENH: GeometricBoundaryField evaluate with specified communication type - evaluate() the communication type is exposed as a parameter to allow for more tuning, but default parameter remains defaultCommsType so there is no change in behaviour for existing code - evaluate_if() supports a general selection predicate - evaluateSelected() now does initEvaluate() for all patches, waits and then calls evaluate(). This avoids potential deadlocks when multiple patches are inter-communicating. ENH: align DimensionedField reading with GeometricField treatment - use localIOdictionary to obtain the dictionary contents ENH: update GeometricField code - change GeometricField writeData() as primary output method (not operator<<) for better clarity of purpose - use unique_ptr for GeometricField demand-driven data --- .../DimensionedField/DimensionedField.H | 10 +- .../DimensionedField/DimensionedFieldIO.C | 58 +++-- .../GeometricField/GeometricBoundaryField.C | 218 +++++++++++------- .../GeometricField/GeometricBoundaryField.H | 58 +++-- .../GeometricField/GeometricField.C | 159 ++++--------- .../GeometricField/GeometricField.H | 21 +- 6 files changed, 282 insertions(+), 242 deletions(-) diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H index e7b4d21c6f..d37b651781 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H @@ -115,8 +115,12 @@ private: //- Assert that non-zero field size == mesh size void checkFieldSize() const; + //- Read from file if it is present. Checks the readOption flag void readIfPresent(const word& fieldDictEntry = "value"); + //- Read the field - create the field dictionary on-the-fly + void readField(const word& fieldDictEntry = "value"); + //- Implementation for 'New' with specified registerObject preference. // For LEGACY_REGISTER, registration is determined by // objectRegistry::is_cacheTemporaryObject(). @@ -580,8 +584,8 @@ public: bool writeData(Ostream& os, const word& fieldDictEntry) const; //- The writeData function (required by regIOobject), - //- call writeData with dictionary entry name = "value" - bool writeData(Ostream& os) const; + //- calls writeData with dictionary entry name = "value" + bool writeData(Ostream& os) const { return writeData(os, "value"); } // Member Operators @@ -613,12 +617,14 @@ public: // Ostream Operators + //- Calls DimensionedField::writeData() friend Ostream& operator<< ( Ostream& os, const DimensionedField& df ); + //- Calls DimensionedField::writeData() friend Ostream& operator<< ( Ostream& os, diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C index 57a0da9e66..7ad8544616 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C @@ -28,6 +28,7 @@ License #include "DimensionedField.H" #include "IOstreams.H" +#include "localIOdictionary.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -58,15 +59,49 @@ void Foam::DimensionedField::readField } +template +void Foam::DimensionedField::readField +( + const word& fieldDictEntry +) +{ + dictionary dict + ( + localIOdictionary::readContents + ( + IOobject + ( + this->name(), + this->instance(), + this->local(), + this->db(), + IOobjectOption::MUST_READ, + IOobjectOption::NO_WRITE, + IOobjectOption::NO_REGISTER + ), + typeName + ) + ); + + this->close(); + + readField(dict, fieldDictEntry); +} + + template void Foam::DimensionedField::readIfPresent ( const word& fieldDictEntry ) { - if (this->isReadRequired() || (this->isReadOptional() && this->headerOk())) + if + ( + this->isReadRequired() + || (this->isReadOptional() && this->headerOk()) + ) { - readField(dictionary(readStream(typeName)), fieldDictEntry); + readField(fieldDictEntry); } } @@ -87,7 +122,7 @@ Foam::DimensionedField::DimensionedField dimensions_(dimless), oriented_() { - readField(dictionary(readStream(typeName)), fieldDictEntry); + readField(fieldDictEntry); } @@ -134,23 +169,16 @@ bool Foam::DimensionedField::writeData } -template -bool Foam::DimensionedField::writeData(Ostream& os) const -{ - return writeData(os, "value"); -} - - // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // template Foam::Ostream& Foam::operator<< ( Ostream& os, - const DimensionedField& df + const DimensionedField& fld ) { - df.writeData(os); + fld.writeData(os); return os; } @@ -160,11 +188,11 @@ template Foam::Ostream& Foam::operator<< ( Ostream& os, - const tmp>& tdf + const tmp>& tfld ) { - tdf().writeData(os); - tdf.clear(); + tfld().writeData(os); + tfld.clear(); return os; } diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C index 70d5ce2556..aff9204eef 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C @@ -91,7 +91,7 @@ bool Foam::GeometricBoundaryField::checkConsistency } } - // Wait for outstanding requests + // Wait for outstanding requests (non-blocking) UPstream::waitRequests(startOfRequests); for (auto& pfld : bfld) @@ -193,10 +193,7 @@ void Foam::GeometricBoundaryField::readField const dictionary& dict ) { - ///if (GeometricFieldclear(); @@ -363,10 +360,7 @@ Foam::GeometricBoundaryField::GeometricBoundaryField FieldField(bmesh.size()), bmesh_(bmesh) { - ///if (GeometricField::GeometricBoundaryField FieldField(bmesh.size()), bmesh_(bmesh) { - ///if (GeometricField::GeometricBoundaryField FieldField(bmesh.size()), bmesh_(bmesh) { - ///if (GeometricField::GeometricBoundaryField FieldField(btf.size()), bmesh_(btf.bmesh_) { - ///if (GeometricField::GeometricBoundaryField FieldField(btf.size()), bmesh_(btf.bmesh_) { - ///if (GeometricField::GeometricBoundaryField : FieldField(btf), bmesh_(btf.bmesh_) -{ - ///if (GeometricField class PatchField, class GeoMesh> @@ -573,10 +550,7 @@ Foam::GeometricBoundaryField::GeometricBoundaryField template class PatchField, class GeoMesh> void Foam::GeometricBoundaryField::updateCoeffs() { - ///if (GeometricField::updateCoeffs() template class PatchField, class GeoMesh> -void Foam::GeometricBoundaryField::evaluate() +void Foam::GeometricBoundaryField::evaluate +( + const UPstream::commsTypes commsType +) { - ///if (GeometricField::evaluate() else { FatalErrorInFunction - << "Unsupported communications type " - << UPstream::commsTypeNames[commsType] + << "Unsupported communications type " << int(commsType) << nl + << exit(FatalError); + } +} + + +template class PatchField, class GeoMesh> +template +void Foam::GeometricBoundaryField::evaluate_if +( + const UnaryPredicate& pred, + const UPstream::commsTypes commsType +) +{ + if + ( + commsType == UPstream::commsTypes::buffered + || commsType == UPstream::commsTypes::nonBlocking + ) + { + const label startOfRequests = UPstream::nRequests(); + + for (auto& pfld : *this) + { + if (pred(pfld)) + { + pfld.initEvaluate(commsType); + } + } + + // Wait for outstanding requests (non-blocking) + UPstream::waitRequests(startOfRequests); + + for (auto& pfld : *this) + { + if (pred(pfld)) + { + 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]; + + if (pred(pfld)) + { + if (schedEval.init) + { + pfld.initEvaluate(commsType); + } + else + { + pfld.evaluate(commsType); + } + } + } + } + else + { + FatalErrorInFunction + << "Unsupported communications type " << int(commsType) << nl << exit(FatalError); } } @@ -651,58 +685,60 @@ void Foam::GeometricBoundaryField::evaluate() template class PatchField, class GeoMesh> void Foam::GeometricBoundaryField::evaluateSelected ( - const UList