fieldAverage.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "fieldAverage.H"
27 #include "fieldAverageItem.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34 namespace functionObjects
35 {
36  defineTypeNameAndDebug(fieldAverage, 0);
37  addToRunTimeSelectionTable(functionObject, fieldAverage, dictionary);
38 }
39 }
40 
41 
42 template<>
43 const char* Foam::NamedEnum
44 <
46  2
47 >::names[] = { "iteration", "time"};
48 
49 const Foam::NamedEnum
50 <
52  2
54 
55 
56 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
57 
59 {
60  forAll(faItems_, i)
61  {
62  if (faItems_[i].mean())
63  {
64  if (obr_.found(faItems_[i].meanFieldName()))
65  {
66  obr_.checkOut(*obr_[faItems_[i].meanFieldName()]);
67  }
68  }
69 
70  if (faItems_[i].prime2Mean())
71  {
72  if (obr_.found(faItems_[i].prime2MeanFieldName()))
73  {
74  obr_.checkOut(*obr_[faItems_[i].prime2MeanFieldName()]);
75  }
76  }
77  }
78 }
79 
80 
82 {
83  if (!totalIter_.size())
84  {
85  totalIter_.setSize(faItems_.size(), 1);
86  }
87 
88  if (!totalTime_.size())
89  {
90  totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue());
91  }
92  else
93  {
94  // Check if totalTime_ has been set otherwise initialize
95  forAll(totalTime_, fieldi)
96  {
97  if (totalTime_[fieldi] < 0)
98  {
99  totalTime_[fieldi] = obr_.time().deltaTValue();
100  }
101  }
102  }
103 
104  resetFields();
105 
106  // Add mean fields to the field lists
107  forAll(faItems_, fieldi)
108  {
109  addMeanField<scalar>(fieldi);
110  addMeanField<vector>(fieldi);
111  addMeanField<sphericalTensor>(fieldi);
112  addMeanField<symmTensor>(fieldi);
113  addMeanField<tensor>(fieldi);
114  }
115 
116  // Add prime-squared mean fields to the field lists
117  forAll(faItems_, fieldi)
118  {
119  addPrime2MeanField<scalar, scalar>(fieldi);
120  addPrime2MeanField<vector, symmTensor>(fieldi);
121  }
122 
123  // ensure first averaging works unconditionally
124  prevTimeIndex_ = -1;
125 
126  initialised_ = true;
127 }
128 
129 
131 {
132  Log << " Restarting averaging at time " << obr_.time().timeName()
133  << nl << endl;
134 
135  totalIter_.clear();
136  totalTime_.clear();
137 
138  initialize();
139 }
140 
141 
143 {
144  if (!initialised_)
145  {
146  initialize();
147  }
148 
149  const label currentTimeIndex = obr_.time().timeIndex();
150  const scalar currentTime = obr_.time().value();
151 
152  if (prevTimeIndex_ == currentTimeIndex)
153  {
154  return;
155  }
156  else
157  {
158  prevTimeIndex_ = currentTimeIndex;
159  }
160 
161  if (periodicRestart_ && currentTime > restartPeriod_*periodIndex_)
162  {
163  restart();
164  periodIndex_++;
165  }
166 
167  Log << type() << " " << name() << nl
168  << " Calculating averages" << nl;
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  forAll(faItems_, fieldi)
183  {
184  totalIter_[fieldi]++;
185  totalTime_[fieldi] += obr_.time().deltaTValue();
186  }
187 
188  Log << endl;
189 }
190 
191 
193 {
194  Log << " Writing average fields" << endl;
195 
196  writeFields<scalar>();
197  writeFields<vector>();
198  writeFields<sphericalTensor>();
199  writeFields<symmTensor>();
200  writeFields<tensor>();
201 
202  Log << endl;
203 }
204 
205 
207 {
209  (
210  IOobject
211  (
212  name() + "Properties",
213  obr_.time().timeName(),
214  "uniform",
215  obr_,
218  false
219  )
220  );
221 
222  forAll(faItems_, fieldi)
223  {
224  const word& fieldName = faItems_[fieldi].fieldName();
225  propsDict.add(fieldName, dictionary());
226  propsDict.subDict(fieldName).add("totalIter", totalIter_[fieldi]);
227  propsDict.subDict(fieldName).add("totalTime", totalTime_[fieldi]);
228  }
229 
230  propsDict.regIOobject::write();
231 
232  Log << endl;
233 }
234 
235 
237 {
238  if ((restartOnRestart_ || restartOnOutput_) && log)
239  {
240  Info<< " Starting averaging at time " << obr_.time().timeName()
241  << nl;
242  }
243  else
244  {
245  IOobject propsDictHeader
246  (
247  name() + "Properties",
248  obr_.time().timeName(obr_.time().startTime().value()),
249  "uniform",
250  obr_,
253  false
254  );
255 
256  if (!propsDictHeader.typeHeaderOk<IOdictionary>())
257  {
258  Log << " Starting averaging at time "
259  << obr_.time().timeName() << nl;
260 
261  return;
262  }
263 
264  IOdictionary propsDict(propsDictHeader);
265 
266  Log << " Restarting averaging for fields:" << nl;
267 
268  totalIter_.setSize(faItems_.size(), 1);
269 
270  // Initialize totalTime with negative values
271  // to indicate that it has not been set
272  totalTime_.setSize(faItems_.size(), -1);
273 
274  forAll(faItems_, fieldi)
275  {
276  const word& fieldName = faItems_[fieldi].fieldName();
277  if (propsDict.found(fieldName))
278  {
279  dictionary fieldDict(propsDict.subDict(fieldName));
280 
281  totalIter_[fieldi] = fieldDict.lookup<label>("totalIter");
282  totalTime_[fieldi] = fieldDict.lookup<scalar>("totalTime");
283 
284  Log << " " << fieldName
285  << " iters = " << totalIter_[fieldi]
286  << " time = " << totalTime_[fieldi] << nl;
287  }
288  }
289  }
290 }
291 
292 
293 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
294 
296 (
297  const word& name,
298  const Time& runTime,
299  const dictionary& dict
300 )
301 :
302  fvMeshFunctionObject(name, runTime, dict),
303  prevTimeIndex_(-1),
304  restartOnRestart_(false),
305  restartOnOutput_(false),
306  periodicRestart_(false),
307  restartPeriod_(great),
308  initialised_(false),
309  base_(baseType::iter),
310  window_(-1.0),
311  windowName_(""),
312  faItems_(),
313  totalIter_(),
314  totalTime_(),
315  periodIndex_(1)
316 {
317  read(dict);
318 }
319 
320 
321 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
322 
324 {}
325 
326 
327 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
328 
330 {
332 
333  initialised_ = false;
334 
335  Log << type() << " " << name() << ":" << nl;
336 
337  dict.readIfPresent("restartOnRestart", restartOnRestart_);
338  dict.readIfPresent("restartOnOutput", restartOnOutput_);
339  dict.readIfPresent("periodicRestart", periodicRestart_);
340 
341  mean_ = dict.lookupOrDefault<Switch>("mean", true);
342  prime2Mean_ = dict.lookupOrDefault<Switch>("prime2Mean", false);
343  base_ = baseTypeNames_
344  [
345  dict.lookupOrDefault<word>("base", "time")
346  ];
347  window_ = dict.lookupOrDefault<scalar>("window", -1);
348  windowName_ = dict.lookupOrDefault<word>("windowName", "");
349 
350  faItems_ = PtrList<fieldAverageItem>
351  (
352  dict.lookup("fields"),
354  );
355 
356  if (periodicRestart_)
357  {
358  dict.lookup("restartPeriod") >> restartPeriod_;
359  }
360 
361  readAveragingProperties();
362 
363  Log << endl;
364 
365  return true;
366 }
367 
368 
370 {
371  calcAverages();
372 
373  return true;
374 }
375 
376 
378 {
379  writeAverages();
380  writeAveragingProperties();
381 
382  if (restartOnOutput_)
383  {
384  restart();
385  }
386 
387  return true;
388 }
389 
390 
391 // ************************************************************************* //
void writeAveragingProperties() const
Write averaging properties - steps and time.
Definition: fieldAverage.C:206
Class used for the read-construction of.
Calculates the natural logarithm of the specified scalar field.
Definition: log.H:103
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:667
virtual bool read(const dictionary &)
Read the field average data.
Definition: fieldAverage.C:329
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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:59
bool typeHeaderOk(const bool checkType=true)
Read header (uses typeFilePath to find file) and check header.
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
virtual bool write()
Write the field averages.
Definition: fieldAverage.C:377
addToRunTimeSelectionTable(functionObject, Qdot, dictionary)
static const NamedEnum< baseType, 2 > baseTypeNames_
Averaging base type names.
Definition: fieldAverage.H:198
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, y/n, t/f, or none/any.
Definition: Switch.H:60
virtual bool execute()
Calculate the field averages.
Definition: fieldAverage.C:369
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:51
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
IOdictionary propsDict(IOobject("particleTrackProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED))
Macros for easy insertion into run-time selection tables.
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:1056
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:52
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:934
virtual bool read(const dictionary &)
Read optional controls.
bool read(const char *, int32_t &)
Definition: int32IO.C:85
fieldAverage(const word &name, const Time &runTime, const dictionary &)
Construct from Time and dictionary.
Definition: fieldAverage.C:296
void readAveragingProperties()
Read averaging properties - steps and time.
Definition: fieldAverage.C:236
A class for handling words, derived from string.
Definition: word.H:59
virtual void calcAverages()
Main calculation routine.
Definition: fieldAverage.C:142
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
static const char nl
Definition: Ostream.H:260
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
defineTypeNameAndDebug(Qdot, 0)
void initialize()
Reset lists (clear existing values) and initialize averaging.
Definition: fieldAverage.C:81
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:70
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
void resetFields()
Checkout fields (causes deletion) from the database.
Definition: fieldAverage.C:58
void restart()
Restart averaging for restartOnOutput.
Definition: fieldAverage.C:130
#define Log
Report write to Foam::Info if the local log switch is true.
messageStream Info
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
virtual ~fieldAverage()
Destructor.
Definition: fieldAverage.C:323
virtual void writeAverages() const
Write averages.
Definition: fieldAverage.C:192
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
baseType
Enumeration defining the averaging base type.
Definition: fieldAverage.H:168
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:812