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-2021 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 #include "dictionaryContent.H"
30 
31 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
32 
33 template<class Type>
35 {
36  if (expressions::patchExprFieldBase::debug_ && !debug)
37  {
38  debug = 1;
39  }
40 }
41 
42 
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44 
45 template<class Type>
47 (
48  const fvPatch& p,
50 )
51 :
52  parent_bctype(p, iF),
54  dict_(),
55  driver_(this->patch())
56 {
57  this->refValue() = Zero;
58  this->refGrad() = Zero;
59  this->valueFraction() = scalar(1);
60 }
61 
62 
63 template<class Type>
65 (
66  const exprMixedFvPatchField<Type>& rhs,
67  const fvPatch& p,
69  const fvPatchFieldMapper& mapper
70 )
71 :
72  parent_bctype(rhs, p, iF, mapper),
74  dict_(rhs.dict_), // Deep copy
75  driver_(this->patch(), rhs.driver_, dict_)
76 {
77  setDebug();
79 }
80 
81 
82 template<class Type>
84 (
85  const fvPatch& p,
87  const dictionary& dict
88 )
89 :
90  parent_bctype(p, iF),
92  (
93  dict,
94  expressions::patchExprFieldBase::expectedTypes::MIXED_TYPE
95  ),
96  dict_
97  (
98  // Copy dictionary without "heavy" data chunks
99  dictionaryContent::copyDict
100  (
101  dict,
102  wordList(), // allow
103  wordList // deny
104  ({
105  "type", // redundant
106  "value", "refValue", "refGradient", "valueFraction"
107  })
108  )
109  ),
110  driver_(this->patch(), dict_)
111 {
112  setDebug();
113  DebugInFunction << nl;
114 
115  // Require one or both of valueExpr, gradientExpr
116  if (this->valueExpr_.empty() && this->gradExpr_.empty())
117  {
119  << "For " << this->internalField().name() << " on "
120  << this->patch().name() << nl
121  << "Require either or both: valueExpr and gradientExpr" << nl
122  << exit(FatalIOError);
123  }
124 
125  if (this->fracExpr_.empty())
126  {
127  // No fractionExpr. Expect only one of valueExpr or gradientExpr
128  if (!this->valueExpr_.empty() && !this->gradExpr_.empty())
129  {
131  << "For " << this->internalField().name() << " on "
132  << this->patch().name() << nl
133  << "Recommend using fractionExpr when specifying both"
134  << " valueExpr and gradientExpr. Assuming a value of 1."
135  << nl << endl;
136  }
137  }
138  else if (this->fracExpr_ == "0")
139  {
140  // Gradient only. Expect gradientExpr
141  if (this->gradExpr_.empty())
142  {
144  << "For " << this->internalField().name() << " on "
145  << this->patch().name() << nl
146  << "Gradient only, but did not specify gradientExpr."
147  << nl << endl;
148  }
149  }
150  else if (this->fracExpr_ == "1")
151  {
152  // Value only. Expect valueExpr
153  if (this->valueExpr_.empty())
154  {
156  << "For " << this->internalField().name() << " on "
157  << this->patch().name() << nl
158  << "Value only, but did not specify valueExpr."
159  << nl << endl;
160  }
161  }
162 
163 
164  driver_.readDict(dict_);
165 
166  // Similar to fvPatchField constructor, which we have bypassed
167  dict.readIfPresent("patchType", this->patchType());
168 
169  bool needsRefValue = true;
170  if (dict.found("refValue"))
171  {
172  needsRefValue = false;
173  this->refValue() = Field<Type>("refValue", dict, p.size());
174  }
175 
176  if (dict.found("value"))
177  {
178  fvPatchField<Type>::operator=
179  (
180  Field<Type>("value", dict, p.size())
181  );
182 
183  if (needsRefValue)
184  {
185  // Ensure refValue has a sensible value for the "update" below
186  this->refValue() = static_cast<const Field<Type>&>(*this);
187  }
188  }
189  else
190  {
191  if (needsRefValue)
192  {
193  this->refValue() = this->patchInternalField();
194  }
195 
196  fvPatchField<Type>::operator=(this->refValue());
197 
198  #ifdef FULLDEBUG
200  << "No value defined for "
201  << this->internalField().name() << " on "
202  << this->patch().name() << " - using patch internal field" << endl;
203  #endif
204  }
205 
206 
207  if (dict.found("refGradient"))
208  {
209  this->refGrad() = Field<Type>("refGradient", dict, p.size());
210  }
211  else
212  {
213  this->refGrad() = Zero;
214  }
215 
216  if (dict.found("valueFraction"))
217  {
218  this->valueFraction() = Field<scalar>("valueFraction", dict, p.size());
219  }
220  else
221  {
222  this->valueFraction() = scalar(1);
223  }
224 
225 
226  if (this->evalOnConstruct_)
227  {
228  // For potentialFoam or other solvers that don't evaluate
229  this->evaluate();
230  }
231  else
232  {
233  // Emulate mixedFvPatchField<Type>::evaluate,
234  // but avoid our own updateCoeffs
235  if (!this->updated())
236  {
237  this->parent_bctype::updateCoeffs();
238  }
239 
240  Field<Type>::operator=
241  (
242  this->valueFraction()*this->refValue()
243  +
244  (1.0 - this->valueFraction())*
245  (
246  this->patchInternalField()
247  + this->refGrad()/this->patch().deltaCoeffs()
248  )
249  );
250 
252  }
253 }
254 
255 
256 template<class Type>
258 (
259  const exprMixedFvPatchField<Type>& rhs
260 )
261 :
262  parent_bctype(rhs),
264  dict_(rhs.dict_), // Deep copy
265  driver_(this->patch(), rhs.driver_, dict_)
266 {
267  setDebug();
268  DebugInFunction << nl;
269 }
270 
271 
272 template<class Type>
274 (
275  const exprMixedFvPatchField<Type>& rhs,
277 )
278 :
279  parent_bctype(rhs, iF),
281  dict_(rhs.dict_), // Deep copy
282  driver_(this->patch(), rhs.driver_, dict_)
283 {
284  setDebug();
285  DebugInFunction << nl;
286 }
287 
288 
289 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
290 
291 template<class Type>
293 {
294  if (this->updated())
295  {
296  return;
297  }
298 
299  if (debug)
300  {
302  << "Value: " << this->valueExpr_ << nl
303  << "Gradient: " << this->gradExpr_ << nl
304  << "Fraction: " << this->fracExpr_ << nl
305  << "Variables: ";
306  driver_.writeVariableStrings(Info) << nl;
307  Info<< "... updating" << endl;
308  }
309 
310 
311  // Expression evaluation
312  {
313  bool evalValue = (!this->valueExpr_.empty() && this->valueExpr_ != "0");
314  bool evalGrad = (!this->gradExpr_.empty() && this->gradExpr_ != "0");
315  bool evalFrac = (!this->fracExpr_.empty());
316  scalar fraction = 1;
317 
318  // Have one or both of valueExpr, gradientExpr (checked in constructor)
319 
320  if (this->valueExpr_.empty())
321  {
322  // No value expression -> gradient only
323  fraction = 0;
324  evalValue = false;
325  evalFrac = false;
326  }
327  else if (this->gradExpr_.empty())
328  {
329  // No gradient expression -> value only
330  fraction = 1;
331  evalGrad = false;
332  evalFrac = false;
333  }
334  else if (this->fracExpr_.empty())
335  {
336  // No fractionExpr, but has both valueExpr and gradientExpr
337  // -> treat as value only (warning in constructor)
338  fraction = 1;
339  evalGrad = false;
340  evalFrac = false;
341  }
342  else if (this->fracExpr_ == "0")
343  {
344  // Gradient only
345  fraction = 0;
346  evalValue = false;
347  evalFrac = false;
348  }
349  else if (this->fracExpr_ == "1")
350  {
351  // Value only
352  fraction = 1;
353  evalGrad = false;
354  evalFrac = false;
355  }
356 
357 
358  driver_.clearVariables();
359 
360  if (evalValue)
361  {
362  this->refValue() = driver_.evaluate<Type>(this->valueExpr_);
363  }
364  else
365  {
366  this->refValue() = Zero;
367  }
368 
369  if (evalGrad)
370  {
371  this->refGrad() = driver_.evaluate<Type>(this->gradExpr_);
372  }
373  else
374  {
375  this->refGrad() = Zero;
376  }
377 
378  if (evalFrac)
379  {
380  this->valueFraction() = driver_.evaluate<scalar>(this->fracExpr_);
381  }
382  else
383  {
384  this->valueFraction() = fraction;
385  }
386  }
387 
388  this->parent_bctype::updateCoeffs();
389 }
390 
391 
392 template<class Type>
394 {
395  this->parent_bctype::write(os);
397 
398  driver_.writeCommon(os, this->debug_ || debug);
399 }
400 
401 
402 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:350
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::exprMixedFvPatchField::write
virtual void write(Ostream &os) const
Write.
Definition: exprMixedFvPatchField.C:393
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: dictionaryI.H:87
Foam::exprMixedFvPatchField::exprMixedFvPatchField
exprMixedFvPatchField(const fvPatch &p, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
Definition: exprMixedFvPatchField.C:47
exprMixedFvPatchField.H
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::exprMixedFvPatchField::updateCoeffs
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
Definition: exprMixedFvPatchField.C:292
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:62
Foam::exprMixedFvPatchField::driver_
expressions::patchExpr::parseDriver driver_
The expression driver.
Definition: exprMixedFvPatchField.H:107
Foam::expressions::patchExprFieldBase
Base class for managing patches with expressions. The expected input supports value,...
Definition: patchExprFieldBase.H:83
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::exprMixedFvPatchField::dict_
dictionary dict_
Dictionary contents for the boundary condition.
Definition: exprMixedFvPatchField.H:104
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
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
dictionaryContent.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::List< word >
Foam::exprMixedFvPatchField::setDebug
void setDebug()
Set debug ON if "debug" is enabled.
Definition: exprMixedFvPatchField.C:34
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:36
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
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:340
Foam::exprMixedFvPatchField
A mixed boundary condition with expressions.
Definition: exprMixedFvPatchField.H:90
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::DimensionedField
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: DimensionedField.H:54
Foam::stringOps::evaluate
string evaluate(label fieldWidth, const std::string &s, size_t pos=0, size_t len=std::string::npos)
String evaluation with specified (positive, non-zero) field width.
Definition: stringOpsEvaluate.C:37