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 -------------------------------------------------------------------------------
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 "fieldAverage.H"
30 #include "volFields.H"
31 #include "fieldAverageItem.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 namespace functionObjects
39 {
40  defineTypeNameAndDebug(fieldAverage, 0);
41  addToRunTimeSelectionTable(functionObject, fieldAverage, dictionary);
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  {
61  addMeanField<scalar>(item);
62  addMeanField<vector>(item);
63  addMeanField<sphericalTensor>(item);
64  addMeanField<symmTensor>(item);
65  addMeanField<tensor>(item);
66  }
67 
68  // Add prime-squared mean fields to the field lists
69  for (fieldAverageItem& item : faItems_)
70  {
71  addPrime2MeanField<scalar, scalar>(item);
72  addPrime2MeanField<vector, symmTensor>(item);
73  }
74 
75  // Add window fields to the field lists
76  for (const fieldAverageItem& item : faItems_)
77  {
78  restoreWindowFields<scalar>(item);
79  restoreWindowFields<vector>(item);
80  restoreWindowFields<sphericalTensor>(item);
81  restoreWindowFields<symmTensor>(item);
82  restoreWindowFields<tensor>(item);
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
97  prevTimeIndex_ = -1;
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_ && currentTime > restartPeriod_*periodIndex_)
140  {
141  doRestart = true;
142  periodIndex_++;
143  }
144 
145  if (currentTime >= restartTime_)
146  {
147  doRestart = true; // Restart is overdue.
148  restartTime_ = GREAT; // Avoid triggering again
149  }
150 
151  if (doRestart)
152  {
153  restart();
154  }
155 
156  Log << type() << " " << name() << " write:" << nl
157  << " Calculating averages" << nl;
158 
159  forAll(faItems_, fieldi)
160  {
161  faItems_[fieldi].evolve(obr());
162  }
163 
164  storeWindowFields<scalar>();
165  storeWindowFields<vector>();
166  storeWindowFields<sphericalTensor>();
167  storeWindowFields<symmTensor>();
168  storeWindowFields<tensor>();
169 
170  addMeanSqrToPrime2Mean<scalar, scalar>();
171  addMeanSqrToPrime2Mean<vector, symmTensor>();
172 
173  calculateMeanFields<scalar>();
174  calculateMeanFields<vector>();
175  calculateMeanFields<sphericalTensor>();
176  calculateMeanFields<symmTensor>();
177  calculateMeanFields<tensor>();
178 
179  calculatePrime2MeanFields<scalar, scalar>();
180  calculatePrime2MeanFields<vector, symmTensor>();
181 
182  Log << endl;
183 }
184 
185 
187 {
188  Log << " Writing average fields" << endl;
189 
190  writeFields<scalar>();
191  writeFields<vector>();
192  writeFields<sphericalTensor>();
193  writeFields<symmTensor>();
194  writeFields<tensor>();
195 
196  Log << endl;
197 }
198 
199 
201 {
202  for (const fieldAverageItem& item : faItems_)
203  {
205  item.writeState(propsDict);
206  setProperty(item.fieldName(), propsDict);
207  }
208 }
209 
210 
212 {
213  if (restartOnRestart_ || restartOnOutput_)
214  {
215  Info<< " Starting averaging at time "
216  << obr().time().timeOutputValue()
217  << nl;
218  }
219  else
220  {
221  Info<< " Restarting averaging for fields:" << nl;
222 
223 
224  for (fieldAverageItem& item : faItems_)
225  {
226  const word& fieldName = item.fieldName();
227  if (foundProperty(fieldName))
228  {
229  dictionary fieldDict;
230  getDict(fieldName, fieldDict);
231  item.readState(fieldDict);
232 
233  if (item.allowRestart())
234  {
235  scalar userTotalTime =
236  obr().time().timeToUserTime(item.totalTime());
237 
238  Info<< " " << fieldName
239  << ": iters = " << item.totalIter()
240  << " time = " << userTotalTime << nl;
241  }
242  else
243  {
244  item.clear(obr(), true);
245 
246  Info<< " " << fieldName
247  << ": starting averaging at time "
248  << obr().time().timeOutputValue() << endl;
249  }
250  }
251  else
252  {
253  Info<< " " << fieldName
254  << ": starting averaging at time "
255  << obr().time().timeOutputValue() << endl;
256  }
257  }
258  }
259 }
260 
261 
262 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
263 
265 (
266  const word& name,
267  const Time& runTime,
268  const dictionary& dict
269 )
270 :
272  prevTimeIndex_(-1),
273  initialised_(false),
274  restartOnRestart_(false),
275  restartOnOutput_(false),
276  periodicRestart_(false),
277  restartPeriod_(GREAT),
278  restartTime_(GREAT),
279  faItems_(),
280  periodIndex_(1)
281 {
282  read(dict);
283 }
284 
285 
286 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
287 
289 {
291 
292  // Make certain that the values are consistent with the defaults:
293  initialised_ = false;
294  restartOnRestart_ = false;
295  restartOnOutput_ = false;
296  periodicRestart_ = false;
297  restartPeriod_ = GREAT;
298  restartTime_ = GREAT;
299 
300  Info<< type() << " " << name() << ":" << nl;
301 
302  dict.readIfPresent("restartOnRestart", restartOnRestart_);
303  dict.readIfPresent("restartOnOutput", restartOnOutput_);
304  dict.readIfPresent("periodicRestart", periodicRestart_);
305  dict.readEntry("fields", faItems_);
306 
307  const scalar currentTime = obr().time().value();
308 
309  if (periodicRestart_)
310  {
311  scalar userRestartPeriod = dict.get<scalar>("restartPeriod");
312  restartPeriod_ = obr().time().userTimeToTime(userRestartPeriod);
313 
314  if (restartPeriod_ > 0)
315  {
316  // Determine the appropriate interval for the next restart
317  periodIndex_ = 1;
318  while (currentTime > restartPeriod_*periodIndex_)
319  {
320  ++periodIndex_;
321  }
322 
323  Info<< " Restart period " << userRestartPeriod
324  << " - next restart at " << (userRestartPeriod*periodIndex_)
325  << nl << endl;
326  }
327  else
328  {
329  periodicRestart_ = false;
330 
331  Info<< " Restart period " << userRestartPeriod
332  << " - ignored"
333  << nl << endl;
334  }
335  }
336 
337  scalar userRestartTime = 0;
338  if (dict.readIfPresent("restartTime", userRestartTime))
339  {
340  restartTime_ = obr().time().userTimeToTime(userRestartTime);
341 
342  if (currentTime > restartTime_)
343  {
344  // The restart time is already in the past - ignore
345  restartTime_ = GREAT;
346  }
347  else
348  {
349  Info<< " Restart scheduled at time " << userRestartTime
350  << nl << endl;
351  }
352  }
353 
354  readAveragingProperties();
355 
356  Info<< endl;
357 
358  return true;
359 }
360 
361 
363 {
364  calcAverages();
365 
366  return true;
367 }
368 
369 
371 {
372  writeAverages();
373  writeAveragingProperties();
374 
375  if (restartOnOutput_)
376  {
377  restart();
378  }
379 
380  return true;
381 }
382 
383 
384 // ************************************************************************* //
volFields.H
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::functionObjects::fvMeshFunctionObject
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
Definition: fvMeshFunctionObject.H:64
Foam::functionObjects::fieldAverage::calcAverages
virtual void calcAverages()
Main calculation routine.
Definition: fieldAverage.C:119
fieldAverage.H
Foam::functionObjects::addToRunTimeSelectionTable
addToRunTimeSelectionTable(functionObject, add, dictionary)
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::functionObjects::fieldAverage::readAveragingProperties
void readAveragingProperties()
Read averaging properties - steps and time.
Definition: fieldAverage.C:211
Foam::functionObjects::fieldAverage::restart
void restart()
Restart averaging for restartOnOutput.
Definition: fieldAverage.C:104
Foam::functionObjects::fieldAverage::execute
virtual bool execute()
Calculate the field averages.
Definition: fieldAverage.C:362
Foam::functionObjects::fieldAverage::read
virtual bool read(const dictionary &)
Read the field average data.
Definition: fieldAverage.C:288
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::functionObjects::fieldAverage::write
virtual bool write()
Write the field averages.
Definition: fieldAverage.C:370
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
fieldAverageItem.H
propsDict
IOdictionary propsDict(IOobject("particleTrackProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED))
Foam::functionObjects::fieldAverage::fieldAverage
fieldAverage(const fieldAverage &)=delete
No copy construct.
Foam::functionObjects::fieldAverage::prevTimeIndex_
label prevTimeIndex_
Time at last call, prevents repeated averaging.
Definition: fieldAverage.H:209
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::functionObjects::fieldAverage::writeAverages
virtual void writeAverages() const
Write averages.
Definition: fieldAverage.C:186
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::functionObjects::regionFunctionObject::read
virtual bool read(const dictionary &dict)
Read optional controls.
Definition: regionFunctionObject.C:166
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::functionObjects::defineTypeNameAndDebug
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
Foam::functionObjects::fieldAverageItem
Helper class to describe what form of averaging to apply. A set will be applied to each base field in...
Definition: fieldAverageItem.H:90
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::functionObject::name
const word & name() const
Return the name of this functionObject.
Definition: functionObject.C:131
Foam::functionObject::type
virtual const word & type() const =0
Runtime type information.
Foam::functionObjects::regionFunctionObject::obr
virtual const objectRegistry & obr() const
The region or sub-region registry being used.
Definition: regionFunctionObject.C:47
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::functionObjects::fieldAverage::initialize
void initialize()
Reset lists (clear existing values) and initialize averaging.
Definition: fieldAverage.C:48
Foam::functionObjects::fieldAverage::writeAveragingProperties
void writeAveragingProperties()
Write averaging properties - steps and time.
Definition: fieldAverage.C:200
Foam::functionObjects::fieldAverage::initialised_
bool initialised_
Initialised flag.
Definition: fieldAverage.H:212
Foam::functionObjects::fieldAverage::faItems_
List< fieldAverageItem > faItems_
List of field average items, describing what averages to be.
Definition: fieldAverage.H:231
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
Log
#define Log
Report write to Foam::Info if the local log switch is true.
Definition: messageStream.H:332