ENH: support multiple weights on some field function objects (#1930)
- weight fields are combined by multiplication - volFieldValue: * 0-N scalar fields - surfaceFieldValue: * 0-N scalar fields * 0-1 vector fields In some cases this can be used to avoid creating additional fields. weightFields (rho U); vs. derivedFields (rhoU); weightField rhoU;
This commit is contained in:
parent
f8d08a805b
commit
ab692caf7c
@ -645,9 +645,14 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
|
||||
writeHeaderValue(os, "Area", totalArea_);
|
||||
writeHeaderValue(os, "Scale factor", scaleFactor_);
|
||||
|
||||
if (weightFieldName_ != "none")
|
||||
if (weightFieldNames_.size())
|
||||
{
|
||||
writeHeaderValue(os, "Weight field", weightFieldName_);
|
||||
writeHeaderValue
|
||||
(
|
||||
os,
|
||||
"Weight field",
|
||||
flatOutput(weightFieldNames_, FlatOutput::BareComma{})
|
||||
);
|
||||
}
|
||||
|
||||
writeCommented(os, "Time");
|
||||
@ -915,7 +920,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
needsUpdate_(true),
|
||||
writeArea_(false),
|
||||
selectionNames_(),
|
||||
weightFieldName_("none"),
|
||||
weightFieldNames_(),
|
||||
totalArea_(0),
|
||||
nFaces_(0),
|
||||
faceId_(),
|
||||
@ -949,7 +954,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
needsUpdate_(true),
|
||||
writeArea_(false),
|
||||
selectionNames_(),
|
||||
weightFieldName_("none"),
|
||||
weightFieldNames_(),
|
||||
totalArea_(0),
|
||||
nFaces_(0),
|
||||
faceId_(),
|
||||
@ -971,7 +976,8 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
|
||||
needsUpdate_ = true;
|
||||
writeArea_ = dict.getOrDefault("writeArea", false);
|
||||
weightFieldName_ = "none";
|
||||
weightFieldNames_.clear();
|
||||
|
||||
totalArea_ = 0;
|
||||
nFaces_ = 0;
|
||||
faceId_.clear();
|
||||
@ -1054,11 +1060,29 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (dict.readIfPresent("weightField", weightFieldName_))
|
||||
// Can have "weightFields" or "weightField"
|
||||
|
||||
bool missing = true;
|
||||
if (dict.readIfPresent("weightFields", weightFieldNames_))
|
||||
{
|
||||
Info<< " weight field = " << weightFieldName_ << nl;
|
||||
missing = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
weightFieldNames_.resize(1);
|
||||
|
||||
if (dict.readIfPresent("weightField", weightFieldNames_.first()))
|
||||
{
|
||||
missing = false;
|
||||
if ("none" == weightFieldNames_.first())
|
||||
{
|
||||
// "none" == no weighting
|
||||
weightFieldNames_.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing)
|
||||
{
|
||||
// Suggest possible alternative unweighted operation?
|
||||
FatalIOErrorInFunction(dict)
|
||||
@ -1069,6 +1093,16 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
<< "or use a different operation."
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
Info<< " weight field = ";
|
||||
if (weightFieldNames_.empty())
|
||||
{
|
||||
Info<< "none" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< flatOutput(weightFieldNames_) << nl;
|
||||
}
|
||||
}
|
||||
|
||||
// Backwards compatibility for v1612 and older
|
||||
@ -1177,46 +1211,79 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
|
||||
}
|
||||
}
|
||||
|
||||
// Only a few weight types (scalar, vector)
|
||||
if (weightFieldName_ != "none")
|
||||
|
||||
// Check availability and type of weight field
|
||||
// Only support a few weight types:
|
||||
// scalar: 0-N fields
|
||||
// vector: 0-1 fields
|
||||
|
||||
// Default is a zero-size scalar weight field (ie, weight = 1)
|
||||
scalarField scalarWeights;
|
||||
vectorField vectorWeights;
|
||||
|
||||
for (const word& weightName : weightFieldNames_)
|
||||
{
|
||||
if (validField<scalar>(weightFieldName_))
|
||||
if (validField<scalar>(weightName))
|
||||
{
|
||||
scalarField weightField
|
||||
(
|
||||
getFieldValues<scalar>(weightFieldName_, true)
|
||||
);
|
||||
tmp<scalarField> tfld = getFieldValues<scalar>(weightName, true);
|
||||
|
||||
// Process the fields
|
||||
writeAll(Sf, weightField, points, faces);
|
||||
if (scalarWeights.empty())
|
||||
{
|
||||
scalarWeights = tfld;
|
||||
}
|
||||
else
|
||||
{
|
||||
scalarWeights *= tfld;
|
||||
}
|
||||
}
|
||||
else if (validField<vector>(weightFieldName_))
|
||||
else if (validField<vector>(weightName))
|
||||
{
|
||||
vectorField weightField
|
||||
(
|
||||
getFieldValues<vector>(weightFieldName_, true)
|
||||
);
|
||||
tmp<vectorField> tfld = getFieldValues<vector>(weightName, true);
|
||||
|
||||
// Process the fields
|
||||
writeAll(Sf, weightField, points, faces);
|
||||
if (vectorWeights.empty())
|
||||
{
|
||||
vectorWeights = tfld;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "weightField " << weightName
|
||||
<< " - only one vector weight field allowed. " << nl
|
||||
<< "weights: " << flatOutput(weightFieldNames_) << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (weightName != "none")
|
||||
{
|
||||
// Silently ignore "none", flag everything else as an error
|
||||
|
||||
// TBD: treat missing "rho" like incompressible with rho = 1
|
||||
// and/or provided rhoRef value
|
||||
|
||||
FatalErrorInFunction
|
||||
<< "weightField " << weightFieldName_
|
||||
<< " not found or an unsupported type"
|
||||
<< "weightField " << weightName
|
||||
<< " not found or an unsupported type" << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Process the fields
|
||||
if (vectorWeights.size())
|
||||
{
|
||||
if (scalarWeights.size())
|
||||
{
|
||||
vectorWeights *= scalarWeights;
|
||||
}
|
||||
|
||||
writeAll(Sf, vectorWeights, points, faces);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default is a zero-size scalar weight field (ie, weight = 1)
|
||||
scalarField weightField;
|
||||
|
||||
// Process the fields
|
||||
writeAll(Sf, weightField, points, faces);
|
||||
writeAll(Sf, scalarWeights, points, faces);
|
||||
}
|
||||
|
||||
|
||||
if (operation_ != opNone)
|
||||
{
|
||||
file() << endl;
|
||||
|
@ -84,7 +84,7 @@ Usage
|
||||
names (<zone-name> <zone-regex>);
|
||||
|
||||
postOperation none;
|
||||
weightField alpha1;
|
||||
weightFields (rho U);
|
||||
scaleFactor 1.0;
|
||||
writeArea false;
|
||||
surfaceFormat none;
|
||||
@ -105,7 +105,8 @@ Usage
|
||||
names | Extended selection | word/regex list | no | -
|
||||
operation | Operation type: see below | word | yes | -
|
||||
postOperation | Post-operation type: see below | word | no | none
|
||||
weightField | Name of field to apply weighting | word | no | none
|
||||
weightField | Name of field to apply weighting | word | maybe |
|
||||
weightFields | Names of fields to apply weighting | wordList | maybe |
|
||||
scaleFactor | Output value scaling factor | scalar | no | 1.0
|
||||
writeArea | Write the surface area | bool | no | false
|
||||
surfaceFormat | Output value format | word <!--
|
||||
@ -403,8 +404,8 @@ protected:
|
||||
//- Extended selections
|
||||
wordRes selectionNames_;
|
||||
|
||||
//- Weight field name - optional
|
||||
word weightFieldName_;
|
||||
//- Weight field name(s) - optional
|
||||
wordList weightFieldNames_;
|
||||
|
||||
//- Total area of the surfaceFieldValue
|
||||
scalar totalArea_;
|
||||
|
@ -118,7 +118,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
||||
if (mandatory)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Field " << fieldName << " not found in database"
|
||||
<< "Field " << fieldName << " not found in database" << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
@ -135,9 +135,15 @@ void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
|
||||
) const
|
||||
{
|
||||
volRegion::writeFileHeader(*this, os);
|
||||
if (weightFieldName_ != "none")
|
||||
|
||||
if (weightFieldNames_.size())
|
||||
{
|
||||
writeHeaderValue(os, "Weight field", weightFieldName_);
|
||||
writeHeaderValue
|
||||
(
|
||||
os,
|
||||
"Weight field",
|
||||
flatOutput(weightFieldNames_, FlatOutput::BareComma{})
|
||||
);
|
||||
}
|
||||
|
||||
writeCommented(os, "Time");
|
||||
@ -210,7 +216,7 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
||||
true // Failsafe behaviour
|
||||
)
|
||||
),
|
||||
weightFieldName_("none")
|
||||
weightFieldNames_()
|
||||
{
|
||||
read(dict);
|
||||
writeFileHeader(file());
|
||||
@ -237,7 +243,7 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
||||
true // Failsafe behaviour
|
||||
)
|
||||
),
|
||||
weightFieldName_("none")
|
||||
weightFieldNames_()
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
@ -252,15 +258,33 @@ bool Foam::functionObjects::fieldValues::volFieldValue::read
|
||||
{
|
||||
fieldValue::read(dict);
|
||||
|
||||
weightFieldName_ = "none";
|
||||
weightFieldNames_.clear();
|
||||
|
||||
if (usesWeight())
|
||||
{
|
||||
if (dict.readIfPresent("weightField", weightFieldName_))
|
||||
// Can have "weightFields" or "weightField"
|
||||
|
||||
bool missing = true;
|
||||
if (dict.readIfPresent("weightFields", weightFieldNames_))
|
||||
{
|
||||
Info<< " weight field = " << weightFieldName_;
|
||||
missing = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
weightFieldNames_.resize(1);
|
||||
|
||||
if (dict.readIfPresent("weightField", weightFieldNames_.first()))
|
||||
{
|
||||
missing = false;
|
||||
if ("none" == weightFieldNames_.first())
|
||||
{
|
||||
// "none" == no weighting
|
||||
weightFieldNames_.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing)
|
||||
{
|
||||
// Suggest possible alternative unweighted operation?
|
||||
FatalIOErrorInFunction(dict)
|
||||
@ -271,6 +295,16 @@ bool Foam::functionObjects::fieldValues::volFieldValue::read
|
||||
<< "or use a different operation."
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
Info<< " weight field = ";
|
||||
if (weightFieldNames_.empty())
|
||||
{
|
||||
Info<< "none" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< flatOutput(weightFieldNames_) << nl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< nl << endl;
|
||||
@ -297,14 +331,45 @@ bool Foam::functionObjects::fieldValues::volFieldValue::write()
|
||||
V = filterField(fieldValue::mesh_.V());
|
||||
}
|
||||
|
||||
// Weight field - zero-size means weight = 1
|
||||
scalarField weightField;
|
||||
if (weightFieldName_ != "none")
|
||||
// Check availability and type of weight field
|
||||
// Only support a few weight types:
|
||||
// scalar: 0-N fields
|
||||
|
||||
// Default is a zero-size scalar weight field (ie, weight = 1)
|
||||
scalarField scalarWeights;
|
||||
|
||||
for (const word& weightName : weightFieldNames_)
|
||||
{
|
||||
weightField = getFieldValues<scalar>(weightFieldName_, true);
|
||||
if (validField<scalar>(weightName))
|
||||
{
|
||||
tmp<scalarField> tfld = getFieldValues<scalar>(weightName, true);
|
||||
|
||||
if (scalarWeights.empty())
|
||||
{
|
||||
scalarWeights = tfld;
|
||||
}
|
||||
else
|
||||
{
|
||||
scalarWeights *= tfld;
|
||||
}
|
||||
}
|
||||
else if (weightName != "none")
|
||||
{
|
||||
// Silently ignore "none", flag everything else as an error
|
||||
|
||||
// TBD: treat missing "rho" like incompressible with rho = 1
|
||||
// and/or provided rhoRef value
|
||||
|
||||
FatalErrorInFunction
|
||||
<< "weightField " << weightName
|
||||
<< " not found or an unsupported type" << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
writeAll(V, weightField);
|
||||
|
||||
// Process the fields
|
||||
writeAll(V, scalarWeights);
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
|
@ -69,7 +69,8 @@ Usage
|
||||
name | Name for regionType | word | yes | -
|
||||
operation | Operation type: see below | word | yes | -
|
||||
postOperation | Post-operation type: see below | word | no | none
|
||||
weightField | Name of field to apply weighting | word | no | none
|
||||
weightField | Name of field to apply weighting | word | maybe |
|
||||
weightFields | Names of fields to apply weighting | wordList | maybe |
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
@ -214,8 +215,8 @@ protected:
|
||||
//- Optional post-evaluation operation
|
||||
postOperationType postOperation_;
|
||||
|
||||
//- Weight field name - only used for weighted modes
|
||||
word weightFieldName_;
|
||||
//- Weight field name(s) - optional
|
||||
wordList weightFieldNames_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
@ -233,7 +234,7 @@ protected:
|
||||
// Checks for availability on any processor.
|
||||
inline bool canWeight(const scalarField& weightField) const;
|
||||
|
||||
//- True if the field name is valid (exists, and a supported type)
|
||||
//- Return true if the field name is valid
|
||||
template<class Type>
|
||||
bool validField(const word& fieldName) const;
|
||||
|
||||
|
@ -71,7 +71,7 @@ Foam::functionObjects::fieldValues::volFieldValue::getFieldValues
|
||||
if (mandatory)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Field " << fieldName << " not found in database"
|
||||
<< "Field " << fieldName << " not found in database" << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
@ -182,6 +182,7 @@ areaAverage
|
||||
|
||||
operation weightedAreaAverage;
|
||||
weightField rhoU;
|
||||
weightFields ( rho U none ); // 2012 and later
|
||||
fields ( p pTotal );
|
||||
}
|
||||
|
||||
@ -194,6 +195,7 @@ areaIntegrate
|
||||
|
||||
operation weightedAreaIntegrate;
|
||||
weightField rhoU;
|
||||
weightFields ( rho U ); // 2012 and later
|
||||
fields ( T );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user