Loading...
Searching...
No Matches
fieldAverage.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) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2015-2017 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 "fieldAverage.H"
30#include "volFields.H"
31#include "fieldAverageItem.H"
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
36namespace Foam
37{
38namespace functionObjects
39{
42}
43}
44
45
46// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
47
49{
50 for (fieldAverageItem& item : faItems_)
51 {
52 // Note: not clearing data needed for restart
53 item.clear(obr(), false);
54 }
55
56 Log << type() << " " << name() << ":" << nl;
57
58 // Add mean fields to the field lists
59 for (fieldAverageItem& item : faItems_)
60 {
66 }
67
68 // Add prime-squared mean fields to the field lists
69 for (fieldAverageItem& item : faItems_)
70 {
73 }
74
75 // Add window fields to the field lists
76 for (const fieldAverageItem& item : faItems_)
77 {
83 }
84
85
86 for (const fieldAverageItem& item : faItems_)
87 {
88 if (!item.active())
89 {
91 << "Field " << item.fieldName()
92 << " not found in database for averaging";
93 }
94 }
95
96 // Ensure first averaging works unconditionally
98
99 Log << endl;
100 initialised_ = true;
101}
102
103
105{
106 Log << " Restarting averaging at time "
107 << obr().time().timeOutputValue()
108 << nl << endl;
109
110 for (fieldAverageItem& item : faItems_)
111 {
112 item.clear(obr(), true);
113 }
114
115 initialize();
116}
117
118
120{
121 if (!initialised_)
122 {
123 initialize();
124 }
125
126 const label currentTimeIndex = obr().time().timeIndex();
127 const scalar currentTime = obr().time().value();
128
129 if (prevTimeIndex_ == currentTimeIndex)
130 {
131 return;
132 }
133 else
134 {
135 prevTimeIndex_ = currentTimeIndex;
136 }
137
138 bool doRestart = false;
139 if (periodicRestart_)
140 {
141 const scalar deltaT = obr().time().deltaTValue();
142 const scalar nextTime = restartPeriod_*periodIndex_ + 0.5*deltaT;
143
144 if (currentTime > nextTime)
145 {
146 doRestart = true;
147 ++periodIndex_;
148 }
149 }
150
151 if (currentTime >= restartTime_)
152 {
153 doRestart = true; // Restart is overdue.
154 restartTime_ = GREAT; // Avoid triggering again
155 }
156
157 if (doRestart)
158 {
159 restart();
160 }
161
162 Log << type() << " " << name() << " write:" << nl
163 << " Calculating averages" << nl;
164
165 forAll(faItems_, fieldi)
166 {
167 faItems_[fieldi].evolve(obr());
168 }
169
170 storeWindowFields<scalar>();
171 storeWindowFields<vector>();
172 storeWindowFields<sphericalTensor>();
173 storeWindowFields<symmTensor>();
174 storeWindowFields<tensor>();
175
176 addMeanSqrToPrime2Mean<scalar, scalar>();
177 addMeanSqrToPrime2Mean<vector, symmTensor>();
178
179 calculateMeanFields<scalar>();
180 calculateMeanFields<vector>();
181 calculateMeanFields<sphericalTensor>();
182 calculateMeanFields<symmTensor>();
183 calculateMeanFields<tensor>();
184
208 for (const fieldAverageItem& item : faItems_)
209 {
211 item.writeState(propsDict);
212 setProperty(item.fieldName(), propsDict);
213 }
214}
215
216
218{
219 if (restartOnRestart_ || restartOnOutput_)
220 {
221 Info<< " Starting averaging at time "
222 << obr().time().timeOutputValue()
223 << nl;
224 }
225 else
226 {
227 Info<< " Restarting averaging for fields:" << nl;
228
229
230 for (fieldAverageItem& item : faItems_)
231 {
232 const word& fieldName = item.fieldName();
233 if (foundProperty(fieldName))
234 {
235 dictionary fieldDict;
236 getDict(fieldName, fieldDict);
237 item.readState(fieldDict);
238
239 if (item.allowRestart())
240 {
241 scalar userTotalTime =
242 obr().time().timeToUserTime(item.totalTime());
243
244 Info<< " " << fieldName
245 << ": iters = " << item.totalIter()
246 << " time = " << userTotalTime << nl;
247 }
248 else
249 {
250 item.clear(obr(), true);
251
252 Info<< " " << fieldName
253 << ": starting averaging at time "
254 << obr().time().timeOutputValue() << endl;
255 }
256 }
257 else
258 {
259 Info<< " " << fieldName
260 << ": starting averaging at time "
261 << obr().time().timeOutputValue() << endl;
262 }
264 }
265}
266
267
268// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
269
271(
272 const word& name,
273 const Time& runTime,
274 const dictionary& dict
275)
276:
277 fvMeshFunctionObject(name, runTime, dict),
278 prevTimeIndex_(-1),
279 initialised_(false),
280 restartOnRestart_(false),
281 restartOnOutput_(false),
282 periodicRestart_(false),
283 restartPeriod_(GREAT),
284 restartTime_(GREAT),
285 faItems_(),
286 periodIndex_(1)
288 read(dict);
289}
290
291
292// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
293
295{
297
298 // Make certain that the values are consistent with the defaults:
299 initialised_ = false;
300 restartOnRestart_ = false;
301 restartOnOutput_ = false;
302 periodicRestart_ = false;
303 restartPeriod_ = GREAT;
304 restartTime_ = GREAT;
305
306 Info<< type() << " " << name() << ":" << nl;
307
308 dict.readIfPresent("restartOnRestart", restartOnRestart_);
309 dict.readIfPresent("restartOnOutput", restartOnOutput_);
310 dict.readIfPresent("periodicRestart", periodicRestart_);
311
312 List<fieldAverageItem> faItems0;
313 dict.readEntry("fields", faItems0);
314
315 DynamicList<fieldAverageItem> faItems(faItems0.size());
316
318 for (auto& item : faItems0)
319 {
320 if (names.insert(item.fieldName()))
321 {
322 item.setMeanFieldName(scopedName(item.meanFieldName()));
323 item.setPrime2MeanFieldName(scopedName(item.prime2MeanFieldName()));
324 faItems.push_back(item);
325 }
326 else
327 {
329 << "Duplicate entry found: " << item.fieldName()
330 << " (ignored)" << endl;
331 }
332 }
333
334 faItems_.transfer(faItems);
335
336 const scalar currentTime = obr().time().value();
337
338 if (periodicRestart_)
339 {
340 scalar userRestartPeriod = dict.get<scalar>("restartPeriod");
341 restartPeriod_ = obr().time().userTimeToTime(userRestartPeriod);
342
343 if (restartPeriod_ > 0)
344 {
345 // Determine the appropriate interval for the next restart
346 periodIndex_ = 1;
347 while (currentTime > restartPeriod_*periodIndex_)
348 {
349 ++periodIndex_;
350 }
351
352 Info<< " Restart period " << userRestartPeriod
353 << " - next restart at " << (userRestartPeriod*periodIndex_)
354 << nl << endl;
355 }
356 else
357 {
358 periodicRestart_ = false;
359
360 Info<< " Restart period " << userRestartPeriod
361 << " - ignored"
362 << nl << endl;
363 }
364 }
365
366 scalar userRestartTime = 0;
367 if (dict.readIfPresent("restartTime", userRestartTime))
368 {
369 restartTime_ = obr().time().userTimeToTime(userRestartTime);
370
371 if (currentTime > restartTime_)
372 {
373 // The restart time is already in the past - ignore
374 restartTime_ = GREAT;
375 }
376 else
377 {
378 Info<< " Restart scheduled at time " << userRestartTime
379 << nl << endl;
380 }
381 }
382
383 readAveragingProperties();
385 Info<< endl;
386
387 return true;
388}
389
390
393 calcAverages();
394
395 return true;
396}
397
398
400{
401 writeAverages();
402 writeAveragingProperties();
403
404 if (restartOnOutput_)
405 {
406 restart();
407 }
408
409 return true;
410}
411
412
413// ************************************************************************* //
#define Log
Definition PDRblock.C:28
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
IOdictionary propsDict(dictIO)
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void push_back(const T &val)
Copy append an element to the end of this list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Abstract base-class for Time/database function objects.
const word & name() const noexcept
Return the name of this functionObject.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
word scopedName(const word &name) const
Return a scoped (prefixed) name.
virtual const word & type() const =0
Runtime type information.
Helper class to describe what form of averaging to apply. A set will be applied to each base field in...
Computes ensemble- and/or time-based field averages, with optional windowing, for a user-specified se...
Switch periodicRestart_
Periodically restart the averaging process.
label prevTimeIndex_
Time at last call, prevents repeated averaging.
void writeAveragingProperties()
Write averaging properties - steps and time.
void restart()
Restart averaging for restartOnOutput.
void initialize()
Reset lists (clear existing values) and initialize averaging.
Switch restartOnRestart_
Restart the averaging process on restart.
Switch restartOnOutput_
Restart the averaging process on output.
label periodIndex_
Index for periodic restart.
virtual void calcAverages()
Main calculation routine.
scalar restartPeriod_
Restart period.
bool addMeanField(fieldAverageItem &item)
Add mean average field to database.
scalar restartTime_
Specific restart time.
bool initialised_
Initialised flag.
void calculatePrime2MeanFields() const
Calculate prime-squared average fields.
List< fieldAverageItem > faItems_
List of field average items, describing what averages to be calculated and output.
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
bool addPrime2MeanField(fieldAverageItem &item)
Add prime-squared average field to database.
virtual void writeAverages() const
Write averages.
void readAveragingProperties()
Read averaging properties - steps and time.
virtual bool execute()
Execute the function-object operations.
virtual bool write()
Write the function-object results.
fieldAverage(const word &name, const Time &runTime, const dictionary &)
Construct from name, Time and dictionary.
void calculateMeanFields() const
Calculate mean average fields.
void restoreWindowFields(const fieldAverageItem &item)
void addMeanSqrToPrime2Mean() const
Add mean-squared field value to prime-squared mean field.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
virtual const objectRegistry & obr() const
The region or sub-region registry being used.
bool getDict(const word &entryName, dictionary &dict) const
Set dictionary, return true if set.
bool foundProperty(const word &entryName) const
Return true if the property exists.
void setProperty(const word &entryName, const Type &value)
Add generic property.
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
engineTime & runTime
auto & name
auto & names
#define WarningInFunction
Report a warning using Foam::Warning.
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
Namespace for OpenFOAM.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition HashSet.H:80
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition int32.H:127
messageStream Info
Information stream (stdout output on master, null elsewhere).
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
static bool initialised_(false)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299