tabulatedDensity.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "tabulatedDensity.H"
27 #include "unintegrable.H"
28 #include "SubField.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 namespace distributions
36 {
39 }
40 }
41 
42 
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44 
46 (
47  const unitSet& defaultUnits,
48  const dictionary& dict,
49  const label sampleQ,
51 )
52 :
54  (
55  typeName,
56  defaultUnits,
57  dict,
58  sampleQ,
59  std::move(rndGen)
60  ),
61  reader_
62  (
63  TableReader<scalar, scalar>::New
64  (
65  word::null,
66  {defaultUnits, units::any},
67  dict
68  )
69  )
70 {
72  reader_->read({defaultUnits, units::any}, dict, "distribution");
73 
74  // Checks
75  forAll(values, i)
76  {
77  if (i && values[i].first() - values[i - 1].first() < 0)
78  {
80  << typeName << ": The probability density function is not "
81  << "in order" << abort(FatalIOError);
82  }
83 
84  if (values[i].second() < 0)
85  {
87  << typeName << ": The probability density function is not "
88  << "positive" << abort(FatalIOError);
89  }
90  }
91 
92  // Copy the coordinates
93  x_.resize(values.size());
94  forAll(values, i)
95  {
96  x_[i] = values[i].first();
97  }
98 
99  // Copy the PDF. Scale if q != 0.
100  PDF_.resize(values.size());
101  forAll(values, i)
102  {
103  PDF_[i] = integerPow(x_[i], q())*values[i].second();
104  }
105 
106  // Compute the CDF
107  CDF_.resize(values.size());
108  CDF_ = unintegrable::integrate(x_, PDF_);
109 
110  // Normalise the PDF and the CDF
111  PDF_ /= CDF_.last();
112  CDF_ /= CDF_.last();
113 
114  // More checks
115  validateBounds(dict);
116  if (q() != 0) validatePositive(dict);
117 }
118 
119 
121 (
122  const tabulatedDensity& d,
123  const label sampleQ
124 )
125 :
127  reader_(d.reader_, false),
128  x_(d.x_),
129  PDF_(d.PDF_),
130  CDF_(d.CDF_)
131 {
132  if (q() == d.q()) return;
133 
134  // Scale the PDF
135  PDF_ = integerPow(x_, q() - d.q())*d.PDF_;
136 
137  // Compute the CDF
138  CDF_ = unintegrable::integrate(x_, PDF_);
139 
140  // Normalise the PDF and the CDF
141  PDF_ /= CDF_.last();
142  CDF_ /= CDF_.last();
143 }
144 
145 
146 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
147 
149 {}
150 
151 
152 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
153 
155 {
156  return unintegrable::sample(x_, PDF_, CDF_, rndGen_.sample01<scalar>());
157 }
158 
159 
161 {
162  return x_.first();
163 }
164 
165 
167 {
168  return x_.last();
169 }
170 
171 
173 {
174  return unintegrable::integrateX(x_, PDF_)->last();
175 }
176 
177 
180 (
181  const scalarField& x,
182  const label e,
183  const bool
184 ) const
185 {
186  return unintegrable::interpolateIntegrateXPow(x_, e, PDF_, x);
187 }
188 
189 
191 (
192  Ostream& os,
193  const unitSet& units
194 ) const
195 {
197 
198  // Recover the PDF
199  scalarField PDF(integerPow(x_, -q())*PDF_);
200 
201  // Normalise the PDF
202  PDF /= unintegrable::integrate(x_, PDF)->last();
203 
204  // Construct and write the values
205  List<Tuple2<scalar, scalar>> values(PDF_.size());
206  forAll(values, i)
207  {
208  values[i].first() = x_[i];
209  values[i].second() = PDF[i];
210  }
211  reader_->write(os, {units, units::any}, values, "distribution");
212 }
213 
214 
217 {
218  const scalar x0 = min(), x1 = max(), d = 0.1*(x1 - x0);
219 
220  tmp<scalarField> tResult(new scalarField(x_.size() + 4));
221  scalarField& result = tResult.ref();
222 
223  result[0] = Foam::max(x0 - d, q() < 0 ? x0/2 : rootVSmall);
224  result[1] = x0;
225 
226  SubField<scalar>(result, x_.size(), 2) = x_;
227 
228  result[x_.size() + 2] = x1;
229  result[x_.size() + 3] = x1 + d;
230 
231  return tResult;
232 }
233 
234 
237 {
238  tmp<scalarField> tResult(new scalarField(PDF_.size() + 4, 0));
239  scalarField& result = tResult.ref();
240 
241  SubField<scalar>(result, PDF_.size(), 2) = PDF_;
242 
243  return tResult;
244 }
245 
246 
247 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
Pre-declare related SubField type.
Definition: SubField.H:63
Base class to read table data for tables.
Definition: TableReader.H:51
T & first()
Return the first element of the list.
Definition: UListI.H:114
T & last()
Return the last element of the list.
Definition: UListI.H:128
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Base class for statistical distributions.
Definition: distribution.H:76
label q() const
Return the effective distribution size exponent.
Definition: distribution.H:107
Distribution in which the probability density function is given as a table of values.
virtual tmp< scalarField > integralPDFxPow(const scalarField &x, const label e, const bool consistent=false) const
Return the integral of the PDF multiplied by an integer power of x.
virtual scalar min() const
Return the minimum value.
virtual scalar sample() const
Sample the distribution.
tabulatedDensity(const unitSet &units, const dictionary &dict, const label sampleQ, randomGenerator &&rndGen)
Construct from a dictionary.
virtual tmp< scalarField > plotPDF(const scalarField &x) const
Return values to plot the probability density function.
virtual void write(Ostream &os, const unitSet &units) const
Write to a stream.
virtual scalar max() const
Return the maximum value.
virtual scalar mean() const
Return the mean value.
virtual tmp< scalarField > plotX(const label n) const
Return coordinates to plot across the range of the distribution.
virtual scalar sample() const
Sample the distribution.
Definition: unintegrable.C:416
static tmp< scalarField > integrate(const scalarField &x, const scalarField &y)
Integrate the values y with respect to the coordinates x.
Definition: unintegrable.C:34
static tmp< scalarField > integrateX(const scalarField &x, const scalarField &y)
Integrate the values x*y with respect to the coordinates x.
Definition: unintegrable.C:54
static tmp< scalarField > interpolateIntegrateXPow(const scalarField &xStar, const label e, const scalarField &yStar, const scalarField &x)
Integrate the values x^e*y with respect to the coordinates x,.
Definition: unintegrable.C:79
Random number generator.
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
Unit conversion structure. Contains the associated dimensions and the multiplier with which to conver...
Definition: unitSet.H:68
A class for handling words, derived from string.
Definition: word.H:63
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
defineTypeNameAndDebug(exponential, 0)
addToRunTimeSelectionTable(distribution, exponential, dictionary)
const unitSet any
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:106
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
errorManip< error > abort(error &err)
Definition: errorManip.H:131
scalar integerPow(const scalar x, const label e)
Compute the power of the number x to the integer e.
Definition: scalarI.H:30
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
IOerror FatalIOError
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dictionary dict
randomGenerator rndGen(653213)