volFieldValue.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) 2017-2021 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 "volFieldValue.H"
30#include "fvMesh.H"
31#include "volFields.H"
33
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
36namespace Foam
37{
38namespace functionObjects
39{
40namespace fieldValues
41{
45}
46}
47}
48
49const Foam::Enum
50<
52>
54({
55 // Normal operations
56 { operationType::opNone, "none" },
57 { operationType::opMin, "min" },
58 { operationType::opMax, "max" },
59 { operationType::opSum, "sum" },
60 { operationType::opSumMag, "sumMag" },
61 { operationType::opAverage, "average" },
62 { operationType::opVolAverage, "volAverage" },
63 { operationType::opVolIntegrate, "volIntegrate" },
64 { operationType::opCoV, "CoV" },
65
66 // Using weighting
67 { operationType::opWeightedSum, "weightedSum" },
68 { operationType::opWeightedAverage, "weightedAverage" },
69 { operationType::opWeightedVolAverage, "weightedVolAverage" },
70 { operationType::opWeightedVolIntegrate, "weightedVolIntegrate" },
71});
72
73const Foam::Enum
74<
76>
78({
79 { postOperationType::postOpNone, "none" },
80 { postOperationType::postOpMag, "mag" },
81 { postOperationType::postOpSqrt, "sqrt" },
82});
83
84
85// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
86
88const noexcept
89{
90 // Few operations require the cell volume
91 switch (operation_)
92 {
93 case opVolAverage:
94 case opVolIntegrate:
97 case opCoV:
98 return true;
99
100 default:
101 return false;
102 }
103}
104
105
107(
108 Ostream& os
109) const
110{
112
113 if (weightFieldNames_.size())
114 {
115 writeHeaderValue
116 (
117 os,
118 "Weight field",
119 flatOutput(weightFieldNames_, FlatOutput::BareComma{})
120 );
121 }
122
123 writeCommented(os, "Time");
124
125 // TBD: add in postOperation information?
126
127 for (const word& fieldName : fields_)
128 {
129 os << tab << operationTypeNames_[operation_]
130 << "(" << fieldName << ")";
131 }
132
133 os << endl;
134}
135
136
138(
139 const scalarField& V,
140 const scalarField& weightField
141)
142{
143 label nProcessed = 0;
144
145 for (const word& fieldName : fields_)
146 {
147 if
148 (
149 writeValues<scalar>(fieldName, V, weightField)
150 || writeValues<vector>(fieldName, V, weightField)
151 || writeValues<sphericalTensor>(fieldName, V, weightField)
152 || writeValues<symmTensor>(fieldName, V, weightField)
153 || writeValues<tensor>(fieldName, V, weightField)
154 )
155 {
156 ++nProcessed;
157 }
158 else
159 {
161 << "Requested field " << fieldName
162 << " not found in database and not processed"
163 << endl;
164 }
165 }
166
167 return nProcessed;
168}
169
170
171// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
172
174(
175 const word& name,
176 const Time& runTime,
177 const dictionary& dict
178)
179:
180 fieldValue(name, runTime, dict, typeName),
181 volRegion(fieldValue::mesh_, dict),
182 operation_(operationTypeNames_.get("operation", dict)),
183 postOperation_
184 (
185 postOperationTypeNames_.getOrDefault
186 (
187 "postOperation",
188 dict,
189 postOperationType::postOpNone,
190 true // Failsafe behaviour
191 )
192 ),
193 weightFieldNames_()
194{
195 read(dict);
197}
198
199
201(
202 const word& name,
203 const objectRegistry& obr,
204 const dictionary& dict
205)
206:
207 fieldValue(name, obr, dict, typeName),
208 volRegion(fieldValue::mesh_, dict),
209 operation_(operationTypeNames_.get("operation", dict)),
210 postOperation_
211 (
212 postOperationTypeNames_.getOrDefault
213 (
214 "postOperation",
215 dict,
216 postOperationType::postOpNone,
217 true // Failsafe behaviour
218 )
219 ),
220 weightFieldNames_()
221{
222 read(dict);
223}
224
225
226// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
227
229(
230 const dictionary& dict
231)
232{
234
235 weightFieldNames_.clear();
236
237 if (is_weightedOp())
238 {
239 // Can have "weightFields" or "weightField"
240
241 bool missing = true;
242 if (dict.readIfPresent("weightFields", weightFieldNames_))
243 {
244 missing = false;
245 }
246 else
247 {
248 weightFieldNames_.resize(1);
249
250 if (dict.readIfPresent("weightField", weightFieldNames_.first()))
251 {
252 missing = false;
253 if ("none" == weightFieldNames_.first())
254 {
255 // "none" == no weighting
256 weightFieldNames_.clear();
257 }
258 }
259 }
260
261 if (missing)
262 {
263 // Suggest possible alternative unweighted operation?
265 << "The '" << operationTypeNames_[operation_]
266 << "' operation is missing a weightField." << nl
267 << "Either provide the weightField, "
268 << "use weightField 'none' to suppress weighting," << nl
269 << "or use a different operation."
270 << exit(FatalIOError);
271 }
272
273 Info<< " weight field = ";
274 if (weightFieldNames_.empty())
275 {
276 Info<< "none" << nl;
277 }
278 else
279 {
280 Info<< flatOutput(weightFieldNames_) << nl;
281 }
282
283 Info<< nl << endl;
284 }
285
286 return true;
287}
288
289
291{
292 volRegion::update(); // Ensure cached values are valid
293
295
296 if (Pstream::master())
297 {
298 writeCurrentTime(file());
299 }
300
301 // Only some operations need the cell volume
302 scalarField V;
303 if (usesVol())
304 {
305 V = filterField(fieldValue::mesh_.V());
306 }
307
308 // Check availability and type of weight field
309 // Only support a few weight types:
310 // scalar: 0-N fields
311
312 // Default is a zero-size scalar weight field (ie, weight = 1)
313 scalarField scalarWeights;
314
315 for (const word& weightName : weightFieldNames_)
316 {
317 if (validField<scalar>(weightName))
318 {
319 tmp<scalarField> tfld = getFieldValues<scalar>(weightName, true);
320
321 if (scalarWeights.empty())
322 {
323 scalarWeights = tfld;
324 }
325 else
326 {
327 scalarWeights *= tfld;
328 }
329 }
330 else if (weightName != "none")
331 {
332 // Silently ignore "none", flag everything else as an error
333
334 // TBD: treat missing "rho" like incompressible with rho = 1
335 // and/or provided rhoRef value
336
338 << "weightField " << weightName
339 << " not found or an unsupported type" << nl
340 << abort(FatalError);
341 }
342 }
343
344
345 // Process the fields
346 writeAll(V, scalarWeights);
347
348 if (Pstream::master())
349 {
350 file()<< endl;
351 }
352
353 Log << endl;
354
355 return true;
356}
357
358
359// ************************************************************************* //
#define Log
Definition: PDRblock.C:35
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
virtual bool read()
Re-read model coefficients if they have changed.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
const fvMesh & mesh_
Reference to the mesh database.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Abstract base-class for Time/database function objects.
Watches for presence of the named trigger file in the case directory and signals a simulation stop (o...
Definition: abort.H:128
Intermediate class for handling field value-based function objects.
Definition: fieldValue.H:123
const dictionary & dict() const noexcept
Return the reference to the construction dictionary.
Definition: fieldValueI.H:31
virtual bool write()
Write.
Definition: fieldValue.C:115
Provides a 'volRegion' specialization of the fieldValue function object.
bool usesVol() const noexcept
True if the operation needs the cell-volume.
Definition: volFieldValue.C:87
postOperationType
Post-operation type enumeration.
virtual bool read(const dictionary &dict)
Read from dictionary.
operationType operation_
Operation to apply to values.
label writeAll(const scalarField &V, const scalarField &weightField)
Helper function to output field values.
static const Enum< operationType > operationTypeNames_
Operation type names.
virtual void writeFileHeader(Ostream &os) const
Output file header information.
static const Enum< postOperationType > postOperationTypeNames_
Operation type names.
virtual bool write()
Calculate and write.
Volume (cell) region selection class.
Definition: volRegion.H:116
bool update()
Update the cached values as required.
Definition: volRegion.C:250
void writeFileHeader(const writeFile &wf, Ostream &file) const
Output file header information.
Definition: volRegion.C:134
virtual OFstream & file()
Return access to the file (if only 1)
Definition: writeFile.C:233
Registry of regIOobjects.
splitCell * master() const
Definition: splitCell.H:113
A class for managing temporary objects.
Definition: tmp.H:65
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
engineTime & runTime
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
IOerror FatalIOError
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
constexpr char tab
The tab '\t' character(0x09)
Definition: Ostream.H:52
dictionary dict
Surround with '\0' and '\0' separate with ','.
Definition: FlatOutput.H:84