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
This commit is contained in:
Mark Olesen
2020-09-02 14:44:59 +02:00
parent a85446cad3
commit b2feb6a8d8
3 changed files with 77 additions and 101 deletions

View File

@ -27,8 +27,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "readFields.H" #include "readFields.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -53,7 +51,7 @@ Foam::functionObjects::readFields::readFields
) )
: :
fvMeshFunctionObject(name, runTime, dict), fvMeshFunctionObject(name, runTime, dict),
readOnStart_(true), readOnStart_(dict.getOrDefault("readOnStart", true)),
fieldSet_() fieldSet_()
{ {
read(dict); read(dict);
@ -71,7 +69,6 @@ bool Foam::functionObjects::readFields::read(const dictionary& dict)
{ {
fvMeshFunctionObject::read(dict); fvMeshFunctionObject::read(dict);
dict.readIfPresent("readOnStart", readOnStart_);
dict.readEntry("fields", fieldSet_); dict.readEntry("fields", fieldSet_);
return true; return true;
@ -80,16 +77,49 @@ bool Foam::functionObjects::readFields::read(const dictionary& dict)
bool Foam::functionObjects::readFields::execute() 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<regIOobject>(fieldName);
// If necessary load field if (ptr)
loadField<scalar>(fieldName); {
loadField<vector>(fieldName); DebugInfo
loadField<sphericalTensor>(fieldName); << "readFields : "
loadField<symmTensor>(fieldName); << ptr->name() << " (" << ptr->type()
loadField<tensor>(fieldName); << ") 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<regIOobject>(false) // Preload header info
&& !io.headerClassName().empty() // Extra safety
&&
(
loadField<scalar>(io)
|| loadField<vector>(io)
|| loadField<sphericalTensor>(io)
|| loadField<symmTensor>(io)
|| loadField<tensor>(io)
)
);
if (!ok)
{
DebugInfo
<< "readFields : failed to load " << fieldName << endl;
}
} }
return true; return true;

View File

@ -56,7 +56,7 @@ Usage
// Mandatory entries (runtime modifiable) // Mandatory entries (runtime modifiable)
fields (<field1> <field2> ... <fieldN>); fields (<field1> <field2> ... <fieldN>);
// Optional entries (runtime modifiable) // Optional entries (runtime unmodifiable)
readOnStart true; readOnStart true;
// Optional (inherited) entries // Optional (inherited) entries
@ -115,7 +115,7 @@ protected:
// Protected Data // Protected Data
//- Flag to read on construction //- Read immediately on construction (default: true)
bool readOnStart_; bool readOnStart_;
//- Fields to load //- Fields to load
@ -124,9 +124,13 @@ protected:
// Protected Member Functions // Protected Member Functions
//- Load field //- Attempt load from io, store on database if successful
template<class FieldType>
bool loadAndStore(const IOobject& io);
//- Forward to loadAndStore for supported types
template<class Type> template<class Type>
bool loadField(const word&); bool loadField(const IOobject& io);
public: public:
@ -160,7 +164,7 @@ public:
// Member Functions // Member Functions
//- Read the set of fields from dictionary //- Read the set of fields from dictionary
virtual bool read(const dictionary&); virtual bool read(const dictionary& dict);
//- Read the fields //- Read the fields
virtual bool execute(); virtual bool execute();

View File

@ -31,97 +31,39 @@ License
#include "surfaceFields.H" #include "surfaceFields.H"
#include "Time.H" #include "Time.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type> template<class FieldType>
bool Foam::functionObjects::readFields::loadField(const word& fieldName) bool Foam::functionObjects::readFields::loadAndStore(const IOobject& io)
{ {
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; if (FieldType::typeName == io.headerClassName())
typedef typename VolFieldType::Internal IntVolFieldType; {
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType; // Store field on mesh database
/// typedef DimensionedField<Type, surfGeoMesh> SurfFieldType; Log << " Reading " << io.name()
<< " (" << FieldType::typeName << ')' << endl;
if (foundObject<VolFieldType>(fieldName)) mesh_.objectRegistry::store(new FieldType(io, mesh_));
{ return true;
DebugInfo
<< "readFields : " << VolFieldType::typeName
<< " " << fieldName << " already in database"
<< endl;
}
else if (foundObject<IntVolFieldType>(fieldName))
{
DebugInfo
<< "readFields : " << IntVolFieldType::typeName
<< " " << fieldName << " already in database"
<< endl;
}
else if (foundObject<SurfaceFieldType>(fieldName))
{
DebugInfo
<< "readFields: " << SurfaceFieldType::typeName
<< " " << fieldName << " already exists in database"
<< " already in database" << endl;
}
/// else if (foundObject<SurfFieldType>(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<VolFieldType>(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<IntVolFieldType>(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<SurfaceFieldType>(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<SurfFieldType>(true, true, false))
/// {
/// const surfMesh* surfptr = isA<surfMesh>(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;
/// }
/// }
} }
return false; return false;
} }
template<class Type>
bool Foam::functionObjects::readFields::loadField(const IOobject& io)
{
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
typedef typename VolFieldType::Internal IntVolFieldType;
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
return
(
loadAndStore<VolFieldType>(io)
|| loadAndStore<IntVolFieldType>(io)
|| loadAndStore<SurfaceFieldType>(io)
);
}
// ************************************************************************* // // ************************************************************************* //