ENH: functionObjects: refactor and extend histogram

- new submodels:
  - 'equalBinWidth': groups data into bins of equal widths (previous behaviour)
  - 'unequalBinWidth': groups data into bins of unequal widths

- output files per time-step are replaced with a single output file

- silently deprecates the input entries: 'setFormat' and 'formatOptions'
This commit is contained in:
Kutalmis Bercin
2022-09-06 11:30:32 +01:00
committed by Andrew Heather
parent fd75d38757
commit 941cd7fef4
11 changed files with 1111 additions and 198 deletions

View File

@ -66,6 +66,10 @@ surfaceInterpolate/surfaceInterpolate.C
regionSizeDistribution/regionSizeDistribution.C
histogram/histogram.C
histogram/histogramModels/histogramModel/histogramModel.C
histogram/histogramModels/histogramModel/histogramModelNew.C
histogram/histogramModels/equalBinWidth/equalBinWidth.C
histogram/histogramModels/unequalBinWidth/unequalBinWidth.C
fieldExpression/fieldExpression.C
components/components.C

View File

@ -27,8 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "histogram.H"
#include "volFields.H"
#include "ListOps.H"
#include "histogramModel.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -52,11 +51,8 @@ Foam::functionObjects::histogram::histogram
const dictionary& dict
)
:
functionObjects::fvMeshFunctionObject(name, runTime, dict),
functionObjects::writeFile(obr_, name),
max_(-GREAT),
min_(GREAT),
setWriterPtr_(nullptr)
fvMeshFunctionObject(name, runTime, dict),
histogramModelPtr_(nullptr)
{
read(dict);
}
@ -66,30 +62,14 @@ Foam::functionObjects::histogram::histogram
bool Foam::functionObjects::histogram::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
writeFile::read(dict);
dict.readEntry("field", fieldName_);
max_ = dict.getOrDefault<scalar>("max", -GREAT);
min_ = dict.getOrDefault<scalar>("min", GREAT);
dict.readEntry("nBins", nBins_);
if (nBins_ < 1)
if (!fvMeshFunctionObject::read(dict))
{
FatalErrorInFunction
<< "Number of histogram bins = " << nBins_
<< " cannot be negative or zero."
<< abort(FatalError);
return false;
}
const word writeType(dict.get<word>("setFormat"));
Info<< type() << " " << name() << ":" << endl;
setWriterPtr_ = coordSetWriter::New
(
writeType,
dict.subOrEmptyDict("formatOptions").optionalSubDict(writeType)
);
histogramModelPtr_.reset(histogramModel::New(name(), mesh_, dict));
return true;
}
@ -103,115 +83,13 @@ bool Foam::functionObjects::histogram::execute()
bool Foam::functionObjects::histogram::write()
{
Log << type() << " " << name() << " write:" << nl;
Log << type() << " " << name() << " write:" << endl;
tmp<volScalarField> tfield;
tfield.cref(obr_.cfindObject<volScalarField>(fieldName_));
if (tfield)
if (!histogramModelPtr_->write(log))
{
Log << " Looking up field " << fieldName_ << endl;
}
else
{
Log << " Reading field " << fieldName_ << endl;
tfield = tmp<volScalarField>::New
(
IOobject
(
fieldName_,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE
),
mesh_
);
}
const auto& field = tfield();
scalar histMax = max_;
scalar histMin = min_;
if (max_ == -GREAT)
{
// Determine current min and max
histMax = max(field).value();
if (min_ == GREAT)
{
histMin = min(field).value();
}
Log << " Determined histogram bounds from field"
<< " min/max(" << fieldName_ << ") = "
<< histMin << ' ' << histMax << endl;
}
else if (min_ == GREAT)
{
histMin = 0;
}
// Calculate the mid-points of bins for the graph axis
pointField xBin(nBins_, Zero);
const scalar delta = (histMax - histMin)/nBins_;
{
scalar x = histMin + 0.5*delta;
for (point& p : xBin)
{
p.x() = x;
x += delta;
}
}
scalarField dataNormalized(nBins_, Zero);
labelField dataCount(nBins_, Zero);
const scalarField& V = mesh_.V();
forAll(field, celli)
{
const label bini = (field[celli] - histMin)/delta;
if (bini >= 0 && bini < nBins_)
{
dataNormalized[bini] += V[celli];
dataCount[bini]++;
}
}
Pstream::listCombineGather(dataNormalized, plusEqOp<scalar>());
Pstream::listCombineGather(dataCount, plusEqOp<label>());
if (Pstream::master())
{
const scalar sumData = sum(dataNormalized);
if (sumData > SMALL)
{
dataNormalized /= sumData;
const coordSet coords(fieldName_, "x", xBin, mag(xBin));
auto& writer = *setWriterPtr_;
writer.open
(
coords,
(
writeFile::baseTimeDir()
/ (coords.name() + coordSetWriter::suffix(fieldName_))
)
);
Log << " Writing histogram of " << fieldName_
<< " to " << writer.path() << endl;
writer.nFields(2);
writer.write(fieldName_, dataNormalized);
writer.write(fieldName_ + "Count", dataCount);
writer.close(true);
}
return false;
}
Log << endl;
return true;
}

View File

@ -35,65 +35,58 @@ Description
Operands:
\table
Operand | Type | Location
input | volScalarField | $FOAM_CASE/\<time\>/\<inpField\>
output file | dat | $FOAM_CASE/postProcessing/\<FO\>/\<time\>/\<file\>
output field | - | -
Operand | Type | Location
input | volScalarField | \<time\>/\<inpField\>
output file | dat | postProcessing/\<FO\>/\<time\>/histogram
output field | - | -
\endtable
The set written contains two columns, the first the volume averaged values,
the second the raw bin count.
The data written contains four columns (from left to right):
- time
- mid-point of histogram bin
- histogram counts - number of samples in each bin
- volume-weighted histogram values
Usage
Minimal example by using \c system/controlDict.functions:
\verbatim
histogram1
{
// Mandatory entries (unmodifiable)
type histogram;
libs (fieldFunctionObjects);
// Mandatory entries
type histogram;
libs (fieldFunctionObjects);
field <word>;
model <word>;
// Mandatory (inherited) entries (runtime modifiable)
field p;
nBins 100;
setFormat gnuplot;
// Conditional entries
// Optional entries (runtime modifiable)
max 5;
min -5;
// Option-1: when model == equalBinWidth
// Optional (inherited) entries
// Option-2: when model == unequalBinWidth
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Req'd | Dflt
type | Type name: histogram | word | yes | -
libs | Library name: fieldFunctionObjects | word | yes | -
field | Name of operand field | word | yes | -
nBins | Number of histogram bins | label | yes | -
setFormat | Output format | word | yes | -
max | Maximum value sampled | scalar | no | fieldMax
min | minimum value sampled | scalar | no | 0.0
Property | Description | Type | Reqd | Deflt
type | Type name: histogram | word | yes | -
libs | Library name: fieldFunctionObjects | word | yes | -
field | Name of operand field | word | yes | -
model | Name of the histogram model | word | yes | -
\endtable
Options for the \c model entry:
\verbatim
equalBinWidth | Use equal-bin width
unequalBinWidth | Use unequal-bin widths
\endverbatim
The inherited entries are elaborated in:
- \link functionObject.H \endlink
- \link writeFile.H \endlink
Usage by the \c postProcess utility is not available.
Note
If \c max is not provided it will use the field's min and max as the bin
extremes. If \c max is provided but not \c min it will use 0.
See also
- Foam::functionObject
- Foam::functionObjects::fvMeshFunctionObject
- Foam::functionObjects::writeFile
- ExtendedCodeGuide::functionObjects::field::histogram
- \link functionObject.H \endlink
- \link writeFile.H \endlink
SourceFiles
histogram.C
@ -104,41 +97,30 @@ SourceFiles
#define Foam_functionObjects_histogram_H
#include "fvMeshFunctionObject.H"
#include "writeFile.H"
#include "coordSetWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class histogramModel;
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class histogram Declaration
Class histogram Declaration
\*---------------------------------------------------------------------------*/
class histogram
:
public functionObjects::fvMeshFunctionObject,
public functionObjects::writeFile
public fvMeshFunctionObject
{
// Private Data
//- Number of bins
label nBins_;
//- Name of field
word fieldName_;
//- Maximum value
scalar max_;
//- Minimum value
scalar min_;
//- Output formatter to write
mutable autoPtr<coordSetWriter> setWriterPtr_;
//- Histogram model
autoPtr<histogramModel> histogramModelPtr_;
public:
@ -170,8 +152,8 @@ public:
// Member Functions
//- Read the histogram data
virtual bool read(const dictionary&);
//- Read the top-level dictionary
virtual bool read(const dictionary& dict);
//- Execute (effectively no-op)
virtual bool execute();

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "equalBinWidth.H"
#include "histogramModel.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace histogramModels
{
defineTypeNameAndDebug(equalBinWidth, 0);
addToRunTimeSelectionTable(histogramModel, equalBinWidth, dictionary);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::histogramModels::equalBinWidth::equalBinWidth
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
:
histogramModel(name, mesh, dict),
nBins_(0),
min_(GREAT),
max_(-GREAT)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::histogramModels::equalBinWidth::read(const dictionary& dict)
{
if (!histogramModel::read(dict))
{
return false;
}
nBins_ = dict.getScalar("nBins");
if (nBins_ < 1)
{
FatalIOErrorInFunction(dict)
<< "Number of histogram bins = " << nBins_
<< " cannot be negative or zero."
<< abort(FatalIOError);
}
min_ = dict.getOrDefault<scalar>("min", GREAT);
max_ = dict.getOrDefault<scalar>("max", -GREAT);
return true;
}
bool Foam::histogramModels::equalBinWidth::write(const bool log)
{
// Retrieve operand field
const volScalarField& field = histogramModel::getOrReadField(fieldName());
// Determine min and max from the operand field
// if the user did not provide any min or max
scalar histMax = max_;
scalar histMin = min_;
if (max_ == -GREAT)
{
histMax = max(field).value();
if (min_ == GREAT)
{
histMin = min(field).value();
}
if (log)
{
Info<< " Determined histogram bounds from field"
<< " min/max(" << fieldName() << ") = "
<< histMin << ' ' << histMax << endl;
}
}
else if (min_ == GREAT)
{
histMin = 0;
}
if (histMax < histMin)
{
FatalErrorInFunction
<< "Histogram minimum = " << histMin
<< ", cannot be larger than histogram maximum = " << histMax
<< exit(FatalError);
}
// Calculate the mid-points of bins for the graph axis
pointField binMidPoints(nBins_, Zero);
const scalar delta = (histMax - histMin)/nBins_;
{
scalar x = histMin + 0.5*delta;
for (point& p : binMidPoints)
{
p.x() = x;
x += delta;
}
}
// Calculate the histogram data
scalarField dataNormalised(nBins_, Zero);
labelField dataCount(nBins_, Zero);
const scalarField& V = mesh().V();
forAll(field, celli)
{
const label bini = (field[celli] - histMin)/delta;
if (bini >= 0 && bini < nBins_)
{
dataNormalised[bini] += V[celli];
dataCount[bini]++;
}
}
Pstream::listCombineGather(dataNormalised, plusEqOp<scalar>());
Pstream::listCombineGather(dataCount, plusEqOp<label>());
// Write histogram data
histogramModel::write(dataNormalised, dataCount, mag(binMidPoints));
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::histogramModels::equalBinWidth
Description
Histogram model which groups data into bins of equal width.
Usage
Minimal example by using \c system/controlDict.functions:
\verbatim
histogram1
{
// Inherited entries
...
// Mandatory entries
nBins <label>;
// Optional entries
min <scalar>;
max <scalar>;
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
nBins | Number of histogram bins | label | yes | -
min | Minimum value of histogram data | scalar | no | -
max | Maximum value of histogram data | scalar | no | -
\endtable
Note
- If \c max is not provided, \c histogram will use operand
field's min and max as the bin extremes.
- If \c max is provided without \c min,
\c histogram will use 0 for the \c min.
SourceFiles
equalBinWidth.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_histogramModels_equalBinWidth_H
#define Foam_histogramModels_equalBinWidth_H
#include "histogramModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace histogramModels
{
/*---------------------------------------------------------------------------*\
Class equalBinWidth Declaration
\*---------------------------------------------------------------------------*/
class equalBinWidth
:
public histogramModel
{
// Private Data
//- Number of bins
label nBins_;
//- Minimum value of histogram data
scalar min_;
//- Maximum value of histogram data
scalar max_;
public:
//- Runtime type information
TypeName("equalBinWidth");
// Constructors
//- Construct from components
equalBinWidth
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- No copy construct
equalBinWidth(const equalBinWidth&) = delete;
//- No copy assignment
void operator=(const equalBinWidth&) = delete;
// Destructor
virtual ~equalBinWidth() = default;
// Member Functions
//- Read top-level dictionary
virtual bool read(const dictionary& dict);
//- Write data to stream and files
virtual bool write(const bool log);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace histogramModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,152 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "histogramModel.H"
#include "fvMesh.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(histogramModel, 0);
defineRunTimeSelectionTable(histogramModel, dictionary);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::histogramModel::writeFileHeader(Ostream& os)
{
writeHeader(os, "Histogram");
writeCommented(os, "Time");
writeTabbed(os, "binMidPoints");
writeTabbed(os, "dataCounts");
writeTabbed(os, "dataValues");
os << endl;
}
Foam::volScalarField& Foam::histogramModel::getOrReadField
(
const word& fieldName
) const
{
auto* ptr = mesh_.getObjectPtr<volScalarField>(fieldName);
if (!ptr)
{
ptr = new volScalarField
(
IOobject
(
fieldName,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh_
);
mesh_.objectRegistry::store(ptr);
}
return *ptr;
}
void Foam::histogramModel::write
(
scalarField& dataNormalised,
const labelField& dataCount,
const scalarField& magBinMidPoint
)
{
if (!Pstream::master())
{
return;
}
const scalar sumData = sum(dataNormalised);
if (sumData < SMALL)
{
return;
}
dataNormalised /= sumData;
const auto time = mesh().time().value();
forAll(dataNormalised, i)
{
file()
<< time << tab
<< magBinMidPoint[i] << tab
<< dataCount[i] << tab
<< dataNormalised[i]
<< endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::histogramModel::histogramModel
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
:
writeFile(mesh, name, "histogram", dict),
mesh_(mesh),
fieldName_(word::null)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::histogramModel::read(const dictionary& dict)
{
if (!functionObjects::writeFile::read(dict))
{
return false;
}
fieldName_ = dict.get<word>("field");
if (writeToFile() && !writtenHeader_)
{
writeFileHeader(file());
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,184 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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/>.
Namespace
Foam::histogramModels
Description
A namespace for various histogram model implementations.
Class
Foam::histogramModel
Description
A base class for histogram models.
SourceFiles
histogramModel.C
histogramModelNew.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_histogramModel_H
#define Foam_histogramModel_H
#include "writeFile.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class fvMesh;
/*---------------------------------------------------------------------------*\
Class histogramModel Declaration
\*---------------------------------------------------------------------------*/
class histogramModel
:
public functionObjects::writeFile
{
// Private Data
//- Const reference to the mesh
const fvMesh& mesh_;
//- Name of operand field
word fieldName_;
protected:
// Protected Member Functions
//- Output file header information
virtual void writeFileHeader(Ostream& os);
//- Return requested field from the object registry
//- or read+register the field to the object registry
volScalarField& getOrReadField(const word& fieldName) const;
//- Write histogram data
void write
(
scalarField& dataNormalised,
const labelField& dataCount,
const scalarField& magMidBin
);
public:
//- Runtime type information
TypeName("histogramModel");
// Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
histogramModel,
dictionary,
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
),
(name, mesh, dict)
);
// Selectors
//- Return a reference to the selected histogram model
static autoPtr<histogramModel> New
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
// Constructors
//- Construct from components
histogramModel
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- No copy construct
histogramModel(const histogramModel&) = delete;
//- No copy assignment
void operator=(const histogramModel&) = delete;
//- Destructor
virtual ~histogramModel() = default;
// Member Functions
// Access
//- Return const reference to the mesh
const fvMesh& mesh() const noexcept
{
return mesh_;
}
//- Return const reference to the operand field name
const word& fieldName() const noexcept
{
return fieldName_;
}
// I-O
//- Read top-level dictionary
virtual bool read(const dictionary& dict);
//- Write data to stream and files
virtual bool write(const bool log) = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "histogramModel.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::histogramModel> Foam::histogramModel::New
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
{
const word modelType(dict.get<word>("model"));
Info<< " Selecting model: " << modelType << nl << endl;
auto* ctorPtr = dictionaryConstructorTable(modelType);
if (!ctorPtr)
{
FatalIOErrorInLookup
(
dict,
"histogramModel",
modelType,
*dictionaryConstructorTablePtr_
) << exit(FatalIOError);
}
return autoPtr<histogramModel>(ctorPtr(name, mesh, dict));
}
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "unequalBinWidth.H"
#include "histogramModel.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace histogramModels
{
defineTypeNameAndDebug(unequalBinWidth, 0);
addToRunTimeSelectionTable(histogramModel, unequalBinWidth, dictionary);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::histogramModels::unequalBinWidth::unequalBinWidth
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
:
histogramModel(name, mesh, dict),
nBins_(-1),
ranges_(Zero)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::histogramModels::unequalBinWidth::read(const dictionary& dict)
{
if (!histogramModel::read(dict))
{
return false;
}
ranges_ = dict.get<List<Pair<scalar>>>("ranges");
forAll(ranges_, bini)
{
const auto& range = ranges_[bini];
const scalar min = range.first();
const scalar max = range.second();
if (max < min)
{
FatalIOErrorInFunction(dict)
<< "For bin-" << bini
<< ", min is larger than max."
<< " min = " << min
<< " max = " << max
<< abort(FatalIOError);
}
}
nBins_ = ranges_.size();
if (nBins_ < 1)
{
FatalIOErrorInFunction(dict)
<< "Number of histogram bins = " << nBins_
<< " cannot be negative or zero."
<< abort(FatalIOError);
}
return true;
}
bool Foam::histogramModels::unequalBinWidth::write(const bool log)
{
// Retrieve operand field
const volScalarField& field = histogramModel::getOrReadField(fieldName());
// Calculate the mid-points of bins for the graph axis
pointField midBin(nBins_, Zero);
forAll(ranges_, bini)
{
point& p = midBin[bini];
const auto& range = ranges_[bini];
const scalar min = range.first();
const scalar max = range.second();
const scalar delta = max - min;
p.x() = min + 0.5*delta;
}
// Calculate the histogram data
scalarField dataNormalised(nBins_, Zero);
labelField dataCount(nBins_, Zero);
const scalarField& V = mesh().V();
forAll(field, celli)
{
forAll(ranges_, bini)
{
const auto& range = ranges_[bini];
const scalar min = range.first();
const scalar max = range.second();
if (field[celli] >= min && field[celli] < max)
{
dataNormalised[bini] += V[celli];
dataCount[bini]++;
break;
}
}
}
Pstream::listCombineGather(dataNormalised, plusEqOp<scalar>());
Pstream::listCombineGather(dataCount, plusEqOp<label>());
// Write histogram data
histogramModel::write(dataNormalised, dataCount, mag(midBin));
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,144 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::histogramModels::unequalBinWidth
Description
Histogram model which groups data into bins of unequal widths.
Usage
Minimal example by using \c system/controlDict.functions:
\verbatim
histogram1
{
// Inherited entries
...
// Mandatory entries
ranges
(
// min max
(<scalar> <scalar>) // bin-0
(<scalar> <scalar>) // bin-1
...
);
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
ranges | Min-max values of histogram data <!--
--> | List\<Pair\<scalar\>\> | no | -
\endtable
Note
- All bins are half-open, that is [min, max).
- Bins should be specified as consecutive, non-overlapping
and adjacent intervals of the field variable. No warning
or runtime error will be emitted, otherwise.
SourceFiles
unequalBinWidth.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_histogramModels_unequalBinWidth_H
#define Foam_histogramModels_unequalBinWidth_H
#include "histogramModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace histogramModels
{
/*---------------------------------------------------------------------------*\
Class unequalBinWidth Declaration
\*---------------------------------------------------------------------------*/
class unequalBinWidth
:
public histogramModel
{
// Private Data
//- Number of bins
label nBins_;
//- Lower and upper ranges of operand bins
List<Pair<scalar>> ranges_;
public:
//- Runtime type information
TypeName("unequalBinWidth");
// Constructors
//- Construct from components
unequalBinWidth
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- No copy construct
unequalBinWidth(const unequalBinWidth&) = delete;
//- No copy assignment
void operator=(const unequalBinWidth&) = delete;
// Destructor
virtual ~unequalBinWidth() = default;
// Member Functions
//- Read top-level dictionary
virtual bool read(const dictionary& dict);
//- Write data to stream and files
virtual bool write(const bool log);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace histogramModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -12,15 +12,54 @@ histogram1
type histogram;
libs (fieldFunctionObjects);
field p;
nBins 100;
setFormat raw;
model equalBinWidth;
// Optional entries
// Conditional entries
nBins 100;
max 10;
min -10;
// Optional (inherited) entries
writePrecision 16;
// Inherited entries
writePrecision 6;
writeToFile true;
useUserTime true;
region region0;
enabled true;
log true;
timeStart 0;
timeEnd 1000;
executeControl timeStep;
executeInterval 1;
writeControl writeTime;
writeInterval -1;
}
histogram2
{
// Mandatory entries
type histogram;
libs (fieldFunctionObjects);
field p;
model unequalBinWidth;
// Conditional entries
ranges
(
// min max
(-10 -9) // bin-0
(-9 -8) // bin-1
(-8 -7)
(-7 -6)
(-6 -2)
(-2 0)
(0 5)
(5 10)
);
// Inherited entries
writePrecision 6;
writeToFile true;
useUserTime true;