From b2feb6a8d84fc189fca878cff79992232ef1b758 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 2 Sep 2020 14:44:59 +0200 Subject: [PATCH] ENH: avoid redundant IO in readFields function object (fixes #1825) - read header info once and reuse - short-circuit logic to avoid unneeded checks - additional debug information if field cannot be found STYLE: remove unused old code remnants from #1206 --- .../field/readFields/readFields.C | 54 +++++++-- .../field/readFields/readFields.H | 14 ++- .../field/readFields/readFieldsTemplates.C | 110 +++++------------- 3 files changed, 77 insertions(+), 101 deletions(-) diff --git a/src/functionObjects/field/readFields/readFields.C b/src/functionObjects/field/readFields/readFields.C index 888d45221a..de70dd5d5f 100644 --- a/src/functionObjects/field/readFields/readFields.C +++ b/src/functionObjects/field/readFields/readFields.C @@ -27,8 +27,6 @@ License \*---------------------------------------------------------------------------*/ #include "readFields.H" -#include "volFields.H" -#include "surfaceFields.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -53,7 +51,7 @@ Foam::functionObjects::readFields::readFields ) : fvMeshFunctionObject(name, runTime, dict), - readOnStart_(true), + readOnStart_(dict.getOrDefault("readOnStart", true)), fieldSet_() { read(dict); @@ -71,7 +69,6 @@ bool Foam::functionObjects::readFields::read(const dictionary& dict) { fvMeshFunctionObject::read(dict); - dict.readIfPresent("readOnStart", readOnStart_); dict.readEntry("fields", fieldSet_); return true; @@ -80,16 +77,49 @@ bool Foam::functionObjects::readFields::read(const dictionary& dict) bool Foam::functionObjects::readFields::execute() { - forAll(fieldSet_, fieldi) + for (const word& fieldName : fieldSet_) { - const word& fieldName = fieldSet_[fieldi]; + // Already loaded? + const auto* ptr = mesh_.cfindObject(fieldName); - // If necessary load field - loadField(fieldName); - loadField(fieldName); - loadField(fieldName); - loadField(fieldName); - loadField(fieldName); + if (ptr) + { + DebugInfo + << "readFields : " + << ptr->name() << " (" << ptr->type() + << ") already in database" << endl; + continue; + } + + // Load field as necessary + IOobject io + ( + fieldName, + mesh_.time().timeName(), + mesh_, + IOobject::MUST_READ, + IOobject::NO_WRITE + ); + + const bool ok = + ( + io.typeHeaderOk(false) // Preload header info + && !io.headerClassName().empty() // Extra safety + && + ( + loadField(io) + || loadField(io) + || loadField(io) + || loadField(io) + || loadField(io) + ) + ); + + if (!ok) + { + DebugInfo + << "readFields : failed to load " << fieldName << endl; + } } return true; diff --git a/src/functionObjects/field/readFields/readFields.H b/src/functionObjects/field/readFields/readFields.H index feb521a75c..a275e6e523 100644 --- a/src/functionObjects/field/readFields/readFields.H +++ b/src/functionObjects/field/readFields/readFields.H @@ -56,7 +56,7 @@ Usage // Mandatory entries (runtime modifiable) fields ( ... ); - // Optional entries (runtime modifiable) + // Optional entries (runtime unmodifiable) readOnStart true; // Optional (inherited) entries @@ -115,7 +115,7 @@ protected: // Protected Data - //- Flag to read on construction + //- Read immediately on construction (default: true) bool readOnStart_; //- Fields to load @@ -124,9 +124,13 @@ protected: // Protected Member Functions - //- Load field + //- Attempt load from io, store on database if successful + template + bool loadAndStore(const IOobject& io); + + //- Forward to loadAndStore for supported types template - bool loadField(const word&); + bool loadField(const IOobject& io); public: @@ -160,7 +164,7 @@ public: // Member Functions //- Read the set of fields from dictionary - virtual bool read(const dictionary&); + virtual bool read(const dictionary& dict); //- Read the fields virtual bool execute(); diff --git a/src/functionObjects/field/readFields/readFieldsTemplates.C b/src/functionObjects/field/readFields/readFieldsTemplates.C index cdd0ca5ca5..42415c4c56 100644 --- a/src/functionObjects/field/readFields/readFieldsTemplates.C +++ b/src/functionObjects/field/readFields/readFieldsTemplates.C @@ -31,97 +31,39 @@ License #include "surfaceFields.H" #include "Time.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -template -bool Foam::functionObjects::readFields::loadField(const word& fieldName) +template +bool Foam::functionObjects::readFields::loadAndStore(const IOobject& io) { - typedef GeometricField VolFieldType; - typedef typename VolFieldType::Internal IntVolFieldType; - typedef GeometricField SurfaceFieldType; - /// typedef DimensionedField SurfFieldType; + if (FieldType::typeName == io.headerClassName()) + { + // Store field on mesh database + Log << " Reading " << io.name() + << " (" << FieldType::typeName << ')' << endl; - if (foundObject(fieldName)) - { - DebugInfo - << "readFields : " << VolFieldType::typeName - << " " << fieldName << " already in database" - << endl; - } - else if (foundObject(fieldName)) - { - DebugInfo - << "readFields : " << IntVolFieldType::typeName - << " " << fieldName << " already in database" - << endl; - } - else if (foundObject(fieldName)) - { - DebugInfo - << "readFields: " << SurfaceFieldType::typeName - << " " << fieldName << " already exists in database" - << " already in database" << endl; - } - /// else if (foundObject(fieldName)) - /// { - /// DebugInfo - /// << "readFields: " << SurfFieldType::typeName - /// << " " << fieldName << " already exists in database" - /// << " already in database" << endl; - /// } - else - { - IOobject fieldHeader - ( - fieldName, - mesh_.time().timeName(), - mesh_, - IOobject::MUST_READ, - IOobject::NO_WRITE - ); - - if (fieldHeader.typeHeaderOk(true, true, false)) - { - // Store field on mesh database - Log << " Reading " << fieldName << endl; - auto* fldPtr(new VolFieldType(fieldHeader, mesh_)); - mesh_.objectRegistry::store(fldPtr); - return true; - } - else if (fieldHeader.typeHeaderOk(true, true, false)) - { - // Store field on mesh database - Log << " Reading " << fieldName << endl; - auto* fldPtr(new IntVolFieldType(fieldHeader, mesh_)); - mesh_.objectRegistry::store(fldPtr); - return true; - } - else if (fieldHeader.typeHeaderOk(true, true, false)) - { - // Store field on mesh database - Log << " Reading " << fieldName << endl; - auto* fldPtr(new SurfaceFieldType(fieldHeader, mesh_)); - mesh_.objectRegistry::store(fldPtr); - return true; - } - /// else if (fieldHeader.typeHeaderOk(true, true, false)) - /// { - /// const surfMesh* surfptr = isA(obr()); - /// if (surfptr) - /// { - /// const surfMesh& s = surfptr; - /// - /// // Store field on surfMesh database - /// Log << " Reading " << fieldName << endl; - /// auto* fldPtr(new SurfFieldType(fieldHeader, s)); - /// s.store(fldPtr); - /// return true; - /// } - /// } + mesh_.objectRegistry::store(new FieldType(io, mesh_)); + return true; } return false; } +template +bool Foam::functionObjects::readFields::loadField(const IOobject& io) +{ + typedef GeometricField VolFieldType; + typedef typename VolFieldType::Internal IntVolFieldType; + typedef GeometricField SurfaceFieldType; + + return + ( + loadAndStore(io) + || loadAndStore(io) + || loadAndStore(io) + ); +} + + // ************************************************************************* //