outletMachNumberPressureFvPatchScalarField.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) 2018-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
30 #include "fvPatchFieldMapper.H"
31 #include "volFields.H"
32 #include "surfaceFields.H"
33 #include "fluidThermo.H"
34 #include "constants.H"
35 
36 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
37 
40 (
41  const fvPatch& p,
43 )
44 :
45  fixedValueFvPatchScalarField(p, iF),
46  M_(1),
47  pBack_(0.0),
48  c1_(0.0),
49  A1_(0.0),
50  phiName_("phi"),
51  rhoName_("rho"),
52  UName_("U"),
53  choked_(false),
54  relax_(0.0)
55 {}
56 
57 
60 (
61  const fvPatch& p,
63  const dictionary& dict
64 )
65 :
66  fixedValueFvPatchScalarField(p, iF, dict),
67  M_(dict.getOrDefault<scalar>("M", 0)),
68  pBack_(dict.get<scalar>("pBack")),
69  c1_(dict.getOrDefault<scalar>("c1", 0)),
70  A1_(dict.getOrDefault<scalar>("A1", 0)),
71  phiName_(dict.getOrDefault<word>("phi", "phi")),
72  rhoName_(dict.getOrDefault<word>("rho", "rho")),
73  UName_(dict.getOrDefault<word>("U", "U")),
74  choked_(dict.get<Switch>("choked")),
75  relax_(dict.getOrDefault<scalar>("relax", 0))
76 {}
77 
78 
81 (
83  const fvPatch& p,
85  const fvPatchFieldMapper& mapper
86 )
87 :
88  fixedValueFvPatchScalarField(ptf, p, iF, mapper),
89  M_(ptf.M_),
90  pBack_(ptf.pBack_),
91  c1_(ptf.c1_),
92  A1_(ptf.A1_),
93  phiName_(ptf.phiName_),
94  rhoName_(ptf.rhoName_),
95  UName_(ptf.UName_),
96  choked_(ptf.choked_),
97  relax_(ptf.relax_)
98 {}
99 
100 
103 (
105 )
106 :
107  fixedValueFvPatchScalarField(tppsf),
108  M_(tppsf.M_),
109  pBack_(tppsf.pBack_),
110  c1_(tppsf.c1_),
111  A1_(tppsf.A1_),
112  phiName_(tppsf.phiName_),
113  rhoName_(tppsf.rhoName_),
114  UName_(tppsf.UName_),
115  choked_(tppsf.choked_),
116  relax_(tppsf.relax_)
117 {}
118 
119 
122 (
125 )
126 :
127  fixedValueFvPatchScalarField(tppsf, iF),
128  M_(tppsf.M_),
129  pBack_(tppsf.pBack_),
130  c1_(tppsf.c1_),
131  A1_(tppsf.A1_),
132  phiName_(tppsf.phiName_),
133  rhoName_(tppsf.rhoName_),
134  UName_(tppsf.UName_),
135  choked_(tppsf.choked_),
136  relax_(tppsf.relax_)
137 {}
138 
139 
140 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
141 
143 {
144  if (updated())
145  {
146  return;
147  }
148 
149  const volScalarField& p =
150  db().lookupObject<volScalarField>
151  (
152  this->internalField().name()
153  );
154 
155  const label patchi = patch().index();
156 
157  const scalarField pb(p.oldTime().boundaryField()[patchi]);
158 
159  const auto& phi = patch().lookupPatchField<surfaceScalarField>(phiName_);
160 
161  // Calculate the current mass flow rate
162  if (phi.internalField().dimensions() != dimMass/dimTime)
163  {
165  <<"phi is not a mass flux." << exit(FatalError);
166  }
167 
168  const fluidThermo* thermoPtr =
169  db().findObject<fluidThermo>(basicThermo::dictName);
170 
171  const volVectorField& U = db().lookupObject<volVectorField>(UName_);
172 
173  vectorField Ub(U.boundaryField()[patchi]);
174  const vectorField UbOld(U.oldTime().boundaryField()[patchi]);
175 
176  // relax U
177  Ub = relax_*UbOld + (1 - relax_)*Ub;
178 
179  const scalarField gamma(thermoPtr->gamma()().boundaryField()[patchi]);
180 
181  const auto& rho = patch().lookupPatchField<volScalarField>(rhoName_);
182 
183  const scalarField Mb(mag(Ub)/sqrt(gamma*pb/rho));
184 
185  const scalarField ptot
186  (
187  pb*(pow(1 + (gamma-1)/2*sqr(gAverage(Mb)), gamma/(gamma-1)))
188  );
189 
190  scalarField M(patch().size(), 1.0);
191 
192  if (choked_)
193  {
194  if (M_ > 0.0)
195  {
196  M = M_;
197  }
198  else
199  {
200  FatalErrorInFunction <<" Mach number is lower than zero" << endl
201  << "Pelase specify M in the dictionary"
202  << exit(FatalError);
203  }
204  }
205  else
206  {
207 
208  if (A1_ == 0.0 || c1_ == 0.0)
209  {
210  FatalErrorInFunction <<" Please enter values for A1 and c1" << endl
211  << exit(FatalError);
212  }
213 
214  const scalarField r(pBack_/ptot);
215  const scalar area = gSum(mag(patch().Sf()));
216  M =
217  A1_/(c1_*area)
218  *sqrt(2/(gamma-1)*(pow(r, 2/gamma) - pow(r, (gamma+1)/gamma)));
219 
220  forAll(M, i)
221  {
222  if (M[i] < 0 || r[i] >=1)
223  {
224  WarningInFunction <<" Mach number is lower than zero" << endl
225  << "or pBack/ptot ratio is larger then one"
226  << endl;
227  }
228  }
229  }
230 
231  scalarField pbNew
232  (
233  ptot/(pow(1 + (gamma-1)/2*sqr(gAverage(M)), gamma/(gamma-1)))
234  );
235 
236  // relax pressure
237  pbNew = relax_*pb + (1 -relax_)*pbNew;
239  operator==(pbNew);
240 
241  fixedValueFvPatchScalarField::updateCoeffs();
242 }
243 
244 
246 {
248  os.writeEntry("pBack", pBack_);
249  os.writeEntryIfDifferent<scalar>("c1", 0, c1_);
250  os.writeEntryIfDifferent<scalar>("A1", 0, A1_);
251  os.writeEntry("choked", choked_);
252  os.writeEntryIfDifferent<scalar>("relax", 0, relax_);
253 
254  os.writeEntryIfDifferent<word>("phi", "phi", phiName_);
255  os.writeEntryIfDifferent<word>("rho", "rho", rhoName_);
256  os.writeEntryIfDifferent<word>("U", "U", UName_);
257  os.writeEntryIfDifferent<scalar>("M", 0, M_);
258 
260 }
261 
262 
263 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
264 
265 namespace Foam
266 {
268  (
270  outletMachNumberPressureFvPatchScalarField
271  );
272 }
273 
274 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
Foam::surfaceFields.
word dictName() const
The local dictionary name (final part of scoped name)
Definition: dictionaryI.H:53
dictionary dict
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:70
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, any/none. Also accepts 0/1 as a string and shortcuts t/f, y/n.
Definition: Switch.H:77
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:321
void writeValueEntry(Ostream &os) const
Write *this field as a "value" entry.
Definition: fvPatchField.H:375
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
virtual void write(Ostream &) const
Write.
Definition: fvPatchField.C:372
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:82
Macros for easy insertion into run-time selection tables.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:81
Type gSum(const FieldField< Field, Type > &f)
fvPatchField< scalar > fvPatchScalarField
const wordList area
Standard area field types (scalar, vector, tensor, etc)
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
A FieldMapper for finite-volume patch fields.
This boundary condition maintains a certain subsonic Mach number at an outlet patch by dynamically ad...
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Definition: Ostream.H:336
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
U
Definition: pEqn.H:72
#define WarningInFunction
Report a warning using Foam::Warning.
Type gAverage(const FieldField< Field, Type > &f)
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: areaFieldsFwd.H:42
const std::string patch
OpenFOAM patch number as a std::string.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
Field< vector > vectorField
Specialisation of Field<T> for vector.
outletMachNumberPressureFvPatchScalarField(const fvPatch &p, const DimensionedField< scalar, volMesh > &iF)
Construct from patch and internal field.
const scalar gamma
Definition: EEqn.H:9
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:49
volScalarField & p
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
makePatchTypeField(fvPatchScalarField, atmBoundaryLayerInletEpsilonFvPatchScalarField)
#define M(I)
Namespace for OpenFOAM.