mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve surfaceFieldValue sampling and writing (#1999)
- ensure surface writing is time-step and nFields aware.
This avoids overwriting (ignoring) previous output fields.
- allow sampled surfaces to be used for weight fields as well.
Not sure why this restriction was still there.
- remove old compatibility reading of orientedFields.
Last used in v1612, now removed.
- only use face sampling. For surfaceFieldValue we can only do
something meaningful with face values.
ENH: modify interface methods for surfaceWriter
- replace direct modification of values with setter methods.
Eg,
old: writer.isPointData() = true;
new: writer.isPointData(true);
This makes it possible to add internal hooks to catch state changes.
ENH: allow post-construction change to sampledSurface interpolation
- rename interpolate() method to isPointData() for consistency with
other classes and to indicate that it is a query.
- additional isPointData(bool) setter method to change the expected
representation type after construction
- remove 'interpolate' restriction on isoSurfacePoint which was
previously flagged as an error but within sampledSurfaces can use
sampleScheme cellPoint and obtain representative samples.
Relax this restriction since this particular iso-surface algorithm
is slated for removal in the foreseeable future.
This commit is contained in:
@ -971,6 +971,8 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
needsUpdate_ = true;
|
||||
writeArea_ = dict.getOrDefault("writeArea", false);
|
||||
weightFieldNames_.clear();
|
||||
// future?
|
||||
// sampleFaceScheme_ = dict.getOrDefault<word>("sampleScheme", "cell");
|
||||
|
||||
totalArea_ = 0;
|
||||
nFaces_ = 0;
|
||||
@ -1029,15 +1031,8 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
dict.subDict("sampledSurfaceDict")
|
||||
);
|
||||
|
||||
if (sampledPtr_->interpolate())
|
||||
{
|
||||
// Should probably ignore interpolate entirely,
|
||||
// but the oldest isoSurface algorithm requires it!
|
||||
WarningInFunction
|
||||
<< type() << ' ' << name() << ": "
|
||||
<< "sampledSurface with interpolate = true "
|
||||
<< "is likely incorrect" << nl << nl;
|
||||
}
|
||||
// Internal consistency. Want face values, never point values!
|
||||
sampledPtr_->isPointData(false);
|
||||
}
|
||||
|
||||
Info<< type() << ' ' << name() << ':' << nl
|
||||
@ -1055,15 +1050,6 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
|
||||
if (usesWeight())
|
||||
{
|
||||
if (stSampled == regionType_)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot use weighted operation '"
|
||||
<< operationTypeNames_[operation_]
|
||||
<< "' for sampledSurface"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Can have "weightFields" or "weightField"
|
||||
|
||||
bool missing = true;
|
||||
@ -1109,18 +1095,6 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
}
|
||||
}
|
||||
|
||||
// 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"));
|
||||
@ -1134,6 +1108,9 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
)
|
||||
);
|
||||
|
||||
// Propagate field counts (per surface)
|
||||
surfaceWriterPtr_->nFields(fields_.size());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
surfaceWriterPtr_->verbose(true);
|
||||
|
||||
@ -177,12 +177,11 @@ Note
|
||||
Instead specify the regionType 'functionObjectSurface' and provide
|
||||
the name.
|
||||
- Using \c sampledSurface:
|
||||
- not available for surface fields
|
||||
- if interpolate=true they use \c interpolationCellPoint
|
||||
otherwise they use cell values
|
||||
- each triangle in \c sampledSurface is logically only in one cell
|
||||
so interpolation will be wrong when triangles are larger than
|
||||
cells. This can only happen for sampling on a \c triSurfaceMesh
|
||||
- surface fields only supported by some surfaces
|
||||
- default uses sampleScheme \c cell
|
||||
- each face in \c sampledSurface is logically only in one cell
|
||||
so sampling will be wrong when they are larger than cells.
|
||||
This can only happen for sampling on a \c triSurfaceMesh
|
||||
- take care when using isoSurfaces - these might have duplicate
|
||||
triangles and so integration might be wrong
|
||||
|
||||
|
||||
@ -96,18 +96,13 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
||||
|
||||
if (sampledPtr_)
|
||||
{
|
||||
if (sampledPtr_->interpolate())
|
||||
{
|
||||
const interpolationCellPoint<Type> interp(fld);
|
||||
// Could be runtime selectable
|
||||
// auto sampler = interpolation<Type>::New(sampleFaceScheme_, fld);
|
||||
|
||||
return sampledPtr_->interpolate(interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
const interpolationCell<Type> interp(fld);
|
||||
// const interpolationCellPoint<Type> interp(fld);
|
||||
const interpolationCell<Type> interp(fld);
|
||||
|
||||
return sampledPtr_->sample(interp);
|
||||
}
|
||||
return sampledPtr_->sample(interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -324,6 +319,30 @@ Foam::label Foam::functionObjects::fieldValues::surfaceFieldValue::writeAll
|
||||
{
|
||||
label nProcessed = 0;
|
||||
|
||||
// If using the surface writer, the points/faces parameters have already
|
||||
// been merged on the master and the writeValues routine will also gather
|
||||
// all data onto the master before calling the writer.
|
||||
// Thus only call the writer on master!
|
||||
|
||||
// Begin writer time step
|
||||
if (Pstream::master() && surfaceWriterPtr_ && surfaceWriterPtr_->enabled())
|
||||
{
|
||||
auto& writer = *surfaceWriterPtr_;
|
||||
|
||||
writer.open
|
||||
(
|
||||
points,
|
||||
faces,
|
||||
(
|
||||
outputDir()
|
||||
/ regionTypeNames_[regionType_] + ("_" + regionName_)
|
||||
),
|
||||
false // serial - already merged
|
||||
);
|
||||
|
||||
writer.beginTime(time_);
|
||||
}
|
||||
|
||||
for (const word& fieldName : fields_)
|
||||
{
|
||||
if
|
||||
@ -349,6 +368,23 @@ Foam::label Foam::functionObjects::fieldValues::surfaceFieldValue::writeAll
|
||||
}
|
||||
}
|
||||
|
||||
// Finish writer time step
|
||||
if (Pstream::master() && surfaceWriterPtr_ && surfaceWriterPtr_->enabled())
|
||||
{
|
||||
auto& writer = *surfaceWriterPtr_;
|
||||
|
||||
// Write geometry if no fields were written so that we still
|
||||
// can have something to look at.
|
||||
|
||||
if (!writer.wroteData())
|
||||
{
|
||||
writer.write();
|
||||
}
|
||||
|
||||
writer.endTime();
|
||||
writer.clear();
|
||||
}
|
||||
|
||||
return nProcessed;
|
||||
}
|
||||
|
||||
@ -377,26 +413,6 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
surfaceWriterPtr_->open
|
||||
(
|
||||
points,
|
||||
faces,
|
||||
(
|
||||
outputDir()
|
||||
/ regionTypeNames_[regionType_] + ("_" + regionName_)
|
||||
),
|
||||
false // serial - already merged
|
||||
);
|
||||
|
||||
// Point data? Should probably disallow
|
||||
if (sampledPtr_)
|
||||
{
|
||||
surfaceWriterPtr_->isPointData() =
|
||||
sampledPtr_->interpolate();
|
||||
}
|
||||
|
||||
surfaceWriterPtr_->nFields() = 1; // Needed for VTK legacy
|
||||
|
||||
fileName outputName =
|
||||
surfaceWriterPtr_->write(fieldName, allValues);
|
||||
|
||||
@ -404,8 +420,6 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||
dictionary propsDict;
|
||||
propsDict.add("file", time_.relativePath(outputName, true));
|
||||
this->setProperty(fieldName, propsDict);
|
||||
|
||||
surfaceWriterPtr_->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -306,7 +306,7 @@ bool Foam::areaWrite::write()
|
||||
|
||||
|
||||
// Propagate field counts (per surface)
|
||||
outWriter.nFields() = nAreaFields;
|
||||
outWriter.nFields(nAreaFields);
|
||||
|
||||
|
||||
// Begin writing
|
||||
@ -351,7 +351,7 @@ void Foam::areaWrite::expire()
|
||||
{
|
||||
surfaceWriter& writer = *(iter.val());
|
||||
writer.expire();
|
||||
writer.mergeDim() = mergeDim;
|
||||
writer.mergeDim(mergeDim);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user