Updates to the fieldValues function object

- Updates to enable correct operation in parallel
- Added weighted average operation for cell sources
This commit is contained in:
andy
2010-01-08 17:14:53 +00:00
parent 711e0a42dd
commit 1812773b25
8 changed files with 249 additions and 174 deletions

View File

@ -46,10 +46,13 @@ namespace Foam
fieldValues::cellSource::sourceTypeNames_; fieldValues::cellSource::sourceTypeNames_;
template<> template<>
const char* NamedEnum<fieldValues::cellSource::operationType, 4>:: const char* NamedEnum<fieldValues::cellSource::operationType, 5>::
names[] = {"none", "sum", "volAverage", "volIntegrate"}; names[] =
{
"none", "sum", "volAverage", "volIntegrate", "weightedAverage"
};
const NamedEnum<fieldValues::cellSource::operationType, 4> const NamedEnum<fieldValues::cellSource::operationType, 5>
fieldValues::cellSource::operationTypeNames_; fieldValues::cellSource::operationTypeNames_;
} }
@ -93,7 +96,7 @@ void Foam::fieldValues::cellSource::setCellZoneCells()
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fieldValues::cellSource::initialise() void Foam::fieldValues::cellSource::initialise(const dictionary& dict)
{ {
switch (source_) switch (source_)
{ {
@ -104,7 +107,7 @@ void Foam::fieldValues::cellSource::initialise()
} }
default: default:
{ {
FatalErrorIn("cellSource::constructCellAddressing()") FatalErrorIn("cellSource::initialise()")
<< "Unknown source type. Valid source types are:" << "Unknown source type. Valid source types are:"
<< sourceTypeNames_ << nl << exit(FatalError); << sourceTypeNames_ << nl << exit(FatalError);
} }
@ -114,6 +117,29 @@ void Foam::fieldValues::cellSource::initialise()
<< " total cells = " << cellId_.size() << nl << " total cells = " << cellId_.size() << nl
<< " total volume = " << sum(filterField(mesh().V())) << " total volume = " << sum(filterField(mesh().V()))
<< nl << endl; << nl << endl;
if (operation_ == opWeightedAverage)
{
dict.lookup("weightField") >> weightFieldName_;
if
(
obr().foundObject<volScalarField>(weightFieldName_)
)
{
Info<< " weight field = " << weightFieldName_;
}
else
{
FatalErrorIn("cellSource::initialise()")
<< type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl << " Weight field " << weightFieldName_
<< " must be a " << volScalarField::typeName
<< nl << exit(FatalError);
}
}
Info<< nl << endl;
} }
@ -172,7 +198,7 @@ void Foam::fieldValues::cellSource::read(const dictionary& dict)
if (active_) if (active_)
{ {
// no additional info to read // no additional info to read
initialise(); initialise(dict);
} }
} }
@ -183,9 +209,12 @@ void Foam::fieldValues::cellSource::write()
if (active_) if (active_)
{ {
outputFilePtr_() if (Pstream::master())
<< obr_.time().value() << tab {
<< sum(filterField(mesh().V())); outputFilePtr_()
<< obr_.time().value() << tab
<< sum(filterField(mesh().V()));
}
forAll(fields_, i) forAll(fields_, i)
{ {
@ -196,7 +225,10 @@ void Foam::fieldValues::cellSource::write()
writeValues<tensor>(fields_[i]); writeValues<tensor>(fields_[i]);
} }
outputFilePtr_()<< endl; if (Pstream::master())
{
outputFilePtr_()<< endl;
}
if (log_) if (log_)
{ {

View File

@ -39,7 +39,7 @@ Description
valueOutput true; // Write values at run-time output times? valueOutput true; // Write values at run-time output times?
source cellZone; // Type of cell source source cellZone; // Type of cell source
sourceName c0; sourceName c0;
operation volAverage; // none, sum, volAverage, volIntegrate operation volAverage;
fields fields
( (
p p
@ -47,6 +47,13 @@ Description
); );
} }
where operation is one of:
- none
- sum
- volAverage
- volIntegrate
- weightedAverage
SourceFiles SourceFiles
cellSource.C cellSource.C
@ -96,11 +103,12 @@ public:
opNone, opNone,
opSum, opSum,
opVolAverage, opVolAverage,
opVolIntegrate opVolIntegrate,
opWeightedAverage
}; };
//- Operation type names //- Operation type names
static const NamedEnum<operationType, 4> operationTypeNames_; static const NamedEnum<operationType, 5> operationTypeNames_;
private: private:
@ -127,23 +135,34 @@ protected:
//- Local list of cell IDs //- Local list of cell IDs
labelList cellId_; labelList cellId_;
//- Weight field name - only used for opWeightedAverage mode
word weightFieldName_;
// Protected member functions // Protected member functions
//- Initialise, e.g. cell addressing //- Initialise, e.g. cell addressing
void initialise(); void initialise(const dictionary& dict);
//- Return true if the field name is valid
template<class Type>
bool validField(const word& fieldName) const;
//- Insert field values into values list //- Insert field values into values list
template<class Type> template<class Type>
bool setFieldValues tmp<Field<Type> > setFieldValues
( (
const word& fieldName, const word& fieldName
List<Type>& values
) const; ) const;
//- Apply the 'operation' to the values //- Apply the 'operation' to the values
template<class Type> template<class Type>
Type processValues(const List<Type>& values) const; Type processValues
(
const Field<Type>& values,
const scalarField& V,
const scalarField& weightField
) const;
//- Output file header information //- Output file header information
virtual void writeFileHeader(); virtual void writeFileHeader();

View File

@ -27,27 +27,16 @@ License
#include "cellSource.H" #include "cellSource.H"
#include "volFields.H" #include "volFields.H"
#include "IOList.H" #include "IOList.H"
#include "ListListOps.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type> template<class Type>
bool Foam::fieldValues::cellSource::setFieldValues bool Foam::fieldValues::cellSource::validField(const word& fieldName) const
(
const word& fieldName,
List<Type>& values
) const
{ {
values.setSize(cellId_.size(), pTraits<Type>::zero);
typedef GeometricField<Type, fvPatchField, volMesh> vf; typedef GeometricField<Type, fvPatchField, volMesh> vf;
if (obr_.foundObject<vf>(fieldName)) if (obr_.foundObject<vf>(fieldName))
{ {
const vf& field = obr_.lookupObject<vf>(fieldName);
values = UIndirectList<Type>(field, cellId_);
return true; return true;
} }
@ -55,10 +44,29 @@ bool Foam::fieldValues::cellSource::setFieldValues
} }
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::cellSource::setFieldValues
(
const word& fieldName
) const
{
typedef GeometricField<Type, fvPatchField, volMesh> vf;
if (obr_.foundObject<vf>(fieldName))
{
return filterField(obr_.lookupObject<vf>(fieldName));
}
return tmp<Field<Type> >(new Field<Type>(0.0));
}
template<class Type> template<class Type>
Type Foam::fieldValues::cellSource::processValues Type Foam::fieldValues::cellSource::processValues
( (
const List<Type>& values const Field<Type>& values,
const scalarField& V,
const scalarField& weightField
) const ) const
{ {
Type result = pTraits<Type>::zero; Type result = pTraits<Type>::zero;
@ -71,13 +79,17 @@ Type Foam::fieldValues::cellSource::processValues
} }
case opVolAverage: case opVolAverage:
{ {
tmp<scalarField> V = filterField(mesh().V()); result = sum(values*V)/sum(V);
result = sum(values*V())/sum(V());
break; break;
} }
case opVolIntegrate: case opVolIntegrate:
{ {
result = sum(values*filterField(mesh().V())); result = sum(values*V);
break;
}
case opWeightedAverage:
{
result = sum(values*weightField)/sum(weightField);
break; break;
} }
default: default:
@ -95,25 +107,20 @@ Type Foam::fieldValues::cellSource::processValues
template<class Type> template<class Type>
bool Foam::fieldValues::cellSource::writeValues(const word& fieldName) bool Foam::fieldValues::cellSource::writeValues(const word& fieldName)
{ {
List<List<Type> > allValues(Pstream::nProcs()); const bool ok = validField<Type>(fieldName);
bool validField = if (ok)
setFieldValues<Type>(fieldName, allValues[Pstream::myProcNo()]);
if (validField)
{ {
Pstream::gatherList(allValues); Field<Type> values = combineFields(setFieldValues<Type>(fieldName));
scalarField V = combineFields(filterField(mesh().V()));
scalarField weightField =
combineFields(setFieldValues<scalar>(weightFieldName_));
if (Pstream::master()) if (Pstream::master())
{ {
List<Type> values = Type result = processValues(values, V, weightField);
ListListOps::combine<List<Type> >
(
allValues,
accessOp<List<Type> >()
);
Type result = processValues(values);
if (valueOutput_) if (valueOutput_)
{ {
@ -144,7 +151,7 @@ bool Foam::fieldValues::cellSource::writeValues(const word& fieldName)
} }
} }
return validField; return ok;
} }

View File

@ -220,7 +220,7 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
} }
default: default:
{ {
FatalErrorIn("faceSource::constructFaceAddressing()") FatalErrorIn("faceSource::initiliase()")
<< type() << " " << name_ << ": " << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl << " Unknown source type. Valid source types are:" << nl << " Unknown source type. Valid source types are:"
@ -245,7 +245,7 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
} }
else else
{ {
FatalErrorIn("faceSource::constructFaceAddressing()") FatalErrorIn("faceSource::initialise()")
<< type() << " " << name_ << ": " << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl << " Weight field " << weightFieldName_ << nl << " Weight field " << weightFieldName_
@ -326,9 +326,12 @@ void Foam::fieldValues::faceSource::write()
if (active_) if (active_)
{ {
outputFilePtr_() if (Pstream::master())
<< obr_.time().value() << tab {
<< sum(filterField(mesh().magSf())); outputFilePtr_()
<< obr_.time().value() << tab
<< sum(filterField(mesh().magSf()));
}
forAll(fields_, i) forAll(fields_, i)
{ {
@ -339,7 +342,10 @@ void Foam::fieldValues::faceSource::write()
writeValues<tensor>(fields_[i]); writeValues<tensor>(fields_[i]);
} }
outputFilePtr_()<< endl; if (Pstream::master())
{
outputFilePtr_()<< endl;
}
if (log_) if (log_)
{ {
@ -350,4 +356,3 @@ void Foam::fieldValues::faceSource::write()
// ************************************************************************* // // ************************************************************************* //

View File

@ -153,17 +153,22 @@ protected:
//- Initialise, e.g. face addressing //- Initialise, e.g. face addressing
void initialise(const dictionary& dict); void initialise(const dictionary& dict);
//- Insert field values into values list //- Return true if the field name is valid
template<class Type> template<class Type>
bool setFieldValues bool validField(const word& fieldName) const;
(
const word& fieldName, //- Return field values by looking up field name
List<Type>& values template<class Type>
) const; tmp<Field<Type> > setFieldValues(const word& fieldName) const;
//- Apply the 'operation' to the values //- Apply the 'operation' to the values
template<class Type> template<class Type>
Type processValues(const List<Type>& values) const; Type processValues
(
const Field<Type>& values,
const scalarField& magSf,
const scalarField& weightField
) const;
//- Output file header information //- Output file header information
virtual void writeFileHeader(); virtual void writeFileHeader();

View File

@ -33,70 +33,17 @@ License
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type> template<class Type>
bool Foam::fieldValues::faceSource::setFieldValues bool Foam::fieldValues::faceSource::validField(const word& fieldName) const
(
const word& fieldName,
List<Type>& values
) const
{ {
values.setSize(faceId_.size(), pTraits<Type>::zero);
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf; typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
typedef GeometricField<Type, fvPatchField, volMesh> vf; typedef GeometricField<Type, fvPatchField, volMesh> vf;
if (obr_.foundObject<sf>(fieldName)) if (obr_.foundObject<sf>(fieldName))
{ {
const sf& field = obr_.lookupObject<sf>(fieldName);
forAll(values, i)
{
label faceI = faceId_[i];
label patchI = facePatchId_[i];
if (patchI >= 0)
{
values[i] = field.boundaryField()[patchI][faceI];
}
else
{
values[i] = field[faceI];
}
values[i] *= flipMap_[i];
}
return true; return true;
} }
else if (obr_.foundObject<vf>(fieldName)) else if (obr_.foundObject<vf>(fieldName))
{ {
const vf& field = obr_.lookupObject<vf>(fieldName);
forAll(values, i)
{
label faceI = faceId_[i];
label patchI = facePatchId_[i];
if (patchI >= 0)
{
values[i] = field.boundaryField()[patchI][faceI];
}
else
{
FatalErrorIn
(
"fieldValues::faceSource::setFieldValues"
"("
"const word&, "
"List<Type>&"
") const"
) << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl
<< " Unable to process internal faces for volume field "
<< fieldName << nl << abort(FatalError);
}
values[i] *= flipMap_[i];
}
return true; return true;
} }
@ -104,10 +51,34 @@ bool Foam::fieldValues::faceSource::setFieldValues
} }
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::setFieldValues
(
const word& fieldName
) const
{
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
typedef GeometricField<Type, fvPatchField, volMesh> vf;
if (obr_.foundObject<sf>(fieldName))
{
return filterField(obr_.lookupObject<sf>(fieldName));
}
else if (obr_.foundObject<vf>(fieldName))
{
return filterField(obr_.lookupObject<vf>(fieldName));
}
return tmp<Field<Type> >(new Field<Type>(0.0));
}
template<class Type> template<class Type>
Type Foam::fieldValues::faceSource::processValues Type Foam::fieldValues::faceSource::processValues
( (
const List<Type>& values const Field<Type>& values,
const scalarField& magSf,
const scalarField& weightField
) const ) const
{ {
Type result = pTraits<Type>::zero; Type result = pTraits<Type>::zero;
@ -120,54 +91,17 @@ Type Foam::fieldValues::faceSource::processValues
} }
case opAreaAverage: case opAreaAverage:
{ {
tmp<scalarField> magSf = filterField(mesh().magSf()); result = sum(values*magSf)/sum(magSf);
result = sum(values*magSf())/sum(magSf());
break; break;
} }
case opAreaIntegrate: case opAreaIntegrate:
{ {
result = sum(values*filterField(mesh().magSf())); result = sum(values*magSf);
break; break;
} }
case opWeightedAverage: case opWeightedAverage:
{ {
if (mesh().foundObject<volScalarField>(weightFieldName_)) result = sum(values*weightField)/sum(weightField);
{
tmp<scalarField> wField =
filterField
(
mesh().lookupObject<volScalarField>(weightFieldName_)
);
result = sum(values*wField())/sum(wField());
}
else if (mesh().foundObject<surfaceScalarField>(weightFieldName_))
{
tmp<scalarField> wField =
filterField
(
mesh().lookupObject<surfaceScalarField>
(
weightFieldName_
)
);
result = sum(values*wField())/sum(wField());
}
else
{
FatalErrorIn
(
"fieldValues::faceSource::processValues"
"("
"List<Type>&"
") const"
) << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl
<< " Weight field " << weightFieldName_
<< " must be either a " << volScalarField::typeName
<< " or " << surfaceScalarField::typeName << nl
<< abort(FatalError);
}
break; break;
} }
default: default:
@ -185,25 +119,20 @@ Type Foam::fieldValues::faceSource::processValues
template<class Type> template<class Type>
bool Foam::fieldValues::faceSource::writeValues(const word& fieldName) bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
{ {
List<List<Type> > allValues(Pstream::nProcs()); const bool ok = validField<Type>(fieldName);
bool validField = if (ok)
setFieldValues<Type>(fieldName, allValues[Pstream::myProcNo()]);
if (validField)
{ {
Pstream::gatherList(allValues); Field<Type> values = combineFields(setFieldValues<Type>(fieldName));
scalarField magSf = combineFields(filterField(mesh().magSf()));
scalarField weightField =
combineFields(setFieldValues<scalar>(weightFieldName_));
if (Pstream::master()) if (Pstream::master())
{ {
List<Type> values = Type result = processValues(values, magSf, weightField);
ListListOps::combine<List<Type> >
(
allValues,
accessOp<List<Type> >()
);
Type result = processValues(values);
if (valueOutput_) if (valueOutput_)
{ {
@ -222,7 +151,6 @@ bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
).write(); ).write();
} }
outputFilePtr_()<< tab << result; outputFilePtr_()<< tab << result;
if (log_) if (log_)
@ -234,7 +162,7 @@ bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
} }
} }
return validField; return ok;
} }

View File

@ -164,6 +164,13 @@ public:
//- Execute the at the final time-loop, currently does nothing //- Execute the at the final time-loop, currently does nothing
virtual void end(); virtual void end();
//- Comnbine fields from all processor domains into single field
template<class Type>
tmp<Field<Type> > combineFields
(
const tmp<Field<Type> >& field
) const;
}; };
@ -177,6 +184,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "fieldValueTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fieldValue.H"
#include "ListListOps.H"
#include "Pstream.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValue::combineFields
(
const tmp<Field<Type> >& field
) const
{
List<Field<Type> > allValues(Pstream::nProcs());
allValues[Pstream::myProcNo()] = field();
Pstream::gatherList(allValues);
if (Pstream::master())
{
return tmp<Field<Type> >
(
new Field<Type>
(
ListListOps::combine<Field<Type> >
(
allValues,
accessOp<Field<Type> >()
)
)
);
}
else
{
return field();
}
}
// ************************************************************************* //