pressure.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2012-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "pressure.H"
30#include "volFields.H"
31#include "basicThermo.H"
34
35// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36
37namespace Foam
38{
39namespace functionObjects
40{
43}
44}
45
46
47const Foam::Enum
48<
50>
52({
53 { STATIC, "static" },
54 { TOTAL, "total" },
55 { ISENTROPIC, "isentropic" },
56 { STATIC_COEFF, "staticCoeff" },
57 { TOTAL_COEFF, "totalCoeff" },
58});
59
60
61const Foam::Enum
62<
64>
66({
67 { NONE, "none" },
68 { ADD, "add" },
69 { SUBTRACT, "subtract" },
70});
71
72
73// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
74
75Foam::word Foam::functionObjects::pressure::resultName() const
76{
77 word rName;
78
79 if (mode_ & STATIC)
80 {
81 rName = "static(" + fieldName_ + ")";
82 }
83 else if (mode_ & TOTAL)
84 {
85 rName = "total(" + fieldName_ + ")";
86 }
87 else if (mode_ & ISENTROPIC)
88 {
89 rName = "isentropic(" + fieldName_ + ")";
90 }
91 else
92 {
94 << "Unhandled calculation mode " << modeNames[mode_]
95 << abort(FatalError);
96 }
97
98 switch (hydrostaticMode_)
99 {
100 case NONE:
101 {
102 break;
103 }
104 case ADD:
105 {
106 rName = rName + "+rgh";
107
108 break;
109 }
110 case SUBTRACT:
111 {
112 rName = rName + "-rgh";
113
114 break;
115 }
116 }
117
118 if (mode_ & COEFF)
119 {
120 rName += "_coeff";
121 }
122
123 return rName;
124}
125
126
127Foam::tmp<Foam::volScalarField> Foam::functionObjects::pressure::rhoScale
128(
129 const volScalarField& p
130) const
131{
132 if (p.dimensions() == dimPressure)
133 {
135 (
136 IOobject
137 (
138 "rhoScale",
139 p.mesh().time().timeName(),
140 p.mesh(),
143 false
144 ),
145 p,
146 fvPatchField<scalar>::calculatedType()
147 );
148 }
149
150 if (!rhoInfInitialised_)
151 {
153 << type() << " " << name() << ": "
154 << "pressure identified as incompressible, but reference "
155 << "density is not set. Please set 'rho' to 'rhoInf', and "
156 << "set an appropriate value for 'rhoInf'"
157 << exit(FatalError);
158 }
159
160 return dimensionedScalar("rhoInf", dimDensity, rhoInf_)*p;
161}
162
163
164Foam::tmp<Foam::volScalarField> Foam::functionObjects::pressure::rhoScale
165(
166 const volScalarField& p,
167 const tmp<volScalarField>& tsf
168) const
169{
170 if (p.dimensions() == dimPressure)
171 {
172 return lookupObject<volScalarField>(rhoName_)*tsf;
173 }
174
175 return dimensionedScalar("rhoInf", dimDensity, rhoInf_)*tsf;
176}
177
178
179void Foam::functionObjects::pressure::addHydrostaticContribution
180(
181 const volScalarField& p,
182 volScalarField& prgh
183) const
184{
185 // Add/subtract hydrostatic contribution
186
187 if (hydrostaticMode_ == NONE)
188 {
189 return;
190 }
191
192 if (!gInitialised_)
193 {
194 g_ = mesh_.time().lookupObject<uniformDimensionedVectorField>("g");
195 }
196
197 if (!hRefInitialised_)
198 {
199 hRef_ = mesh_.lookupObject<uniformDimensionedScalarField>("hRef");
200 }
201
202 const dimensionedScalar ghRef
203 (
204 (g_ & (cmptMag(g_.value())/mag(g_.value())))*hRef_
205 );
206
207 tmp<volScalarField> rgh = rhoScale(p, (g_ & mesh_.C()) - ghRef);
208
209 switch (hydrostaticMode_)
210 {
211 case ADD:
212 {
213 prgh += rgh;
214 break;
215 }
216 case SUBTRACT:
217 {
218 prgh -= rgh;
219 break;
220 }
221 default:
222 {}
223 }
224}
225
226
227Foam::tmp<Foam::volScalarField> Foam::functionObjects::pressure::calcPressure
228(
229 const volScalarField& p,
230 const tmp<volScalarField>& tp
231) const
232{
233 // Initialise to the pressure reference level
234 auto tresult =
236 (
237 IOobject
238 (
239 scopedName("p"),
240 mesh_.time().timeName(),
241 mesh_,
243 ),
244 mesh_,
245 dimensionedScalar("p", dimPressure, pRef_)
246 );
247
248 volScalarField& result = tresult.ref();
249
250 addHydrostaticContribution(p, result);
251
252 if (mode_ & STATIC)
253 {
254 result += tp;
255 return tresult;
256 }
257
258 if (mode_ & TOTAL)
259 {
260 result +=
261 tp
262 + rhoScale(p, 0.5*magSqr(lookupObject<volVectorField>(UName_)));
263 return tresult;
264 }
265
266 if (mode_ & ISENTROPIC)
267 {
268 const basicThermo* thermoPtr =
269 p.mesh().cfindObject<basicThermo>(basicThermo::dictName);
270
271 if (!thermoPtr)
272 {
274 << "Isentropic pressure calculation requires a "
275 << "thermodynamics package"
276 << exit(FatalError);
277 }
278
279 const volScalarField gamma(thermoPtr->gamma());
280 const volScalarField Mb
281 (
282 mag(lookupObject<volVectorField>(UName_))
283 /sqrt(gamma*tp.ref()/thermoPtr->rho())
284 );
285
286 result += tp*(pow(1 + (gamma - 1)/2*sqr(Mb), gamma/(gamma - 1)));
287 return tresult;
288 }
289
290 return tresult;
291}
292
293
294Foam::tmp<Foam::volScalarField> Foam::functionObjects::pressure::coeff
295(
296 const tmp<volScalarField>& tp
297) const
298{
299 if (mode_ & COEFF)
300 {
301 tmp<volScalarField> tpCoeff(tp.ptr());
302 volScalarField& pCoeff = tpCoeff.ref();
303
304 pCoeff -= dimensionedScalar("pInf", dimPressure, pInf_);
305
306 const dimensionedScalar pSmall("pSmall", dimPressure, SMALL);
307 const dimensionedVector U("U", dimVelocity, UInf_);
308 const dimensionedScalar rho("rho", dimDensity, rhoInf_);
309
310 pCoeff /= 0.5*rho*magSqr(U) + pSmall;
311
312 return tpCoeff;
313 }
314
315 return std::move(tp);
316}
317
318
319// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
320
321bool Foam::functionObjects::pressure::calc()
322{
323 if (foundObject<volScalarField>(fieldName_))
324 {
325 const volScalarField& p = lookupObject<volScalarField>(fieldName_);
326
328 (
329 IOobject
330 (
331 resultName_,
332 p.mesh().time().timeName(),
333 p.mesh(),
336 ),
337 coeff(calcPressure(p, rhoScale(p)))
338 );
339
340 return store(resultName_, tp);
341 }
342
343 return false;
344}
345
346
347// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
348
350(
351 const word& name,
352 const Time& runTime,
353 const dictionary& dict
354)
355:
357 mode_(STATIC),
358 hydrostaticMode_(NONE),
359 UName_("U"),
360 rhoName_("rho"),
361 pRef_(0),
362 pInf_(0),
363 UInf_(Zero),
364 rhoInf_(1),
365 rhoInfInitialised_(false),
366 g_(dimAcceleration),
367 gInitialised_(false),
368 hRef_(dimLength),
369 hRefInitialised_(false)
370{
371 read(dict);
372}
373
374
375// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
376
378{
379 Info<< type() << " " << name() << ":" << nl;
380
382
383 UName_ = dict.getOrDefault<word>("U", "U");
384 rhoName_ = dict.getOrDefault<word>("rho", "rho");
385
386 if (rhoName_ == "rhoInf")
387 {
388 dict.readEntry("rhoInf", rhoInf_);
389 rhoInfInitialised_ = true;
390 }
391
392 if (!modeNames.readIfPresent("mode", dict, mode_))
393 {
394 // Backwards compatibility
395 // - check for the presence of 'calcTotal' and 'calcCoeff'
396
397 bool calcTotal =
398 dict.getOrDefaultCompat<bool>("mode", {{"calcTotal", 1812}}, false);
399 bool calcCoeff =
400 dict.getOrDefaultCompat<bool>("mode", {{"calcCoeff", 1812}}, false);
401
402 if (calcTotal)
403 {
404 mode_ = TOTAL;
405 }
406 else
407 {
408 mode_ = STATIC;
409 }
410
411 if (calcCoeff)
412 {
413 mode_ = static_cast<mode>(COEFF | mode_);
414 }
415 }
416
417 Info<< " Operating mode: " << modeNames[mode_] << nl;
418
419 pRef_ = dict.getOrDefault<scalar>("pRef", 0);
420
421 if
422 (
423 hydrostaticModeNames.readIfPresent
424 (
425 "hydrostaticMode",
426 dict,
427 hydrostaticMode_
428 )
429 && hydrostaticMode_
430 )
431 {
432 Info<< " Hydrostatic mode: "
433 << hydrostaticModeNames[hydrostaticMode_]
434 << nl;
435 gInitialised_ = dict.readIfPresent("g", g_);
436 hRefInitialised_ = dict.readIfPresent("hRef", hRef_);
437 }
438 else
439 {
440 Info<< " Not including hydrostatic effects" << nl;
441 }
442
443
444 if (mode_ & COEFF)
445 {
446 dict.readEntry("pInf", pInf_);
447 dict.readEntry("UInf", UInf_);
448 dict.readEntry("rhoInf", rhoInf_);
449
450 const scalar zeroCheck = 0.5*rhoInf_*magSqr(UInf_) + pInf_;
451
452 if (mag(zeroCheck) < ROOTVSMALL)
453 {
455 << type() << " " << name() << ": "
456 << "Coefficient calculation requested, but reference "
457 << "pressure level is zero. Please check the supplied "
458 << "values of pInf, UInf and rhoInf" << endl;
459 }
460
461 rhoInfInitialised_ = true;
462 }
463
464 resultName_ = dict.getOrDefault<word>("result", resultName());
465
466 Info<< endl;
467
468 return true;
469}
470
471
472// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
Internal & ref(const bool updateAccessTime=true)
Return a reference to the dimensioned internal field.
virtual bool read()
Re-read model coefficients if they have changed.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
static const word dictName
Definition: basicThermo.H:256
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Abstract base-class for Time/database function objects.
Intermediate class for handling field expression function objects (e.g. blendingFactor etc....
word fieldName_
Name of field to process.
Computes the magnitude of the square of an input field.
Definition: magSqr.H:153
Computes the magnitude of an input field.
Definition: mag.H:153
Provides several methods to convert an input pressure field into derived forms, including:
Definition: pressure.H:352
static const Enum< hydrostaticMode > hydrostaticModeNames
Definition: pressure.H:378
hydrostaticMode
Enumeration for hydrostatic contributions.
Definition: pressure.H:372
static const Enum< mode > modeNames
Definition: pressure.H:368
mode
Enumeration for pressure calculation mode.
Definition: pressure.H:359
@ COEFF
Coefficient manipulator.
Definition: pressure.H:363
@ ISENTROPIC
Isentropic pressure.
Definition: pressure.H:362
@ STATIC
Static pressure.
Definition: pressure.H:360
virtual bool read(const dictionary &)
Read the pressure data.
Definition: pressure.C:377
A class for managing temporary objects.
Definition: tmp.H:65
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
U
Definition: pEqn.H:72
volScalarField & p
const scalar gamma
Definition: EEqn.H:9
engineTime & runTime
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define WarningInFunction
Report a warning using Foam::Warning.
@ NONE
No type, or default initialized type.
Namespace for OpenFOAM.
const dimensionSet dimPressure
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:82
UniformDimensionedField< scalar > uniformDimensionedScalarField
const dimensionSet dimVelocity
messageStream Info
Information stream (stdout output on master, null elsewhere)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
UniformDimensionedField< vector > uniformDimensionedVectorField
errorManip< error > abort(error &err)
Definition: errorManip.H:144
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
const dimensionSet dimAcceleration
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
const dimensionSet dimDensity
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict