fieldAverageItemTemplates.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) 2017-2019 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "objectRegistry.H"
29 #include "Time.H"
30 
31 template<class Type>
33 (
34  const objectRegistry& obr
35 ) const
36 {
37  if (!mean_)
38  {
39  return false;
40  }
41 
42  const Type* baseFieldPtr = obr.findObject<Type>(fieldName_);
43 
44  if (!baseFieldPtr)
45  {
46  return false;
47  }
48 
49  const Type& baseField = *baseFieldPtr;
50  Type& meanField = obr.lookupObjectRef<Type>(meanFieldName_);
51 
52  switch (windowType_)
53  {
54  case windowType::NONE:
55  {
56  scalar dt = this->dt(obr.time().deltaTValue());
57  scalar Dt = this->Dt();
58  scalar beta = dt/Dt;
59 
60  meanField = (1 - beta)*meanField + beta*baseField;
61 
62  break;
63  }
65  {
66  scalar dt = this->dt(obr.time().deltaTValue());
67  scalar Dt = this->Dt();
68  scalar beta = dt/Dt;
69 
70  if (Dt - dt >= window_)
71  {
72  beta = dt/window_;
73  }
74 
75  meanField = (1 - beta)*meanField + beta*baseField;
76 
77  break;
78  }
79  case windowType::EXACT:
80  {
81  switch (base_)
82  {
83  case baseType::ITER:
84  {
85  // Uniform time step - can use simplified algorithm
86  // Note: stores an additional old time field, but only
87  // needs to do 1 field lookup
88 
89  label n = windowTimes_.size();
90  const Type& lastField =
91  obr.lookupObject<Type>(windowFieldNames_.first());
92 
93  if (n <= round(window_))
94  {
95  scalar beta = 1.0/scalar(n);
96  meanField = (1 - beta)*meanField + beta*baseField;
97  }
98  else
99  {
100  meanField += (baseField - lastField)/scalar(n - 1);
101  }
102 
103  break;
104  }
105  case baseType::TIME:
106  {
107  // Assuming non-uniform time step
108  // Note: looks up all window fields from the registry
109 
110  meanField = 0*baseField;
111 
112  auto timeIter = windowTimes_.cbegin();
113  auto nameIter = windowFieldNames_.cbegin();
114 
115  const Type* wOld = nullptr;
116 
117  for
118  (
119  ;
120  timeIter.good();
121  ++timeIter, ++nameIter
122  )
123  {
124  const word& fieldName = nameIter();
125  const scalar dt = timeIter();
126  const Type* w = obr.findObject<Type>(fieldName);
127 
128  meanField += dt*(*w);
129 
130  if (wOld)
131  {
132  meanField -= dt*(*wOld);
133  }
134 
135  wOld = w;
136  }
137 
138  meanField /= windowTimes_.first();
139 
140  break;
141  }
142  default:
143  {
145  << "Unhandled baseType enumeration "
146  << baseTypeNames_[base_]
147  << abort(FatalError);
148  }
149  }
150 
151  break;
152  }
153  default:
154  {
156  << "Unhandled windowType enumeration "
157  << windowTypeNames_[windowType_]
158  << abort(FatalError);
159  }
160  }
162  return true;
163 }
164 
165 
166 template<class Type1, class Type2>
168 (
169  const objectRegistry& obr
170 ) const
171 {
172  if (!prime2Mean_)
173  {
174  return false;
175  }
176 
177  const Type1* baseFieldPtr = obr.findObject<Type1>(fieldName_);
178 
179  if (!baseFieldPtr)
180  {
181  return false;
182  }
183 
184  const Type1& baseField = *baseFieldPtr;
185  const Type1& meanField = obr.lookupObject<Type1>(meanFieldName_);
186 
187  Type2& prime2MeanField =
188  obr.lookupObjectRef<Type2>(prime2MeanFieldName_);
189 
190  switch (windowType_)
191  {
192  case windowType::NONE:
193  {
194  scalar dt = this->dt(obr.time().deltaTValue());
195  scalar Dt = this->Dt();
196  scalar beta = dt/Dt;
197 
198  prime2MeanField =
199  (1 - beta)*prime2MeanField
200  + beta*sqr(baseField)
201  - sqr(meanField);
202 
203  break;
204  }
205  case windowType::APPROXIMATE:
206  {
207  scalar dt = this->dt(obr.time().deltaTValue());
208  scalar Dt = this->Dt();
209  scalar beta = dt/Dt;
210 
211  if (Dt - dt >= window_)
212  {
213  beta = dt/window_;
214  }
215 
216  prime2MeanField =
217  (1 - beta)*prime2MeanField
218  + beta*sqr(baseField)
219  - sqr(meanField);
220 
221  break;
222  }
223  case windowType::EXACT:
224  {
225  // Not storing old time mean fields - treat all as TIME (integrated)
226  prime2MeanField = 0*prime2MeanField;
227 
228  auto timeIter = windowTimes_.cbegin();
229  auto nameIter = windowFieldNames_.cbegin();
230 
231  switch (base_)
232  {
233  case baseType::ITER:
234  {
235  // ITER method stores an additional entry compared to TIME
236  ++timeIter;
237  ++nameIter;
238 
239  if (!timeIter.good()) return false;
240 
241  break;
242  }
243  default:
244  {}
245  }
246 
247 
248  scalar windowLength = timeIter();
249 
250  const Type1* wOld = nullptr;
251 
252  for
253  (
254  ;
255  timeIter.good();
256  ++timeIter, ++nameIter
257  )
258  {
259  const word& fieldName = nameIter();
260  const scalar dt = timeIter();
261  const Type1* w = obr.findObject<Type1>(fieldName);
262 
263  prime2MeanField += dt*(sqr((*w) - meanField));
264 
265  if (wOld)
266  {
267  prime2MeanField -= dt*(sqr((*wOld) - meanField));
268  }
269 
270  wOld = w;
271  }
272 
273  prime2MeanField /= windowLength;
274 
275  break;
276  }
277  default:
278  {
280  << "Unhandled windowType enumeration "
281  << windowTypeNames_[windowType_]
282  << abort(FatalError);
283  }
284  }
285 
286  return true;
287 }
288 
289 
290 // ************************************************************************* //
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
scalar deltaTValue() const noexcept
Return time step value.
Definition: TimeStateI.H:49
Type & lookupObjectRef(const word &name, const bool recursive=false) const
Lookup and return non-const reference to the object of the given Type. Fatal if not found or the wron...
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
scalar dt(const scalar deltaT) const
Return the current time interval.
scalar Dt() const
Return the total time interval.
const word & fieldName() const
Return const access to the field name.
A class for handling words, derived from Foam::string.
Definition: word.H:63
const Time & time() const noexcept
Return time registry.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
reference first()
The first entry in the list.
Definition: LList.H:702
const_iterator cbegin() const
Iterator to first item in list with const access.
Definition: LList.H:608
dimensionedScalar beta("beta", dimless/dimTemperature, laminarTransport)
label n
Registry of regIOobjects.
bool calculatePrime2MeanField(const objectRegistry &obr) const
Calculate prime-squared average fields.
bool calculateMeanField(const objectRegistry &obr) const
Calculate the mean field value.