Commit b2feb6a8 authored by Mark Olesen's avatar Mark Olesen

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
parent a85446ca
......@@ -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];
// If necessary load field
loadField<scalar>(fieldName);
loadField<vector>(fieldName);
loadField<sphericalTensor>(fieldName);
loadField<symmTensor>(fieldName);
loadField<tensor>(fieldName);
// Already loaded?
const auto* ptr = mesh_.cfindObject<regIOobject>(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<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;
......
......@@ -56,7 +56,7 @@ Usage
// Mandatory entries (runtime modifiable)
fields (<field1> <field2> ... <fieldN>);
// 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<class FieldType>
bool loadAndStore(const IOobject& io);
//- Forward to loadAndStore for supported types
template<class Type>
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();
......
......@@ -31,97 +31,39 @@ License
#include "surfaceFields.H"
#include "Time.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
bool Foam::functionObjects::readFields::loadField(const word& fieldName)
template<class FieldType>
bool Foam::functionObjects::readFields::loadAndStore(const IOobject& io)
{
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
typedef typename VolFieldType::Internal IntVolFieldType;
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
/// typedef DimensionedField<Type, surfGeoMesh> SurfFieldType;
if (foundObject<VolFieldType>(fieldName))
{
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
if (FieldType::typeName == io.headerClassName())
{
IOobject fieldHeader
(
fieldName,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
// Store field on mesh database
Log << " Reading " << io.name()
<< " (" << FieldType::typeName << ')' << endl;
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;
/// }
/// }
mesh_.objectRegistry::store(new FieldType(io, mesh_));
return true;
}
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)
);
}
// ************************************************************************* //
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment