From ab692caf7cb8afe46708c93ac2144574503a519f Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 24 Nov 2020 17:03:00 +0100 Subject: [PATCH] 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; --- .../surfaceFieldValue/surfaceFieldValue.C | 129 +++++++++++++----- .../surfaceFieldValue/surfaceFieldValue.H | 9 +- .../surfaceFieldValueTemplates.C | 2 +- .../fieldValues/volFieldValue/volFieldValue.C | 89 ++++++++++-- .../fieldValues/volFieldValue/volFieldValue.H | 9 +- .../volFieldValue/volFieldValueTemplates.C | 2 +- .../rhoSimpleFoam/squareBend/system/sampling | 2 + 7 files changed, 189 insertions(+), 53 deletions(-) diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C index 5f429e1214..bc55e59523 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C @@ -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(weightFieldName_)) + if (validField(weightName)) { - scalarField weightField - ( - getFieldValues(weightFieldName_, true) - ); + tmp tfld = getFieldValues(weightName, true); - // Process the fields - writeAll(Sf, weightField, points, faces); + if (scalarWeights.empty()) + { + scalarWeights = tfld; + } + else + { + scalarWeights *= tfld; + } } - else if (validField(weightFieldName_)) + else if (validField(weightName)) { - vectorField weightField - ( - getFieldValues(weightFieldName_, true) - ); + tmp tfld = getFieldValues(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; diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H index 5687e9f4a4..1933802913 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.H @@ -84,7 +84,7 @@ Usage names ( ); 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