ENH: delay evaluation of surfaces for fluxSummary (issue #1202)

- complete any pending initialisation on write().
  Allows lazier evaluation until when surfaces are actually available.
This commit is contained in:
Mark Olesen
2019-02-12 12:39:49 +01:00
parent 63389af16f
commit 2aca6b35ce
2 changed files with 189 additions and 113 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd. \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2015 OpenFOAM Foundation | Copyright (C) 2015 OpenFOAM Foundation
@ -131,19 +131,20 @@ void Foam::functionObjects::fluxSummary::initialiseSurface
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const ) const
{ {
const surfMesh* sPtr = mesh_.findObject<surfMesh>(surfName); const surfMesh* surfptr = mesh_.cfindObject<surfMesh>(surfName);
if (!sPtr)
if (!surfptr)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unable to find surface " << surfName << "Unable to find surface " << surfName
<< ". Valid surfaces are: " << mesh_.sortedNames<surfMesh>() << ". Valid surfaces: "
<< '.' << mesh_.sortedNames<surfMesh>() << nl
<< exit(FatalError); << exit(FatalError);
} }
names.append(surfName); names.append(surfName);
directions.append(Zero); // dummy value directions.append(Zero); // dummy value
faceFlip.append(boolList(0)); // no flip-map faceFlip.append(boolList()); // no flip-map
} }
@ -156,17 +157,18 @@ void Foam::functionObjects::fluxSummary::initialiseSurfaceAndDirection
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const ) const
{ {
const surfMesh* sPtr = mesh_.findObject<surfMesh>(surfName); const surfMesh* surfptr = mesh_.cfindObject<surfMesh>(surfName);
if (!sPtr)
if (!surfptr)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unable to find surface " << surfName << "Unable to find surface " << surfName
<< ". Valid surfaces are: " << mesh_.sortedNames<surfMesh>() << ". Valid surfaces: "
<< '.' << mesh_.sortedNames<surfMesh>() << nl
<< exit(FatalError); << exit(FatalError);
} }
const surfMesh& s = *sPtr; const surfMesh& s = *surfptr;
const vector refDir = dir/(mag(dir) + ROOTVSMALL); const vector refDir = dir/(mag(dir) + ROOTVSMALL);
names.append(surfName); names.append(surfName);
@ -198,8 +200,8 @@ void Foam::functionObjects::fluxSummary::initialiseFaceZone
const word& faceZoneName, const word& faceZoneName,
DynamicList<word>& names, DynamicList<word>& names,
DynamicList<vector>& directions, DynamicList<vector>& directions,
DynamicList<List<label>>& faceID, DynamicList<labelList>& faceID,
DynamicList<List<label>>& facePatchID, DynamicList<labelList>& facePatchID,
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const ) const
{ {
@ -208,7 +210,8 @@ void Foam::functionObjects::fluxSummary::initialiseFaceZone
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unable to find faceZone " << faceZoneName << "Unable to find faceZone " << faceZoneName
<< ". Valid faceZones are: " << mesh_.faceZones().names() << ". Valid zones: "
<< mesh_.faceZones().sortedNames() << nl
<< exit(FatalError); << exit(FatalError);
} }
const faceZone& fZone = mesh_.faceZones()[zonei]; const faceZone& fZone = mesh_.faceZones()[zonei];
@ -287,8 +290,8 @@ void Foam::functionObjects::fluxSummary::initialiseFaceZoneAndDirection
const vector& dir, const vector& dir,
DynamicList<word>& names, DynamicList<word>& names,
DynamicList<vector>& directions, DynamicList<vector>& directions,
DynamicList<List<label>>& faceID, DynamicList<labelList>& faceID,
DynamicList<List<label>>& facePatchID, DynamicList<labelList>& facePatchID,
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const ) const
{ {
@ -299,7 +302,8 @@ void Foam::functionObjects::fluxSummary::initialiseFaceZoneAndDirection
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unable to find faceZone " << faceZoneName << "Unable to find faceZone " << faceZoneName
<< ". Valid faceZones are: " << mesh_.faceZones().names() << ". Valid zones: "
<< mesh_.faceZones().sortedNames() << nl
<< exit(FatalError); << exit(FatalError);
} }
const faceZone& fZone = mesh_.faceZones()[zonei]; const faceZone& fZone = mesh_.faceZones()[zonei];
@ -393,8 +397,8 @@ void Foam::functionObjects::fluxSummary::initialiseCellZoneAndDirection
const vector& dir, const vector& dir,
DynamicList<word>& names, DynamicList<word>& names,
DynamicList<vector>& directions, DynamicList<vector>& directions,
DynamicList<List<label>>& faceID, DynamicList<labelList>& faceID,
DynamicList<List<label>>& facePatchID, DynamicList<labelList>& facePatchID,
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const ) const
{ {
@ -405,7 +409,8 @@ void Foam::functionObjects::fluxSummary::initialiseCellZoneAndDirection
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unable to find cellZone " << cellZoneName << "Unable to find cellZone " << cellZoneName
<< ". Valid zones are: " << mesh_.cellZones().names() << ". Valid zones: "
<< mesh_.cellZones().sortedNames() << nl
<< exit(FatalError); << exit(FatalError);
} }
@ -781,67 +786,29 @@ bool Foam::functionObjects::fluxSummary::surfaceModeWrite()
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // bool Foam::functionObjects::fluxSummary::update()
Foam::functionObjects::fluxSummary::fluxSummary
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
writeFile(obr_, name),
mode_(mdFaceZone),
scaleFactor_(1),
phiName_("phi"),
zoneNames_(),
faceID_(),
facePatchID_(),
faceFlip_(),
filePtrs_(),
tolerance_(0.8)
{ {
read(dict); if (!needsUpdate_)
} {
return false;
}
// Initialise with capacity == number of input names
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // DynamicList<word> faceZoneName(zoneNames_.size());
DynamicList<vector> refDir(faceZoneName.capacity());
Foam::functionObjects::fluxSummary::~fluxSummary() DynamicList<labelList> faceID(faceZoneName.capacity());
{} DynamicList<labelList> facePatchID(faceZoneName.capacity());
DynamicList<boolList> faceFlips(faceZoneName.capacity());
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
writeFile::read(dict);
mode_ = modeTypeNames_.get("mode", dict);
phiName_ = dict.lookupOrDefault<word>("phi", "phi");
scaleFactor_ = dict.lookupOrDefault<scalar>("scaleFactor", 1.0);
tolerance_ = dict.lookupOrDefault<scalar>("tolerance", 0.8);
// Initialise with capacity of 10 faceZones
DynamicList<word> faceZoneName(10);
DynamicList<vector> refDir(faceZoneName.capacity());
DynamicList<List<label>> faceID(faceZoneName.capacity());
DynamicList<List<label>> facePatchID(faceZoneName.capacity());
DynamicList<boolList> faceFlips(faceZoneName.capacity());
switch (mode_) switch (mode_)
{ {
case mdFaceZone: case mdFaceZone:
{ {
wordList zones(dict.get<wordList>("faceZones")); forAll(zoneNames_, zonei)
forAll(zones, i)
{ {
initialiseFaceZone initialiseFaceZone
( (
zones[i], zoneNames_[zonei],
faceZoneName, faceZoneName,
refDir, // fill with dummy value refDir, // fill with dummy value
faceID, faceID,
@ -853,15 +820,12 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
case mdFaceZoneAndDirection: case mdFaceZoneAndDirection:
{ {
List<Tuple2<word, vector>> zoneAndDirection; forAll(zoneNames_, zonei)
dict.readEntry("faceZoneAndDirection", zoneAndDirection);
forAll(zoneAndDirection, i)
{ {
initialiseFaceZoneAndDirection initialiseFaceZoneAndDirection
( (
zoneAndDirection[i].first(), zoneNames_[zonei],
zoneAndDirection[i].second(), zoneDirections_[zonei],
faceZoneName, faceZoneName,
refDir, refDir,
faceID, faceID,
@ -873,15 +837,12 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
case mdCellZoneAndDirection: case mdCellZoneAndDirection:
{ {
List<Tuple2<word, vector>> zoneAndDirection; forAll(zoneNames_, zonei)
dict.readEntry("cellZoneAndDirection", zoneAndDirection);
forAll(zoneAndDirection, i)
{ {
initialiseCellZoneAndDirection initialiseCellZoneAndDirection
( (
zoneAndDirection[i].first(), zoneNames_[zonei],
zoneAndDirection[i].second(), zoneDirections_[zonei],
faceZoneName, faceZoneName,
refDir, refDir,
faceID, faceID,
@ -893,13 +854,11 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
case mdSurface: case mdSurface:
{ {
wordList surfs(dict.get<wordList>("surfaces")); forAll(zoneNames_, zonei)
forAll(surfs, i)
{ {
initialiseSurface initialiseSurface
( (
surfs[i], zoneNames_[zonei],
faceZoneName, faceZoneName,
refDir, refDir,
faceFlips faceFlips
@ -909,15 +868,12 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
case mdSurfaceAndDirection: case mdSurfaceAndDirection:
{ {
List<Tuple2<word, vector>> surfAndDirection; forAll(zoneNames_, zonei)
dict.readEntry("surfaceAndDirection", surfAndDirection);
forAll(surfAndDirection, i)
{ {
initialiseSurfaceAndDirection initialiseSurfaceAndDirection
( (
surfAndDirection[i].first(), zoneNames_[zonei],
surfAndDirection[i].second(), zoneDirections_[zonei],
faceZoneName, faceZoneName,
refDir, refDir,
faceFlips faceFlips
@ -925,12 +881,8 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
break; break;
} }
default:
{ // Compiler warning if we forgot an enumeration
FatalIOErrorInFunction(dict)
<< "unhandled enumeration " << modeTypeNames_[mode_]
<< abort(FatalIOError);
}
} }
zoneNames_.transfer(faceZoneName); zoneNames_.transfer(faceZoneName);
@ -962,7 +914,7 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
if (writeToFile()) if (writeToFile())
{ {
filePtrs_.setSize(zoneNames_.size()); filePtrs_.resize(zoneNames_.size());
forAll(filePtrs_, zonei) forAll(filePtrs_, zonei)
{ {
@ -978,6 +930,118 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
} }
Info<< endl;
needsUpdate_ = false;
return true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::fluxSummary::fluxSummary
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
writeFile(obr_, name),
needsUpdate_(true),
mode_(mdFaceZone),
scaleFactor_(1),
phiName_("phi"),
zoneNames_(),
zoneDirections_(),
faceID_(),
facePatchID_(),
faceFlip_(),
filePtrs_(),
tolerance_(0.8)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
writeFile::read(dict);
needsUpdate_ = true;
mode_ = modeTypeNames_.get("mode", dict);
phiName_ = dict.lookupOrDefault<word>("phi", "phi");
scaleFactor_ = dict.lookupOrDefault<scalar>("scaleFactor", 1.0);
tolerance_ = dict.lookupOrDefault<scalar>("tolerance", 0.8);
zoneNames_.clear();
zoneDirections_.clear();
List<Tuple2<word, vector>> nameAndDirection;
switch (mode_)
{
case mdFaceZone:
{
dict.readEntry("faceZones", zoneNames_);
break;
}
case mdFaceZoneAndDirection:
{
dict.readEntry("faceZoneAndDirection", nameAndDirection);
break;
}
case mdCellZoneAndDirection:
{
dict.readEntry("cellZoneAndDirection", nameAndDirection);
break;
}
case mdSurface:
{
dict.readEntry("surfaces", zoneNames_);
break;
}
case mdSurfaceAndDirection:
{
dict.readEntry("surfaceAndDirection", nameAndDirection);
break;
}
default:
{
FatalIOErrorInFunction(dict)
<< "unhandled enumeration " << modeTypeNames_[mode_]
<< abort(FatalIOError);
}
}
// Split name/vector into separate lists
if (nameAndDirection.size())
{
zoneNames_.resize(nameAndDirection.size());
zoneDirections_.resize(nameAndDirection.size());
label zonei = 0;
for (const Tuple2<word, vector>& nameDirn : nameAndDirection)
{
zoneNames_[zonei] = nameDirn.first();
zoneDirections_[zonei] = nameDirn.second();
++zonei;
}
nameAndDirection.clear();
}
Info<< type() << ' ' << name() << " ("
<< modeTypeNames_[mode_] << ") with selection:\n "
<< flatOutput(zoneNames_) << endl;
return !zoneNames_.empty(); return !zoneNames_.empty();
} }
@ -1033,6 +1097,8 @@ bool Foam::functionObjects::fluxSummary::execute()
bool Foam::functionObjects::fluxSummary::write() bool Foam::functionObjects::fluxSummary::write()
{ {
update();
if (isSurfaceMode()) if (isSurfaceMode())
{ {
return surfaceModeWrite(); return surfaceModeWrite();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2015 OpenFOAM Foundation | Copyright (C) 2015 OpenFOAM Foundation
@ -92,7 +92,6 @@ SourceFiles
#include "writeFile.H" #include "writeFile.H"
#include "vector.H" #include "vector.H"
#include "DynamicList.H" #include "DynamicList.H"
#include "boolList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -102,6 +101,7 @@ class dimensionSet;
namespace functionObjects namespace functionObjects
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class fluxSummary Declaration Class fluxSummary Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -131,7 +131,10 @@ public:
protected: protected:
// Protected data // Protected Data
//- Track if the surface needs an update
bool needsUpdate_;
//- Mode for face determination //- Mode for face determination
modeType mode_; modeType mode_;
@ -148,11 +151,14 @@ protected:
//- Region (zone/surface) names //- Region (zone/surface) names
List<word> zoneNames_; List<word> zoneNames_;
//- Region (zone/surface) directions
List<vector> zoneDirections_;
//- Face IDs //- Face IDs
List<List<label>> faceID_; List<labelList> faceID_;
//- Face patch IDs //- Face patch IDs
List<List<label>> facePatchID_; List<labelList> facePatchID_;
//- Face flip map signs //- Face flip map signs
List<boolList> faceFlip_; List<boolList> faceFlip_;
@ -203,8 +209,8 @@ protected:
const word& faceZoneName, const word& faceZoneName,
DynamicList<word>& names, DynamicList<word>& names,
DynamicList<vector>& dir, DynamicList<vector>& dir,
DynamicList<List<label>>& faceID, DynamicList<labelList>& faceID,
DynamicList<List<label>>& facePatchID, DynamicList<labelList>& facePatchID,
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const; ) const;
@ -215,8 +221,8 @@ protected:
const vector& refDir, const vector& refDir,
DynamicList<word>& names, DynamicList<word>& names,
DynamicList<vector>& dir, DynamicList<vector>& dir,
DynamicList<List<label>>& faceID, DynamicList<labelList>& faceID,
DynamicList<List<label>>& facePatchID, DynamicList<labelList>& facePatchID,
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const; ) const;
@ -227,14 +233,18 @@ protected:
const vector& refDir, const vector& refDir,
DynamicList<word>& names, DynamicList<word>& names,
DynamicList<vector>& dir, DynamicList<vector>& dir,
DynamicList<List<label>>& faceID, DynamicList<labelList>& faceID,
DynamicList<List<label>>& facePatchID, DynamicList<labelList>& facePatchID,
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const; ) const;
//- Calculate the total area for the surface or derived faceZone //- Calculate the total area for the surface or derived faceZone
scalar totalArea(const label idx) const; scalar totalArea(const label idx) const;
//- Initialise - after read(), before write()
bool update();
//- Output file header information //- Output file header information
virtual void writeFileHeader virtual void writeFileHeader
( (
@ -272,7 +282,7 @@ public:
//- Destructor //- Destructor
virtual ~fluxSummary(); virtual ~fluxSummary() = default;
// Member Functions // Member Functions