mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -645,9 +645,14 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
|
|||||||
writeHeaderValue(os, "Area", totalArea_);
|
writeHeaderValue(os, "Area", totalArea_);
|
||||||
writeHeaderValue(os, "Scale factor", scaleFactor_);
|
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");
|
writeCommented(os, "Time");
|
||||||
@ -915,7 +920,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
|||||||
needsUpdate_(true),
|
needsUpdate_(true),
|
||||||
writeArea_(false),
|
writeArea_(false),
|
||||||
selectionNames_(),
|
selectionNames_(),
|
||||||
weightFieldName_("none"),
|
weightFieldNames_(),
|
||||||
totalArea_(0),
|
totalArea_(0),
|
||||||
nFaces_(0),
|
nFaces_(0),
|
||||||
faceId_(),
|
faceId_(),
|
||||||
@ -949,7 +954,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
|||||||
needsUpdate_(true),
|
needsUpdate_(true),
|
||||||
writeArea_(false),
|
writeArea_(false),
|
||||||
selectionNames_(),
|
selectionNames_(),
|
||||||
weightFieldName_("none"),
|
weightFieldNames_(),
|
||||||
totalArea_(0),
|
totalArea_(0),
|
||||||
nFaces_(0),
|
nFaces_(0),
|
||||||
faceId_(),
|
faceId_(),
|
||||||
@ -971,7 +976,8 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
|||||||
|
|
||||||
needsUpdate_ = true;
|
needsUpdate_ = true;
|
||||||
writeArea_ = dict.getOrDefault("writeArea", false);
|
writeArea_ = dict.getOrDefault("writeArea", false);
|
||||||
weightFieldName_ = "none";
|
weightFieldNames_.clear();
|
||||||
|
|
||||||
totalArea_ = 0;
|
totalArea_ = 0;
|
||||||
nFaces_ = 0;
|
nFaces_ = 0;
|
||||||
faceId_.clear();
|
faceId_.clear();
|
||||||
@ -1054,11 +1060,29 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
|||||||
<< exit(FatalIOError);
|
<< 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
|
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?
|
// Suggest possible alternative unweighted operation?
|
||||||
FatalIOErrorInFunction(dict)
|
FatalIOErrorInFunction(dict)
|
||||||
@ -1069,6 +1093,16 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
|||||||
<< "or use a different operation."
|
<< "or use a different operation."
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< " weight field = ";
|
||||||
|
if (weightFieldNames_.empty())
|
||||||
|
{
|
||||||
|
Info<< "none" << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< flatOutput(weightFieldNames_) << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backwards compatibility for v1612 and older
|
// 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
|
tmp<scalarField> tfld = getFieldValues<scalar>(weightName, true);
|
||||||
(
|
|
||||||
getFieldValues<scalar>(weightFieldName_, true)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Process the fields
|
if (scalarWeights.empty())
|
||||||
writeAll(Sf, weightField, points, faces);
|
{
|
||||||
|
scalarWeights = tfld;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scalarWeights *= tfld;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (validField<vector>(weightFieldName_))
|
else if (validField<vector>(weightName))
|
||||||
{
|
{
|
||||||
vectorField weightField
|
tmp<vectorField> tfld = getFieldValues<vector>(weightName, true);
|
||||||
(
|
|
||||||
getFieldValues<vector>(weightFieldName_, true)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Process the fields
|
if (vectorWeights.empty())
|
||||||
writeAll(Sf, weightField, points, faces);
|
{
|
||||||
|
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
|
FatalErrorInFunction
|
||||||
<< "weightField " << weightFieldName_
|
<< "weightField " << weightName
|
||||||
<< " not found or an unsupported type"
|
<< " not found or an unsupported type" << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Process the fields
|
||||||
|
if (vectorWeights.size())
|
||||||
|
{
|
||||||
|
if (scalarWeights.size())
|
||||||
|
{
|
||||||
|
vectorWeights *= scalarWeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeAll(Sf, vectorWeights, points, faces);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Default is a zero-size scalar weight field (ie, weight = 1)
|
writeAll(Sf, scalarWeights, points, faces);
|
||||||
scalarField weightField;
|
|
||||||
|
|
||||||
// Process the fields
|
|
||||||
writeAll(Sf, weightField, points, faces);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (operation_ != opNone)
|
if (operation_ != opNone)
|
||||||
{
|
{
|
||||||
file() << endl;
|
file() << endl;
|
||||||
|
|||||||
@ -84,7 +84,7 @@ Usage
|
|||||||
names (<zone-name> <zone-regex>);
|
names (<zone-name> <zone-regex>);
|
||||||
|
|
||||||
postOperation none;
|
postOperation none;
|
||||||
weightField alpha1;
|
weightFields (rho U);
|
||||||
scaleFactor 1.0;
|
scaleFactor 1.0;
|
||||||
writeArea false;
|
writeArea false;
|
||||||
surfaceFormat none;
|
surfaceFormat none;
|
||||||
@ -105,7 +105,8 @@ Usage
|
|||||||
names | Extended selection | word/regex list | no | -
|
names | Extended selection | word/regex list | no | -
|
||||||
operation | Operation type: see below | word | yes | -
|
operation | Operation type: see below | word | yes | -
|
||||||
postOperation | Post-operation type: see below | word | no | none
|
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
|
scaleFactor | Output value scaling factor | scalar | no | 1.0
|
||||||
writeArea | Write the surface area | bool | no | false
|
writeArea | Write the surface area | bool | no | false
|
||||||
surfaceFormat | Output value format | word <!--
|
surfaceFormat | Output value format | word <!--
|
||||||
@ -403,8 +404,8 @@ protected:
|
|||||||
//- Extended selections
|
//- Extended selections
|
||||||
wordRes selectionNames_;
|
wordRes selectionNames_;
|
||||||
|
|
||||||
//- Weight field name - optional
|
//- Weight field name(s) - optional
|
||||||
word weightFieldName_;
|
wordList weightFieldNames_;
|
||||||
|
|
||||||
//- Total area of the surfaceFieldValue
|
//- Total area of the surfaceFieldValue
|
||||||
scalar totalArea_;
|
scalar totalArea_;
|
||||||
|
|||||||
@ -118,7 +118,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
|||||||
if (mandatory)
|
if (mandatory)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Field " << fieldName << " not found in database"
|
<< "Field " << fieldName << " not found in database" << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -135,9 +135,15 @@ void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
volRegion::writeFileHeader(*this, os);
|
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");
|
writeCommented(os, "Time");
|
||||||
@ -210,7 +216,7 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
|||||||
true // Failsafe behaviour
|
true // Failsafe behaviour
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
weightFieldName_("none")
|
weightFieldNames_()
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
writeFileHeader(file());
|
writeFileHeader(file());
|
||||||
@ -237,7 +243,7 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
|||||||
true // Failsafe behaviour
|
true // Failsafe behaviour
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
weightFieldName_("none")
|
weightFieldNames_()
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
}
|
}
|
||||||
@ -252,15 +258,33 @@ bool Foam::functionObjects::fieldValues::volFieldValue::read
|
|||||||
{
|
{
|
||||||
fieldValue::read(dict);
|
fieldValue::read(dict);
|
||||||
|
|
||||||
weightFieldName_ = "none";
|
weightFieldNames_.clear();
|
||||||
|
|
||||||
if (usesWeight())
|
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
|
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?
|
// Suggest possible alternative unweighted operation?
|
||||||
FatalIOErrorInFunction(dict)
|
FatalIOErrorInFunction(dict)
|
||||||
@ -271,6 +295,16 @@ bool Foam::functionObjects::fieldValues::volFieldValue::read
|
|||||||
<< "or use a different operation."
|
<< "or use a different operation."
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< " weight field = ";
|
||||||
|
if (weightFieldNames_.empty())
|
||||||
|
{
|
||||||
|
Info<< "none" << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< flatOutput(weightFieldNames_) << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl << endl;
|
Info<< nl << endl;
|
||||||
@ -297,14 +331,45 @@ bool Foam::functionObjects::fieldValues::volFieldValue::write()
|
|||||||
V = filterField(fieldValue::mesh_.V());
|
V = filterField(fieldValue::mesh_.V());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weight field - zero-size means weight = 1
|
// Check availability and type of weight field
|
||||||
scalarField weightField;
|
// Only support a few weight types:
|
||||||
if (weightFieldName_ != "none")
|
// 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())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -69,7 +69,8 @@ Usage
|
|||||||
name | Name for regionType | word | yes | -
|
name | Name for regionType | word | yes | -
|
||||||
operation | Operation type: see below | word | yes | -
|
operation | Operation type: see below | word | yes | -
|
||||||
postOperation | Post-operation type: see below | word | no | none
|
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
|
\endtable
|
||||||
|
|
||||||
The inherited entries are elaborated in:
|
The inherited entries are elaborated in:
|
||||||
@ -214,8 +215,8 @@ protected:
|
|||||||
//- Optional post-evaluation operation
|
//- Optional post-evaluation operation
|
||||||
postOperationType postOperation_;
|
postOperationType postOperation_;
|
||||||
|
|
||||||
//- Weight field name - only used for weighted modes
|
//- Weight field name(s) - optional
|
||||||
word weightFieldName_;
|
wordList weightFieldNames_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
@ -233,7 +234,7 @@ protected:
|
|||||||
// Checks for availability on any processor.
|
// Checks for availability on any processor.
|
||||||
inline bool canWeight(const scalarField& weightField) const;
|
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>
|
template<class Type>
|
||||||
bool validField(const word& fieldName) const;
|
bool validField(const word& fieldName) const;
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ Foam::functionObjects::fieldValues::volFieldValue::getFieldValues
|
|||||||
if (mandatory)
|
if (mandatory)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Field " << fieldName << " not found in database"
|
<< "Field " << fieldName << " not found in database" << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -182,6 +182,7 @@ areaAverage
|
|||||||
|
|
||||||
operation weightedAreaAverage;
|
operation weightedAreaAverage;
|
||||||
weightField rhoU;
|
weightField rhoU;
|
||||||
|
weightFields ( rho U none ); // 2012 and later
|
||||||
fields ( p pTotal );
|
fields ( p pTotal );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +195,7 @@ areaIntegrate
|
|||||||
|
|
||||||
operation weightedAreaIntegrate;
|
operation weightedAreaIntegrate;
|
||||||
weightField rhoU;
|
weightField rhoU;
|
||||||
|
weightFields ( rho U ); // 2012 and later
|
||||||
fields ( T );
|
fields ( T );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user