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-------------------------------------------------------------------------------
11License
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
36namespace Foam
37{
38namespace expressions
39{
40
42
43} // End namespace expressions
44} // End namespace Foam
45
46
47// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
48
49int Foam::expressions::exprDriver::getSearchControls(const dictionary& dict)
50{
51 int val = 0;
52
53 if (dict.getOrDefault("searchInMemory", true))
54 {
56 }
57 if (dict.getOrDefault("searchFiles", false))
58 {
60 }
61 if (dict.getOrDefault("cacheReadFields", false))
62 {
64 }
65
66 return val;
67}
68
69
70// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
71
72namespace Foam
73{
74#if 0
75static 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
98 return exprTools::expressionEntry::evaluate(*eptr);
99}
100#endif
101
102
103template<class Type>
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(
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
234}
235
236
238(
239 const dictionary& dict
240)
241:
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
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 (
418 expressions::exprString::toExpr
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 (
454 expressions::exprString::toExpr
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(
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(
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// ************************************************************************* //
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition: Function1.H:96
A HashTable similar to std::unordered_map.
Definition: HashTable.H:123
The time value with time-stepping information, user-defined remapping, etc.
Definition: TimeState.H:54
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Base driver for parsing (field) values.
Definition: exprDriver.H:141
virtual void updateSpecialVariables(bool force=false)
Examine current variable values and update stored variables.
Definition: exprDriver.C:327
void clearResult()
Clear the result.
Definition: exprDriver.C:315
void addVariables(const expressions::exprString &expr, bool clear=true)
Add/set string expressions for variables.
Definition: exprDriver.C:379
const TimeState * timeState() const noexcept
Reference to the current time-state (can be nullptr)
Definition: exprDriver.C:254
void resetDb(const objectRegistry *obrPtr=nullptr)
Reset the objectRegistry (for functions)
Definition: exprDriver.C:142
HashTable< refPtr< Function1< scalar > > > scalarFuncs_
Definition: exprDriver.H:201
bool debugParser_
Request debugging for parser.
Definition: exprDriver.H:229
HashTable< refPtr< Function1< vector > > > vectorFuncs_
Definition: exprDriver.H:205
searchControls
Search/caching controls.
Definition: exprDriver.H:148
@ SEARCH_REGISTRY
Search registry before disk.
Definition: exprDriver.H:150
@ SEARCH_FILES
Search disk (eg, standalone app)
Definition: exprDriver.H:151
@ CACHE_READ_FIELDS
Cache fields read from disk.
Definition: exprDriver.H:152
virtual void evaluateVariableRemote(string remote, const word &varName, const expressions::exprString &expr)
Definition: exprDriver.C:357
bool debugScanner_
Request debugging for scanner.
Definition: exprDriver.H:226
virtual bool readDict(const dictionary &dict)
Read variables, tables etc.
Definition: exprDriver.C:297
virtual scalar deltaT() const
The current deltaT value.
Definition: exprDriver.C:282
const dictionary & dict_
The dictionary with all input data/specification.
Definition: exprDriver.H:188
searchControls searchCtrl_
Registry/disk/caching control.
Definition: exprDriver.H:238
void setDebugging(bool scannerDebug, bool parserDebug)
Set the scanner/parser debug.
Definition: exprDriver.C:493
void setSearchBehaviour(enum searchControls search, const bool caching=false)
Definition: exprDriver.C:542
virtual exprResult getRemoteResult(const exprDriver &other) const
Get the result from another driver.
Definition: exprDriver.C:369
virtual bool update()
Update things.
Definition: exprDriver.C:321
const exprResult & result() const noexcept
Const access to expression result.
Definition: exprDriver.H:391
void evaluateVariable(const word &varName, const expressions::exprString &expr)
Definition: exprDriver.C:339
void resetTimeReference(const TimeState *ts)
Reset the time-state reference.
Definition: exprDriver.C:130
virtual void clearVariables()
Clear temporary variables, reset from expression strings.
Definition: exprDriver.C:331
const dictionary & dict() const noexcept
The dictionary with all input data/specification.
Definition: exprDriver.H:385
virtual scalar timeValue() const
The current time value.
Definition: exprDriver.C:268
bool setCaching(bool on) noexcept
Toggle CACHE_READ_FIELDS control.
Definition: exprDriver.C:513
A polymorphic field/result from evaluating an expression.
Definition: exprResult.H:127
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
virtual void validate()
Validate the turbulence fields after construction.
Definition: kkLOmega.C:597
Registry of regIOobjects.
A class for managing references or pointers (no reference counting)
Definition: refPtr.H:58
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
patchWriters clear()
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:517
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define DebugInfo
Report an information message using Foam::Info.
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
string trim(const std::string &s)
Return string trimmed of leading and trailing whitespace.
Definition: stringOps.C:1046
void inplaceTrim(std::string &s)
Trim leading and trailing whitespace inplace.
Definition: stringOps.C:1067
Namespace for OpenFOAM.
void func(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
static void shallowCloneFunctions(HashTable< refPtr< Function1< Type > > > &dest, const HashTable< refPtr< Function1< Type > > > &rhs)
Definition: exprDriver.C:105
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
IOerror FatalIOError
const direction noexcept
Definition: Scalar.H:223
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:624
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:260
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition: stdFoam.H:278