exprDriver.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) 2010-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 
29 #include "exprDriver.H"
30 #include "expressionEntry.H"
31 #include "stringOps.H"
32 #include "Time.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 namespace expressions
39 {
40 
41  defineTypeNameAndDebug(exprDriver, 0);
42 
43 } // End namespace expressions
44 } // End namespace Foam
45 
46 
47 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
48 
49 int Foam::expressions::exprDriver::getSearchControls(const dictionary& dict)
50 {
51  int val = 0;
52 
53  if (dict.getOrDefault("searchInMemory", true))
54  {
55  val |= int(searchControls::SEARCH_REGISTRY);
56  }
57  if (dict.getOrDefault("searchFiles", false))
58  {
59  val |= int(searchControls::SEARCH_FILES);
60  }
61  if (dict.getOrDefault("cacheReadFields", false))
62  {
63  val |= int(searchControls::CACHE_READ_FIELDS);
64  }
65 
66  return val;
67 }
68 
69 
70 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
71 
72 namespace Foam
73 {
74 #if 0
75 static string getEntryString
76 (
77  const dictionary& dict,
78  const string& key
79 )
80 {
81  const entry* eptr = dict.findEntry(key, keyType::REGEX_RECURSIVE);
82 
83  if (!eptr)
84  {
86  << "Entry " << key << " not found in "
87  << dict.name() << nl
88  << exit(FatalError);
89  }
90  else if (eptr->isDict())
91  {
93  << "Entry " << key << " found in "
94  << dict.name() << " but is a dictionary" << nl
95  << exit(FatalError);
96  }
97 
99 }
100 #endif
101 
102 
103 template<class Type>
104 static void shallowCloneFunctions
105 (
107  const HashTable<refPtr<Function1<Type>>>& rhs
108 )
109 {
110  // Add in shallow copy for other functions
111  forAllConstIters(rhs, iter)
112  {
113  const word& key = iter.key();
114 
115  if (!dest.found(key))
116  {
118  func.cref(iter.val().shallowClone());
119 
120  dest.emplace_set(key, std::move(func));
121  }
122  }
123 }
124 
125 } // End namespace Foam
126 
127 
128 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
129 
131 {
132  timeStatePtr_ = ts;
133 }
134 
135 
137 {
138  timeStatePtr_ = &ts;
139 }
140 
141 
143 {
144  obrPtr_ = obrPtr;
145 
146  forAllIters(scalarFuncs_, iter)
147  {
148  auto& funcPtr = iter.val();
149  if (funcPtr && !funcPtr.is_const())
150  {
151  (*funcPtr).resetDb(obrPtr_);
152  }
153  }
154  forAllIters(vectorFuncs_, iter)
155  {
156  auto& funcPtr = iter.val();
157  if (funcPtr && !funcPtr.is_const())
158  {
159  (*funcPtr).resetDb(obrPtr_);
160  }
161  }
162 }
163 
164 
166 {
167  resetDb(&db);
168 }
169 
170 
171 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
172 
174 (
175  enum searchControls search,
176  const dictionary& dict
177 )
178 :
179  dict_(dict),
180  result_(),
181  variableStrings_(),
182  variables_(16),
183  scalarFuncs_(0),
184  vectorFuncs_(0),
185  contextObjects_(0),
186  arg1Value_(0),
187  timeStatePtr_(nullptr),
188  obrPtr_(nullptr),
189  stashedTokenId_(0),
190 
191  // Controls
192  debugScanner_(dict.getOrDefault("debug.scanner", false)),
193  debugParser_(dict.getOrDefault("debug.parser", false)),
194  allowShadowing_(dict.getOrDefault("allowShadowing", false)),
195  prevIterIsOldTime_(dict.getOrDefault("prevIterIsOldTime", false)),
196  searchCtrl_(search)
197 {}
198 
199 
201 (
202  const exprDriver& rhs,
203  const dictionary& dict
204 )
205 :
206  dict_(dict),
207  result_(rhs.result_),
208  variableStrings_(rhs.variableStrings_),
209  variables_(rhs.variables_),
210  scalarFuncs_(0),
211  vectorFuncs_(0),
212  contextObjects_(rhs.contextObjects_),
213  arg1Value_(rhs.arg1Value_),
214  timeStatePtr_(rhs.timeStatePtr_),
215  obrPtr_(rhs.obrPtr_),
216  stashedTokenId_(0),
217 
218  // Controls
219  debugScanner_(rhs.debugScanner_),
220  debugParser_(rhs.debugParser_),
221  allowShadowing_(rhs.allowShadowing_),
222  prevIterIsOldTime_(rhs.prevIterIsOldTime_),
223 
224  searchCtrl_(rhs.searchCtrl_)
225 {
226  // Partially like readDict()
227 
228  // Create Function1s from dictionary content
229  resetFunctions(dict_);
230 
231  // Add in shallow copy for other functions
232  shallowCloneFunctions(scalarFuncs_, rhs.scalarFuncs_);
233  shallowCloneFunctions(vectorFuncs_, rhs.vectorFuncs_);
234 }
235 
236 
238 (
239  const dictionary& dict
240 )
241 :
242  exprDriver
243  (
244  searchControls(exprDriver::getSearchControls(dict)),
245  dict
246  )
247 {
248  readDict(dict);
249 }
250 
251 
252 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
253 
255 {
256  if (timeStatePtr_)
257  {
258  return timeStatePtr_;
259  }
260  else if (obrPtr_)
261  {
262  return &(obrPtr_->time());
263  }
264  return nullptr;
265 }
266 
267 
269 {
270  if (timeStatePtr_)
271  {
272  return timeStatePtr_->value();
273  }
274  else if (obrPtr_)
275  {
276  return obrPtr_->time().value();
277  }
278  return 0;
279 }
280 
281 
283 {
284  if (timeStatePtr_)
285  {
286  return timeStatePtr_->deltaT().value();
287  }
288  else if (obrPtr_)
289  {
290  return obrPtr_->time().deltaT().value();
291  }
292  return 0;
293 }
294 
295 
297 (
298  const dictionary& dict
299 )
300 {
301  dict.readIfPresent("debug.driver", debug);
302 
303  // Regular variables
304  variableStrings_ = readVariableStrings(dict);
305 
306  // Create Function1s from dictionary content
307  resetFunctions(dict);
308 
309  // readTable("lookuptables2D", dict, lookup2D_);
310 
311  return true;
312 }
313 
314 
316 {
317  result_.clear();
318 }
319 
320 
322 {
323  return true;
324 }
325 
326 
328 {}
329 
330 
332 {
333  variables_.clear();
334  addVariables(variableStrings_, false);
335 }
336 
337 
339 (
340  const word& varName,
341  const expressions::exprString& expr
342 )
343 {
344  parse(expr);
345  result_.testIfSingleValue();
346 
347  DebugInfo
348  << "Evaluating: " << expr << " -> " << varName << endl
349  << result_;
350 
351  // Overwrite with a copy
352  variables_.set(varName, exprResult(result_));
353 }
354 
355 
357 (
358  string remote,
359  const word& varName,
360  const expressions::exprString& expr
361 )
362 {
364 }
365 
366 
369 (
370  const exprDriver& other
371 ) const
372 {
373  // With warnings (noWarn = false)
374  return other.result().getUniform(this->size(), false);
375 }
376 
377 
379 (
380  const expressions::exprString& expr,
381  bool clear
382 )
383 {
384  if (clear)
385  {
386  clearVariables();
387  }
388 
389  // Allow inline list of semicolon-separated variables
390  const auto varExpressions =
391  stringOps::split<expressions::exprString>(expr, ';');
392 
393  for (const auto& subMatch : varExpressions)
394  {
395  string varExpr(stringOps::trim(subMatch.str()));
396  if (varExpr.empty())
397  {
398  continue;
399  }
400 
401  // Split on '=' for lhsExpr = rhsExpr
402  //
403  // varName = rhsExpr
404  // varName{where} = rhsExpr
405 
406  const auto eqPos = varExpr.find('=');
407 
408  if (eqPos == std::string::npos)
409  {
411  << "No '=' found in expression " << varExpr << nl << nl
412  << exit(FatalIOError);
413  }
414 
415  // The RHS
417  (
419  (
420  stringOps::trim(varExpr.substr(eqPos+1))
421  )
422  );
423 
424  // The LHS
425  varExpr.resize(eqPos);
426  stringOps::inplaceTrim(varExpr);
427 
428  // Check for varName{where}
429  const auto lbrace = varExpr.find('{');
430 
431  if (lbrace != std::string::npos)
432  {
433  const auto rbrace = varExpr.find('}');
434 
435  if (rbrace == std::string::npos || rbrace < lbrace)
436  {
438  // << "Context: " << driverContext_ << nl
439  << "No closing '}' found in " << varExpr << nl
440  << exit(FatalError);
441  }
442  else if (lbrace+1 == rbrace)
443  {
445  // << "Context: " << driverContext_ << nl
446  << "Empty '{}' location in " << varExpr << nl
447  << exit(FatalError);
448  }
449 
450  const word varName(word::validate(varExpr.substr(0, lbrace)));
451 
452  const expressions::exprString remoteExpr
453  (
455  (
456  varExpr.substr(lbrace+1, rbrace-lbrace-1)
457  )
458  );
459 
460  // Fails if derived class does not implement!
461 
462  evaluateVariableRemote(remoteExpr, varName, rhsExpr);
463  }
464  else
465  {
466  const word varName(word::validate(varExpr));
467 
468  evaluateVariable(varName, rhsExpr);
469  }
470  }
471 }
472 
473 
475 (
476  const UList<expressions::exprString>& list,
477  bool clear
478 )
479 {
480  if (clear)
481  {
482  clearVariables();
483  }
484 
485  for (const auto& expr : list)
486  {
487  addVariables(expr, false); // No clear (already done)
488  }
489 }
490 
491 
493 (
494  bool scannerDebug,
495  bool parserDebug
496 )
497 {
498  debugScanner_ = scannerDebug;
499  debugParser_ = parserDebug;
500 }
501 
502 
504 (
505  const exprDriver& rhs
506 )
507 {
508  debugScanner_ = rhs.debugScanner_;
509  debugParser_ = rhs.debugParser_;
510 }
511 
512 
514 {
515  int val(searchCtrl_);
516  bool old = (val & searchControls::CACHE_READ_FIELDS);
517 
518  if (!on)
519  {
520  // Off
521  val &= ~(searchControls::CACHE_READ_FIELDS);
522  }
523  else if (!old)
524  {
525  // Toggled on.
526  // Caching read fields implies both registry and disk use
527  val |=
528  (
529  searchControls::SEARCH_REGISTRY
530  | searchControls::SEARCH_FILES
531  | searchControls::CACHE_READ_FIELDS
532  );
533  }
534 
535  searchCtrl_ = searchControls(val);
536 
537  return old;
538 }
539 
540 
542 (
543  enum searchControls search,
544  const bool caching
545 )
546 {
547  int val(search);
548  if (caching || (val & searchControls::CACHE_READ_FIELDS))
549  {
550  // Caching read fields implies both registry and disk use
551  val |=
552  (
553  searchControls::SEARCH_REGISTRY
554  | searchControls::SEARCH_FILES
555  | searchControls::CACHE_READ_FIELDS
556  );
557  }
558  searchCtrl_ = searchControls(val);
559 
560  #ifdef FULLDEBUG
561  Info<< "Searching "
562  << " registry:" << searchRegistry()
563  << " disk:" << searchFiles()
564  << " cache-read:" << cacheReadFields() << nl;
565  #endif
566 }
567 
568 
570 (
571  const exprDriver& rhs
572 )
573 {
574  searchCtrl_ = rhs.searchCtrl_;
575 }
576 
577 
578 // ************************************************************************* //
Foam::expressions::exprDriver::updateSpecialVariables
virtual void updateSpecialVariables(bool force=false)
Examine current variable values and update stored variables.
Definition: exprDriver.C:327
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::exprTools::expressionEntry::evaluate
static string evaluate(const entry &e)
Generic concatenate tokens to space-separated string.
Definition: expressionEntryI.H:34
Foam::expressions::exprDriver::contextObjects_
contextObjectTableType contextObjects_
Externally defined context fields.
Definition: exprDriver.H:207
Foam::expressions::exprDriver::prevIterIsOldTime_
bool prevIterIsOldTime_
Use value of previous iteration when oldTime is requested.
Definition: exprDriver.H:234
Foam::expressions::exprDriver::searchCtrl_
searchControls searchCtrl_
Registry/disk/caching control.
Definition: exprDriver.H:237
Foam::expressions::exprDriver::debugParser_
bool debugParser_
Request debugging for parser.
Definition: exprDriver.H:228
Foam::expressions::exprDriver::addVariables
void addVariables(const expressions::exprString &expr, bool clear=true)
Add/set string expressions for variables.
Definition: exprDriver.C:379
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::expressions::exprDriver::deltaT
virtual scalar deltaT() const
The current deltaT value.
Definition: exprDriver.C:282
Foam::expressions::exprDriver::timeValue
virtual scalar timeValue() const
The current time value.
Definition: exprDriver.C:268
Foam::expressions::exprDriver::setCaching
bool setCaching(bool on) noexcept
Toggle CACHE_READ_FIELDS control.
Definition: exprDriver.C:513
Foam::expressions::exprDriver::exprDriver
exprDriver(const exprDriver &)=delete
No copy construct.
Foam::stringOps::inplaceTrim
void inplaceTrim(std::string &s)
Trim leading and trailing whitespace inplace.
Definition: stringOps.C:1067
Foam::expressions::exprDriver::readDict
virtual bool readDict(const dictionary &dict)
Read variables, tables etc.
Definition: exprDriver.C:297
Foam::expressions::exprDriver::vectorFuncs_
HashTable< refPtr< Function1< vector > > > vectorFuncs_
Definition: exprDriver.H:204
Foam::expressions::exprDriver::evaluateVariable
void evaluateVariable(const word &varName, const expressions::exprString &expr)
Definition: exprDriver.C:339
Foam::glTF::key
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:108
Foam::expressions::exprString::toExpr
static exprString toExpr(const std::string &str)
Copy convert string to exprString.
Definition: exprStringI.H:143
Foam::stringOps::trim
string trim(const std::string &s)
Return string trimmed of leading and trailing whitespace.
Definition: stringOps.C:1046
Foam::word::validate
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:45
Foam::expressions::exprDriver::result
const exprResult & result() const noexcept
Const access to expression result.
Definition: exprDriver.H:390
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::expressions::exprDriver::debugScanner_
bool debugScanner_
Request debugging for scanner.
Definition: exprDriver.H:225
Foam::expressions::exprDriver::timeState
const TimeState * timeState() const noexcept
Reference to the current time-state (can be nullptr)
Definition: exprDriver.C:254
Foam::expressions::exprDriver::setDebugging
void setDebugging(bool scannerDebug, bool parserDebug)
Set the scanner/parser debug.
Definition: exprDriver.C:493
Foam::expressions::exprDriver::allowShadowing_
bool allowShadowing_
Allow variable names to mask field names.
Definition: exprDriver.H:231
Foam::Function1
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition: propellerInfo.H:291
exprDriver.H
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::expressions::exprDriver::resetTimeReference
void resetTimeReference(const TimeState *ts)
Reset the time-state reference.
Definition: exprDriver.C:130
NotImplemented
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:517
Foam::TimeState
The time value with time-stepping information, user-defined remapping, etc.
Definition: TimeState.H:51
Foam::expressions::exprDriver::getRemoteResult
virtual exprResult getRemoteResult(const exprDriver &other) const
Get the result from another driver.
Definition: exprDriver.C:369
Foam::expressions::exprResult
A polymorphic field/result from evaluating an expression.
Definition: exprResult.H:124
expressionEntry.H
Foam::expressions::exprDriver::searchControls
searchControls
Search/caching controls.
Definition: exprDriver.H:146
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::expressions::exprDriver::variables_
HashTable< exprResult > variables_
The variables table.
Definition: exprDriver.H:196
Foam::expressions::exprDriver
Base driver for parsing (field) values.
Definition: exprDriver.H:139
Foam::expressions::exprDriver::arg1Value_
scalar arg1Value_
Special-purpose scalar reference argument.
Definition: exprDriver.H:210
Foam::func
void func(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
forAllIters
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:223
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::expressions::exprDriver::setSearchBehaviour
void setSearchBehaviour(enum searchControls search, const bool caching=false)
Definition: exprDriver.C:542
Foam::expressions::exprDriver::clearVariables
virtual void clearVariables()
Clear temporary variables, reset from expression strings.
Definition: exprDriver.C:331
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::expressions::exprDriver::variableStrings_
List< expressions::exprString > variableStrings_
Variable definitions, as read from a dictionary.
Definition: exprDriver.H:193
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::expressions::exprResult::getUniform
exprResult getUniform(const label size, const bool noWarn, const bool parRun=Pstream::parRun()) const
Construct a uniform field from the current results.
Definition: exprResult.C:436
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::expressions::exprDriver::resetDb
void resetDb(const objectRegistry *obrPtr=nullptr)
Reset the objectRegistry (for functions)
Definition: exprDriver.C:142
Foam::expressions::exprDriver::scalarFuncs_
HashTable< refPtr< Function1< scalar > > > scalarFuncs_
Definition: exprDriver.H:200
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:382
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:404
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::expressions::exprDriver::dict
const dictionary & dict() const noexcept
The dictionary with all input data/specification.
Definition: exprDriver.H:384
Foam::expressions::exprDriver::obrPtr_
const objectRegistry * obrPtr_
Pointer to an object registry (for functions etc).
Definition: exprDriver.H:216
Foam::expressions::exprString
Definition: exprString.H:60
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::search
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:571
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::expressions::exprDriver::evaluateVariableRemote
virtual void evaluateVariableRemote(string remote, const word &varName, const expressions::exprString &expr)
Definition: exprDriver.C:357
Foam::expressions::exprDriver::clearResult
void clearResult()
Clear the result.
Definition: exprDriver.C:315
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::shallowCloneFunctions
static void shallowCloneFunctions(HashTable< refPtr< Function1< Type >>> &dest, const HashTable< refPtr< Function1< Type >>> &rhs)
Definition: exprDriver.C:105
Foam::expressions::defineTypeNameAndDebug
defineTypeNameAndDebug(fvExprDriver, 0)
stringOps.H
Foam::expressions::exprDriver::update
virtual bool update()
Update things.
Definition: exprDriver.C:321
Foam::expressions::exprDriver::result_
exprResult result_
The result.
Definition: exprDriver.H:190
Foam::expressions::exprDriver::timeStatePtr_
const TimeState * timeStatePtr_
Reference to the time-state.
Definition: exprDriver.H:213
Foam::refPtr
A class for managing references or pointers (no reference counting)
Definition: PtrList.H:60
Foam::keyType::REGEX_RECURSIVE
Definition: keyType.H:87