From 1a54b2ecfc6b1503d10690244bb23a3f5ed985bc Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Fri, 16 Aug 2019 09:01:30 +0100 Subject: [PATCH] lagrangian: distributionModels: Cumulative general distribution The general distribution has been extended to accept cumulative distribution data, by means of a "cumulative" switch. The calculation of the mean value has also been corrected for this distribution, and additional header documentation and parameter checking has been added. In addition, the distribution models now all print some basic information (min, max and mean) into the log file to help in checking that the specification is correct. Patch contributed by Timo Niemi, VTT. --- applications/test/Distribution2/Make/files | 3 + applications/test/Distribution2/Make/options | 5 + .../test/Distribution2/Test-Distribution2.C | 105 ++++++++++++++++++ applications/test/Distribution2/createGraphs | 24 ++++ .../Distribution2/cumulativeTest_expected | 17 +++ .../test/Distribution2/densityTest_expected | 17 +++ applications/test/Distribution2/testDict | 77 +++++++++++++ .../RosinRammler/RosinRammler.C | 3 +- .../distributionModel/distributionModel.C | 9 +- .../distributionModel/distributionModel.H | 3 + .../exponential/exponential.C | 3 +- .../fixedValue/fixedValue.C | 6 +- .../distributionModels/general/general.C | 73 ++++++++++-- .../distributionModels/general/general.H | 19 +++- .../massRosinRammler/massRosinRammler.C | 3 +- .../multiNormal/multiNormal.C | 4 +- .../distributionModels/normal/normal.C | 19 +--- .../distributionModels/uniform/uniform.C | 3 +- 18 files changed, 360 insertions(+), 33 deletions(-) create mode 100644 applications/test/Distribution2/Make/files create mode 100644 applications/test/Distribution2/Make/options create mode 100644 applications/test/Distribution2/Test-Distribution2.C create mode 100755 applications/test/Distribution2/createGraphs create mode 100644 applications/test/Distribution2/cumulativeTest_expected create mode 100644 applications/test/Distribution2/densityTest_expected create mode 100644 applications/test/Distribution2/testDict diff --git a/applications/test/Distribution2/Make/files b/applications/test/Distribution2/Make/files new file mode 100644 index 0000000000..723a0b5e3e --- /dev/null +++ b/applications/test/Distribution2/Make/files @@ -0,0 +1,3 @@ +Test-Distribution2.C + +EXE = $(FOAM_USER_APPBIN)/Test-Distribution2 diff --git a/applications/test/Distribution2/Make/options b/applications/test/Distribution2/Make/options new file mode 100644 index 0000000000..ae86ebecef --- /dev/null +++ b/applications/test/Distribution2/Make/options @@ -0,0 +1,5 @@ +EXE_INC = \ + -I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \ + +EXE_LIBS = \ + -ldistributionModels diff --git a/applications/test/Distribution2/Test-Distribution2.C b/applications/test/Distribution2/Test-Distribution2.C new file mode 100644 index 0000000000..96816a4907 --- /dev/null +++ b/applications/test/Distribution2/Test-Distribution2.C @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2019 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 . + +Application + Test-Distribution2 + +Description + Test the general distributionModel. + +\*---------------------------------------------------------------------------*/ + +#include "Distribution.H" +#include "Random.H" +#include "dimensionedTypes.H" +#include "argList.H" +#include "distributionModel.H" +#include "IFstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +using namespace Foam; + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + + Random R(918273); + + dictionary dict(IFstream("testDict")()); + + Info << nl << "Testing general distribution" << endl; + Info << nl << "Continuous probability density function:" << endl; + + autoPtr dist1 + ( + distributionModel::New + ( + dict.subDict("densityFunction"), + R + ) + ); + + label randomDistributionTestSize = 50000000; + Distribution dS(scalar(1e-6)); + + Info<< nl + << "Sampling " << randomDistributionTestSize << " times." << endl; + + for (label i = 0; i < randomDistributionTestSize; i++) + { + dS.add(dist1->sample()); + } + + Info<< "Produced mean " << dS.mean() << endl; + dS.write("densityTest"); + dS.clear(); + + Info << nl << "Discrete probability density function:" << endl; + dist1.clear(); + + dist1 = + distributionModel::New + ( + dict.subDict("cumulativeFunction"), + R + ); + + Info<< nl + << "Sampling " << randomDistributionTestSize << " times." << endl; + + for (label i = 0; i < randomDistributionTestSize; i++) + { + dS.add(dist1->sample()); + } + + Info<< "Produced mean " << dS.mean() << endl; + dS.write("cumulativeTest"); + + Info<< nl << "End" << nl << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/Distribution2/createGraphs b/applications/test/Distribution2/createGraphs new file mode 100755 index 0000000000..bbcb522f08 --- /dev/null +++ b/applications/test/Distribution2/createGraphs @@ -0,0 +1,24 @@ +#!/bin/sh + +gnuplot< 0 && xy_[i][0] <= xy_[i-1][0]) + { + FatalErrorInFunction + << type() << "distribution: " + << "The points must be specified in ascending order." + << abort(FatalError); + } + + if (xy_[i][1] < 0) + { + FatalErrorInFunction + << type() << "distribution: " + << "The distribution can't be negative." + << abort(FatalError); + } + + if (i > 0 && cumulative_ && xy_[i][1] < xy_[i-1][1]) + { + FatalErrorInFunction + << type() << "distribution: " + << "Cumulative distribution must be non-decreasing." + << abort(FatalError); + } + } + + // Fill out the integral table (x, P(x<=0)) and calculate mean + // For density function: P(x<=0) = int f(x) and mean = int x*f(x) + // For cumulative function: mean = int 1-P(x<=0) = maxValue_ - int P(x<=0) integral_[0] = 0.0; for (label i=1; i, scalar, 2> pair; + //- List of (x, y=f(x)) pairs List xy_; + //- Amount of entries in the xy_ list label nEntries_; - //- Min and max values of the distribution + //- Distribution minimum scalar minValue_; + + //- Distribution maximum scalar maxValue_; + //- Distribution mean scalar meanValue_; + //- Values of cumulative distribution function List integral_; + //- Is the distribution specified as cumulative or as density + Switch cumulative_; + public: diff --git a/src/lagrangian/distributionModels/massRosinRammler/massRosinRammler.C b/src/lagrangian/distributionModels/massRosinRammler/massRosinRammler.C index f79856f7a6..bfac21ff43 100644 --- a/src/lagrangian/distributionModels/massRosinRammler/massRosinRammler.C +++ b/src/lagrangian/distributionModels/massRosinRammler/massRosinRammler.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2016-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2016-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -52,6 +52,7 @@ Foam::distributionModels::massRosinRammler::massRosinRammler n_(readScalar(distributionModelDict_.lookup("n"))) { check(); + info(); } diff --git a/src/lagrangian/distributionModels/multiNormal/multiNormal.C b/src/lagrangian/distributionModels/multiNormal/multiNormal.C index 5f99be88b9..e098f84558 100644 --- a/src/lagrangian/distributionModels/multiNormal/multiNormal.C +++ b/src/lagrangian/distributionModels/multiNormal/multiNormal.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -78,6 +78,8 @@ Foam::distributionModels::multiNormal::multiNormal { strength_[i] /= sMax; } + + info(); } diff --git a/src/lagrangian/distributionModels/normal/normal.C b/src/lagrangian/distributionModels/normal/normal.C index 7c9d3d687d..037a87c008 100644 --- a/src/lagrangian/distributionModels/normal/normal.C +++ b/src/lagrangian/distributionModels/normal/normal.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -53,21 +53,8 @@ Foam::distributionModels::normal::normal variance_(readScalar(distributionModelDict_.lookup("variance"))), a_(0.147) { - if (minValue_ < 0) - { - FatalErrorInFunction - << "Minimum value must be greater than zero. " - << "Supplied minValue = " << minValue_ - << abort(FatalError); - } - - if (maxValue_ < minValue_) - { - FatalErrorInFunction - << "Maximum value is smaller than the minimum value:" - << " maxValue = " << maxValue_ << ", minValue = " << minValue_ - << abort(FatalError); - } + check(); + info(); } diff --git a/src/lagrangian/distributionModels/uniform/uniform.C b/src/lagrangian/distributionModels/uniform/uniform.C index 56cc2e6730..0aa726b9aa 100644 --- a/src/lagrangian/distributionModels/uniform/uniform.C +++ b/src/lagrangian/distributionModels/uniform/uniform.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -50,6 +50,7 @@ Foam::distributionModels::uniform::uniform maxValue_(readScalar(distributionModelDict_.lookup("maxValue"))) { check(); + info(); }