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-------------------------------------------------------------------------------
10License
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
31template<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 {
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 }
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 }
161
162 return true;
163}
164
165
166template<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// ************************************************************************* //
label n
const_iterator cbegin() const
Iterator to first item in list with const access.
Definition: LList.H:509
reference first()
The first entry in the list.
Definition: LList.H:208
scalar deltaTValue() const noexcept
Return time step value.
Definition: TimeStateI.H:43
Watches for presence of the named trigger file in the case directory and signals a simulation stop (o...
Definition: abort.H:128
bool calculatePrime2MeanField(const objectRegistry &obr) const
Calculate prime-squared average fields.
const word & fieldName() const
Return const access to the field name.
scalar dt(const scalar deltaT) const
Return the current time interval.
scalar Dt() const
Return the total time interval.
bool calculateMeanField(const objectRegistry &obr) const
Calculate the mean field value.
Registry of regIOobjects.
const Time & time() const noexcept
Return time registry.
Type & lookupObjectRef(const word &name, const bool recursive=false) const
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
const Type & lookupObject(const word &name, const bool recursive=false) const
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
dimensionedSymmTensor sqr(const dimensionedVector &dv)
error FatalError
dimensionedScalar beta("beta", dimless/dimTemperature, laminarTransport)