ENH: fieldValues FOs updated following update to use functionObjectState

This commit is contained in:
Andrew Heather
2015-11-11 16:10:01 +00:00
parent 40680a43b1
commit d26b4ee490
14 changed files with 351 additions and 360 deletions

View File

@ -79,8 +79,6 @@ void Foam::fieldValues::cellSource::setCellZoneCells()
{ {
case stCellZone: case stCellZone:
{ {
dict().lookup("sourceName") >> sourceName_;
label zoneId = mesh().cellZones().findZoneID(sourceName_); label zoneId = mesh().cellZones().findZoneID(sourceName_);
if (zoneId < 0) if (zoneId < 0)
@ -135,7 +133,8 @@ void Foam::fieldValues::cellSource::initialise(const dictionary& dict)
WarningIn WarningIn
( (
"Foam::fieldValues::cellSource::initialise(const dictionary&)" "Foam::fieldValues::cellSource::initialise(const dictionary&)"
) << type() << " " << name_ << ": " )
<< type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
<< " Source has no cells - deactivating" << endl; << " Source has no cells - deactivating" << endl;
@ -145,44 +144,46 @@ void Foam::fieldValues::cellSource::initialise(const dictionary& dict)
volume_ = volume(); volume_ = volume();
Info<< type() << " " << name_ << ":" if (log_)
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl {
<< " total cells = " << nCells_ << nl Info<< type() << " " << name_ << ":"
<< " total volume = " << volume_ << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
<< nl << endl; << " total cells = " << nCells_ << nl
<< " total volume = " << volume_
<< nl << endl;
}
if (dict.readIfPresent("weightField", weightFieldName_)) if (dict.readIfPresent("weightField", weightFieldName_))
{ {
Info<< " weight field = " << weightFieldName_; if (log_) Info << " weight field = " << weightFieldName_;
} }
Info<< nl << endl; if (log_) Info << nl << endl;
} }
void Foam::fieldValues::cellSource::writeFileHeader(const label i) void Foam::fieldValues::cellSource::writeFileHeader(Ostream& os) const
{ {
writeCommented(file(), "Source : "); writeHeaderValue(os, "Source", sourceTypeNames_[source_]);
file() << sourceTypeNames_[source_] << " " << sourceName_ << endl; writeHeaderValue(os, "Name", sourceName_);
writeCommented(file(), "Cells : "); writeHeaderValue(os, "Cells", nCells_);
file() << nCells_ << endl; writeHeaderValue(os, "Volume", volume_);
writeCommented(file(), "Volume : "); writeHeaderValue(os, "Scale factor", scaleFactor_);
file() << volume_ << endl;
writeCommented(file(), "Time");
writeCommented(os, "Time");
if (writeVolume_) if (writeVolume_)
{ {
file() << tab << "Volume"; os << tab << "Volume";
} }
forAll(fields_, i) forAll(fields_, i)
{ {
file() os << tab << operationTypeNames_[operation_]
<< tab << operationTypeNames_[operation_]
<< "(" << fields_[i] << ")"; << "(" << fields_[i] << ")";
} }
file() << endl; os << endl;
} }
@ -204,7 +205,11 @@ Foam::fieldValues::cellSource::cellSource
weightFieldName_("none"), weightFieldName_("none"),
writeVolume_(dict.lookupOrDefault("writeVolume", false)) writeVolume_(dict.lookupOrDefault("writeVolume", false))
{ {
read(dict); if (active_)
{
read(dict);
writeFileHeader(file());
}
} }
@ -218,11 +223,11 @@ Foam::fieldValues::cellSource::~cellSource()
void Foam::fieldValues::cellSource::read(const dictionary& dict) void Foam::fieldValues::cellSource::read(const dictionary& dict)
{ {
fieldValue::read(dict);
if (active_) if (active_)
{ {
// no additional info to read fieldValue::read(dict);
// No additional info to read
initialise(dict); initialise(dict);
} }
} }
@ -234,33 +239,34 @@ void Foam::fieldValues::cellSource::write()
if (active_) if (active_)
{ {
if (Pstream::master()) file() << obr_.time().value();
{
file() << obr_.time().value();
}
// Construct weight field. Note: zero size indicates unweighted
scalarField weightField;
if (weightFieldName_ != "none")
{
weightField = setFieldValues<scalar>(weightFieldName_, true);
}
if (writeVolume_) if (writeVolume_)
{ {
volume_ = volume(); volume_ = volume();
if (Pstream::master()) file() << tab << volume_;
{
file() << tab << volume_;
}
if (log_) Info<< " total volume = " << volume_ << endl; if (log_) Info<< " total volume = " << volume_ << endl;
} }
forAll(fields_, i) forAll(fields_, i)
{ {
const word& fieldName = fields_[i]; const word& fieldName = fields_[i];
bool processed = false; bool ok = false;
processed = processed || writeValues<scalar>(fieldName); ok = ok || writeValues<scalar>(fieldName, weightField);
processed = processed || writeValues<vector>(fieldName); ok = ok || writeValues<vector>(fieldName, weightField);
processed = processed || writeValues<sphericalTensor>(fieldName); ok = ok || writeValues<sphericalTensor>(fieldName, weightField);
processed = processed || writeValues<symmTensor>(fieldName); ok = ok || writeValues<symmTensor>(fieldName, weightField);
processed = processed || writeValues<tensor>(fieldName); ok = ok || writeValues<tensor>(fieldName, weightField);
if (!processed) if (!ok)
{ {
WarningIn("void Foam::fieldValues::cellSource::write()") WarningIn("void Foam::fieldValues::cellSource::write()")
<< "Requested field " << fieldName << "Requested field " << fieldName
@ -269,10 +275,7 @@ void Foam::fieldValues::cellSource::write()
} }
} }
if (Pstream::master()) file()<< endl;
{
file()<< endl;
}
if (log_) Info<< endl; if (log_) Info<< endl;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -62,11 +62,11 @@ Description
log | Write data to standard output | no | no log | Write data to standard output | no | no
valueOutput | Write the raw output values | yes | valueOutput | Write the raw output values | yes |
writeVolume | Write the volume of the cellSource | no | writeVolume | Write the volume of the cellSource | no |
source | cell source: see below | yes | source | Cell source: see below | yes |
sourceName | name of cell source if required | no | sourceName | Name of cell source if required | no |
operation | operation to perform | yes | operation | Operation to perform | yes |
weightField | name of field to apply weighting | no | weightField | Name of field to apply weighting | no |
fields | list of fields to operate on | yes | fields | List of fields to operate on | yes |
\endtable \endtable
\linebreak \linebreak
@ -228,7 +228,7 @@ protected:
) const; ) const;
//- Output file header information //- Output file header information
virtual void writeFileHeader(const label i); virtual void writeFileHeader(Ostream& os) const;
public: public:
@ -272,7 +272,11 @@ public:
//- Templated helper function to output field values //- Templated helper function to output field values
template<class Type> template<class Type>
bool writeValues(const word& fieldName); bool writeValues
(
const word& fieldName,
const scalarField& weightField
);
//- Filter a field according to cellIds //- Filter a field according to cellIds
template<class Type> template<class Type>

View File

@ -87,52 +87,65 @@ Type Foam::fieldValues::cellSource::processValues
{ {
case opSum: case opSum:
{ {
result = sum(values); result = gSum(values);
break; break;
} }
case opSumMag: case opSumMag:
{ {
result = sum(cmptMag(values)); result = gSum(cmptMag(values));
break; break;
} }
case opAverage: case opAverage:
{ {
result = sum(values)/values.size(); label n = returnReduce(values.size(), sumOp<label>());
result = gSum(values)/(scalar(n) + ROOTVSMALL);
break; break;
} }
case opWeightedAverage: case opWeightedAverage:
{ {
result = sum(weightField*values)/sum(weightField); label wSize = returnReduce(weightField.size(), sumOp<label>());
if (wSize > 0)
{
result = gSum(weightField*values)/(gSum(weightField) + ROOTVSMALL);
}
else
{
label n = returnReduce(values.size(), sumOp<label>());
result = gSum(values)/(scalar(n) + ROOTVSMALL);
}
break; break;
} }
case opVolAverage: case opVolAverage:
{ {
result = sum(V*values)/sum(V); result = gSum(values*V)/(gSum(V) + ROOTVSMALL);
break; break;
} }
case opWeightedVolAverage: case opWeightedVolAverage:
{ {
result = sum(weightField*V*values)/sum(weightField*V); result = gSum(weightField*V*values)/gSum(weightField*V);
break; break;
} }
case opVolIntegrate: case opVolIntegrate:
{ {
result = sum(V*values); result = gSum(V*values);
break; break;
} }
case opMin: case opMin:
{ {
result = min(values); result = gMin(values);
break; break;
} }
case opMax: case opMax:
{ {
result = max(values); result = gMax(values);
break; break;
} }
case opCoV: case opCoV:
{ {
Type meanValue = sum(values*V)/sum(V); const scalar sumV = gSum(V);
Type meanValue = gSum(V*values)/sumV;
const label nComp = pTraits<Type>::nComponents; const label nComp = pTraits<Type>::nComponents;
@ -142,7 +155,7 @@ Type Foam::fieldValues::cellSource::processValues
scalar mean = component(meanValue, d); scalar mean = component(meanValue, d);
scalar& res = setComponent(result, d); scalar& res = setComponent(result, d);
res = sqrt(sum(V*sqr(vals - mean))/sum(V))/mean; res = sqrt(gSum(V*sqr(vals - mean))/sumV)/(mean + ROOTVSMALL);
} }
break; break;
@ -160,7 +173,11 @@ Type Foam::fieldValues::cellSource::processValues
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
bool Foam::fieldValues::cellSource::writeValues(const word& fieldName) bool Foam::fieldValues::cellSource::writeValues
(
const word& fieldName,
const scalarField& weightField
)
{ {
const bool ok = validField<Type>(fieldName); const bool ok = validField<Type>(fieldName);
@ -168,26 +185,13 @@ bool Foam::fieldValues::cellSource::writeValues(const word& fieldName)
{ {
Field<Type> values(setFieldValues<Type>(fieldName)); Field<Type> values(setFieldValues<Type>(fieldName));
scalarField V(filterField(mesh().V())); scalarField V(filterField(mesh().V()));
scalarField weightField(values.size(), 1.0);
if (weightFieldName_ != "none") if (valueOutput_)
{ {
weightField = setFieldValues<scalar>(weightFieldName_, true); Field<Type> allValues(values);
} combineFields(allValues);
// Combine onto master if (Pstream::master())
combineFields(values);
combineFields(V);
combineFields(weightField);
if (Pstream::master())
{
Type result = processValues(values, V, weightField);
// Add to result dictionary, over-writing any previous entry
resultDict_.add(fieldName, result, true);
if (valueOutput_)
{ {
IOField<Type> IOField<Type>
( (
@ -200,17 +204,29 @@ bool Foam::fieldValues::cellSource::writeValues(const word& fieldName)
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
weightField*values allValues
).write(); ).write();
} }
}
// Apply scale factor
values *= scaleFactor_;
file()<< tab << result; Type result = processValues(values, V, weightField);
if (log_) Info<< " " << operationTypeNames_[operation_] file()<< tab << result;
if (log_)
{
Info<< " " << operationTypeNames_[operation_]
<< "(" << sourceName_ << ") of " << fieldName << "(" << sourceName_ << ") of " << fieldName
<< " = " << result << endl; << " = " << result << endl;
} }
// write state/results information
const word& opName = operationTypeNames_[operation_];
word resultName = opName + '(' + sourceName_ + ',' + fieldName + ')';
this->setResult(resultName, result);
} }
return ok; return ok;

View File

@ -60,10 +60,13 @@ functions
// Output field values as well // Output field values as well
valueOutput true; valueOutput true;
// Output format for field values
surfaceFormat vtk;
// Type of source: patch/faceZone/sampledSurface // Type of source: patch/faceZone/sampledSurface
source patch; source patch;
// if patch or faceZone: name of patch or faceZone // If patch or faceZone: name of patch or faceZone
sourceName movingWall; sourceName movingWall;
//// if sampledSurface: dictionary with a sampledSurface //// if sampledSurface: dictionary with a sampledSurface
@ -96,6 +99,7 @@ functions
outputControl outputTime; outputControl outputTime;
log true; log true;
valueOutput true; valueOutput true;
surfaceFormat vtk;
source faceZone; source faceZone;
sourceName f0; sourceName f0;
operation sum; operation sum;

View File

@ -352,7 +352,7 @@ void Foam::fieldValues::faceSource::combineSurfaceGeometry
if (Pstream::parRun()) if (Pstream::parRun())
{ {
// dimension as fraction of mesh bounding box // Dimension as fraction of mesh bounding box
scalar mergeDim = 1e-10*mesh().bounds().mag(); scalar mergeDim = 1e-10*mesh().bounds().mag();
labelList pointsMap; labelList pointsMap;
@ -400,8 +400,6 @@ Foam::scalar Foam::fieldValues::faceSource::totalArea() const
void Foam::fieldValues::faceSource::initialise(const dictionary& dict) void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
{ {
dict.lookup("sourceName") >> sourceName_;
switch (source_) switch (source_)
{ {
case stFaceZone: case stFaceZone:
@ -450,15 +448,14 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
totalArea_ = totalArea(); totalArea_ = totalArea();
Info<< type() << " " << name_ << ":" << nl if (log_) Info
<< " total faces = " << nFaces_ << type() << " " << name_ << ":" << nl
<< nl << " total faces = " << nFaces_ << nl
<< " total area = " << totalArea_ << " total area = " << totalArea_ << nl;
<< nl;
if (dict.readIfPresent("weightField", weightFieldName_)) if (dict.readIfPresent("weightField", weightFieldName_))
{ {
Info<< " weight field = " << weightFieldName_ << nl; if (log_) Info << " weight field = " << weightFieldName_ << nl;
if (source_ == stSampledSurface) if (source_ == stSampledSurface)
{ {
@ -480,7 +477,7 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
if (weightFieldName_ == "none") if (weightFieldName_ == "none")
{ {
dict.lookup("orientedWeightField") >> weightFieldName_; dict.lookup("orientedWeightField") >> weightFieldName_;
Info<< " weight field = " << weightFieldName_ << nl; if (log_) Info << " weight field = " << weightFieldName_ << nl;
orientWeightField_ = true; orientWeightField_ = true;
} }
else else
@ -506,12 +503,7 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
fields_.append(orientedFields); fields_.append(orientedFields);
} }
if (dict.readIfPresent("scaleFactor", scaleFactor_)) if (log_) Info << nl << endl;
{
Info<< " scale factor = " << scaleFactor_ << nl;
}
Info<< nl << endl;
if (valueOutput_) if (valueOutput_)
{ {
@ -530,29 +522,27 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
} }
void Foam::fieldValues::faceSource::writeFileHeader(const label i) void Foam::fieldValues::faceSource::writeFileHeader(Ostream& os) const
{ {
writeCommented(file(), "Source : "); writeHeaderValue(os, "Source", sourceTypeNames_[source_]);
file() << sourceTypeNames_[source_] << " " << sourceName_ << endl; writeHeaderValue(os, "Name", sourceName_);
writeCommented(file(), "Faces : "); writeHeaderValue(os, "Faces", nFaces_);
file() << nFaces_ << endl; writeHeaderValue(os, "Total area", totalArea_);
writeCommented(file(), "Area : "); writeHeaderValue(os, "Scale factor", scaleFactor_);
file() << totalArea_ << endl;
writeCommented(file(), "Time"); writeCommented(os, "Time");
if (writeArea_) if (writeArea_)
{ {
file() << tab << "Area"; os << tab << "Area";
} }
forAll(fields_, i) forAll(fields_, i)
{ {
file() os << tab << operationTypeNames_[operation_]
<< tab << operationTypeNames_[operation_]
<< "(" << fields_[i] << ")"; << "(" << fields_[i] << ")";
} }
file() << endl; os << endl;
} }
@ -569,14 +559,14 @@ Foam::scalar Foam::fieldValues::faceSource::processValues
case opSumDirection: case opSumDirection:
{ {
vector n(dict_.lookup("direction")); vector n(dict_.lookup("direction"));
return sum(pos(values*(Sf & n))*mag(values)); return gSum(pos(values*(Sf & n))*mag(values));
} }
case opSumDirectionBalance: case opSumDirectionBalance:
{ {
vector n(dict_.lookup("direction")); vector n(dict_.lookup("direction"));
const scalarField nv(values*(Sf & n)); const scalarField nv(values*(Sf & n));
return sum(pos(nv)*mag(values) - neg(nv)*mag(values)); return gSum(pos(nv)*mag(values) - neg(nv)*mag(values));
} }
default: default:
{ {
@ -603,7 +593,7 @@ Foam::vector Foam::fieldValues::faceSource::processValues
n /= mag(n) + ROOTVSMALL; n /= mag(n) + ROOTVSMALL;
const scalarField nv(n & values); const scalarField nv(n & values);
return sum(pos(nv)*n*(nv)); return gSum(pos(nv)*n*(nv));
} }
case opSumDirectionBalance: case opSumDirectionBalance:
{ {
@ -611,16 +601,16 @@ Foam::vector Foam::fieldValues::faceSource::processValues
n /= mag(n) + ROOTVSMALL; n /= mag(n) + ROOTVSMALL;
const scalarField nv(n & values); const scalarField nv(n & values);
return sum(pos(nv)*n*(nv)); return gSum(pos(nv)*n*(nv));
} }
case opAreaNormalAverage: case opAreaNormalAverage:
{ {
scalar result = sum(values & Sf)/sum(mag(Sf)); scalar result = gSum(values & Sf)/gSum(mag(Sf));
return vector(result, 0.0, 0.0); return vector(result, 0.0, 0.0);
} }
case opAreaNormalIntegrate: case opAreaNormalIntegrate:
{ {
scalar result = sum(values & Sf); scalar result = gSum(values & Sf);
return vector(result, 0.0, 0.0); return vector(result, 0.0, 0.0);
} }
default: default:
@ -649,14 +639,17 @@ Foam::fieldValues::faceSource::faceSource
weightFieldName_("none"), weightFieldName_("none"),
orientWeightField_(false), orientWeightField_(false),
orientedFieldsStart_(labelMax), orientedFieldsStart_(labelMax),
scaleFactor_(1.0),
writeArea_(dict.lookupOrDefault("writeArea", false)), writeArea_(dict.lookupOrDefault("writeArea", false)),
nFaces_(0), nFaces_(0),
faceId_(), faceId_(),
facePatchId_(), facePatchId_(),
faceSign_() faceSign_()
{ {
read(dict); if (active_)
{
read(dict);
writeFileHeader(file());
}
} }
@ -670,10 +663,11 @@ Foam::fieldValues::faceSource::~faceSource()
void Foam::fieldValues::faceSource::read(const dictionary& dict) void Foam::fieldValues::faceSource::read(const dictionary& dict)
{ {
fieldValue::read(dict);
if (active_) if (active_)
{ {
fieldValue::read(dict);
// No additional info to read
initialise(dict); initialise(dict);
} }
} }
@ -690,27 +684,21 @@ void Foam::fieldValues::faceSource::write()
surfacePtr_().update(); surfacePtr_().update();
} }
if (Pstream::master()) file() << obr_.time().value();
{
file() << obr_.time().value();
}
if (writeArea_) if (writeArea_)
{ {
totalArea_ = totalArea(); totalArea_ = totalArea();
if (Pstream::master()) file() << tab << totalArea_;
{
file() << tab << totalArea_;
}
if (log_) Info<< " total area = " << totalArea_ << endl; if (log_) Info<< " total area = " << totalArea_ << endl;
} }
// construct weight field. Note: zero size means weight = 1 // Construct weight field. Note: zero size indicates unweighted
scalarField weightField; scalarField weightField;
if (weightFieldName_ != "none") if (weightFieldName_ != "none")
{ {
weightField = weightField =
getFieldValues<scalar> setFieldValues<scalar>
( (
weightFieldName_, weightFieldName_,
true, true,
@ -718,10 +706,7 @@ void Foam::fieldValues::faceSource::write()
); );
} }
// Combine onto master // Process the fields
combineFields(weightField);
// process the fields
forAll(fields_, i) forAll(fields_, i)
{ {
const word& fieldName = fields_[i]; const word& fieldName = fields_[i];
@ -730,8 +715,8 @@ void Foam::fieldValues::faceSource::write()
bool orient = i >= orientedFieldsStart_; bool orient = i >= orientedFieldsStart_;
ok = ok || writeValues<scalar>(fieldName, weightField, orient); ok = ok || writeValues<scalar>(fieldName, weightField, orient);
ok = ok || writeValues<vector>(fieldName, weightField, orient); ok = ok || writeValues<vector>(fieldName, weightField, orient);
ok = ok ok = ok ||
|| writeValues<sphericalTensor>(fieldName, weightField, orient); writeValues<sphericalTensor>(fieldName, weightField, orient);
ok = ok || writeValues<symmTensor>(fieldName, weightField, orient); ok = ok || writeValues<symmTensor>(fieldName, weightField, orient);
ok = ok || writeValues<tensor>(fieldName, weightField, orient); ok = ok || writeValues<tensor>(fieldName, weightField, orient);
@ -744,10 +729,7 @@ void Foam::fieldValues::faceSource::write()
} }
} }
if (Pstream::master()) file()<< endl;
{
file()<< endl;
}
if (log_) Info<< endl; if (log_) Info<< endl;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -257,9 +257,6 @@ protected:
//- Start index of fields that require application of flipMap //- Start index of fields that require application of flipMap
label orientedFieldsStart_; label orientedFieldsStart_;
//- Scale factor - optional
scalar scaleFactor_;
//- Total area of the faceSource //- Total area of the faceSource
scalar totalArea_; scalar totalArea_;
@ -300,7 +297,7 @@ protected:
//- Return field values by looking up field name //- Return field values by looking up field name
template<class Type> template<class Type>
tmp<Field<Type> > getFieldValues tmp<Field<Type> > setFieldValues
( (
const word& fieldName, const word& fieldName,
const bool mustGet = false, const bool mustGet = false,
@ -328,7 +325,7 @@ protected:
) const; ) const;
//- Output file header information //- Output file header information
virtual void writeFileHeader(const label i); virtual void writeFileHeader(Ostream& os) const;
public: public:

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -51,7 +51,7 @@ bool Foam::fieldValues::faceSource::validField(const word& fieldName) const
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::getFieldValues Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::setFieldValues
( (
const word& fieldName, const word& fieldName,
const bool mustGet, const bool mustGet,
@ -113,7 +113,7 @@ Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::getFieldValues
FatalErrorIn FatalErrorIn
( (
"Foam::tmp<Foam::Field<Type> > " "Foam::tmp<Foam::Field<Type> > "
"Foam::fieldValues::faceSource::getFieldValues" "Foam::fieldValues::faceSource::setFieldValues"
"(" "("
"const word&, " "const word&, "
"const bool, " "const bool, "
@ -140,12 +140,12 @@ Type Foam::fieldValues::faceSource::processSameTypeValues
{ {
case opSum: case opSum:
{ {
result = sum(values); result = gSum(values);
break; break;
} }
case opSumMag: case opSumMag:
{ {
result = sum(cmptMag(values)); result = gSum(cmptMag(values));
break; break;
} }
case opSumDirection: case opSumDirection:
@ -190,18 +190,23 @@ Type Foam::fieldValues::faceSource::processSameTypeValues
} }
case opAverage: case opAverage:
{ {
result = sum(values)/values.size(); label n = returnReduce(values.size(), sumOp<label>());
result = gSum(values)/(scalar(n) + ROOTVSMALL);
break; break;
} }
case opWeightedAverage: case opWeightedAverage:
{ {
if (weightField.size()) label wSize = returnReduce(weightField.size(), sumOp<label>());
if (wSize > 0)
{ {
result = sum(weightField*values)/sum(weightField); result =
gSum(weightField*values)/(gSum(weightField) + ROOTVSMALL);
} }
else else
{ {
result = sum(values)/values.size(); label n = returnReduce(values.size(), sumOp<label>());
result = gSum(values)/(scalar(n) + ROOTVSMALL);
} }
break; break;
} }
@ -209,20 +214,21 @@ Type Foam::fieldValues::faceSource::processSameTypeValues
{ {
const scalarField magSf(mag(Sf)); const scalarField magSf(mag(Sf));
result = sum(magSf*values)/sum(magSf); result = gSum(magSf*values)/gSum(magSf);
break; break;
} }
case opWeightedAreaAverage: case opWeightedAreaAverage:
{ {
const scalarField magSf(mag(Sf)); const scalarField magSf(mag(Sf));
label wSize = returnReduce(weightField.size(), sumOp<label>());
if (weightField.size()) if (wSize > 0)
{ {
result = sum(weightField*magSf*values)/sum(magSf*weightField); result = gSum(weightField*magSf*values)/gSum(magSf*weightField);
} }
else else
{ {
result = sum(magSf*values)/sum(magSf); result = gSum(magSf*values)/gSum(magSf);
} }
break; break;
} }
@ -230,24 +236,26 @@ Type Foam::fieldValues::faceSource::processSameTypeValues
{ {
const scalarField magSf(mag(Sf)); const scalarField magSf(mag(Sf));
result = sum(magSf*values); result = gSum(magSf*values);
break; break;
} }
case opMin: case opMin:
{ {
result = min(values); result = gMin(values);
break; break;
} }
case opMax: case opMax:
{ {
result = max(values); result = gMax(values);
break; break;
} }
case opCoV: case opCoV:
{ {
const scalarField magSf(mag(Sf)); const scalarField magSf(mag(Sf));
Type meanValue = sum(values*magSf)/sum(magSf); const scalar gSumMagSf = gSum(magSf);
Type meanValue = gSum(values*magSf)/gSumMagSf;
const label nComp = pTraits<Type>::nComponents; const label nComp = pTraits<Type>::nComponents;
@ -257,7 +265,9 @@ Type Foam::fieldValues::faceSource::processSameTypeValues
scalar mean = component(meanValue, d); scalar mean = component(meanValue, d);
scalar& res = setComponent(result, d); scalar& res = setComponent(result, d);
res = sqrt(sum(magSf*sqr(vals - mean))/sum(magSf))/mean; res =
sqrt(gSum(magSf*sqr(vals - mean))/gSumMagSf)
/(mean + ROOTVSMALL);
} }
break; break;
@ -299,7 +309,7 @@ bool Foam::fieldValues::faceSource::writeValues
if (ok) if (ok)
{ {
Field<Type> values(getFieldValues<Type>(fieldName, true, orient)); Field<Type> values(setFieldValues<Type>(fieldName, true, orient));
vectorField Sf; vectorField Sf;
if (surfacePtr_.valid()) if (surfacePtr_.valid())
@ -313,13 +323,12 @@ bool Foam::fieldValues::faceSource::writeValues
Sf = filterField(mesh().Sf(), true); Sf = filterField(mesh().Sf(), true);
} }
// Combine onto master
combineFields(values);
combineFields(Sf);
// Write raw values on surface if specified // Write raw values on surface if specified
if (surfaceWriterPtr_.valid()) if (surfaceWriterPtr_.valid())
{ {
Field<Type> allValues(values);
combineFields(allValues);
faceList faces; faceList faces;
pointField points; pointField points;
@ -344,29 +353,30 @@ bool Foam::fieldValues::faceSource::writeValues
points, points,
faces, faces,
fieldName, fieldName,
values, allValues,
false false
); );
} }
} }
// Apply scale factor // Apply scale factor
values *= scaleFactor_; values *= scaleFactor_;
if (Pstream::master()) Type result = processValues(values, Sf, weightField);
file()<< tab << result;
if (log_)
{ {
Type result = processValues(values, Sf, weightField); Info<< " " << operationTypeNames_[operation_]
<< "(" << sourceName_ << ") for " << fieldName
// Add to result dictionary, over-writing any previous entry
resultDict_.add(fieldName, result, true);
file()<< tab << result;
if (log_) Info<< " " << operationTypeNames_[operation_]
<< "(" << sourceName_ << ") of " << fieldName
<< " = " << result << endl; << " = " << result << endl;
} }
// Write state/results information
const word& opName = operationTypeNames_[operation_];
word resultName = opName + '(' + sourceName_ + ',' + fieldName + ')';
this->setResult(resultName, result);
} }
return ok; return ok;

View File

@ -75,10 +75,10 @@ Foam::fieldValue::fieldValue
const bool loadFromFiles const bool loadFromFiles
) )
: :
functionObjectState(obr, name),
functionObjectFile(obr, name, valueType, dict), functionObjectFile(obr, name, valueType, dict),
obr_(obr), obr_(obr),
dict_(dict), dict_(dict),
active_(true),
log_(true), log_(true),
sourceName_(dict.lookupOrDefault<word>("sourceName", "sampledSurface")), sourceName_(dict.lookupOrDefault<word>("sourceName", "sampledSurface")),
fields_(), fields_(),
@ -86,25 +86,10 @@ Foam::fieldValue::fieldValue
scaleFactor_(1.0) scaleFactor_(1.0)
{ {
// Only active if obr is an fvMesh // Only active if obr is an fvMesh
if (isA<fvMesh>(obr_)) if (setActive<fvMesh>())
{ {
read(dict); read(dict);
} }
else
{
WarningIn
(
"fieldValue::fieldValue"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating " << name << nl
<< endl;
active_ = false;
}
} }

View File

@ -38,6 +38,7 @@ SourceFiles
#ifndef fieldValue_H #ifndef fieldValue_H
#define fieldValue_H #define fieldValue_H
#include "functionObjectState.H"
#include "functionObjectFile.H" #include "functionObjectFile.H"
#include "Switch.H" #include "Switch.H"
#include "OFstream.H" #include "OFstream.H"
@ -62,6 +63,7 @@ class mapPolyMesh;
class fieldValue class fieldValue
: :
public functionObjectState,
public functionObjectFile public functionObjectFile
{ {
@ -69,18 +71,12 @@ protected:
// Protected data // Protected data
//- Name of this fieldValue object
word name_;
//- Database this class is registered to //- Database this class is registered to
const objectRegistry& obr_; const objectRegistry& obr_;
//- Construction dictionary //- Construction dictionary
dictionary dict_; dictionary dict_;
//- Active flag
bool active_;
//- Switch to send output to Info as well as to file //- Switch to send output to Info as well as to file
Switch log_; Switch log_;
@ -93,9 +89,6 @@ protected:
//- Output field values flag //- Output field values flag
Switch valueOutput_; Switch valueOutput_;
//- Results dictionary for external access of results
dictionary resultDict_;
//- Scale factor - optional //- Scale factor - optional
scalar scaleFactor_; scalar scaleFactor_;
@ -176,9 +169,6 @@ public:
//- Helper function to return the reference to the mesh //- Helper function to return the reference to the mesh
inline const fvMesh& mesh() const; inline const fvMesh& mesh() const;
//- Return access to the latest set of results
inline const dictionary& resultDict() const;
// Function object functions // Function object functions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -82,10 +82,4 @@ inline const Foam::fvMesh& Foam::fieldValue::mesh() const
} }
inline const Foam::dictionary& Foam::fieldValue::resultDict() const
{
return resultDict_;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,16 +37,14 @@ void Foam::fieldValue::combineFields(Field<Type>& field)
allValues[Pstream::myProcNo()] = field; allValues[Pstream::myProcNo()] = field;
Pstream::gatherList(allValues); Pstream::gatherList(allValues);
Pstream::scatterList(allValues);
if (Pstream::master()) field =
{ ListListOps::combine<Field<Type> >
field = (
ListListOps::combine<Field<Type> > allValues,
( accessOp<Field<Type> >()
allValues, );
accessOp<Field<Type> >()
);
}
} }

View File

@ -95,34 +95,16 @@ Foam::fieldValues::fieldValueDelta::fieldValueDelta
const bool loadFromFiles const bool loadFromFiles
) )
: :
functionObjectState(obr, name),
functionObjectFile(obr, name, typeName, dict), functionObjectFile(obr, name, typeName, dict),
name_(name),
obr_(obr), obr_(obr),
active_(true),
loadFromFiles_(loadFromFiles), loadFromFiles_(loadFromFiles),
log_(true), log_(true),
operation_(opSubtract), operation_(opSubtract),
source1Ptr_(NULL), source1Ptr_(NULL),
source2Ptr_(NULL) source2Ptr_(NULL)
{ {
// Check if the available mesh is an fvMesh otherise deactivate if (setActive<fvMesh>())
if (!isA<fvMesh>(obr_))
{
active_ = false;
WarningIn
(
"fieldMinMax::fieldMinMax"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating " << name_
<< endl;
}
if (active_)
{ {
read(dict); read(dict);
writeFileHeader(file()); writeFileHeader(file());
@ -175,54 +157,96 @@ void Foam::fieldValues::fieldValueDelta::read(const dictionary& dict)
void Foam::fieldValues::fieldValueDelta::write() void Foam::fieldValues::fieldValueDelta::write()
{ {
if (active_) // Do nothing
{
source1Ptr_->write();
source2Ptr_->write();
if (Pstream::master())
{
file()<< obr_.time().value();
}
if (log_) Info<< type() << " " << name_ << " output:" << endl;
bool found = false;
processFields<scalar>(found);
processFields<vector>(found);
processFields<sphericalTensor>(found);
processFields<symmTensor>(found);
processFields<tensor>(found);
if (Pstream::master())
{
file()<< endl;
}
if (log_)
{
if (!found)
{
Info<< " none" << endl;
}
else
{
Info<< endl;
}
}
}
} }
void Foam::fieldValues::fieldValueDelta::execute() void Foam::fieldValues::fieldValueDelta::execute()
{ {
// Do nothing if (active_)
{
source1Ptr_->write();
source2Ptr_->write();
file()<< obr_.time().value();
if (log_) Info << type() << " " << name_ << " output:" << endl;
const word& name1 = source1Ptr_->name();
const word& name2 = source2Ptr_->name();
const wordList entries1 = objectResultEntries(name1);
const wordList entries2 = objectResultEntries(name2);
if (entries1.size() != entries2.size())
{
FatalErrorIn("void Foam::fieldValues::fieldValueDelta::execute()")
<< name_ << ": objects must generate the same number of results"
<< nl
<< " " << name1 << " objects: " << entries1 << nl
<< " " << name2 << " objects: " << entries2 << nl
<< exit(FatalError);
}
forAll(entries1, i)
{
const word& entry1(entries1[i]);
const word& entry2(entries2[i]);
const word type1 = objectResultType(name1, entry1);
const word type2 = objectResultType(name2, entry2);
if (type1 != type2)
{
FatalErrorIn
(
"void Foam::fieldValues::fieldValueDelta::execute()"
)
<< name_
<< ": input values for operation must be of the same type"
<< nl
<< " " << entry1 << ": " << type1 << nl
<< " " << entry2 << ": " << type2 << nl
<< exit(FatalError);
}
bool found = false;
apply<scalar>(type1, name1, name2, entry1, entry2, found);
apply<vector>(type1, name1, name2, entry1, entry2, found);
apply<sphericalTensor>(type1, name1, name2, entry1, entry2, found);
apply<symmTensor>(type1, name1, name2, entry1, entry2, found);
apply<tensor>(type1, name1, name2, entry1, entry2, found);
if (log_ && !found)
{
Info<< "Operation between "
<< name1 << " with result " << entry1 << " and "
<< name2 << " with result " << entry2 << " not applied"
<< endl;
}
}
if (log_)
{
if (entries1.empty())
{
Info<< " none";
}
Info<< endl;
}
file()<< endl;
}
} }
void Foam::fieldValues::fieldValueDelta::end() void Foam::fieldValues::fieldValueDelta::end()
{ {
// Do nothing if (active_)
{
execute();
}
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,8 +28,11 @@ Group
grpFieldFunctionObjects grpFieldFunctionObjects
Description Description
This function object provides a differencing option between two 'field This function object provides applies an operation to the output of two
value' function objects. fieldValue function objects.
The operation is applied to all results of each fieldValue object.
Accordingly, each object must generate the same number and type of results.
Example of function object specification: Example of function object specification:
\verbatim \verbatim
@ -39,11 +42,11 @@ Description
functionObjectLibs ("libfieldFunctionObjects.so"); functionObjectLibs ("libfieldFunctionObjects.so");
operation subtract; operation subtract;
fieldValue1 source1
{ {
... ...
} }
fieldValue2 source2
{ {
... ...
} }
@ -65,6 +68,7 @@ Description
max | maximum max | maximum
average | average average | average
\endplaintable \endplaintable
SeeAlso SeeAlso
Foam::fieldValue Foam::fieldValue
@ -76,6 +80,7 @@ SourceFiles
#ifndef fieldValueDelta_H #ifndef fieldValueDelta_H
#define fieldValueDelta_H #define fieldValueDelta_H
#include "functionObjectState.H"
#include "functionObjectFile.H" #include "functionObjectFile.H"
#include "fieldValue.H" #include "fieldValue.H"
#include "autoPtr.H" #include "autoPtr.H"
@ -94,6 +99,7 @@ namespace fieldValues
class fieldValueDelta class fieldValueDelta
: :
public functionObjectState,
public functionObjectFile public functionObjectFile
{ {
public: public:
@ -115,15 +121,9 @@ private:
// Private data // Private data
//- Name of this fieldValue object
word name_;
//- Database this class is registered to //- Database this class is registered to
const objectRegistry& obr_; const objectRegistry& obr_;
//- On/off switch
bool active_;
//- Flag to indicate to load from files //- Flag to indicate to load from files
bool loadFromFiles_; bool loadFromFiles_;
@ -142,13 +142,17 @@ private:
// Private Member Functions // Private Member Functions
//- Templated function to process common fields
template<class Type>
void processFields(bool& found);
//- Templated function to apply the operation //- Templated function to apply the operation
template<class Type> template<class Type>
Type applyOperation(const Type& value1, const Type& value2) const; void apply
(
const word& resultType,
const word& name1,
const word& name2,
const word& entryName1,
const word& entryName2,
bool& found
);
protected: protected:

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -23,21 +23,31 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "GeometricField.H"
#include "volMesh.H"
#include "surfaceMesh.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
Type Foam::fieldValues::fieldValueDelta::applyOperation void Foam::fieldValues::fieldValueDelta::apply
( (
const Type& value1, const word& resultType,
const Type& value2 const word& name1,
) const const word& name2,
const word& entryName1,
const word& entryName2,
bool& found
)
{ {
if (pTraits<Type>::typeName != resultType)
{
return;
}
Type result = pTraits<Type>::zero; Type result = pTraits<Type>::zero;
Type value1 = this->getObjectResult<Type>(name1, entryName1);
Type value2 = this->getObjectResult<Type>(name2, entryName2);
const word& opName = operationTypeNames_[operation_];
switch (operation_) switch (operation_)
{ {
case opAdd: case opAdd:
@ -69,63 +79,33 @@ Type Foam::fieldValues::fieldValueDelta::applyOperation
{ {
FatalErrorIn FatalErrorIn
( (
"Type Foam::fieldValues::fieldValueDelta::applyOperation" "void Foam::fieldValues::fieldValueDelta::applyOperation"
"(" "("
"const Type&, " "const word&, "
"const Type&" "const word&, "
"const word&, "
"const word&, "
"const word&"
"bool&"
") const" ") const"
) )
<< "Unable to process operation " << "Operation not supported: "
<< operationTypeNames_[operation_] << opName
<< abort(FatalError); << abort(FatalError);
} }
} }
return result; const word
} resultName(opName + '(' + entryName1 + ',' + entryName2 + ')');
if (log_) Info << " " << resultName << " = " << result << endl;
template<class Type> this->file()<< tab << result;
void Foam::fieldValues::fieldValueDelta::processFields(bool& found)
{
typedef GeometricField<Type, fvPatchField, volMesh> vf;
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
const wordList& fields1 = source1Ptr_->fields(); // Write state/results information
this->setResult(resultName, result);
const dictionary& results1 = source1Ptr_->resultDict(); found = true;
const dictionary& results2 = source2Ptr_->resultDict();
Type r1(pTraits<Type>::zero);
Type r2(pTraits<Type>::zero);
forAll(fields1, i)
{
const word& fieldName = fields1[i];
if
(
(obr_.foundObject<vf>(fieldName) || obr_.foundObject<sf>(fieldName))
&& results2.found(fieldName)
)
{
results1.lookup(fieldName) >> r1;
results2.lookup(fieldName) >> r2;
Type result = applyOperation(r1, r2);
if (log_) Info<< " " << operationTypeNames_[operation_]
<< "(" << fieldName << ") = " << result
<< endl;
if (Pstream::master())
{
file()<< tab << result;
}
found = true;
}
}
} }