functionObjects: surfaceFieldValue, volFieldValue: Various improvements
A number of changes have been made to the surfaceFieldValue and volFieldValue function objects to improve their usability and performance, and to extend them so that similar duplicate functionality elsewhere in OpenFOAM can be removed. Weighted operations have been removed. Weighting for averages and sums is now triggered simply by the existence of the "weightField" or "weightFields" entry. Multiple weight fields are now supported in both functions. The distinction between oriented and non-oriented fields has been removed from surfaceFieldValue. There is now just a single list of fields which are operated on. Instead of oriented fields, an "orientedSum" operation has been added, which should be used for flowRate calculations and other similar operations on fluxes. Operations minMag and maxMag have been added to both functions, to calculate the minimum and maximum field magnitudes respectively. The min and max operations are performed component-wise, as was the case previously. In volFieldValue, minMag and maxMag (and min and mag operations when applied to scalar fields) will report the location, cell and processor of the maximum or minimum value. There is also a "writeLocation" option which if set will write this location information into the output file. The fieldMinMax function has been made obsolete by this change, and has therefore been removed. surfaceFieldValue now operates in parallel without accumulating the entire surface on the master processor for calculation of the operation. Collecting the entire surface on the master processor is now only done if the surface itself is to be written out.
This commit is contained in:
@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/surfaceFieldValue/faceZone.cfg"
|
#includeEtc "caseDicts/postProcessing/surfaceFieldValue/faceZone.cfg"
|
||||||
|
|
||||||
fields ();
|
fields (phi);
|
||||||
orientedFields (phi);
|
operation orientedSum;
|
||||||
operation sum;
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Description
|
|
||||||
Writes out the maximum face value for one or more fields.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/minMax/faceMinMax.cfg"
|
|
||||||
|
|
||||||
fields (U p);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Description
|
|
||||||
Writes out the minimum face value for one or more fields.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/minMax/faceMin.cfg"
|
|
||||||
|
|
||||||
fields (U p);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/minMax/faceMinMax.cfg"
|
|
||||||
operation min;
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
type surfaceFieldValue;
|
|
||||||
libs ("libfieldFunctionObjects.so");
|
|
||||||
|
|
||||||
writeControl timeStep;
|
|
||||||
writeInterval 1;
|
|
||||||
|
|
||||||
writeFields false;
|
|
||||||
|
|
||||||
regionType all;
|
|
||||||
operation max;
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
type fieldMinMax;
|
|
||||||
libs ("libfieldFunctionObjects.so");
|
|
||||||
|
|
||||||
writeControl timeStep;
|
|
||||||
writeInterval 1;
|
|
||||||
|
|
||||||
mode magnitude;
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Description
|
|
||||||
Writes out the minimum and maximum values, by component for non-scalar
|
|
||||||
fields, and the locations where they occur.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/minMax/minMaxComponents.cfg"
|
|
||||||
|
|
||||||
fields (U p);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/minMax/fieldMinMax.cfg"
|
|
||||||
mode component;
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Version: dev
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Description
|
|
||||||
Writes out the minimum and maximum values, by magnitude for non-scalar
|
|
||||||
fields, and the locations where they occur.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#includeEtc "caseDicts/postProcessing/minMax/fieldMinMax.cfg"
|
|
||||||
|
|
||||||
fields (U p);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2016-2020 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2016-2021 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -55,15 +55,7 @@ Description
|
|||||||
#includeFunc mag(p)
|
#includeFunc mag(p)
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
Other dictionary entries may also be specified using named arguments, for
|
Other dictionary entries may also be specified using named arguments.
|
||||||
example the \c name of the \c faceZone in the \c flowRateFaceZone \c
|
|
||||||
functionObject configuration set and the \c orientedFields entry which
|
|
||||||
defaults to \c phi may also be overridden as required, e.g.
|
|
||||||
|
|
||||||
\verbatim
|
|
||||||
#includeFunc flowRateFaceZone(name=fZone1)
|
|
||||||
#includeFunc flowRateFaceZone(orientedFields=(phiAlpha),name=fZone1)
|
|
||||||
\endverbatim
|
|
||||||
|
|
||||||
See also
|
See also
|
||||||
Foam::functionObjectList
|
Foam::functionObjectList
|
||||||
|
|||||||
@ -3,7 +3,6 @@ fieldAverage/fieldAverageItem/fieldAverageItem.C
|
|||||||
fieldAverage/fieldAverageItem/fieldAverageItemIO.C
|
fieldAverage/fieldAverageItem/fieldAverageItemIO.C
|
||||||
|
|
||||||
fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
|
fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
|
||||||
fieldMinMax/fieldMinMax.C
|
|
||||||
|
|
||||||
fieldValues/fieldValue/fieldValue.C
|
fieldValues/fieldValue/fieldValue.C
|
||||||
fieldValues/fieldValue/fieldValueNew.C
|
fieldValues/fieldValue/fieldValueNew.C
|
||||||
|
|||||||
@ -1,169 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "fieldMinMax.H"
|
|
||||||
#include "fieldTypes.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace functionObjects
|
|
||||||
{
|
|
||||||
defineTypeNameAndDebug(fieldMinMax, 0);
|
|
||||||
addToRunTimeSelectionTable(functionObject, fieldMinMax, dictionary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
const char* Foam::NamedEnum
|
|
||||||
<
|
|
||||||
Foam::functionObjects::fieldMinMax::modeType,
|
|
||||||
2
|
|
||||||
>::names[] = {"magnitude", "component"};
|
|
||||||
|
|
||||||
const Foam::NamedEnum
|
|
||||||
<
|
|
||||||
Foam::functionObjects::fieldMinMax::modeType,
|
|
||||||
2
|
|
||||||
> Foam::functionObjects::fieldMinMax::modeTypeNames_;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::functionObjects::fieldMinMax::writeFileHeader(const label i)
|
|
||||||
{
|
|
||||||
OFstream& file = this->file();
|
|
||||||
|
|
||||||
writeHeader(file, "Field minima and maxima");
|
|
||||||
writeCommented(file, "Time");
|
|
||||||
|
|
||||||
if (location_)
|
|
||||||
{
|
|
||||||
writeTabbed(file, "field");
|
|
||||||
|
|
||||||
writeTabbed(file, "min");
|
|
||||||
writeTabbed(file, "location(min)");
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
writeTabbed(file, "processor");
|
|
||||||
}
|
|
||||||
|
|
||||||
writeTabbed(file, "max");
|
|
||||||
writeTabbed(file, "location(max)");
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
writeTabbed(file, "processor");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
forAll(fieldSet_, fieldi)
|
|
||||||
{
|
|
||||||
writeTabbed(file, "min(" + fieldSet_[fieldi] + ')');
|
|
||||||
writeTabbed(file, "max(" + fieldSet_[fieldi] + ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::functionObjects::fieldMinMax::fieldMinMax
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const Time& runTime,
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
fvMeshFunctionObject(name, runTime, dict),
|
|
||||||
logFiles(obr_, name),
|
|
||||||
location_(true),
|
|
||||||
mode_(modeType::mag),
|
|
||||||
fieldSet_()
|
|
||||||
{
|
|
||||||
read(dict);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::functionObjects::fieldMinMax::~fieldMinMax()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
bool Foam::functionObjects::fieldMinMax::read(const dictionary& dict)
|
|
||||||
{
|
|
||||||
fvMeshFunctionObject::read(dict);
|
|
||||||
|
|
||||||
location_ = dict.lookupOrDefault<Switch>("location", true);
|
|
||||||
|
|
||||||
mode_ = modeTypeNames_[dict.lookupOrDefault<word>("mode", "magnitude")];
|
|
||||||
dict.lookup("fields") >> fieldSet_;
|
|
||||||
|
|
||||||
resetName(typeName);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::functionObjects::fieldMinMax::execute()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::functionObjects::fieldMinMax::write()
|
|
||||||
{
|
|
||||||
logFiles::write();
|
|
||||||
|
|
||||||
if (Pstream::master() && !location_) writeTime(file());
|
|
||||||
Log << type() << " " << name() << " write:" << nl;
|
|
||||||
|
|
||||||
forAll(fieldSet_, fieldi)
|
|
||||||
{
|
|
||||||
calcMinMaxFields<scalar>(fieldSet_[fieldi], modeType::cmpt);
|
|
||||||
calcMinMaxFields<vector>(fieldSet_[fieldi], mode_);
|
|
||||||
calcMinMaxFields<sphericalTensor>(fieldSet_[fieldi], mode_);
|
|
||||||
calcMinMaxFields<symmTensor>(fieldSet_[fieldi], mode_);
|
|
||||||
calcMinMaxFields<tensor>(fieldSet_[fieldi], mode_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pstream::master() && !location_) file() << endl;
|
|
||||||
Log << endl;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,209 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::functionObjects::fieldMinMax
|
|
||||||
|
|
||||||
Description
|
|
||||||
Calculates the value and location of scalar minimum and maximum for a list
|
|
||||||
of user-specified fields.
|
|
||||||
|
|
||||||
For variables with a rank greater than zero, either the min/max of a
|
|
||||||
component value or the magnitude is reported. When operating in parallel,
|
|
||||||
the processor owning the value is also given.
|
|
||||||
|
|
||||||
Example of function object specification:
|
|
||||||
\verbatim
|
|
||||||
fieldMinMax1
|
|
||||||
{
|
|
||||||
type fieldMinMax;
|
|
||||||
libs ("libfieldFunctionObjects.so");
|
|
||||||
...
|
|
||||||
log yes;
|
|
||||||
location yes;
|
|
||||||
mode magnitude;
|
|
||||||
fields
|
|
||||||
(
|
|
||||||
U
|
|
||||||
p
|
|
||||||
);
|
|
||||||
}
|
|
||||||
\endverbatim
|
|
||||||
|
|
||||||
Usage
|
|
||||||
\table
|
|
||||||
Property | Description | Required | Default value
|
|
||||||
type | type name: fieldMinMax | yes |
|
|
||||||
log | write min/max data to standard output | no | no
|
|
||||||
location | write location of the min/max value | no | yes
|
|
||||||
mode | calculation mode: magnitude or component | no | magnitude
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
Output data is written to the file \<timeDir\>/fieldMinMax.dat
|
|
||||||
|
|
||||||
See also
|
|
||||||
Foam::functionObjects::fvMeshFunctionObject
|
|
||||||
Foam::functionObjects::logFiles
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
fieldMinMax.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef functionObjects_fieldMinMax_H
|
|
||||||
#define functionObjects_fieldMinMax_H
|
|
||||||
|
|
||||||
#include "fvMeshFunctionObject.H"
|
|
||||||
#include "logFiles.H"
|
|
||||||
#include "vector.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace functionObjects
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class fieldMinMax Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class fieldMinMax
|
|
||||||
:
|
|
||||||
public fvMeshFunctionObject,
|
|
||||||
public logFiles
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum class modeType
|
|
||||||
{
|
|
||||||
mag,
|
|
||||||
cmpt
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Protected data
|
|
||||||
|
|
||||||
//- Mode type names
|
|
||||||
static const NamedEnum<modeType, 2> modeTypeNames_;
|
|
||||||
|
|
||||||
//- Switch to write location of min/max values
|
|
||||||
Switch location_;
|
|
||||||
|
|
||||||
//- Mode for min/max - only applicable for ranks > 0
|
|
||||||
modeType mode_;
|
|
||||||
|
|
||||||
//- Fields to assess min/max
|
|
||||||
wordList fieldSet_;
|
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
|
||||||
|
|
||||||
//- Helper function to write the output
|
|
||||||
template<class Type>
|
|
||||||
void output
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const word& outputName,
|
|
||||||
const label minCell,
|
|
||||||
const label maxCell,
|
|
||||||
const vector& minC,
|
|
||||||
const vector& maxC,
|
|
||||||
const label minProci,
|
|
||||||
const label maxProci,
|
|
||||||
const Type& minValue,
|
|
||||||
const Type& maxValue
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Calculate the field min/max
|
|
||||||
template<class Type>
|
|
||||||
void calcMinMaxFields
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const modeType& mode
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Output file header information
|
|
||||||
virtual void writeFileHeader(const label i);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("fieldMinMax");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from Time and dictionary
|
|
||||||
fieldMinMax
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const Time& runTime,
|
|
||||||
const dictionary& dict
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construction
|
|
||||||
fieldMinMax(const fieldMinMax&) = delete;
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~fieldMinMax();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Read the field min/max data
|
|
||||||
virtual bool read(const dictionary&);
|
|
||||||
|
|
||||||
//- Execute, currently does nothing
|
|
||||||
virtual bool execute();
|
|
||||||
|
|
||||||
//- Write the fieldMinMax
|
|
||||||
virtual bool write();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const fieldMinMax&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace functionObjects
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "fieldMinMaxTemplates.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,305 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "fieldMinMax.H"
|
|
||||||
#include "volFields.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::functionObjects::fieldMinMax::output
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const word& outputName,
|
|
||||||
const label minCell,
|
|
||||||
const label maxCell,
|
|
||||||
const vector& minC,
|
|
||||||
const vector& maxC,
|
|
||||||
const label minProci,
|
|
||||||
const label maxProci,
|
|
||||||
const Type& minValue,
|
|
||||||
const Type& maxValue
|
|
||||||
)
|
|
||||||
{
|
|
||||||
OFstream& file = this->file();
|
|
||||||
|
|
||||||
if (location_)
|
|
||||||
{
|
|
||||||
writeTime(file());
|
|
||||||
|
|
||||||
writeTabbed(file, fieldName);
|
|
||||||
|
|
||||||
file<< tab << minValue
|
|
||||||
<< tab << minC;
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
file<< tab << minProci;
|
|
||||||
}
|
|
||||||
|
|
||||||
file<< tab << maxValue
|
|
||||||
<< tab << maxC;
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
file<< tab << maxProci;
|
|
||||||
}
|
|
||||||
|
|
||||||
file<< endl;
|
|
||||||
|
|
||||||
Log << " min(" << outputName << ") = " << minValue
|
|
||||||
<< " in cell " << minCell
|
|
||||||
<< " at location " << minC;
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
Log << " on processor " << minProci;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log << nl << " max(" << outputName << ") = " << maxValue
|
|
||||||
<< " in cell " << maxCell
|
|
||||||
<< " at location " << maxC;
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
Log << " on processor " << maxProci;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file<< tab << minValue << tab << maxValue;
|
|
||||||
|
|
||||||
Log << " min/max(" << outputName << ") = "
|
|
||||||
<< minValue << ' ' << maxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::functionObjects::fieldMinMax::calcMinMaxFields
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const modeType& mode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
|
||||||
|
|
||||||
if (obr_.foundObject<fieldType>(fieldName))
|
|
||||||
{
|
|
||||||
const label proci = Pstream::myProcNo();
|
|
||||||
|
|
||||||
const fieldType& field = obr_.lookupObject<fieldType>(fieldName);
|
|
||||||
|
|
||||||
const volVectorField::Boundary& CfBoundary =
|
|
||||||
mesh_.C().boundaryField();
|
|
||||||
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case modeType::mag:
|
|
||||||
{
|
|
||||||
const volScalarField magField(mag(field));
|
|
||||||
const volScalarField::Boundary& magFieldBoundary =
|
|
||||||
magField.boundaryField();
|
|
||||||
|
|
||||||
scalarList minVs(Pstream::nProcs());
|
|
||||||
labelList minCells(Pstream::nProcs());
|
|
||||||
List<vector> minCs(Pstream::nProcs());
|
|
||||||
label minProci = findMin(magField);
|
|
||||||
minVs[proci] = magField[minProci];
|
|
||||||
minCells[proci] = minProci;
|
|
||||||
minCs[proci] = mesh_.C()[minProci];
|
|
||||||
|
|
||||||
scalarList maxVs(Pstream::nProcs());
|
|
||||||
labelList maxCells(Pstream::nProcs());
|
|
||||||
List<vector> maxCs(Pstream::nProcs());
|
|
||||||
label maxProci = findMax(magField);
|
|
||||||
maxVs[proci] = magField[maxProci];
|
|
||||||
maxCells[proci] = maxProci;
|
|
||||||
maxCs[proci] = mesh_.C()[maxProci];
|
|
||||||
|
|
||||||
forAll(magFieldBoundary, patchi)
|
|
||||||
{
|
|
||||||
const scalarField& mfp = magFieldBoundary[patchi];
|
|
||||||
if (mfp.size())
|
|
||||||
{
|
|
||||||
const vectorField& Cfp = CfBoundary[patchi];
|
|
||||||
|
|
||||||
const labelList& faceCells =
|
|
||||||
magFieldBoundary[patchi].patch().faceCells();
|
|
||||||
|
|
||||||
label minPI = findMin(mfp);
|
|
||||||
if (mfp[minPI] < minVs[proci])
|
|
||||||
{
|
|
||||||
minVs[proci] = mfp[minPI];
|
|
||||||
minCells[proci] = faceCells[minPI];
|
|
||||||
minCs[proci] = Cfp[minPI];
|
|
||||||
}
|
|
||||||
|
|
||||||
label maxPI = findMax(mfp);
|
|
||||||
if (mfp[maxPI] > maxVs[proci])
|
|
||||||
{
|
|
||||||
maxVs[proci] = mfp[maxPI];
|
|
||||||
maxCells[proci] = faceCells[maxPI];
|
|
||||||
maxCs[proci] = Cfp[maxPI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::gatherList(minVs);
|
|
||||||
Pstream::gatherList(minCells);
|
|
||||||
Pstream::gatherList(minCs);
|
|
||||||
|
|
||||||
Pstream::gatherList(maxVs);
|
|
||||||
Pstream::gatherList(maxCells);
|
|
||||||
Pstream::gatherList(maxCs);
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
const label minI = findMin(minVs);
|
|
||||||
const scalar minValue = minVs[minI];
|
|
||||||
const label minCell = minCells[minI];
|
|
||||||
const vector& minC = minCs[minI];
|
|
||||||
|
|
||||||
const label maxI = findMax(maxVs);
|
|
||||||
const scalar maxValue = maxVs[maxI];
|
|
||||||
const label maxCell = maxCells[maxI];
|
|
||||||
const vector& maxC = maxCs[maxI];
|
|
||||||
|
|
||||||
output
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
word("mag(" + fieldName + ")"),
|
|
||||||
minCell,
|
|
||||||
maxCell,
|
|
||||||
minC,
|
|
||||||
maxC,
|
|
||||||
minI,
|
|
||||||
maxI,
|
|
||||||
minValue,
|
|
||||||
maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case modeType::cmpt:
|
|
||||||
{
|
|
||||||
const typename fieldType::Boundary&
|
|
||||||
fieldBoundary = field.boundaryField();
|
|
||||||
|
|
||||||
List<Type> minVs(Pstream::nProcs());
|
|
||||||
labelList minCells(Pstream::nProcs());
|
|
||||||
List<vector> minCs(Pstream::nProcs());
|
|
||||||
label minProci = findMin(field);
|
|
||||||
minVs[proci] = field[minProci];
|
|
||||||
minCells[proci] = minProci;
|
|
||||||
minCs[proci] = mesh_.C()[minProci];
|
|
||||||
|
|
||||||
List<Type> maxVs(Pstream::nProcs());
|
|
||||||
labelList maxCells(Pstream::nProcs());
|
|
||||||
List<vector> maxCs(Pstream::nProcs());
|
|
||||||
label maxProci = findMax(field);
|
|
||||||
maxVs[proci] = field[maxProci];
|
|
||||||
maxCells[proci] = maxProci;
|
|
||||||
maxCs[proci] = mesh_.C()[maxProci];
|
|
||||||
|
|
||||||
forAll(fieldBoundary, patchi)
|
|
||||||
{
|
|
||||||
const Field<Type>& fp = fieldBoundary[patchi];
|
|
||||||
|
|
||||||
if (fp.size())
|
|
||||||
{
|
|
||||||
const vectorField& Cfp = CfBoundary[patchi];
|
|
||||||
|
|
||||||
const labelList& faceCells =
|
|
||||||
fieldBoundary[patchi].patch().faceCells();
|
|
||||||
|
|
||||||
label minPI = findMin(fp);
|
|
||||||
if (fp[minPI] < minVs[proci])
|
|
||||||
{
|
|
||||||
minVs[proci] = fp[minPI];
|
|
||||||
minCells[proci] = faceCells[minPI];
|
|
||||||
minCs[proci] = Cfp[minPI];
|
|
||||||
}
|
|
||||||
|
|
||||||
label maxPI = findMax(fp);
|
|
||||||
if (fp[maxPI] > maxVs[proci])
|
|
||||||
{
|
|
||||||
maxVs[proci] = fp[maxPI];
|
|
||||||
maxCells[proci] = faceCells[maxPI];
|
|
||||||
maxCs[proci] = Cfp[maxPI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::gatherList(minVs);
|
|
||||||
Pstream::gatherList(minCells);
|
|
||||||
Pstream::gatherList(minCs);
|
|
||||||
|
|
||||||
Pstream::gatherList(maxVs);
|
|
||||||
Pstream::gatherList(maxCells);
|
|
||||||
Pstream::gatherList(maxCs);
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
label minI = findMin(minVs);
|
|
||||||
Type minValue = minVs[minI];
|
|
||||||
const label minCell = minCells[minI];
|
|
||||||
const vector& minC = minCs[minI];
|
|
||||||
|
|
||||||
label maxI = findMax(maxVs);
|
|
||||||
Type maxValue = maxVs[maxI];
|
|
||||||
const label maxCell = maxCells[maxI];
|
|
||||||
const vector& maxC = maxCs[maxI];
|
|
||||||
|
|
||||||
output
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
fieldName,
|
|
||||||
minCell,
|
|
||||||
maxCell,
|
|
||||||
minC,
|
|
||||||
maxC,
|
|
||||||
minI,
|
|
||||||
maxI,
|
|
||||||
minValue,
|
|
||||||
maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Unknown min/max mode: " << modeTypeNames_[mode_]
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -63,23 +63,22 @@ template<>
|
|||||||
const char* Foam::NamedEnum
|
const char* Foam::NamedEnum
|
||||||
<
|
<
|
||||||
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
|
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
|
||||||
17
|
16
|
||||||
>::names[] =
|
>::names[] =
|
||||||
{
|
{
|
||||||
"none",
|
"none",
|
||||||
"sum",
|
"sum",
|
||||||
"weightedSum",
|
|
||||||
"sumMag",
|
"sumMag",
|
||||||
"sumDirection",
|
"sumDirection",
|
||||||
"sumDirectionBalance",
|
"sumDirectionBalance",
|
||||||
|
"orientedSum",
|
||||||
"average",
|
"average",
|
||||||
"weightedAverage",
|
|
||||||
"areaAverage",
|
"areaAverage",
|
||||||
"weightedAreaAverage",
|
|
||||||
"areaIntegrate",
|
"areaIntegrate",
|
||||||
"weightedAreaIntegrate",
|
|
||||||
"min",
|
"min",
|
||||||
"max",
|
"max",
|
||||||
|
"minMag",
|
||||||
|
"maxMag",
|
||||||
"CoV",
|
"CoV",
|
||||||
"areaNormalAverage",
|
"areaNormalAverage",
|
||||||
"areaNormalIntegrate"
|
"areaNormalIntegrate"
|
||||||
@ -94,7 +93,7 @@ const Foam::NamedEnum
|
|||||||
const Foam::NamedEnum
|
const Foam::NamedEnum
|
||||||
<
|
<
|
||||||
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
|
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
|
||||||
17
|
16
|
||||||
> Foam::functionObjects::fieldValues::surfaceFieldValue::operationTypeNames_;
|
> Foam::functionObjects::fieldValues::surfaceFieldValue::operationTypeNames_;
|
||||||
|
|
||||||
|
|
||||||
@ -366,7 +365,7 @@ combineSurfaceGeometry
|
|||||||
pointField& points
|
pointField& points
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (surfacePtr_.valid())
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
{
|
{
|
||||||
const sampledSurface& s = surfacePtr_();
|
const sampledSurface& s = surfacePtr_();
|
||||||
|
|
||||||
@ -402,18 +401,14 @@ combineSurfaceGeometry
|
|||||||
Foam::scalar
|
Foam::scalar
|
||||||
Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const
|
Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const
|
||||||
{
|
{
|
||||||
scalar totalArea;
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
|
|
||||||
if (surfacePtr_.valid())
|
|
||||||
{
|
{
|
||||||
totalArea = gSum(surfacePtr_().magSf());
|
return gSum(surfacePtr_().magSf());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
totalArea = gSum(filterField(mesh_.magSf(), false));
|
return gSum(filterField(mesh_.magSf()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalArea;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -462,7 +457,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
|
|||||||
<< " Region has no faces" << exit(FatalError);
|
<< " Region has no faces" << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surfacePtr_.valid())
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
{
|
{
|
||||||
surfacePtr_().update();
|
surfacePtr_().update();
|
||||||
}
|
}
|
||||||
@ -475,42 +470,18 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
|
|||||||
<< " total area = " << totalArea_
|
<< " total area = " << totalArea_
|
||||||
<< nl;
|
<< nl;
|
||||||
|
|
||||||
if (dict.readIfPresent("orientedWeightField", weightFieldName_))
|
if (dict.readIfPresent("weightFields", weightFieldNames_))
|
||||||
{
|
{
|
||||||
Info<< " orientedWeightField = " << weightFieldName_ << nl;
|
Info<< name() << " " << operationTypeNames_[operation_]
|
||||||
orientWeightField_ = true;
|
<< " weight fields " << weightFieldNames_;
|
||||||
|
|
||||||
if (regionType_ == regionTypes::sampledSurface)
|
|
||||||
{
|
|
||||||
FatalIOErrorInFunction(dict)
|
|
||||||
<< "Cannot use orientedWeightField for a sampledSurface"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dict.found("weightField"))
|
|
||||||
{
|
|
||||||
FatalIOErrorInFunction(dict)
|
|
||||||
<< "Either provide weightField or orientedWeightField"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (dict.readIfPresent("weightField", weightFieldName_))
|
else if (dict.found("weightField"))
|
||||||
{
|
{
|
||||||
Info<< " weightField = " << weightFieldName_ << nl;
|
weightFieldNames_.setSize(1);
|
||||||
|
dict.lookup("weightField") >> weightFieldNames_[0];
|
||||||
|
|
||||||
if (regionType_ == regionTypes::sampledSurface)
|
Info<< name() << " " << operationTypeNames_[operation_]
|
||||||
{
|
<< " weight field " << weightFieldNames_[0];
|
||||||
FatalIOErrorInFunction(dict)
|
|
||||||
<< "Cannot use weightField for a sampledSurface"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<word> orientedFields;
|
|
||||||
if (dict.readIfPresent("orientedFields", orientedFields))
|
|
||||||
{
|
|
||||||
orientedFieldsStart_ = fields_.size();
|
|
||||||
fields_.append(orientedFields);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict.readIfPresent("scaleFactor", scaleFactor_))
|
if (dict.readIfPresent("scaleFactor", scaleFactor_))
|
||||||
@ -567,8 +538,9 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||||
(
|
(
|
||||||
const Field<scalar>& values,
|
const Field<scalar>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
scalar& result
|
scalar& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -576,21 +548,28 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
|||||||
{
|
{
|
||||||
case operationType::sumDirection:
|
case operationType::sumDirection:
|
||||||
{
|
{
|
||||||
vector n(dict_.lookup("direction"));
|
const vector n(dict_.lookup("direction"));
|
||||||
result = sum(pos0(values*(Sf & n))*mag(values));
|
result = gSum(weights*pos0(values*(Sf & n))*mag(values));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::sumDirectionBalance:
|
case operationType::sumDirectionBalance:
|
||||||
{
|
{
|
||||||
vector n(dict_.lookup("direction"));
|
const vector n(dict_.lookup("direction"));
|
||||||
const scalarField nv(values*(Sf & n));
|
const scalarField nv(values*(Sf & n));
|
||||||
result = sum(pos0(nv)*mag(values) - neg(nv)*mag(values));
|
result = gSum(weights*(pos0(nv)*mag(values) - neg(nv)*mag(values)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Fall through to same-type operations
|
// Fall through to same-type operations
|
||||||
return processValuesTypeType(values, Sf, weightField, result);
|
return processValuesTypeType
|
||||||
|
(
|
||||||
|
values,
|
||||||
|
signs,
|
||||||
|
weights,
|
||||||
|
Sf,
|
||||||
|
result
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,8 +578,9 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||||
(
|
(
|
||||||
const Field<vector>& values,
|
const Field<vector>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
scalar& result
|
scalar& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -608,12 +588,12 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
|||||||
{
|
{
|
||||||
case operationType::areaNormalAverage:
|
case operationType::areaNormalAverage:
|
||||||
{
|
{
|
||||||
result = sum(values & Sf)/sum(mag(Sf));
|
result = gSum(weights*values & Sf)/gSum(mag(weights*Sf));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::areaNormalIntegrate:
|
case operationType::areaNormalIntegrate:
|
||||||
{
|
{
|
||||||
result = sum(values & Sf);
|
result = gSum(weights*values & Sf);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -627,8 +607,9 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||||
(
|
(
|
||||||
const Field<vector>& values,
|
const Field<vector>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
vector& result
|
vector& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -636,24 +617,29 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
|||||||
{
|
{
|
||||||
case operationType::sumDirection:
|
case operationType::sumDirection:
|
||||||
{
|
{
|
||||||
vector n(dict_.lookup("direction"));
|
const vector n = normalised(dict_.lookup<vector>("direction"));
|
||||||
n /= mag(n) + rootVSmall;
|
|
||||||
const scalarField nv(n & values);
|
const scalarField nv(n & values);
|
||||||
result = sum(pos0(nv)*n*(nv));
|
result = gSum(weights*pos0(nv)*n*(nv));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::sumDirectionBalance:
|
case operationType::sumDirectionBalance:
|
||||||
{
|
{
|
||||||
vector n(dict_.lookup("direction"));
|
const vector n = normalised(dict_.lookup<vector>("direction"));
|
||||||
n /= mag(n) + rootVSmall;
|
|
||||||
const scalarField nv(n & values);
|
const scalarField nv(n & values);
|
||||||
result = sum(pos0(nv)*n*(nv));
|
result = gSum(weights*pos0(nv)*n*(nv));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Fall through to same-type operations
|
// Fall through to same-type operations
|
||||||
return processValuesTypeType(values, Sf, weightField, result);
|
return processValuesTypeType
|
||||||
|
(
|
||||||
|
values,
|
||||||
|
signs,
|
||||||
|
weights,
|
||||||
|
Sf,
|
||||||
|
result
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -672,10 +658,8 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
|||||||
surfaceWriterPtr_(nullptr),
|
surfaceWriterPtr_(nullptr),
|
||||||
regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
|
regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
|
||||||
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
||||||
weightFieldName_("none"),
|
weightFieldNames_(),
|
||||||
orientWeightField_(false),
|
scaleFactor_(1),
|
||||||
orientedFieldsStart_(labelMax),
|
|
||||||
scaleFactor_(1.0),
|
|
||||||
writeArea_(dict.lookupOrDefault("writeArea", false)),
|
writeArea_(dict.lookupOrDefault("writeArea", false)),
|
||||||
nFaces_(0),
|
nFaces_(0),
|
||||||
faceId_(),
|
faceId_(),
|
||||||
@ -696,10 +680,8 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
|||||||
surfaceWriterPtr_(nullptr),
|
surfaceWriterPtr_(nullptr),
|
||||||
regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
|
regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
|
||||||
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
||||||
weightFieldName_("none"),
|
weightFieldNames_(),
|
||||||
orientWeightField_(false),
|
scaleFactor_(1),
|
||||||
orientedFieldsStart_(labelMax),
|
|
||||||
scaleFactor_(1.0),
|
|
||||||
writeArea_(dict.lookupOrDefault("writeArea", false)),
|
writeArea_(dict.lookupOrDefault("writeArea", false)),
|
||||||
nFaces_(0),
|
nFaces_(0),
|
||||||
faceId_(),
|
faceId_(),
|
||||||
@ -737,7 +719,7 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
|
|||||||
fieldValue::write();
|
fieldValue::write();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surfacePtr_.valid())
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
{
|
{
|
||||||
surfacePtr_().update();
|
surfacePtr_().update();
|
||||||
}
|
}
|
||||||
@ -758,12 +740,12 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write the surface geometry
|
// Write the surface geometry
|
||||||
if (surfaceWriterPtr_.valid())
|
if (writeFields_)
|
||||||
{
|
{
|
||||||
faceList faces;
|
faceList faces;
|
||||||
pointField points;
|
pointField points;
|
||||||
|
|
||||||
if (surfacePtr_.valid())
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
{
|
{
|
||||||
combineSurfaceGeometry(faces, points);
|
combineSurfaceGeometry(faces, points);
|
||||||
}
|
}
|
||||||
@ -784,21 +766,24 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct weight field. Note: zero size means weight = 1
|
// Construct the sign and weight fields and the surface normals
|
||||||
scalarField weightField;
|
const scalarField signs
|
||||||
if (weightFieldName_ != "none")
|
(
|
||||||
|
regionType_ == regionTypes::sampledSurface
|
||||||
|
? scalarField(surfacePtr_().Sf().size(), 1)
|
||||||
|
: List<scalar>(faceSign_)
|
||||||
|
);
|
||||||
|
scalarField weights(signs.size(), 1);
|
||||||
|
forAll(weightFieldNames_, i)
|
||||||
{
|
{
|
||||||
weightField =
|
weights *= getFieldValues<scalar>(weightFieldNames_[i]);
|
||||||
getFieldValues<scalar>
|
|
||||||
(
|
|
||||||
weightFieldName_,
|
|
||||||
true,
|
|
||||||
orientWeightField_
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
const vectorField Sf
|
||||||
// Combine onto master
|
(
|
||||||
combineFields(weightField);
|
regionType_ == regionTypes::sampledSurface
|
||||||
|
? surfacePtr_().Sf()
|
||||||
|
: (signs*filterField(mesh_.Sf()))()
|
||||||
|
);
|
||||||
|
|
||||||
// Process the fields
|
// Process the fields
|
||||||
forAll(fields_, i)
|
forAll(fields_, i)
|
||||||
@ -806,12 +791,18 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
|
|||||||
const word& fieldName = fields_[i];
|
const word& fieldName = fields_[i];
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
bool orient = i >= orientedFieldsStart_;
|
#define writeValuesFieldType(fieldType, none) \
|
||||||
ok = ok || writeValues<scalar>(fieldName, weightField, orient);
|
ok = \
|
||||||
ok = ok || writeValues<vector>(fieldName, weightField, orient);
|
ok \
|
||||||
ok = ok || writeValues<sphericalTensor>(fieldName, weightField, orient);
|
|| writeValues<fieldType> \
|
||||||
ok = ok || writeValues<symmTensor>(fieldName, weightField, orient);
|
( \
|
||||||
ok = ok || writeValues<tensor>(fieldName, weightField, orient);
|
fieldName, \
|
||||||
|
signs, \
|
||||||
|
weights, \
|
||||||
|
Sf \
|
||||||
|
);
|
||||||
|
FOR_ALL_FIELD_TYPES(writeValuesFieldType);
|
||||||
|
#undef writeValuesFieldType
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -32,7 +32,7 @@ Description
|
|||||||
averages and integrations.
|
averages and integrations.
|
||||||
|
|
||||||
For example, to calculate the volumetric or mass flux across a patch,
|
For example, to calculate the volumetric or mass flux across a patch,
|
||||||
apply the 'sum' operator to the flux field (typically \c phi)
|
apply the 'orientedSum' operator to the flux field (typically \c phi)
|
||||||
|
|
||||||
Examples of function object specification:
|
Examples of function object specification:
|
||||||
\verbatim
|
\verbatim
|
||||||
@ -96,10 +96,9 @@ Usage
|
|||||||
name | name of face regionType if required | no |
|
name | name of face regionType 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 |
|
||||||
orientedWeightField | name of oriented field to apply weighting | no |
|
weightFields | Names of fields to apply weighting | no |
|
||||||
scaleFactor | scale factor | no | 1
|
scaleFactor | scale factor | no | 1
|
||||||
fields | list of fields to operate on | yes |
|
fields | list of fields to operate on | yes |
|
||||||
orientedFields | list of oriented fields to operate on | no |
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Where \c regionType is defined by
|
Where \c regionType is defined by
|
||||||
@ -113,41 +112,38 @@ Usage
|
|||||||
\plaintable
|
\plaintable
|
||||||
none | no operation
|
none | no operation
|
||||||
sum | sum
|
sum | sum
|
||||||
weightedSum | weighted sum
|
|
||||||
sumMag | sum of component magnitudes
|
sumMag | sum of component magnitudes
|
||||||
sumDirection | sum values which are positive in given direction
|
sumDirection | sum values which are positive in given direction
|
||||||
sumDirectionBalance | sum of balance of values in given direction
|
sumDirectionBalance | sum of balance of values in given direction
|
||||||
|
orientedSum | sum with face orientations
|
||||||
average | ensemble average
|
average | ensemble average
|
||||||
weightedAverage | weighted average
|
|
||||||
areaAverage | area weighted average
|
areaAverage | area weighted average
|
||||||
weightedAreaAverage | weighted area average
|
|
||||||
areaIntegrate | area integral
|
areaIntegrate | area integral
|
||||||
weightedAreaIntegrate | weighted area integral
|
|
||||||
min | minimum
|
min | minimum
|
||||||
max | maximum
|
max | maximum
|
||||||
|
minMag | minimum magnitude
|
||||||
|
maxMag | maximum magnitude
|
||||||
CoV | coefficient of variation: standard deviation/mean
|
CoV | coefficient of variation: standard deviation/mean
|
||||||
areaNormalAverage| area weighted average in face normal direction
|
areaNormalAverage | area weighted average in face normal direction
|
||||||
areaNormalIntegrate | area weighted integral in face normal directon
|
areaNormalIntegrate | area weighted integral in face normal direction
|
||||||
\endplaintable
|
\endplaintable
|
||||||
|
|
||||||
Note
|
Note
|
||||||
- The values reported by the areaNormalAverage and areaNormalIntegrate
|
- Faces on empty patches get ignored.
|
||||||
operations are written as the first component of a field with the same
|
- The `oriented' operations will flip the sign of the field so that all the
|
||||||
rank as the input field.
|
normals point in a consistent direction. This is only of relevance when
|
||||||
- faces on empty patches get ignored
|
summing mesh-oriented fields, such as the flux, on faceZones.
|
||||||
- if the field is a volField the \c faceZone can only consist of boundary
|
- If the field is a volField then a \c faceZone can only consist of
|
||||||
|
boundary faces, because only these faces have a value associated with
|
||||||
|
them. No cell-to-face interpolation is performed.
|
||||||
|
- If the field is a surfaceField then the region cannot be a \c
|
||||||
|
sampledSurface
|
||||||
|
- If a sampledSurface has interpolation set to false then the surface
|
||||||
|
face values will be taken directly from the cell that contains the
|
||||||
|
surface face centre
|
||||||
|
- If a \c sampledSurface has interpolation set to true then the field
|
||||||
|
will be interpolated to the vertices, then averaged onto the surface
|
||||||
faces
|
faces
|
||||||
- the `oriented' entries relate to mesh-oriented fields, such as the
|
|
||||||
flux, phi. These fields will be oriented according to the face normals.
|
|
||||||
- using \c sampledSurface:
|
|
||||||
- not available for surface fields
|
|
||||||
- if interpolate=true they use \c interpolationCellPoint
|
|
||||||
otherwise they use cell values
|
|
||||||
- each triangle in \c sampledSurface is logically only in one cell
|
|
||||||
so interpolation will be wrong when triangles are larger than
|
|
||||||
cells. This can only happen for sampling on a \c triSurfaceMesh
|
|
||||||
- take care when using isoSurfaces - these might have duplicate
|
|
||||||
triangles and so integration might be wrong
|
|
||||||
|
|
||||||
See also
|
See also
|
||||||
Foam::fieldValues
|
Foam::fieldValues
|
||||||
@ -208,25 +204,24 @@ public:
|
|||||||
{
|
{
|
||||||
none,
|
none,
|
||||||
sum,
|
sum,
|
||||||
weightedSum,
|
|
||||||
sumMag,
|
sumMag,
|
||||||
sumDirection,
|
sumDirection,
|
||||||
sumDirectionBalance,
|
sumDirectionBalance,
|
||||||
|
orientedSum,
|
||||||
average,
|
average,
|
||||||
weightedAverage,
|
|
||||||
areaAverage,
|
areaAverage,
|
||||||
weightedAreaAverage,
|
|
||||||
areaIntegrate,
|
areaIntegrate,
|
||||||
weightedAreaIntegrate,
|
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
|
minMag,
|
||||||
|
maxMag,
|
||||||
CoV,
|
CoV,
|
||||||
areaNormalAverage,
|
areaNormalAverage,
|
||||||
areaNormalIntegrate
|
areaNormalIntegrate
|
||||||
};
|
};
|
||||||
|
|
||||||
//- Operation type names
|
//- Operation type names
|
||||||
static const NamedEnum<operationType, 17> operationTypeNames_;
|
static const NamedEnum<operationType, 16> operationTypeNames_;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -273,14 +268,8 @@ protected:
|
|||||||
//- Operation to apply to values
|
//- Operation to apply to values
|
||||||
operationType operation_;
|
operationType operation_;
|
||||||
|
|
||||||
//- Weight field name - optional
|
//- Weight field names - optional
|
||||||
word weightFieldName_;
|
wordList weightFieldNames_;
|
||||||
|
|
||||||
//- Flag to indicate if flipMap should be applied to the weight field
|
|
||||||
bool orientWeightField_;
|
|
||||||
|
|
||||||
//- Start index of fields that require application of flipMap
|
|
||||||
label orientedFieldsStart_;
|
|
||||||
|
|
||||||
//- Scale factor - optional
|
//- Scale factor - optional
|
||||||
scalar scaleFactor_;
|
scalar scaleFactor_;
|
||||||
@ -325,12 +314,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>> getFieldValues(const word& fieldName) const;
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const bool mustGet = false,
|
|
||||||
const bool applyOrientation = false
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Apply the operation to the values, and return true if successful.
|
//- Apply the operation to the values, and return true if successful.
|
||||||
// Does nothing unless overloaded below.
|
// Does nothing unless overloaded below.
|
||||||
@ -338,8 +322,9 @@ protected:
|
|||||||
bool processValues
|
bool processValues
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
ResultType& result
|
ResultType& result
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -349,19 +334,32 @@ protected:
|
|||||||
bool processValues
|
bool processValues
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
Type& result
|
Type& result
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Apply Type -> scalar operation to the values
|
||||||
|
template<class Type>
|
||||||
|
bool processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
|
const vectorField& Sf,
|
||||||
|
scalar& result
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Apply scalar -> scalar operation to the values. Tries to apply
|
//- Apply scalar -> scalar operation to the values. Tries to apply
|
||||||
// scalar -> scalar specific operations, otherwise calls
|
// scalar -> scalar specific operations, otherwise calls
|
||||||
// processValuesTypeType.
|
// processValuesTypeType.
|
||||||
bool processValues
|
bool processValues
|
||||||
(
|
(
|
||||||
const Field<scalar>& values,
|
const Field<scalar>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
scalar& result
|
scalar& result
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -369,8 +367,9 @@ protected:
|
|||||||
bool processValues
|
bool processValues
|
||||||
(
|
(
|
||||||
const Field<vector>& values,
|
const Field<vector>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
scalar& result
|
scalar& result
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -380,8 +379,9 @@ protected:
|
|||||||
bool processValues
|
bool processValues
|
||||||
(
|
(
|
||||||
const Field<vector>& values,
|
const Field<vector>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
vector& result
|
vector& result
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -390,8 +390,9 @@ protected:
|
|||||||
bool processValuesTypeType
|
bool processValuesTypeType
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
Type& result
|
Type& result
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -450,8 +451,9 @@ public:
|
|||||||
bool writeValues
|
bool writeValues
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName,
|
||||||
const scalarField& weightField,
|
const scalarField& signs,
|
||||||
const bool orient
|
const scalarField& weights,
|
||||||
|
const vectorField& Sf
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Templated helper function to output field values
|
//- Templated helper function to output field values
|
||||||
@ -459,8 +461,9 @@ public:
|
|||||||
bool writeValues
|
bool writeValues
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName,
|
||||||
const scalarField& weightField,
|
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf
|
const vectorField& Sf
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -468,16 +471,14 @@ public:
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>> filterField
|
tmp<Field<Type>> filterField
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
|
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
|
||||||
const bool applyOrientation
|
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Filter a volume field according to faceIds
|
//- Filter a volume field according to faceIds
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>> filterField
|
tmp<Field<Type>> filterField
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
const GeometricField<Type, fvPatchField, volMesh>& field
|
||||||
const bool applyOrientation
|
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Read from dictionary
|
//- Read from dictionary
|
||||||
|
|||||||
@ -62,42 +62,29 @@ template<class Type>
|
|||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName
|
||||||
const bool mustGet,
|
|
||||||
const bool applyOrientation
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
|
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> vf;
|
typedef GeometricField<Type, fvPatchField, volMesh> vf;
|
||||||
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
|
||||||
|
|
||||||
if
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
(
|
|
||||||
regionType_ != regionTypes::sampledSurface
|
|
||||||
&& obr_.foundObject<sf>(fieldName)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return filterField(obr_.lookupObject<sf>(fieldName), applyOrientation);
|
if (obr_.foundObject<vf>(fieldName))
|
||||||
}
|
|
||||||
else if (obr_.foundObject<vf>(fieldName))
|
|
||||||
{
|
|
||||||
const vf& fld = obr_.lookupObject<vf>(fieldName);
|
|
||||||
|
|
||||||
if (surfacePtr_.valid())
|
|
||||||
{
|
{
|
||||||
|
const vf& fld = obr_.lookupObject<vf>(fieldName);
|
||||||
|
|
||||||
if (surfacePtr_().interpolate())
|
if (surfacePtr_().interpolate())
|
||||||
{
|
{
|
||||||
|
// Interpolate the field to the surface points
|
||||||
const interpolationCellPoint<Type> interp(fld);
|
const interpolationCellPoint<Type> interp(fld);
|
||||||
tmp<Field<Type>> tintFld(surfacePtr_().interpolate(interp));
|
tmp<Field<Type>> tintFld(surfacePtr_().interpolate(interp));
|
||||||
const Field<Type>& intFld = tintFld();
|
const Field<Type>& intFld = tintFld();
|
||||||
|
|
||||||
// Average
|
// Average the interpolated field onto the surface faces
|
||||||
const faceList& faces = surfacePtr_().faces();
|
const faceList& faces = surfacePtr_().faces();
|
||||||
tmp<Field<Type>> tavg
|
tmp<Field<Type>> tavg(new Field<Type>(faces.size(), Zero));
|
||||||
(
|
|
||||||
new Field<Type>(faces.size(), Zero)
|
|
||||||
);
|
|
||||||
Field<Type>& avg = tavg.ref();
|
Field<Type>& avg = tavg.ref();
|
||||||
|
|
||||||
forAll(faces, facei)
|
forAll(faces, facei)
|
||||||
{
|
{
|
||||||
const face& f = faces[facei];
|
const face& f = faces[facei];
|
||||||
@ -115,20 +102,34 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
|||||||
return surfacePtr_().sample(fld);
|
return surfacePtr_().sample(fld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (obr_.foundObject<sf>(fieldName))
|
||||||
{
|
{
|
||||||
return filterField(fld, applyOrientation);
|
FatalErrorInFunction
|
||||||
|
<< "Surface field " << fieldName
|
||||||
|
<< " cannot be sampled onto surface " << surfacePtr_().name()
|
||||||
|
<< ". Only vol fields can be sampled onto surfaces."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (obr_.foundObject<vf>(fieldName))
|
||||||
|
{
|
||||||
|
const vf& fld = obr_.lookupObject<vf>(fieldName);
|
||||||
|
return filterField(fld);
|
||||||
|
}
|
||||||
|
else if (obr_.foundObject<sf>(fieldName))
|
||||||
|
{
|
||||||
|
const sf& fld = obr_.lookupObject<sf>(fieldName);
|
||||||
|
return filterField(fld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mustGet)
|
FatalErrorInFunction
|
||||||
{
|
<< "Field " << fieldName << " not found in database"
|
||||||
FatalErrorInFunction
|
<< abort(FatalError);
|
||||||
<< "Field " << fieldName << " not found in database"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmp<Field<Type>>(new Field<Type>(0));
|
return tmp<Field<Type>>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -136,8 +137,9 @@ template<class Type, class ResultType>
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
ResultType& result
|
ResultType& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -149,12 +151,43 @@ template<class Type>
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
Type& result
|
Type& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return processValuesTypeType(values, Sf, weightField, result);
|
return processValuesTypeType(values, signs, weights, Sf, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
|
const vectorField& Sf,
|
||||||
|
scalar& result
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
switch (operation_)
|
||||||
|
{
|
||||||
|
case operationType::minMag:
|
||||||
|
{
|
||||||
|
result = gMin(mag(values));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case operationType::maxMag:
|
||||||
|
{
|
||||||
|
result = gMax(mag(values));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -163,8 +196,9 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::
|
|||||||
processValuesTypeType
|
processValuesTypeType
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf,
|
const vectorField& Sf,
|
||||||
const scalarField& weightField,
|
|
||||||
Type& result
|
Type& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -172,104 +206,55 @@ processValuesTypeType
|
|||||||
{
|
{
|
||||||
case operationType::sum:
|
case operationType::sum:
|
||||||
{
|
{
|
||||||
result = sum(values);
|
result = gSum(weights*values);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case operationType::weightedSum:
|
|
||||||
{
|
|
||||||
if (weightField.size())
|
|
||||||
{
|
|
||||||
result = sum(weightField*values);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = sum(values);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::sumMag:
|
case operationType::sumMag:
|
||||||
{
|
{
|
||||||
result = sum(cmptMag(values));
|
result = gSum(weights*cmptMag(values));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case operationType::orientedSum:
|
||||||
|
{
|
||||||
|
result = gSum(signs*weights*values);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::average:
|
case operationType::average:
|
||||||
{
|
{
|
||||||
result = sum(values)/values.size();
|
result =
|
||||||
return true;
|
gSum(weights*values)
|
||||||
}
|
/stabilise(gSum(weights), vSmall);
|
||||||
case operationType::weightedAverage:
|
|
||||||
{
|
|
||||||
if (weightField.size())
|
|
||||||
{
|
|
||||||
result =
|
|
||||||
sum(weightField*values)
|
|
||||||
/stabilise(sum(weightField), vSmall);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = sum(values)/values.size();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::areaAverage:
|
case operationType::areaAverage:
|
||||||
{
|
{
|
||||||
const scalarField magSf(mag(Sf));
|
const scalarField magSf(mag(Sf));
|
||||||
|
result =
|
||||||
result = sum(magSf*values)/sum(magSf);
|
gSum(weights*magSf*values)
|
||||||
return true;
|
/stabilise(gSum(weights*magSf), vSmall);
|
||||||
}
|
|
||||||
case operationType::weightedAreaAverage:
|
|
||||||
{
|
|
||||||
const scalarField magSf(mag(Sf));
|
|
||||||
|
|
||||||
if (weightField.size())
|
|
||||||
{
|
|
||||||
result =
|
|
||||||
sum(weightField*magSf*values)
|
|
||||||
/stabilise(sum(magSf*weightField), vSmall);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = sum(magSf*values)/sum(magSf);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::areaIntegrate:
|
case operationType::areaIntegrate:
|
||||||
{
|
{
|
||||||
const scalarField magSf(mag(Sf));
|
const scalarField magSf(mag(Sf));
|
||||||
|
result = gSum(weights*magSf*values);
|
||||||
result = sum(magSf*values);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case operationType::weightedAreaIntegrate:
|
|
||||||
{
|
|
||||||
const scalarField magSf(mag(Sf));
|
|
||||||
|
|
||||||
if (weightField.size())
|
|
||||||
{
|
|
||||||
result = sum(weightField*magSf*values);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = sum(magSf*values);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::min:
|
case operationType::min:
|
||||||
{
|
{
|
||||||
result = min(values);
|
result = gMin(values);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::max:
|
case operationType::max:
|
||||||
{
|
{
|
||||||
result = max(values);
|
result = gMax(values);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::CoV:
|
case operationType::CoV:
|
||||||
{
|
{
|
||||||
const scalarField magSf(mag(Sf));
|
const scalarField magSf(mag(Sf));
|
||||||
|
|
||||||
Type meanValue = sum(values*magSf)/sum(magSf);
|
Type meanValue = gSum(values*magSf)/gSum(magSf);
|
||||||
|
|
||||||
const label nComp = pTraits<Type>::nComponents;
|
const label nComp = pTraits<Type>::nComponents;
|
||||||
|
|
||||||
@ -279,7 +264,7 @@ processValuesTypeType
|
|||||||
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))/gSum(magSf))/mean;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -302,39 +287,25 @@ template<class Type>
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName,
|
||||||
const scalarField& weightField,
|
const scalarField& signs,
|
||||||
const bool orient
|
const scalarField& weights,
|
||||||
|
const vectorField& Sf
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const bool ok = validField<Type>(fieldName);
|
const bool ok = validField<Type>(fieldName);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
Field<Type> values(getFieldValues<Type>(fieldName, true, orient));
|
// Get the values
|
||||||
|
Field<Type> values(getFieldValues<Type>(fieldName));
|
||||||
vectorField Sf;
|
|
||||||
if (surfacePtr_.valid())
|
|
||||||
{
|
|
||||||
// Get oriented Sf
|
|
||||||
Sf = surfacePtr_().Sf();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get oriented Sf
|
|
||||||
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 (writeFields_)
|
||||||
{
|
{
|
||||||
faceList faces;
|
faceList faces;
|
||||||
pointField points;
|
pointField points;
|
||||||
|
|
||||||
if (surfacePtr_.valid())
|
if (regionType_ == regionTypes::sampledSurface)
|
||||||
{
|
{
|
||||||
combineSurfaceGeometry(faces, points);
|
combineSurfaceGeometry(faces, points);
|
||||||
}
|
}
|
||||||
@ -343,6 +314,9 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
|||||||
combineMeshGeometry(faces, points);
|
combineMeshGeometry(faces, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Field<Type> writeValues(weights*values);
|
||||||
|
combineFields(writeValues);
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
surfaceWriterPtr_->write
|
surfaceWriterPtr_->write
|
||||||
@ -352,39 +326,41 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
|||||||
points,
|
points,
|
||||||
faces,
|
faces,
|
||||||
fieldName,
|
fieldName,
|
||||||
values,
|
writeValues,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do the operation
|
||||||
if (operation_ != operationType::none)
|
if (operation_ != operationType::none)
|
||||||
{
|
{
|
||||||
// Apply scale factor
|
// Apply scale factor
|
||||||
values *= scaleFactor_;
|
values *= scaleFactor_;
|
||||||
|
|
||||||
if (Pstream::master())
|
bool ok = false;
|
||||||
|
|
||||||
|
#define writeValuesFieldType(fieldType, none) \
|
||||||
|
ok = \
|
||||||
|
ok \
|
||||||
|
|| writeValues<Type, fieldType> \
|
||||||
|
( \
|
||||||
|
fieldName, \
|
||||||
|
values, \
|
||||||
|
signs, \
|
||||||
|
weights, \
|
||||||
|
Sf \
|
||||||
|
);
|
||||||
|
FOR_ALL_FIELD_TYPES(writeValuesFieldType);
|
||||||
|
#undef writeValuesFieldType
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
{
|
{
|
||||||
if
|
FatalErrorInFunction
|
||||||
(
|
<< "Operation " << operationTypeNames_[operation_]
|
||||||
!writeValues<Type, scalar>
|
<< " not available for values of type "
|
||||||
(fieldName, weightField, values, Sf)
|
<< pTraits<Type>::typeName
|
||||||
&& !writeValues<Type, vector>
|
<< exit(FatalError);
|
||||||
(fieldName, weightField, values, Sf)
|
|
||||||
&& !writeValues<Type, sphericalTensor>
|
|
||||||
(fieldName, weightField, values, Sf)
|
|
||||||
&& !writeValues<Type, symmTensor>
|
|
||||||
(fieldName, weightField, values, Sf)
|
|
||||||
&& !writeValues<Type, tensor>
|
|
||||||
(fieldName, weightField, values, Sf)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Operation " << operationTypeNames_[operation_]
|
|
||||||
<< " not available for values of type "
|
|
||||||
<< pTraits<Type>::typeName
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,23 +373,27 @@ template<class Type, class ResultType>
|
|||||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName,
|
||||||
const scalarField& weightField,
|
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& signs,
|
||||||
|
const scalarField& weights,
|
||||||
const vectorField& Sf
|
const vectorField& Sf
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ResultType result;
|
ResultType result;
|
||||||
|
|
||||||
if (processValues(values, Sf, weightField, result))
|
if (processValues(values, signs, weights, Sf, result))
|
||||||
{
|
{
|
||||||
// Add to result dictionary, over-writing any previous entry
|
// Add to result dictionary, over-writing any previous entry
|
||||||
resultDict_.add(fieldName, result, true);
|
resultDict_.add(fieldName, result, true);
|
||||||
|
|
||||||
file() << tab << result;
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
file() << tab << result;
|
||||||
|
|
||||||
Log << " " << operationTypeNames_[operation_]
|
Log << " " << operationTypeNames_[operation_]
|
||||||
<< "(" << regionName_ << ") of " << fieldName
|
<< "(" << regionName_ << ") of " << fieldName
|
||||||
<< " = " << result << endl;
|
<< " = " << result << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -426,8 +406,7 @@ template<class Type>
|
|||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
const GeometricField<Type, fvPatchField, volMesh>& field
|
||||||
const bool applyOrientation
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
tmp<Field<Type>> tvalues(new Field<Type>(faceId_.size()));
|
tmp<Field<Type>> tvalues(new Field<Type>(faceId_.size()));
|
||||||
@ -435,8 +414,9 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
|||||||
|
|
||||||
forAll(values, i)
|
forAll(values, i)
|
||||||
{
|
{
|
||||||
label facei = faceId_[i];
|
const label facei = faceId_[i];
|
||||||
label patchi = facePatchId_[i];
|
const label patchi = facePatchId_[i];
|
||||||
|
|
||||||
if (patchi >= 0)
|
if (patchi >= 0)
|
||||||
{
|
{
|
||||||
values[i] = field.boundaryField()[patchi][facei];
|
values[i] = field.boundaryField()[patchi][facei];
|
||||||
@ -452,14 +432,6 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyOrientation)
|
|
||||||
{
|
|
||||||
forAll(values, i)
|
|
||||||
{
|
|
||||||
values[i] *= faceSign_[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tvalues;
|
return tvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,8 +440,7 @@ template<class Type>
|
|||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
|
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
|
||||||
const bool applyOrientation
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
tmp<Field<Type>> tvalues(new Field<Type>(faceId_.size()));
|
tmp<Field<Type>> tvalues(new Field<Type>(faceId_.size()));
|
||||||
@ -477,8 +448,9 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
|||||||
|
|
||||||
forAll(values, i)
|
forAll(values, i)
|
||||||
{
|
{
|
||||||
label facei = faceId_[i];
|
const label facei = faceId_[i];
|
||||||
label patchi = facePatchId_[i];
|
const label patchi = facePatchId_[i];
|
||||||
|
|
||||||
if (patchi >= 0)
|
if (patchi >= 0)
|
||||||
{
|
{
|
||||||
values[i] = field.boundaryField()[patchi][facei];
|
values[i] = field.boundaryField()[patchi][facei];
|
||||||
@ -489,14 +461,6 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyOrientation)
|
|
||||||
{
|
|
||||||
forAll(values, i)
|
|
||||||
{
|
|
||||||
values[i] *= faceSign_[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tvalues;
|
return tvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -48,28 +48,26 @@ const char*
|
|||||||
Foam::NamedEnum
|
Foam::NamedEnum
|
||||||
<
|
<
|
||||||
Foam::functionObjects::fieldValues::volFieldValue::operationType,
|
Foam::functionObjects::fieldValues::volFieldValue::operationType,
|
||||||
13
|
11
|
||||||
>::names[] =
|
>::names[] =
|
||||||
{
|
{
|
||||||
"none",
|
"none",
|
||||||
"sum",
|
"sum",
|
||||||
"weightedSum",
|
|
||||||
"sumMag",
|
"sumMag",
|
||||||
"average",
|
"average",
|
||||||
"weightedAverage",
|
|
||||||
"volAverage",
|
"volAverage",
|
||||||
"weightedVolAverage",
|
|
||||||
"volIntegrate",
|
"volIntegrate",
|
||||||
"weightedVolIntegrate",
|
|
||||||
"min",
|
"min",
|
||||||
"max",
|
"max",
|
||||||
|
"minMag",
|
||||||
|
"maxMag",
|
||||||
"CoV"
|
"CoV"
|
||||||
};
|
};
|
||||||
|
|
||||||
const Foam::NamedEnum
|
const Foam::NamedEnum
|
||||||
<
|
<
|
||||||
Foam::functionObjects::fieldValues::volFieldValue::operationType,
|
Foam::functionObjects::fieldValues::volFieldValue::operationType,
|
||||||
13
|
11
|
||||||
> Foam::functionObjects::fieldValues::volFieldValue::operationTypeNames_;
|
> Foam::functionObjects::fieldValues::volFieldValue::operationTypeNames_;
|
||||||
|
|
||||||
|
|
||||||
@ -80,6 +78,8 @@ void Foam::functionObjects::fieldValues::volFieldValue::initialise
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
dict.readIfPresent<Switch>("writeLocation", writeLocation_);
|
||||||
|
|
||||||
if (dict.readIfPresent("weightFields", weightFieldNames_))
|
if (dict.readIfPresent("weightFields", weightFieldNames_))
|
||||||
{
|
{
|
||||||
Info<< name() << " " << operationTypeNames_[operation_]
|
Info<< name() << " " << operationTypeNames_[operation_]
|
||||||
@ -94,10 +94,57 @@ void Foam::functionObjects::fieldValues::volFieldValue::initialise
|
|||||||
<< " weight field " << weightFieldNames_[0];
|
<< " weight field " << weightFieldNames_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dict.readIfPresent("scaleFactor", scaleFactor_))
|
||||||
|
{
|
||||||
|
Info<< " scale factor = " << scaleFactor_ << nl;
|
||||||
|
}
|
||||||
|
|
||||||
Info<< nl << endl;
|
Info<< nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::functionObjects::fieldValues::volFieldValue::
|
||||||
|
writeFileHeaderLocation()
|
||||||
|
{
|
||||||
|
switch (operation_)
|
||||||
|
{
|
||||||
|
case operationType::minMag:
|
||||||
|
case operationType::maxMag:
|
||||||
|
file() << tab << "location" << tab << "cell";
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
file() << tab << "processor";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Foam::functionObjects::fieldValues::volFieldValue::
|
||||||
|
writeFileHeaderLocation<Foam::scalar>()
|
||||||
|
{
|
||||||
|
switch (operation_)
|
||||||
|
{
|
||||||
|
case operationType::min:
|
||||||
|
case operationType::max:
|
||||||
|
case operationType::minMag:
|
||||||
|
case operationType::maxMag:
|
||||||
|
file() << tab << "location" << tab << "cell";
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
file() << tab << "processor";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
|
void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
|
||||||
(
|
(
|
||||||
const label i
|
const label i
|
||||||
@ -117,12 +164,54 @@ void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
|
|||||||
}
|
}
|
||||||
|
|
||||||
file() << fields_[fieldi] << ")";
|
file() << fields_[fieldi] << ")";
|
||||||
|
|
||||||
|
if (writeLocation_)
|
||||||
|
{
|
||||||
|
#define writeFileHeaderLocationFieldType(fieldType, none) \
|
||||||
|
if (validField<fieldType>(fields_[fieldi])) \
|
||||||
|
{ \
|
||||||
|
writeFileHeaderLocation<fieldType>(); \
|
||||||
|
}
|
||||||
|
FOR_ALL_FIELD_TYPES(writeFileHeaderLocationFieldType)
|
||||||
|
#undef writeHeaderLocationFieldType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file() << endl;
|
file() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::fieldValues::volFieldValue::processValues
|
||||||
|
(
|
||||||
|
const Field<scalar>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<scalar>& result
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
switch (operation_)
|
||||||
|
{
|
||||||
|
case operationType::min:
|
||||||
|
case operationType::minMag:
|
||||||
|
{
|
||||||
|
opMag(values, result, lessOp<scalar>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case operationType::max:
|
||||||
|
case operationType::maxMag:
|
||||||
|
{
|
||||||
|
opMag(values, result, greaterOp<scalar>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// Fall through to same-type operations
|
||||||
|
return processValuesTypeType(values, weights, V, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
||||||
@ -134,7 +223,9 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
|||||||
:
|
:
|
||||||
fieldValue(name, runTime, dict, typeName),
|
fieldValue(name, runTime, dict, typeName),
|
||||||
volRegion(fieldValue::mesh_, dict),
|
volRegion(fieldValue::mesh_, dict),
|
||||||
operation_(operationTypeNames_.read(dict.lookup("operation")))
|
writeLocation_(false),
|
||||||
|
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
||||||
|
scaleFactor_(1)
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
}
|
}
|
||||||
@ -149,7 +240,9 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
|
|||||||
:
|
:
|
||||||
fieldValue(name, obr, dict, typeName),
|
fieldValue(name, obr, dict, typeName),
|
||||||
volRegion(fieldValue::mesh_, dict),
|
volRegion(fieldValue::mesh_, dict),
|
||||||
operation_(operationTypeNames_.read(dict.lookup("operation")))
|
writeLocation_(false),
|
||||||
|
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
||||||
|
scaleFactor_(1)
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
}
|
}
|
||||||
@ -186,24 +279,37 @@ bool Foam::functionObjects::fieldValues::volFieldValue::write()
|
|||||||
writeTime(file());
|
writeTime(file());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Construct the weight field and the volumes
|
||||||
|
scalarField weights
|
||||||
|
(
|
||||||
|
isNull(cellIDs()) ? fieldValue::mesh_.nCells() : cellIDs().size(),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
forAll(weightFieldNames_, i)
|
||||||
|
{
|
||||||
|
weights *= getFieldValues<scalar>(weightFieldNames_[i]);
|
||||||
|
}
|
||||||
|
const scalarField V(filterField(fieldValue::mesh_.V()));
|
||||||
|
|
||||||
forAll(fields_, i)
|
forAll(fields_, i)
|
||||||
{
|
{
|
||||||
const word& fieldName = fields_[i];
|
const word& fieldName = fields_[i];
|
||||||
bool processed = false;
|
bool ok = false;
|
||||||
|
|
||||||
#define processType(fieldType, none) \
|
#define writeValuesFieldType(fieldType, none) \
|
||||||
processed = processed || writeValues<fieldType>(fieldName);
|
ok = ok || writeValues<fieldType>(fieldName, weights, V);
|
||||||
FOR_ALL_FIELD_TYPES(processType)
|
FOR_ALL_FIELD_TYPES(writeValuesFieldType)
|
||||||
|
#undef writeValuesFieldType
|
||||||
|
|
||||||
if (!processed)
|
if (!ok)
|
||||||
{
|
{
|
||||||
cannotFindObject(fieldName);
|
cannotFindObject(fieldName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pstream::master())
|
if (operation_ != operationType::none && Pstream::master())
|
||||||
{
|
{
|
||||||
file()<< endl;
|
file() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log << endl;
|
Log << endl;
|
||||||
|
|||||||
@ -61,6 +61,7 @@ Usage
|
|||||||
type | Type name: volFieldValue | yes |
|
type | Type name: volFieldValue | yes |
|
||||||
log | Write data to standard output | no | no
|
log | Write data to standard output | no | no
|
||||||
writeFields | Write the region field values | yes |
|
writeFields | Write the region field values | yes |
|
||||||
|
writeLocation| Write the location (if available) | no | no
|
||||||
regionType | volRegion type: see below | yes |
|
regionType | volRegion type: see below | yes |
|
||||||
name | Name of volRegion if required | no |
|
name | Name of volRegion if required | no |
|
||||||
operation | Operation to perform | yes |
|
operation | Operation to perform | yes |
|
||||||
@ -79,16 +80,14 @@ Usage
|
|||||||
\plaintable
|
\plaintable
|
||||||
none | No operation
|
none | No operation
|
||||||
sum | Sum
|
sum | Sum
|
||||||
weightedSum | Weighted sum
|
|
||||||
sumMag | Sum of component magnitudes
|
sumMag | Sum of component magnitudes
|
||||||
average | Ensemble average
|
average | Ensemble average
|
||||||
weightedAverage | Weighted average
|
|
||||||
volAverage | Volume weighted average
|
volAverage | Volume weighted average
|
||||||
weightedVolAverage | Weighted volume average
|
|
||||||
volIntegrate | Volume integral
|
volIntegrate | Volume integral
|
||||||
weightedVolIntegrate | Weighted volume integral
|
|
||||||
min | Minimum
|
min | Minimum
|
||||||
max | Maximum
|
max | Maximum
|
||||||
|
minMag | Minimum magnitude
|
||||||
|
maxMag | Maximum magnitude
|
||||||
CoV | Coefficient of variation: standard deviation/mean
|
CoV | Coefficient of variation: standard deviation/mean
|
||||||
\endplaintable
|
\endplaintable
|
||||||
|
|
||||||
@ -136,33 +135,44 @@ public:
|
|||||||
{
|
{
|
||||||
none,
|
none,
|
||||||
sum,
|
sum,
|
||||||
weightedSum,
|
|
||||||
sumMag,
|
sumMag,
|
||||||
average,
|
average,
|
||||||
weightedAverage,
|
|
||||||
volAverage,
|
volAverage,
|
||||||
weightedVolAverage,
|
|
||||||
volIntegrate,
|
volIntegrate,
|
||||||
weightedVolIntegrate,
|
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
|
minMag,
|
||||||
|
maxMag,
|
||||||
CoV
|
CoV
|
||||||
};
|
};
|
||||||
|
|
||||||
//- Operation type names
|
//- Operation type names
|
||||||
static const NamedEnum<operationType, 13> operationTypeNames_;
|
static const NamedEnum<operationType, 11> operationTypeNames_;
|
||||||
|
|
||||||
|
|
||||||
|
// Public classes
|
||||||
|
|
||||||
|
//- Forward declare the result structure
|
||||||
|
template<class Type>
|
||||||
|
struct Result;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected data
|
// Protected data
|
||||||
|
|
||||||
|
//- Write the location if available for this operation - optional
|
||||||
|
Switch writeLocation_;
|
||||||
|
|
||||||
//- Operation to apply to values
|
//- Operation to apply to values
|
||||||
operationType operation_;
|
operationType operation_;
|
||||||
|
|
||||||
//- Weight field names - only used for weighted modes
|
//- Weight field names
|
||||||
wordList weightFieldNames_;
|
wordList weightFieldNames_;
|
||||||
|
|
||||||
|
//- Scale factor - optional
|
||||||
|
scalar scaleFactor_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
@ -175,21 +185,74 @@ protected:
|
|||||||
|
|
||||||
//- Insert field values into values list
|
//- Insert field values into values list
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>> setFieldValues
|
tmp<Field<Type>> getFieldValues(const word& fieldName) const;
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const bool mustGet = false
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Apply the 'operation' to the values
|
//- Apply a comparison operation (min/max) to the field magnitude,
|
||||||
template<class Type>
|
// returning the limiting value, its index and processor index
|
||||||
Type processValues
|
template<class Type, class Op>
|
||||||
|
void opMag
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
const scalarField& V,
|
Result<scalar>& result,
|
||||||
const scalarField& weightField
|
const Op& op
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Apply the operation to the values, and return true if successful.
|
||||||
|
// Does nothing unless overloaded below.
|
||||||
|
template<class Type, class ResultType>
|
||||||
|
bool processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<ResultType>& result
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Apply Type -> Type operation to the values. Calls
|
||||||
|
// processValuesTypeType.
|
||||||
|
template<class Type>
|
||||||
|
bool processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<Type>& result
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Apply Type -> scalar operation to the values
|
||||||
|
template<class Type>
|
||||||
|
bool processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<scalar>& result
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Apply scalar -> scalar operation to the values. Calls
|
||||||
|
// processValuesTypeType.
|
||||||
|
bool processValues
|
||||||
|
(
|
||||||
|
const Field<scalar>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<scalar>& result
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Apply a Type -> Type operation to the values
|
||||||
|
template<class Type>
|
||||||
|
bool processValuesTypeType
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<Type>& result
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Output file header location information for a given type
|
||||||
|
template<class Type>
|
||||||
|
void writeFileHeaderLocation();
|
||||||
|
|
||||||
//- Output file header information
|
//- Output file header information
|
||||||
virtual void writeFileHeader(const label i);
|
virtual void writeFileHeader(const label i);
|
||||||
|
|
||||||
@ -227,7 +290,22 @@ 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& weights,
|
||||||
|
const scalarField& V
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated helper function to output field values
|
||||||
|
template<class Type, class ResultType>
|
||||||
|
bool writeValues
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V
|
||||||
|
);
|
||||||
|
|
||||||
//- Filter a field according to cellIds
|
//- Filter a field according to cellIds
|
||||||
template<class Type>
|
template<class Type>
|
||||||
@ -241,6 +319,46 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void volFieldValue::writeFileHeaderLocation<scalar>();
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class volFieldValue::Result Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
struct volFieldValue::Result
|
||||||
|
{
|
||||||
|
Type value;
|
||||||
|
label celli;
|
||||||
|
label proci;
|
||||||
|
point cc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
inline Istream& operator>>
|
||||||
|
(
|
||||||
|
Istream& is,
|
||||||
|
volFieldValue::Result<Type>& result
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return is >> result.value >> result.celli >> result.proci >> result.cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
inline Ostream& operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const volFieldValue::Result<Type>& result
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return os << result.value << result.celli << result.proci << result.cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace fieldValues
|
} // End namespace fieldValues
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -47,10 +47,9 @@ bool Foam::functionObjects::fieldValues::volFieldValue::validField
|
|||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::functionObjects::fieldValues::volFieldValue::setFieldValues
|
Foam::functionObjects::fieldValues::volFieldValue::getFieldValues
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName
|
||||||
const bool mustGet
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> vf;
|
typedef GeometricField<Type, fvPatchField, volMesh> vf;
|
||||||
@ -60,83 +59,149 @@ Foam::functionObjects::fieldValues::volFieldValue::setFieldValues
|
|||||||
return filterField(obr_.lookupObject<vf>(fieldName));
|
return filterField(obr_.lookupObject<vf>(fieldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mustGet)
|
FatalErrorInFunction
|
||||||
|
<< "Field " << fieldName << " not found in database"
|
||||||
|
<< abort(FatalError);
|
||||||
|
|
||||||
|
return tmp<Field<Type>>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Op>
|
||||||
|
void Foam::functionObjects::fieldValues::volFieldValue::opMag
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
Result<scalar>& result,
|
||||||
|
const Op& op
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const scalarField magValues(mag(values));
|
||||||
|
|
||||||
|
label i = 0;
|
||||||
|
forAll(magValues, j)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
if (op(magValues[j], magValues[i]))
|
||||||
<< "Field " << fieldName << " not found in database"
|
{
|
||||||
<< abort(FatalError);
|
i = j;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp<Field<Type>>(new Field<Type>(0.0));
|
result.value = magValues[i];
|
||||||
|
result.celli = isNull(cellIDs()) ? i : cellIDs()[i];
|
||||||
|
result.proci = Pstream::parRun() ? Pstream::myProcNo() : -1;
|
||||||
|
result.cc = fieldValue::mesh_.C()[result.celli];
|
||||||
|
|
||||||
|
reduce
|
||||||
|
(
|
||||||
|
result,
|
||||||
|
[&op](const Result<scalar>& a, const Result<scalar>& b)
|
||||||
|
{
|
||||||
|
return op(a.value, b.value) ? a : b;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class ResultType>
|
||||||
|
bool Foam::functionObjects::fieldValues::volFieldValue::processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<ResultType>& result
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Type Foam::functionObjects::fieldValues::volFieldValue::processValues
|
bool Foam::functionObjects::fieldValues::volFieldValue::processValues
|
||||||
(
|
(
|
||||||
const Field<Type>& values,
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
const scalarField& V,
|
const scalarField& V,
|
||||||
const scalarField& weightField
|
Result<Type>& result
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return processValuesTypeType(values, weights, V, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool Foam::functionObjects::fieldValues::volFieldValue::processValues
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<scalar>& result
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
switch (operation_)
|
||||||
|
{
|
||||||
|
case operationType::minMag:
|
||||||
|
{
|
||||||
|
opMag(values, result, lessOp<scalar>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case operationType::maxMag:
|
||||||
|
{
|
||||||
|
opMag(values, result, greaterOp<scalar>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool Foam::functionObjects::fieldValues::volFieldValue::processValuesTypeType
|
||||||
|
(
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V,
|
||||||
|
Result<Type>& result
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
Type result = Zero;
|
|
||||||
switch (operation_)
|
switch (operation_)
|
||||||
{
|
{
|
||||||
case operationType::sum:
|
case operationType::sum:
|
||||||
{
|
{
|
||||||
result = gSum(values);
|
result.value = gSum(weights*values);
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
case operationType::weightedSum:
|
|
||||||
{
|
|
||||||
result = gSum(weightField*values);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case operationType::sumMag:
|
case operationType::sumMag:
|
||||||
{
|
{
|
||||||
result = gSum(cmptMag(values));
|
result.value = gSum(cmptMag(values));
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::average:
|
case operationType::average:
|
||||||
{
|
{
|
||||||
result = gSum(values)/nCells();
|
result.value = gSum(weights*values)/max(gSum(weights), vSmall);
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
case operationType::weightedAverage:
|
|
||||||
{
|
|
||||||
result = gSum(weightField*values)/max(gSum(weightField), vSmall);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case operationType::volAverage:
|
case operationType::volAverage:
|
||||||
{
|
{
|
||||||
result = gSum(V*values)/this->V();
|
result.value = gSum(weights*V*values)/max(gSum(weights*V), vSmall);
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
case operationType::weightedVolAverage:
|
|
||||||
{
|
|
||||||
result =
|
|
||||||
gSum(weightField*V*values)/max(gSum(weightField*V), vSmall);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case operationType::volIntegrate:
|
case operationType::volIntegrate:
|
||||||
{
|
{
|
||||||
result = gSum(V*values);
|
result.value = gSum(weights*V*values);
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
case operationType::weightedVolIntegrate:
|
|
||||||
{
|
|
||||||
result = gSum(weightField*V*values);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case operationType::min:
|
case operationType::min:
|
||||||
{
|
{
|
||||||
result = gMin(values);
|
result.value = gMin(values);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::max:
|
case operationType::max:
|
||||||
{
|
{
|
||||||
result = gMax(values);
|
result.value = gMax(values);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::CoV:
|
case operationType::CoV:
|
||||||
{
|
{
|
||||||
@ -148,18 +213,22 @@ Type Foam::functionObjects::fieldValues::volFieldValue::processValues
|
|||||||
{
|
{
|
||||||
scalarField vals(values.component(d));
|
scalarField vals(values.component(d));
|
||||||
scalar mean = component(meanValue, d);
|
scalar mean = component(meanValue, d);
|
||||||
scalar& res = setComponent(result, d);
|
scalar& res = setComponent(result.value, d);
|
||||||
|
|
||||||
res = sqrt(gSum(V*sqr(vals - mean))/this->V())/mean;
|
res = sqrt(gSum(V*sqr(vals - mean))/this->V())/mean;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
case operationType::none:
|
case operationType::none:
|
||||||
{}
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -168,36 +237,19 @@ Type Foam::functionObjects::fieldValues::volFieldValue::processValues
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
bool Foam::functionObjects::fieldValues::volFieldValue::writeValues
|
bool Foam::functionObjects::fieldValues::volFieldValue::writeValues
|
||||||
(
|
(
|
||||||
const word& fieldName
|
const word& fieldName,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const bool ok = validField<Type>(fieldName);
|
const bool ok = validField<Type>(fieldName);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
Field<Type> values(setFieldValues<Type>(fieldName));
|
// Get the values
|
||||||
scalarField V(filterField(fieldValue::mesh_.V()));
|
Field<Type> values(getFieldValues<Type>(fieldName));
|
||||||
scalarField weightField(values.size(), 1.0);
|
|
||||||
|
|
||||||
forAll(weightFieldNames_, i)
|
|
||||||
{
|
|
||||||
weightField *= setFieldValues<scalar>(weightFieldNames_[i], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type result = processValues(values, V, weightField);
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
// Add to result dictionary, over-writing any previous entry
|
|
||||||
resultDict_.add(fieldName, result, true);
|
|
||||||
|
|
||||||
file()<< tab << result;
|
|
||||||
|
|
||||||
Log << " " << operationTypeNames_[operation_]
|
|
||||||
<< "(" << volRegion::regionName_ << ") of " << fieldName
|
|
||||||
<< " = " << result << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Write raw values if specified
|
||||||
if (writeFields_)
|
if (writeFields_)
|
||||||
{
|
{
|
||||||
IOField<Type>
|
IOField<Type>
|
||||||
@ -211,15 +263,98 @@ bool Foam::functionObjects::fieldValues::volFieldValue::writeValues
|
|||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
(weightField*values).ref()
|
(weights*values).ref()
|
||||||
).write();
|
).write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do the operation
|
||||||
|
if (operation_ != operationType::none)
|
||||||
|
{
|
||||||
|
// Apply scale factor
|
||||||
|
values *= scaleFactor_;
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
#define writeValuesFieldType(fieldType, none) \
|
||||||
|
ok = \
|
||||||
|
ok \
|
||||||
|
|| writeValues<Type, fieldType> \
|
||||||
|
( \
|
||||||
|
fieldName, \
|
||||||
|
values, \
|
||||||
|
weights, \
|
||||||
|
V \
|
||||||
|
);
|
||||||
|
FOR_ALL_FIELD_TYPES(writeValuesFieldType);
|
||||||
|
#undef writeValuesFieldType
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Operation " << operationTypeNames_[operation_]
|
||||||
|
<< " not available for values of type "
|
||||||
|
<< pTraits<Type>::typeName
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class ResultType>
|
||||||
|
bool Foam::functionObjects::fieldValues::volFieldValue::writeValues
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalarField& weights,
|
||||||
|
const scalarField& V
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Result<ResultType> result({Zero, -1, -1, point::uniform(NaN)});
|
||||||
|
|
||||||
|
if (processValues(values, weights, V, result))
|
||||||
|
{
|
||||||
|
// Add to result dictionary, over-writing any previous entry
|
||||||
|
resultDict_.add(fieldName, result.value, true);
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
file() << tab << result.value;
|
||||||
|
|
||||||
|
Log << " " << operationTypeNames_[operation_]
|
||||||
|
<< "(" << volRegion::regionName_ << ") of " << fieldName
|
||||||
|
<< " = " << result.value;
|
||||||
|
|
||||||
|
if (result.celli != -1)
|
||||||
|
{
|
||||||
|
Log << " at location " << result.cc;
|
||||||
|
if (writeLocation_) file() << tab << result.cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.celli != -1)
|
||||||
|
{
|
||||||
|
Log << " in cell " << result.celli;
|
||||||
|
if (writeLocation_) file() << tab << result.celli;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.proci != -1)
|
||||||
|
{
|
||||||
|
Log << " on processor " << result.proci;
|
||||||
|
if (writeLocation_) file() << tab << result.proci;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::functionObjects::fieldValues::volFieldValue::filterField
|
Foam::functionObjects::fieldValues::volFieldValue::filterField
|
||||||
|
|||||||
@ -61,7 +61,7 @@ functions
|
|||||||
writeFields no;
|
writeFields no;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedAverage;
|
operation average;
|
||||||
weightField phi;
|
weightField phi;
|
||||||
|
|
||||||
fields
|
fields
|
||||||
|
|||||||
@ -56,7 +56,7 @@ functions
|
|||||||
writeFields no;
|
writeFields no;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedAverage;
|
operation average;
|
||||||
weightField phi;
|
weightField phi;
|
||||||
fields
|
fields
|
||||||
(
|
(
|
||||||
|
|||||||
@ -57,7 +57,7 @@ functions
|
|||||||
writeFields no;
|
writeFields no;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedAverage;
|
operation average;
|
||||||
weightField phi;
|
weightField phi;
|
||||||
fields
|
fields
|
||||||
(
|
(
|
||||||
|
|||||||
@ -82,7 +82,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas2;
|
weightField alphaRhoPhi.gas2;
|
||||||
fields ( h.gas2 );
|
fields ( h.gas2 );
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name outlet;
|
name outlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas;
|
weightField alphaRhoPhi.gas;
|
||||||
fields ( h.gas );
|
fields ( h.gas );
|
||||||
}
|
}
|
||||||
@ -169,7 +169,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.gas2;
|
weightField alphaRhoPhi.gas2;
|
||||||
fields ( h.gas2 );
|
fields ( h.gas2 );
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@ functions
|
|||||||
writeFields false;
|
writeFields false;
|
||||||
regionType patch;
|
regionType patch;
|
||||||
name inlet;
|
name inlet;
|
||||||
operation weightedSum;
|
operation sum;
|
||||||
weightField alphaRhoPhi.liquid;
|
weightField alphaRhoPhi.liquid;
|
||||||
fields ( h.liquid );
|
fields ( h.liquid );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,20 +52,8 @@ maxDeltaT 1e-2;
|
|||||||
|
|
||||||
functions
|
functions
|
||||||
{
|
{
|
||||||
minMax
|
#includeFunc cellMin(T.steam,T.water,p)
|
||||||
{
|
#includeFunc cellMax(T.steam,T.water,p)
|
||||||
type fieldMinMax;
|
|
||||||
functionObjectLibs ("libfieldFunctionObjects.so");
|
|
||||||
fields
|
|
||||||
(
|
|
||||||
T.steam
|
|
||||||
T.water
|
|
||||||
p
|
|
||||||
);
|
|
||||||
location no;
|
|
||||||
writeControl timeStep;
|
|
||||||
writeInterval 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user