exprResultDelayed.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) 2012-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
9 Copyright (C) 2019-2020 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 "exprResultDelayed.H"
30#include "vector.H"
31#include "tensor.H"
32#include "symmTensor.H"
33#include "sphericalTensor.H"
35
36// #include <cassert>
37
38// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39
40namespace Foam
41{
42namespace expressions
43{
45
47 (
51 );
53 (
56 empty
57 );
58
59} // End namespace expressions
60} // End namespace Foam
61
62
63// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
64
66:
67 exprResult(),
68 name_("none"),
69 startExpr_(),
70 settingResult_(),
71 storeInterval_(1),
72 delay_(10)
73{}
74
75
77(
78 const exprResultDelayed& rhs
79)
80:
81 exprResult(rhs),
82 name_(rhs.name_),
83 startExpr_(rhs.startExpr_),
84 settingResult_(rhs.settingResult_),
85 storedValues_(rhs.storedValues_),
86 storeInterval_(rhs.storeInterval_),
87 delay_(rhs.delay_)
88{}
89
90
92(
93 const dictionary& dict
94)
95:
96 exprResult(dict.subOrEmptyDict("value")),
97 name_(dict.get<word>("name")),
98 startExpr_(dict.get<string>("startupValue"), dict),
99 storeInterval_(dict.get<scalar>("storeInterval")),
100 delay_(dict.get<scalar>("delay"))
101{
102 const entry *eptr = dict.findEntry("storedValues");
103
104 if (eptr)
105 {
106 storedValues_ = DLList<ValueAtTime>(eptr->stream());
107 }
108}
109
110
111// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
112
114(
115 const scalar& timeVal
116)
117{
118 if (storedValues_.empty())
119 {
120 return false;
121 }
122
123 const ValueAtTime& first = storedValues_.first();
124
125 if (first.first() > (timeVal-delay_))
126 {
127 // No matching data yet
128 return false;
129 }
130
131 if (storedValues_.size() <= 1)
132 {
134 << "Only one stored value at time " << timeVal
135 << " for delayedVariable " << name() << nl
136 << "Check the values for the interval " << storeInterval_
137 << " and delay " << delay_ << nl
138 << "Probably the interval is too large" << nl << endl
139 << exit(FatalError);
140 }
141
142 auto current = storedValues_.cbegin();
143 auto next = current;
144 ++next;
145
146 // The time without the delay offset
147 const scalar newTime = (timeVal - delay_);
148
149 while (next != storedValues_.end())
150 {
151 if (newTime >= current().first() && newTime <= next().first())
152 {
153 break;
154 }
155
156 current = next;
157 ++next;
158 }
159
160 const scalar f =
161 (
162 (newTime - current().first())
163 / (next().first() - current().first())
164 );
165
166 exprResult val((1-f)*current().second() + f*next().second());
167
168 setReadValue(val);
169
170 return true;
171}
172
173
175(
176 const exprResult& val
177)
178{
180}
181
182
184(
185 const scalar& currTime
186)
187{
188 bool append = storedValues_.empty();
189
190 if (!append)
191 {
192 const scalar lastTime = storedValues_.last().first();
193
194 if (lastTime + SMALL >= currTime)
195 {
196 // Times are essentially identical - replace value
197 }
198 else if ((currTime - lastTime) >= 0.999*storeInterval_)
199 {
200 append = true;
201 }
202 else
203 {
204 // Cannot store in the middle - abandon the attempt
205 return;
206 }
207 }
208
209 if (append)
210 {
211 // Append value
212
213 const scalar oldLastTime =
214 (
215 storedValues_.empty()
216 ? 0
217 : storedValues_.last().first()
218 );
219
220 storedValues_.append(ValueAtTime(currTime, settingResult_));
221
222 while
223 (
224 storedValues_.size() > 1
225 && (oldLastTime - storedValues_.first().first()) >= delay_
226 )
227 {
228 // Remove values that are older than delay_
229 storedValues_.removeHead();
230 }
231 }
232 else
233 {
234 // Replace value
235
236 storedValues_.last().second() = settingResult_;
237 }
238}
239
240
242{
243 os.beginBlock();
244
245 os.writeEntry("name", name_);
246
247 os.writeEntry("startupValue", startExpr_);
248
249 if (!settingResult_.valueType().empty())
250 {
251 os.writeEntry("settingResult", settingResult_);
252 }
253
254 os.writeEntry("storedValues", storedValues_);
255 os.writeEntry("storeInterval", storeInterval_);
256 os.writeEntry("delay", delay_);
257
258 os.writeKeyword("value");
259 os << static_cast<const exprResult&>(*this);
260
261 os.endBlock();
262}
263
264
265// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
266
268(
269 const exprResultDelayed& rhs
270)
271{
272 if (this == &rhs)
273 {
274 return; // Self-assignment is a no-op
275 }
276
278
279 name_ = rhs.name_;
280 startExpr_ = rhs.startExpr_;
281 settingResult_ = rhs.settingResult_;
282 storedValues_ = rhs.storedValues_;
283 storeInterval_ = rhs.storeInterval_;
284 delay_ = rhs.delay_;
285}
286
287
289(
290 const exprResult& rhs
291)
292{
293 settingResult_ = rhs;
294}
295
296
298(
299 exprResult&& rhs
300)
301{
302 settingResult_ = std::move(rhs);
303}
304
305
306// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
307
308Foam::Istream& Foam::operator>>
309(
310 Istream& is,
312)
313{
314 dictionary dict(is);
315
317
318 return is;
319}
320
321
322Foam::Ostream& Foam::operator<<
323(
324 Ostream& os,
326)
327{
328 data.writeDict(os);
329 return os;
330}
331
332
333// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
Template class for non-intrusive linked lists.
Definition: LList.H:79
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:58
const T1 & first() const noexcept
Return first.
Definition: Tuple2.H:118
Database for solution data, solver performance and other reduced data.
Definition: data.H:58
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
Definition: dictionaryI.H:97
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
An exprResult with an additional delay before evaluation.
void storeValue(const scalar &timeVal)
Add a stored value.
bool updateReadValue(const scalar &timeVal)
Update the read-value.
void setReadValue(const exprResult &val)
Set the readValue with a calculated value.
A polymorphic field/result from evaluating an expression.
Definition: exprResult.H:127
virtual void operator=(const exprResult &rhs)
Copy assignment.
Definition: exprResult.C:498
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
Foam::dictionary writeDict() const
Write to dictionary.
A class for handling character strings derived from std::string.
Definition: string.H:79
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeName(Type)
Define the typeName.
Definition: className.H:96
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
rAUs append(new volScalarField(IOobject::groupName("rAU", phase1.name()), 1.0/(U1Eqn.A()+byDt(max(phase1.residualAlpha() - alpha1, scalar(0)) *rho1))))
Namespace for OpenFOAM.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
dictionary dict