Loading...
Searching...
No Matches
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-2025 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 }
99}
100#endif
101
102
103template<class Type>
104static void shallowCloneFunctions
105(
106 HashTable<refPtr<Function1<Type>>>& dest,
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 {
117 refPtr<Function1<Type>> func;
118 func.cref(iter.val().shallowClone());
119
120 dest.emplace_set(key, std::move(func));
121 }
122 }
124
125} // End namespace Foam
126
127
128// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
133}
134
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())
159 (*funcPtr).resetDb(obrPtr_);
160 }
161 }
162}
163
164
165void Foam::expressions::exprDriver::resetDb(const objectRegistry& db)
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)),
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_);
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 )
248 readDict(dict);
249}
250
251
252// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
253
255{
256 if (timeStatePtr_)
257 {
258 return timeStatePtr_;
259 }
260 else if (obrPtr_)
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_)
276 return obrPtr_->time().value();
277 }
278 return 0;
279}
280
281
282Foam::scalar Foam::expressions::exprDriver::deltaT() const
283{
284 if (timeStatePtr_)
285 {
286 return timeStatePtr_->deltaTValue();
287 }
288 else if (obrPtr_)
290 return obrPtr_->time().deltaTValue();
291 }
292 return 0;
293}
294
295
297(
298 const dictionary& dict
299)
300{
301 dict.readIfPresent("debug.driver", debug);
302
303 // Regular variables (optional)
304 variableStrings_ = readVariableStrings(dict, "variables", false);
305
306 // Create Function1s from dictionary content
307 resetFunctions(dict);
309 // readTable("lookuptables2D", dict, lookup2D_);
310
311 return true;
312}
313
318}
319
322{
323 return true;
329
330
332{
333 variables_.clear();
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
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
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 = stringOps::split(expr, ';');
391
392 for (const auto& subMatch : varExpressions)
393 {
394 string varExpr(stringOps::trim(subMatch.str()));
395 if (varExpr.empty())
396 {
397 continue;
398 }
399
400 // Split on '=' for lhsExpr = rhsExpr
401 //
402 // varName = rhsExpr
403 // varName{where} = rhsExpr
404
405 const auto eqPos = varExpr.find('=');
406
407 if (eqPos == std::string::npos)
408 {
410 << "No '=' found in expression " << varExpr << nl << nl
411 << exit(FatalIOError);
412 }
413
414 // The RHS
415 expressions::exprString rhsExpr
416 (
418 (
419 stringOps::trim(varExpr.substr(eqPos+1))
420 )
421 );
422
423 // The LHS
424 varExpr.resize(eqPos);
425 stringOps::inplaceTrim(varExpr);
426
427 // Check for varName{where}
428 const auto lbrace = varExpr.find('{');
429
430 if (lbrace != std::string::npos)
431 {
432 const auto rbrace = varExpr.find('}');
433
434 if (rbrace == std::string::npos || rbrace < lbrace)
435 {
437 // << "Context: " << driverContext_ << nl
438 << "No closing '}' found in " << varExpr << nl
439 << exit(FatalError);
440 }
441 else if (lbrace+1 == rbrace)
442 {
444 // << "Context: " << driverContext_ << nl
445 << "Empty '{}' location in " << varExpr << nl
446 << exit(FatalError);
447 }
448
449 const word varName(word::validate(varExpr.substr(0, lbrace)));
450
451 const expressions::exprString remoteExpr
452 (
454 (
455 varExpr.substr(lbrace+1, rbrace-lbrace-1)
456 )
457 );
458
459 // Fails if derived class does not implement!
460
461 evaluateVariableRemote(remoteExpr, varName, rhsExpr);
462 }
463 else
464 {
465 const word varName(word::validate(varExpr));
467 evaluateVariable(varName, rhsExpr);
468 }
469 }
470}
471
472
474(
475 const UList<expressions::exprString>& list,
476 bool clear
477)
478{
479 if (clear)
480 {
481 clearVariables();
482 }
483
484 for (const auto& expr : list)
485 {
486 addVariables(expr, false); // No clear (already done)
487 }
488}
489
490
492(
493 bool scannerDebug,
494 bool parserDebug
496{
497 debugScanner_ = scannerDebug;
498 debugParser_ = parserDebug;
499}
500
501
503(
504 const exprDriver& rhs
506{
507 debugScanner_ = rhs.debugScanner_;
508 debugParser_ = rhs.debugParser_;
509}
510
511
513{
514 int val(searchCtrl_);
515 bool old = (val & searchControls::CACHE_READ_FIELDS);
516
517 if (!on)
518 {
519 // Off
520 val &= ~(searchControls::CACHE_READ_FIELDS);
521 }
522 else if (!old)
523 {
524 // Toggled on.
525 // Caching read fields implies both registry and disk use
526 val |=
527 (
528 searchControls::SEARCH_REGISTRY
529 | searchControls::SEARCH_FILES
530 | searchControls::CACHE_READ_FIELDS
531 );
532 }
535
536 return old;
537}
538
539
541(
542 enum searchControls search,
543 const bool caching
544)
545{
546 int val(search);
547 if (caching || (val & searchControls::CACHE_READ_FIELDS))
548 {
549 // Caching read fields implies both registry and disk use
550 val |=
551 (
552 searchControls::SEARCH_REGISTRY
553 | searchControls::SEARCH_FILES
554 | searchControls::CACHE_READ_FIELDS
555 );
556 }
557 searchCtrl_ = searchControls(val);
558
559 #ifdef FULLDEBUG
560 Info<< "Searching "
561 << " registry:" << searchRegistry()
562 << " disk:" << searchFiles()
563 << " cache-read:" << cacheReadFields() << nl;
564 #endif
565}
566
567
569(
570 const exprDriver& rhs
571)
572{
573 searchCtrl_ = rhs.searchCtrl_;
574}
575
576
577// ************************************************************************* //
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition Function1.H:92
A HashTable similar to std::unordered_map.
Definition HashTable.H:124
The time value with time-stepping information, user-defined remapping, etc.
Definition TimeState.H:50
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:89
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
const fileName & name() const noexcept
The dictionary name.
Definition dictionaryI.H:41
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
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
static string evaluate(const entry &e)
Generic concatenate tokens to space-separated string.
Base driver for parsing (field) values.
Definition exprDriver.H:137
virtual label size() const
The natural field size for the expression.
Definition exprDriver.H:423
bool searchFiles() const noexcept
bool cacheReadFields() const noexcept
exprResult result_
The result.
Definition exprDriver.H:201
virtual void updateSpecialVariables(bool force=false)
Examine current variable values and update stored variables.
Definition exprDriver.C:320
void clearResult()
Clear the result.
Definition exprDriver.C:308
void addVariables(const expressions::exprString &expr, bool clear=true)
Add/set string expressions for variables.
Definition exprDriver.C:372
const TimeState * timeState() const noexcept
Reference to the current time-state (can be nullptr).
Definition exprDriver.C:247
void resetDb(const objectRegistry *obrPtr=nullptr)
Reset the objectRegistry (for functions).
Definition exprDriver.C:135
bool searchRegistry() const noexcept
exprDriver(const exprDriver &)=delete
No copy construct.
HashTable< refPtr< Function1< scalar > > > scalarFuncs_
Function1 mappings/timelines (scalar), evaluated at the simulation time or with arbitrary scalars.
Definition exprDriver.H:217
bool debugParser_
Request debugging for parser.
Definition exprDriver.H:261
HashTable< refPtr< Function1< vector > > > vectorFuncs_
Function1 mappings/timelines (vector), evaluated at the simulation time or with arbitrary scalars.
Definition exprDriver.H:223
bool allowShadowing_
Allow variable names to mask field names.
Definition exprDriver.H:266
searchControls
Search/caching controls.
Definition exprDriver.H:146
@ SEARCH_REGISTRY
Search registry before disk.
Definition exprDriver.H:148
@ SEARCH_FILES
Search disk (eg, standalone app).
Definition exprDriver.H:149
@ CACHE_READ_FIELDS
Cache fields read from disk.
Definition exprDriver.H:150
virtual void evaluateVariableRemote(string remote, const word &varName, const expressions::exprString &expr)
Evaluate an expression on a remote and save as the specified named variable.
Definition exprDriver.C:350
bool prevIterIsOldTime_
Use value of previous iteration when oldTime is requested.
Definition exprDriver.H:271
bool debugScanner_
Request debugging for scanner.
Definition exprDriver.H:256
virtual bool readDict(const dictionary &dict)
Read variables, tables etc.
Definition exprDriver.C:290
List< expressions::exprString > variableStrings_
Variable definitions, as read from a dictionary.
Definition exprDriver.H:206
virtual scalar deltaT() const
The current deltaT value.
Definition exprDriver.C:275
const objectRegistry * obrPtr_
Pointer to an object registry (for functions etc).
Definition exprDriver.H:243
const TimeState * timeStatePtr_
Reference to the time-state.
Definition exprDriver.H:238
const dictionary & dict_
The dictionary with all input data/specification.
Definition exprDriver.H:196
HashTable< exprResult > variables_
The variables table.
Definition exprDriver.H:211
searchControls searchCtrl_
Registry/disk/caching control.
Definition exprDriver.H:276
void setDebugging(bool scannerDebug, bool parserDebug)
Set the scanner/parser debug.
Definition exprDriver.C:485
void setSearchBehaviour(enum searchControls search, const bool caching=false)
Set search behaviour, with additional CACHE_READ_FIELDS toggle on.
Definition exprDriver.C:534
virtual exprResult getRemoteResult(const exprDriver &other) const
Get the result from another driver.
Definition exprDriver.C:362
virtual bool update()
Update things.
Definition exprDriver.C:314
const exprResult & result() const noexcept
Const access to expression result.
Definition exprDriver.H:463
void evaluateVariable(const word &varName, const expressions::exprString &expr)
Evaluate the expression and save as the specified named variable.
Definition exprDriver.C:332
void resetTimeReference(const TimeState *ts)
Reset the time-state reference.
Definition exprDriver.C:123
virtual void clearVariables()
Clear temporary variables, reset from expression strings.
Definition exprDriver.C:324
contextObjectTableType contextObjects_
Externally defined context fields.
Definition exprDriver.H:228
virtual unsigned parse(const std::string &expr, size_t pos=0, size_t len=std::string::npos)=0
Execute the parser.
static List< expressions::exprString > readVariableStrings(const dictionary &dict, const word &name="variables", bool mandatory=false)
Read the list of variable strings.
const dictionary & dict() const noexcept
The dictionary with all input data/specification.
Definition exprDriver.H:455
virtual scalar timeValue() const
The current time value.
Definition exprDriver.C:261
bool setCaching(bool on) noexcept
Toggle CACHE_READ_FIELDS control.
Definition exprDriver.C:505
int stashedTokenId_
Internal bookkeeping as "look-behind" parsing context.
Definition exprDriver.H:251
scalar arg1Value_
Special-purpose scalar reference argument.
Definition exprDriver.H:233
A polymorphic field/result from evaluating an expression.
Definition exprResult.H:122
exprResult getUniform(const label size, const bool noWarn, const bool parRun=UPstream::parRun()) const
Construct a uniform field from the current results.
Definition exprResult.C:404
A variant of Foam::string with expansion of dictionary variables into a comma-separated form.
Definition exprString.H:58
static exprString toExpr(const std::string &str)
Copy convert string to exprString.
@ REGEX_RECURSIVE
Definition keyType.H:88
Registry of regIOobjects.
A class for managing references or pointers (no reference counting).
Definition refPtr.H:54
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
Definition refPtrI.H:216
A class for handling words, derived from Foam::string.
Definition word.H:66
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition word.C:39
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition error.H:688
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
surface1 clear()
#define DebugInfo
Report an information message using Foam::Info.
Namespace for handling debugging switches.
Definition debug.C:45
A namespace for expression-related classes/traits etc.
constexpr auto key(const Type &t) noexcept
Helper function to return the enum value.
string trim(const std::string &s)
Return string trimmed of leading and trailing whitespace.
Foam::SubStrings split(const std::string &str, const char delim, std::string::size_type pos=0, const bool keepEmpty=false)
Split string into sub-strings at the delimiter character.
void inplaceTrim(std::string &s)
Trim leading and trailing whitespace inplace.
Namespace for OpenFOAM.
static void shallowCloneFunctions(HashTable< refPtr< Function1< Type > > > &dest, const HashTable< refPtr< Function1< Type > > > &rhs)
Definition exprDriver.C:98
messageStream Info
Information stream (stdout output on master, null elsewhere).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition fileName.C:642
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition stdFoam.H:214
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition stdFoam.H:235