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

- complete any pending initialisation on write().
  Allows lazier evaluation until when the surfaces are actually needed.
This commit is contained in:
Mark Olesen
2019-02-12 12:39:49 +01:00
committed by Andrew Heather
parent 52101db781
commit bfb0693bbe
4 changed files with 207 additions and 181 deletions

View File

@ -61,7 +61,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypeNames_
{ regionTypes::stFaceZone, "faceZone" },
{ regionTypes::stPatch, "patch" },
{ regionTypes::stSurface, "surface" },
{ regionTypes::stSampledSurface, "sampledSurface" },
{ regionTypes::stSampled, "sampledSurface" },
});
@ -118,7 +118,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_
const Foam::objectRegistry&
Foam::functionObjects::fieldValues::surfaceFieldValue::obr() const
{
if (regionType_ == stSurface)
if (stSurface == regionType_)
{
return mesh_.lookupObject<objectRegistry>(regionName_);
}
@ -135,7 +135,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
{
FatalErrorInFunction
<< type() << " " << name() << ": "
<< regionTypeNames_[regionType_] << "(" << regionName_ << "):" << nl
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " Unknown face zone name: " << regionName_
<< ". Valid face zones are: " << mesh_.faceZones().names()
<< nl << exit(FatalError);
@ -213,7 +213,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
{
FatalErrorInFunction
<< type() << " " << name() << ": "
<< regionTypeNames_[regionType_] << "(" << regionName_ << "):" << nl
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " Unknown patch name: " << regionName_
<< ". Valid patch names are: "
<< mesh_.boundaryMesh().names() << nl
@ -368,7 +368,7 @@ combineSurfaceGeometry
pointField& points
) const
{
if (regionType_ == stSurface)
if (stSurface == regionType_)
{
const surfMesh& s = dynamicCast<const surfMesh>(obr());
@ -398,9 +398,9 @@ combineSurfaceGeometry
points = s.points();
}
}
else if (surfacePtr_.valid())
else if (sampledPtr_.valid())
{
const sampledSurface& s = surfacePtr_();
const sampledSurface& s = sampledPtr_();
if (Pstream::parRun())
{
@ -436,15 +436,15 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const
{
scalar totalArea = 0;
if (regionType_ == stSurface)
if (stSurface == regionType_)
{
const surfMesh& s = dynamicCast<const surfMesh>(obr());
totalArea = gSum(s.magSf());
}
else if (surfacePtr_.valid())
else if (sampledPtr_.valid())
{
totalArea = gSum(surfacePtr_().magSf());
totalArea = gSum(sampledPtr_().magSf());
}
else
{
@ -481,20 +481,17 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::usesSf() const
}
void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
(
const dictionary& dict
)
bool Foam::functionObjects::fieldValues::surfaceFieldValue::update()
{
dict.readEntry("name", regionName_);
if (sampledPtr_.valid())
{
sampledPtr_->update();
}
totalArea_ = 0;
nFaces_ = 0;
faceId_.clear();
facePatchId_.clear();
faceFlip_.clear();
surfacePtr_.clear();
surfaceWriterPtr_.clear();
if (!needsUpdate_)
{
return false;
}
switch (regionType_)
{
@ -514,124 +511,33 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
nFaces_ = returnReduce(s.size(), sumOp<label>());
break;
}
case stSampledSurface:
case stSampled:
{
surfacePtr_ = sampledSurface::New
(
name(),
mesh_,
dict.subDict("sampledSurfaceDict")
);
surfacePtr_().update();
nFaces_ =
returnReduce(surfacePtr_().faces().size(), sumOp<label>());
nFaces_ = returnReduce(sampledPtr_->faces().size(), sumOp<label>());
break;
}
default:
{
FatalErrorInFunction
<< type() << " " << name() << ": "
<< int(regionType_) << "(" << regionName_ << "):"
<< nl << " Unknown region type. Valid region types are:"
<< regionTypeNames_ << nl
<< exit(FatalError);
}
// Compiler warning if we forgot an enumeration
}
if (nFaces_ == 0)
{
FatalErrorInFunction
<< type() << " " << name() << ": "
<< regionTypeNames_[regionType_] << "(" << regionName_ << "):" << nl
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " Region has no faces" << exit(FatalError);
}
if (surfacePtr_.valid())
{
surfacePtr_().update();
}
totalArea_ = totalArea();
Info<< type() << " " << name() << ":" << nl
<< " operation = ";
if (postOperation_ != postOpNone)
{
Info<< postOperationTypeNames_[postOperation_] << '('
<< operationTypeNames_[operation_] << ')' << nl;
}
else
{
Info<< operationTypeNames_[operation_] << nl;
}
Info<< " total faces = " << nFaces_ << nl
Log
<< " total faces = " << nFaces_ << nl
<< " total area = " << totalArea_ << nl;
writeFileHeader(file());
weightFieldName_ = "none";
if (usesWeight())
{
if (regionType_ == stSampledSurface)
{
FatalIOErrorInFunction(dict)
<< "Cannot use weighted operation '"
<< operationTypeNames_[operation_]
<< "' for sampledSurface"
<< exit(FatalIOError);
}
if (dict.readIfPresent("weightField", weightFieldName_))
{
Info<< " weight field = " << weightFieldName_ << nl;
}
else
{
// Suggest possible alternative unweighted operation?
FatalIOErrorInFunction(dict)
<< "The '" << operationTypeNames_[operation_]
<< "' operation is missing a weightField." << nl
<< "Either provide the weightField, "
<< "use weightField 'none' to suppress weighting," << nl
<< "or use a different operation."
<< exit(FatalIOError);
}
}
// Backwards compatibility for v1612 and older
List<word> orientedFields;
if (dict.readIfPresent("orientedFields", orientedFields))
{
WarningInFunction
<< "The 'orientedFields' option is deprecated. These fields can "
<< "and have been added to the standard 'fields' list."
<< endl;
fields_.append(orientedFields);
}
if (writeFields_)
{
const word surfaceFormat(dict.get<word>("surfaceFormat"));
if (surfaceFormat != "none")
{
surfaceWriterPtr_.reset
(
surfaceWriter::New
(
surfaceFormat,
dict.subOrEmptyDict("formatOptions").
subOrEmptyDict(surfaceFormat)
).ptr()
);
Info<< " surfaceFormat = " << surfaceFormat << nl;
}
}
Info<< nl << endl;
needsUpdate_ = false;
return true;
}
@ -911,15 +817,15 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
)
),
weightFieldName_("none"),
needsUpdate_(true),
writeArea_(false),
totalArea_(0),
writeArea_(dict.lookupOrDefault("writeArea", false)),
nFaces_(0),
faceId_(),
facePatchId_(),
faceFlip_()
{
read(dict);
writeFileHeader(file());
}
@ -944,15 +850,15 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
)
),
weightFieldName_("none"),
needsUpdate_(true),
writeArea_(false),
totalArea_(0),
writeArea_(dict.lookupOrDefault("writeArea", false)),
nFaces_(0),
faceId_(),
facePatchId_(),
faceFlip_()
{
read(dict);
writeFileHeader(file());
}
@ -964,7 +870,106 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
)
{
fieldValue::read(dict);
initialise(dict);
weightFieldName_ = "none";
needsUpdate_ = true;
writeArea_ = dict.lookupOrDefault("writeArea", false);
totalArea_ = 0;
nFaces_ = 0;
faceId_.clear();
facePatchId_.clear();
faceFlip_.clear();
sampledPtr_.clear();
surfaceWriterPtr_.clear();
dict.readEntry("name", regionName_);
// Create sampled surface, but leave 'expired' (ie, no update) since it
// may depend on fields or data that do not yet exist
if (stSampled == regionType_)
{
sampledPtr_ = sampledSurface::New
(
name(),
mesh_,
dict.subDict("sampledSurfaceDict")
);
}
Info<< type() << " " << name() << ":" << nl
<< " operation = ";
if (postOperation_ != postOpNone)
{
Info<< postOperationTypeNames_[postOperation_] << '('
<< operationTypeNames_[operation_] << ')' << nl;
}
else
{
Info<< operationTypeNames_[operation_] << nl;
}
if (usesWeight())
{
if (stSampled == regionType_)
{
FatalIOErrorInFunction(dict)
<< "Cannot use weighted operation '"
<< operationTypeNames_[operation_]
<< "' for sampledSurface"
<< exit(FatalIOError);
}
if (dict.readIfPresent("weightField", weightFieldName_))
{
Info<< " weight field = " << weightFieldName_ << nl;
}
else
{
// Suggest possible alternative unweighted operation?
FatalIOErrorInFunction(dict)
<< "The '" << operationTypeNames_[operation_]
<< "' operation is missing a weightField." << nl
<< "Either provide the weightField, "
<< "use weightField 'none' to suppress weighting," << nl
<< "or use a different operation."
<< exit(FatalIOError);
}
}
// Backwards compatibility for v1612 and older
List<word> orientedFields;
if (dict.readIfPresent("orientedFields", orientedFields))
{
fields_.append(orientedFields);
WarningInFunction
<< "The 'orientedFields' option is deprecated. These fields can "
<< "and have been added to the standard 'fields' list."
<< endl;
}
if (writeFields_)
{
const word formatName(dict.get<word>("surfaceFormat"));
if (formatName != "none")
{
surfaceWriterPtr_.reset
(
surfaceWriter::New
(
formatName,
dict.subOrEmptyDict("formatOptions")
.subOrEmptyDict(formatName)
)
);
Info<< " surfaceFormat = " << formatName << nl;
}
}
Info<< nl << endl;
return true;
}
@ -972,10 +977,7 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
{
if (surfacePtr_.valid())
{
surfacePtr_().update();
}
update();
if (operation_ != opNone)
{
@ -1002,14 +1004,14 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
vectorField Sf;
if (usesSf())
{
if (regionType_ == stSurface)
if (stSurface == regionType_)
{
const surfMesh& s = dynamicCast<const surfMesh>(obr());
Sf = s.Sf();
}
else if (surfacePtr_.valid())
else if (sampledPtr_.valid())
{
Sf = surfacePtr_().Sf();
Sf = sampledPtr_().Sf();
}
else
{
@ -1023,13 +1025,13 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
if (surfaceWriterPtr_.valid())
{
if (regionType_ == stSurface || surfacePtr_.valid())
if (withTopologicalMerge())
{
combineSurfaceGeometry(faces, points);
combineMeshGeometry(faces, points);
}
else
{
combineMeshGeometry(faces, points);
combineSurfaceGeometry(faces, points);
}
}