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 -------------------------------------------------------------------------------
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 "volFieldValue.H"
30 #include "fvMesh.H"
31 #include "volFields.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 namespace functionObjects
39 {
40 namespace fieldValues
41 {
42  defineTypeNameAndDebug(volFieldValue, 0);
43  addToRunTimeSelectionTable(fieldValue, volFieldValue, runTime);
44  addToRunTimeSelectionTable(functionObject, volFieldValue, dictionary);
45 }
46 }
47 }
48 
49 const 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 
73 const 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 
88 const 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);
196  writeFileHeader(file());
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 {
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 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
operationType operation_
Operation to apply to values.
dictionary dict
static const Enum< operationType > operationTypeNames_
Operation type names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
static const Enum< postOperationType > postOperationTypeNames_
Operation type names.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
void writeFileHeader(const writeFile &wf, Ostream &file) const
Output file header information.
Definition: volRegion.C:127
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
virtual void writeFileHeader(Ostream &os) const
Output file header information.
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
virtual bool read(const dictionary &dict)
Read from dictionary.
Definition: fieldValue.C:82
Surround with &#39;\0&#39; and &#39;\0&#39; separate with &#39;,&#39;.
Definition: FlatOutput.H:80
volFieldValue(const word &name, const Time &runTime, const dictionary &dict)
Construct from name, Time and dictionary.
constexpr char tab
The tab &#39;\t&#39; character(0x09)
Definition: Ostream.H:49
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
Macros for easy insertion into run-time selection tables.
const dictionary & dict() const noexcept
Return the reference to the construction dictionary.
Definition: fieldValueI.H:24
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, runTime)
virtual bool read(const dictionary &dict)
Read from dictionary.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
Volume (cell) region selection class.
Definition: volRegion.H:111
OBJstream os(runTime.globalPath()/outputName)
postOperationType
Post-operation type enumeration.
label writeAll(const scalarField &V, const scalarField &weightField)
Helper function to output field values.
#define WarningInFunction
Report a warning using Foam::Warning.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: error.H:64
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
bool update()
Update the cached values as required.
Definition: volRegion.C:243
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
#define Log
Definition: PDRblock.C:28
messageStream Info
Information stream (stdout output on master, null elsewhere)
defineTypeNameAndDebug(surfaceFieldValue, 0)
Intermediate class for handling field value-based function objects.
Definition: fieldValue.H:115
Registry of regIOobjects.
virtual bool write()
Calculate and write.
const fvMesh & mesh_
Reference to the fvMesh.
bool usesVol() const noexcept
True if the operation needs the cell-volume.
Definition: volFieldValue.C:80
Namespace for OpenFOAM.
virtual bool write()
Write.
Definition: fieldValue.C:108
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...