exprMixedFvPatchField.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) 2009-2018 Bernhard Gschaider
9  Copyright (C) 2019-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 #include "exprMixedFvPatchField.H"
29 
30 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
31 
32 template<class Type>
34 {
35  if (expressions::patchExprFieldBase::debug_ && !debug)
36  {
37  debug = 1;
38  }
39 }
40 
41 
42 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
43 
44 template<class Type>
46 (
47  const fvPatch& p,
49 )
50 :
53  driver_(this->patch())
54 {
55  this->refValue() = Zero;
56  this->refGrad() = Zero;
57  this->valueFraction() = scalar(1);
58 }
59 
60 
61 template<class Type>
63 (
64  const exprMixedFvPatchField<Type>& ptf,
65  const fvPatch& p,
67  const fvPatchFieldMapper& mapper
68 )
69 :
70  mixedFvPatchField<Type>(ptf, p, iF, mapper),
72  driver_(this->patch(), ptf.driver_)
73 {
74  setDebug();
76 }
77 
78 
79 template<class Type>
81 (
82  const fvPatch& p,
84  const dictionary& dict
85 )
86 :
89  (
90  dict,
91  expressions::patchExprFieldBase::expectedTypes::MIXED_TYPE
92  ),
93  driver_(this->patch(), dict)
94 {
95  setDebug();
97 
98  // Require one or both of valueExpr, gradientExpr
99  if (this->valueExpr_.empty() && this->gradExpr_.empty())
100  {
102  << "For " << this->internalField().name() << " on "
103  << this->patch().name() << nl
104  << "Require either or both: valueExpr and gradientExpr" << nl
105  << exit(FatalIOError);
106  }
107 
108  if (this->fracExpr_.empty())
109  {
110  // No fractionExpr. Expect only one of valueExpr or gradientExpr
111  if (!this->valueExpr_.empty() && !this->gradExpr_.empty())
112  {
114  << "For " << this->internalField().name() << " on "
115  << this->patch().name() << nl
116  << "Recommend using fractionExpr when specifying both"
117  << " valueExpr and gradientExpr. Assuming a value of 1."
118  << nl << endl;
119  }
120  }
121  else if (this->fracExpr_ == "0")
122  {
123  // Gradient only. Expect gradientExpr
124  if (this->gradExpr_.empty())
125  {
127  << "For " << this->internalField().name() << " on "
128  << this->patch().name() << nl
129  << "Gradient only, but did not specify gradientExpr."
130  << nl << endl;
131  }
132  }
133  else if (this->fracExpr_ == "1")
134  {
135  // Value only. Expect valueExpr
136  if (this->valueExpr_.empty())
137  {
139  << "For " << this->internalField().name() << " on "
140  << this->patch().name() << nl
141  << "Value only, but did not specify valueExpr."
142  << nl << endl;
143  }
144  }
145 
146 
147  driver_.readDict(dict);
148 
149  // Similar to fvPatchField constructor, which we have bypassed
150  dict.readIfPresent("patchType", this->patchType());
151 
152  bool needsRefValue = true;
153  if (dict.found("refValue"))
154  {
155  needsRefValue = false;
156  this->refValue() = Field<Type>("refValue", dict, p.size());
157  }
158 
159  if (dict.found("value"))
160  {
162  (
163  Field<Type>("value", dict, p.size())
164  );
165 
166  if (needsRefValue)
167  {
168  // Ensure refValue has a sensible value for the "update" below
169  this->refValue() = static_cast<const Field<Type>&>(*this);
170  }
171  }
172  else
173  {
174  if (needsRefValue)
175  {
176  this->refValue() = this->patchInternalField();
177  }
178 
179  fvPatchField<Type>::operator=(this->refValue());
180 
181  #ifdef FULLDEBUG
183  << "No value defined for "
184  << this->internalField().name() << " on "
185  << this->patch().name() << " - using patch internal field" << endl;
186  #endif
187  }
188 
189 
190  if (dict.found("refGradient"))
191  {
192  this->refGrad() = Field<Type>("refGradient", dict, p.size());
193  }
194  else
195  {
196  this->refGrad() = Zero;
197  }
198 
199  if (dict.found("valueFraction"))
200  {
201  this->valueFraction() = Field<scalar>("valueFraction", dict, p.size());
202  }
203  else
204  {
205  this->valueFraction() = scalar(1);
206  }
207 
208 
209  if (this->evalOnConstruct_)
210  {
211  // For potentialFoam or other solvers that don't evaluate
212  this->evaluate();
213  }
214  else
215  {
216  // Emulate mixedFvPatchField<Type>::evaluate,
217  // but avoid our own updateCoeffs
218  if (!this->updated())
219  {
221  }
222 
224  (
225  this->valueFraction()*this->refValue()
226  +
227  (1.0 - this->valueFraction())*
228  (
229  this->patchInternalField()
230  + this->refGrad()/this->patch().deltaCoeffs()
231  )
232  );
233 
235  }
236 }
237 
238 
239 template<class Type>
241 (
242  const exprMixedFvPatchField<Type>& ptf
243 )
244 :
247  driver_(this->patch(), ptf.driver_)
248 {
249  setDebug();
250  DebugInFunction << nl;
251 }
252 
253 
254 template<class Type>
256 (
257  const exprMixedFvPatchField<Type>& ptf,
259 )
260 :
261  mixedFvPatchField<Type>(ptf, iF),
263  driver_(this->patch(), ptf.driver_)
264 {
265  setDebug();
266  DebugInFunction << nl;
267 }
268 
269 
270 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
271 
272 template<class Type>
274 {
275  if (this->updated())
276  {
277  return;
278  }
279 
280  if (debug)
281  {
283  << "Value: " << this->valueExpr_ << nl
284  << "Gradient: " << this->gradExpr_ << nl
285  << "Fraction: " << this->fracExpr_ << nl
286  << "Variables: ";
287  driver_.writeVariableStrings(Info) << nl;
288  Info<< "... updating" << endl;
289  }
290 
291 
292  // Expression evaluation
293  {
294  bool evalValue = (!this->valueExpr_.empty() && this->valueExpr_ != "0");
295  bool evalGrad = (!this->gradExpr_.empty() && this->gradExpr_ != "0");
296  bool evalFrac = (!this->fracExpr_.empty());
297  scalar fraction = 1;
298 
299  // Have one or both of valueExpr, gradientExpr (checked in constructor)
300 
301  if (this->valueExpr_.empty())
302  {
303  // No value expression -> gradient only
304  fraction = 0;
305  evalValue = false;
306  evalFrac = false;
307  }
308  else if (this->gradExpr_.empty())
309  {
310  // No gradient expression -> value only
311  fraction = 1;
312  evalGrad = false;
313  evalFrac = false;
314  }
315  else if (this->fracExpr_.empty())
316  {
317  // No fractionExpr, but has both valueExpr and gradientExpr
318  // -> treat as value only (warning in constructor)
319  fraction = 1;
320  evalGrad = false;
321  evalFrac = false;
322  }
323  else if (this->fracExpr_ == "0")
324  {
325  // Gradient only
326  fraction = 0;
327  evalValue = false;
328  evalFrac = false;
329  }
330  else if (this->fracExpr_ == "1")
331  {
332  // Value only
333  fraction = 1;
334  evalGrad = false;
335  evalFrac = false;
336  }
337 
338 
339  driver_.clearVariables();
340 
341  if (evalValue)
342  {
343  this->refValue() = driver_.evaluate<Type>(this->valueExpr_);
344  }
345  else
346  {
347  this->refValue() = Zero;
348  }
349 
350  if (evalGrad)
351  {
352  this->refGrad() = driver_.evaluate<Type>(this->gradExpr_);
353  }
354  else
355  {
356  this->refGrad() = Zero;
357  }
358 
359  if (evalFrac)
360  {
361  this->valueFraction() = driver_.evaluate<scalar>(this->fracExpr_);
362  }
363  else
364  {
365  this->valueFraction() = fraction;
366  }
367  }
368 
370 }
371 
372 
373 template<class Type>
375 {
378 
379  driver_.writeCommon(os, this->debug_ || debug);
380 }
381 
382 
383 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::fvPatchField
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: volSurfaceMapping.H:50
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:325
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::exprMixedFvPatchField::write
virtual void write(Ostream &os) const
Write.
Definition: exprMixedFvPatchField.C:374
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionary.C:364
Foam::exprMixedFvPatchField::exprMixedFvPatchField
exprMixedFvPatchField(const fvPatch &p, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
Definition: exprMixedFvPatchField.C:46
exprMixedFvPatchField.H
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::exprMixedFvPatchField::updateCoeffs
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
Definition: exprMixedFvPatchField.C:273
Foam::exprMixedFvPatchField::driver_
expressions::patchExpr::parseDriver driver_
The expression driver.
Definition: exprMixedFvPatchField.H:100
Foam::expressions::patchExprFieldBase
Base class for managing patches with expressions. The expected input supports value,...
Definition: patchExprFieldBase.H:83
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:365
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::mixedFvPatchField
This boundary condition provides a base class for 'mixed' type boundary conditions,...
Definition: mixedFvPatchField.H:123
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::exprMixedFvPatchField::setDebug
void setDebug()
Set debug ON if "debug" is enabled.
Definition: exprMixedFvPatchField.C:33
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:35
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::fvPatchFieldMapper
Foam::fvPatchFieldMapper.
Definition: fvPatchFieldMapper.H:47
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:315
Foam::exprMixedFvPatchField
A mixed boundary condition with expressions.
Definition: exprMixedFvPatchField.H:90
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
Foam::stringOps::evaluate
string evaluate(const std::string &s, size_t pos=0, size_t len=std::string::npos)
Definition: stringOpsEvaluate.C:37
Foam::DimensionedField
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: DimensionedField.H:54