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),
53  expressions::patchExprFieldBase(),
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),
73  expressions::patchExprFieldBase(rhs),
74  dict_(rhs.dict_), // Deep copy
75  driver_(this->patch(), rhs.driver_, dict_)
76 {
79 }
80 
81 
82 template<class Type>
84 (
85  const fvPatch& p,
87  const dictionary& dict
88 )
89 :
90  parent_bctype(p, iF), // bypass dictionary constructor
91  expressions::patchExprFieldBase
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 {
113  << "Use uniformMixed with Function1 expressions instead." << nl
114  << " This boundary condition will be removed in the future" << endl;
115 
116  setDebug();
117  DebugInFunction << nl;
118 
119  // Require one or both of valueExpr, gradientExpr
120  if (this->valueExpr_.empty() && this->gradExpr_.empty())
121  {
123  << "For " << this->internalField().name() << " on "
124  << this->patch().name() << nl
125  << "Require either or both: valueExpr and gradientExpr" << nl
126  << exit(FatalIOError);
127  }
128 
129  if (this->fracExpr_.empty())
130  {
131  // No fractionExpr. Expect only one of valueExpr or gradientExpr
132  if (!this->valueExpr_.empty() && !this->gradExpr_.empty())
133  {
135  << "For " << this->internalField().name() << " on "
136  << this->patch().name() << nl
137  << "Recommend using fractionExpr when specifying both"
138  << " valueExpr and gradientExpr. Assuming a value of 1."
139  << nl << endl;
140  }
141  }
142  else if (this->fracExpr_ == "0")
143  {
144  // Gradient only. Expect gradientExpr
145  if (this->gradExpr_.empty())
146  {
148  << "For " << this->internalField().name() << " on "
149  << this->patch().name() << nl
150  << "Gradient only, but did not specify gradientExpr."
151  << nl << endl;
152  }
153  }
154  else if (this->fracExpr_ == "1")
155  {
156  // Value only. Expect valueExpr
157  if (this->valueExpr_.empty())
158  {
160  << "For " << this->internalField().name() << " on "
161  << this->patch().name() << nl
162  << "Value only, but did not specify valueExpr."
163  << nl << endl;
164  }
165  }
166 
167  driver_.readDict(dict_);
168 
169  // Since we bypassed dictionary constructor
171 
172  const auto* hasRefValue = dict.findEntry("refValue", keyType::LITERAL);
173 
174  const auto* hasRefGradient
175  = dict.findEntry("refGradient", keyType::LITERAL);
176 
177  const auto* hasValueFraction
178  = dict.findEntry("valueFraction", keyType::LITERAL);
179 
180 
181  if (hasRefValue)
182  {
183  this->refValue().assign(*hasRefValue, p.size());
184  }
185 
186  if (this->readValueEntry(dict))
187  {
188  if (!hasRefValue)
189  {
190  // Ensure refValue has a sensible value for the "update" below
191  this->refValue() = static_cast<const Field<Type>&>(*this);
192  }
193  }
194  else
195  {
196  if (!hasRefValue)
197  {
198  this->refValue() = this->patchInternalField();
199  }
200 
201  fvPatchField<Type>::operator=(this->refValue());
202 
203  #ifdef FULLDEBUG
205  << "No value defined for "
206  << this->internalField().name() << " on "
207  << this->patch().name() << " - using patch internal field" << endl;
208  #endif
209  }
210 
211 
212  if (hasRefGradient)
213  {
214  this->refGrad().assign(*hasRefGradient, p.size());
215  }
216  else
217  {
218  this->refGrad() = Zero;
219  }
220 
221  if (hasValueFraction)
222  {
223  this->valueFraction().assign(*hasValueFraction, p.size());
224  }
225  else
226  {
227  this->valueFraction() = scalar(1);
228  }
229 
230 
231  if (this->evalOnConstruct_)
232  {
233  // For potentialFoam or other solvers that don't evaluate
234  this->evaluate();
235  }
236  else
237  {
238  // Like mixedFvPatchField<Type>::evaluate()
239  // but avoid our own updateCoeffs
240  if (!this->updated())
241  {
243  }
244 
246  }
247 }
248 
249 
250 template<class Type>
252 (
253  const exprMixedFvPatchField<Type>& rhs
254 )
255 :
256  parent_bctype(rhs),
257  expressions::patchExprFieldBase(rhs),
258  dict_(rhs.dict_), // Deep copy
259  driver_(this->patch(), rhs.driver_, dict_)
260 {
262  DebugInFunction << nl;
263 }
264 
265 
266 template<class Type>
268 (
269  const exprMixedFvPatchField<Type>& rhs,
271 )
272 :
273  parent_bctype(rhs, iF),
274  expressions::patchExprFieldBase(rhs),
275  dict_(rhs.dict_), // Deep copy
276  driver_(this->patch(), rhs.driver_, dict_)
277 {
278  setDebug();
280 }
281 
282 
283 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
284 
285 template<class Type>
287 {
288  if (this->updated())
289  {
290  return;
291  }
292 
293  if (debug)
294  {
296  << "Value: " << this->valueExpr_ << nl
297  << "Gradient: " << this->gradExpr_ << nl
298  << "Fraction: " << this->fracExpr_ << nl
299  << "Variables: ";
300  driver_.writeVariableStrings(Info) << nl;
301  Info<< "... updating" << endl;
302  }
303 
304 
305  // Expression evaluation
306  {
307  bool evalValue = (!this->valueExpr_.empty() && this->valueExpr_ != "0");
308  bool evalGrad = (!this->gradExpr_.empty() && this->gradExpr_ != "0");
309  bool evalFrac = (!this->fracExpr_.empty());
310  scalar fraction = 1;
311 
312  // Have one or both of valueExpr, gradientExpr (checked in constructor)
313 
314  if (this->valueExpr_.empty())
315  {
316  // No value expression -> gradient only
317  fraction = 0;
318  evalValue = false;
319  evalFrac = false;
320  }
321  else if (this->gradExpr_.empty())
322  {
323  // No gradient expression -> value only
324  fraction = 1;
325  evalGrad = false;
326  evalFrac = false;
327  }
328  else if (this->fracExpr_.empty())
329  {
330  // No fractionExpr, but has both valueExpr and gradientExpr
331  // -> treat as value only (warning in constructor)
332  fraction = 1;
333  evalGrad = false;
334  evalFrac = false;
335  }
336  else if (this->fracExpr_ == "0")
337  {
338  // Gradient only
339  fraction = 0;
340  evalValue = false;
341  evalFrac = false;
342  }
343  else if (this->fracExpr_ == "1")
344  {
345  // Value only
346  fraction = 1;
347  evalGrad = false;
348  evalFrac = false;
349  }
350 
351 
352  driver_.clearVariables();
353 
354  if (evalValue)
355  {
356  this->refValue() = driver_.evaluate<Type>(this->valueExpr_);
357  }
358  else
359  {
360  this->refValue() = Zero;
361  }
362 
363  if (evalGrad)
364  {
365  this->refGrad() = driver_.evaluate<Type>(this->gradExpr_);
366  }
367  else
368  {
369  this->refGrad() = Zero;
370  }
371 
372  if (evalFrac)
373  {
374  this->valueFraction() = driver_.evaluate<scalar>(this->fracExpr_);
375  }
376  else
377  {
378  this->valueFraction() = fraction;
379  }
380  }
381 
382  this->parent_bctype::updateCoeffs();
383 }
384 
385 
386 template<class Type>
387 void Foam::exprMixedFvPatchField<Type>::write(Ostream& os) const
388 {
389  this->parent_bctype::write(os);
391 
392  driver_.writeCommon(os, this->debug_ || debug);
393 }
394 
395 
396 // ************************************************************************* //
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
A mixed boundary condition with expressions.
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
virtual void readDict(const dictionary &dict)
Read dictionary entries.
virtual void write(Ostream &os) const
Write.
virtual Field< Type > & refValue()
#define DeprecatedInFunction(afterVersion)
Report a warning using Foam::Warning.
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
exprMixedFvPatchField(const fvPatch &p, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
virtual scalarField & valueFraction()
#define DebugInFunction
Report an information message using Foam::Info.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
A FieldMapper for finite-volume patch fields.
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.
String literal.
Definition: keyType.H:82
A wrapper for dictionary content, without operators that could affect inheritance patterns...
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
virtual void evaluate(const Pstream::commsTypes commsType=Pstream::commsTypes::blocking)
Evaluate the patch field.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
Definition: fvPatchField.C:309
virtual void operator=(const UList< Type > &)
Definition: fvPatchField.C:391
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 entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:84
messageStream Info
Information stream (stdout output on master, null elsewhere)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
volScalarField & p
void setDebug()
Set debug ON if "debug" is enabled.
virtual Field< Type > & refGrad()
void write(Ostream &os) const
Write.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127