flowRateOutletVelocityFvPatchVectorField.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) 2017-2024 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 
27 #include "volFields.H"
29 
30 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
31 
32 template<class RhoType>
33 void Foam::flowRateOutletVelocityFvPatchVectorField::updateValues
34 (
35  const RhoType& rho
36 )
37 {
38  const vectorField n(patch().nf());
39 
40  // Extrapolate patch velocity
41  vectorField Up(this->patchInternalField());
42 
43  // Patch normal extrapolated velocity
44  scalarField nUp(n & Up);
45 
46  // Remove the normal component of the extrapolate patch velocity
47  Up -= nUp*n;
48 
49  // Remove any reverse flow
50  nUp = max(nUp, scalar(0));
51 
52  const scalar flowRate = flowRate_->value(db().time().value());
53  const scalar estimatedFlowRate = gSum(rho*(this->patch().magSf()*nUp));
54 
55  if (estimatedFlowRate/flowRate > 0.5)
56  {
57  nUp *= (mag(flowRate)/mag(estimatedFlowRate));
58  }
59  else
60  {
61  nUp += ((flowRate - estimatedFlowRate)/gSum(rho*patch().magSf()));
62  }
63 
64  // Add the corrected normal component of velocity to the patch velocity
65  Up += nUp*n;
66 
67  // Correct the patch velocity
68  this->operator==(Up);
69 }
70 
71 
72 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
73 
76 (
77  const fvPatch& p,
79  const dictionary& dict
80 )
81 :
82  fixedValueFvPatchField<vector>(p, iF, dict, false),
83  flowRate_(),
84  volumetric_(),
85  rhoName_("rho"),
86  rhoOutlet_(dict.lookupOrDefault<scalar>("rhoOutlet", dimDensity, -vGreat))
87 {
88  if (dict.found("volumetricFlowRate"))
89  {
90  flowRate_ =
92  (
93  "volumetricFlowRate",
94  db().time().userUnits(),
96  dict
97  );
98  volumetric_ = true;
99  }
100  else if (dict.found("massFlowRate"))
101  {
102  flowRate_ =
104  (
105  "massFlowRate",
106  db().time().userUnits(),
107  dimMassFlux,
108  dict
109  );
110  volumetric_ = false;
111  rhoName_ = word(dict.lookupOrDefault<word>("rho", "rho"));
112  }
113  else
114  {
116  << "Please supply either 'volumetricFlowRate' or"
117  << " 'massFlowRate' and 'rho'" << exit(FatalIOError);
118  }
119 
120  // Value field required if mass based
121  if (dict.found("value"))
122  {
124  (
125  vectorField("value", iF.dimensions(), dict, p.size())
126  );
127  }
128  else
129  {
131  }
132 }
133 
134 
137 (
139  const fvPatch& p,
141  const fieldMapper& mapper
142 )
143 :
144  fixedValueFvPatchField<vector>(ptf, p, iF, mapper),
145  flowRate_(ptf.flowRate_, false),
146  volumetric_(ptf.volumetric_),
147  rhoName_(ptf.rhoName_),
148  rhoOutlet_(ptf.rhoOutlet_)
149 {}
150 
151 
154 (
157 )
158 :
159  fixedValueFvPatchField<vector>(ptf, iF),
160  flowRate_(ptf.flowRate_, false),
161  volumetric_(ptf.volumetric_),
162  rhoName_(ptf.rhoName_),
163  rhoOutlet_(ptf.rhoOutlet_)
164 {}
165 
166 
167 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
168 
170 {
171  if (updated())
172  {
173  return;
174  }
175 
176  if (volumetric_ || rhoName_ == "none")
177  {
178  updateValues(one());
179  }
180  else
181  {
182  // Mass flow-rate
183  if (db().foundObject<volScalarField>(rhoName_))
184  {
185  const fvPatchField<scalar>& rhop =
186  patch().lookupPatchField<volScalarField, scalar>(rhoName_);
187 
188  updateValues(rhop);
189  }
190  else
191  {
192  // Use constant density
193  if (rhoOutlet_ < 0)
194  {
196  << "Did not find registered density field " << rhoName_
197  << " and no constant density 'rhoOutlet' specified"
198  << exit(FatalError);
199  }
200 
201  updateValues(rhoOutlet_);
202  }
203  }
204 
205  fixedValueFvPatchVectorField::updateCoeffs();
206 }
207 
208 
210 {
212  writeEntry(os, db().time().userUnits(), unitAny, flowRate_());
213  if (!volumetric_)
214  {
215  writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_);
216  writeEntryIfDifferent<scalar>(os, "rhoOutlet", -vGreat, rhoOutlet_);
217  }
218  writeEntry(os, "value", *this);
219 }
220 
221 
222 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
223 
224 namespace Foam
225 {
227  (
230  );
231 }
232 
233 
234 // ************************************************************************* //
label n
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const dimensionSet & dimensions() const
Return dimensions.
static autoPtr< Function1< Type > > New(const word &name, const Function1s::unitConversions &units, const dictionary &dict)
Select from dictionary.
Definition: Function1New.C:32
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
Abstract base class for field mapping.
Definition: fieldMapper.H:48
This boundary condition supplies a fixed value constraint, and is the base class for a number of othe...
Velocity outlet boundary condition which corrects the extrapolated velocity to match the specified fl...
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
flowRateOutletVelocityFvPatchVectorField(const fvPatch &, const DimensionedField< vector, volMesh > &, const dictionary &)
Construct from patch, internal field and dictionary.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:88
virtual void write(Ostream &) const
Write.
Definition: fvPatchField.C:229
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:64
A class representing the concept of 1 (scalar(1)) used to avoid unnecessary manipulations for objects...
Definition: one.H:51
A class for handling words, derived from string.
Definition: word.H:62
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Type gSum(const FieldField< Field, Type > &f)
const unitConversion unitAny
tmp< fvMatrix< Type > > operator==(const fvMatrix< Type > &, const fvMatrix< Type > &)
const dimensionSet dimMassFlux
const dimensionSet dimVolumetricFlux
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
const dimensionSet dimDensity
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:64
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Field< vector > vectorField
Specialisation of Field<T> for vector.
IOerror FatalIOError
void evaluate(GeometricField< Type, PatchField, GeoMesh > &result, const Function1< Type > &func, const GeometricField< Type, PatchField, GeoMesh > &x)
error FatalError
makePatchTypeField(fvPatchScalarField, atmBoundaryLayerInletEpsilonFvPatchScalarField)
dictionary dict
volScalarField & p