multiFieldValue.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) 2012-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2022 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 "multiFieldValue.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 namespace functionObjects
37 {
38 namespace fieldValues
39 {
40  defineTypeNameAndDebug(multiFieldValue, 0);
41  addToRunTimeSelectionTable(functionObject, multiFieldValue, dictionary);
42 }
43 }
44 }
45 
46 
47 const Foam::Enum
48 <
50 >
52 ({
53  { operationType::opSum, "sum" },
54  { operationType::opAdd, "add" },
55  { operationType::opSubtract, "subtract" },
56  { operationType::opDivide, "divide" },
57  { operationType::opCmptDivide, "cmptDivide" },
58  { operationType::opMin, "min" },
59  { operationType::opMax, "max" },
60  { operationType::opAverage, "average" },
61 });
62 
63 
64 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
65 
66 // Implementation
67 #include "multiFieldValueImpl.C"
68 
69 
70 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
71 
73 (
74  const wordList& foNames,
75  const List<wordList>& entries,
76  const List<wordList>& types,
77  Ostream& os
78 ) const
79 {
80  const word groupPrefix("Group");
81 
82  forAll(entries, i)
83  {
84  writeCommented(os, groupPrefix + Foam::name(i));
85  os << nl;
86 
87  forAll(entries[i], functioni)
88  {
90  (
91  os,
92  " - " + foNames[functioni] + ":" + entries[i][functioni]
93  );
94  os << nl;
95  }
96  }
97 
98  writeHeaderValue(os, "Operation", operationTypeNames_[operation_]);
99  writeCommented(os, "Time");
100 
101  forAll(entries, entryi)
102  {
103  writeTabbed(os, groupPrefix + Foam::name(entryi));
104  }
105 
106  os << endl;
107 }
108 
109 
110 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
111 
113 (
114  const word& name,
115  const Time& runTime,
116  const dictionary& dict
117 )
118 :
120  writeFile(runTime, name, typeName, dict),
121  operation_(opSubtract),
122  functions_()
123 {
125 }
126 
127 
128 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
129 
131 (
132  const dictionary& dict
133 )
134 {
136  {
137  return false;
138  }
139 
140  operation_ = operationTypeNames_.get("operation", dict);
141 
142  const dictionary& functionsDict = dict.subDict("functions");
143  functions_.resize(functionsDict.size());
144 
145  if (functions_.empty())
146  {
148  << "No functions specified"
149  << endl;
150  return false;
151  }
152 
153  resultFields_.resize(functions_.size());
154 
155  label functioni = 0;
156  for (const entry& dEntry : functionsDict)
157  {
158  if (!dEntry.isDict())
159  {
161  << "Functions must be specified in dictionary format"
162  << exit(FatalIOError);
163  }
164 
165  const dictionary& localDict = dEntry.dict();
166 
167  functions_.set
168  (
169  functioni,
171  (
172  IOobject::scopedName(name(), localDict.dictName()),
173  time(),
174  localDict
175  ).ptr()
176  );
177 
178  // Deactivate logging for child function objects
179  //functions_[functioni].log = false;
180 
181  // Get result field names; not specified implies all
182  resultFields_[functioni] =
183  localDict.getOrDefault<wordList>("resultFields", wordList());
184 
185  Info<< type() << ' ' << name() << ':' << nl;
186  if (resultFields_[functioni].size())
187  {
188  Info<< " " << functions_[functioni].name()
189  << " " << resultFields_[functioni];
190  }
191  else
192  {
193  Info<< " " << functions_[functioni].name()
194  << " - using all available entries";
195  }
196  Info<< nl << endl;
197 
198  ++functioni;
199  }
200 
201  return true;
202 }
203 
204 
206 {
207  if (functions_.empty())
208  {
209  return false;
210  }
211 
212  Log << type() << " " << name() << " write:" << endl;
213 
214  const label nFunction = functions_.size();
215  wordList entries0;
216  label nEntries = -1;
217 
218  wordList foNames(nFunction);
219  List<wordList> entries;
220  List<wordList> types;
221 
222  forAll(functions_, functioni)
223  {
224  auto& f = functions_[functioni];
225  foNames[functioni] = f.name();
226 
227  // Note: replicating functionObjectList execute() and write()
228  // - results may be written on either
229  f.execute();
230  f.write();
231 
232  wordList e = resultFields_[functioni];
233  if (e.empty())
234  {
235  e = objectResultEntries(f.name());
236  }
237 
238  if (functioni == 0)
239  {
240  entries0 = e;
241  nEntries = e.size();
242  entries.resize(nEntries);
243  types.resize(nEntries);
244 
245  forAll(entries, entryi)
246  {
247  entries[entryi].resize(nFunction);
248  types[entryi].resize(nFunction);
249  }
250  }
251 
252  if (e.size() != nEntries)
253  {
254  const word& f0Name = functions_[0].name();
255 
257  << "Inconsistent number of result entries" << nl
258  << " " << f0Name << " entries:" << entries0 << nl
259  << " " << f.name() << " entries:" << e
260  << exit(FatalError);
261  }
262 
263  forAll(e, entryi)
264  {
265  entries[entryi][functioni] = e[entryi];
266  types[entryi][functioni] = objectResultType(f.name(), e[entryi]);
267 
268  if (types[entryi][functioni] == word::null)
269  {
271  << "Unable to find function object result" << nl
272  << " function object : " << f.name() << nl
273  << " result name : " << e[entryi] << nl
274  << " available results : "
275  << objectResultEntries(f.name())
276  << exit(FatalError);
277  }
278  }
279  }
280 
281  if (!writtenHeader_)
282  {
283  writeFileHeader(foNames, entries, types, file());
284  writtenHeader_ = true;
285  }
286 
287  writeCurrentTime(file());
288 
289  forAll(entries, i)
290  {
291  const wordList& entryi = entries[i];
292  const word& expectedType = types[i][0];
293  const wordList& foTypes = types[i];
294 
295  forAll(foTypes, functioni)
296  {
297  const word& foType = foTypes[functioni];
298 
299  if (foType != expectedType)
300  {
302  << "Inconsistent function result types" << nl
303  << " " << functions_[0].name()
304  << " result type:" << expectedType << nl
305  << " " << functions_[functioni].name()
306  << " result type:" << foType
307  << exit(FatalError);
308  }
309  }
310 
311  const bool ok
312  (
313  applyOperation<scalar>(expectedType, foNames, entryi)
314  || applyOperation<vector>(expectedType, foNames, entryi)
315  || applyOperation<sphericalTensor>(expectedType, foNames, entryi)
316  || applyOperation<symmTensor>(expectedType, foNames, entryi)
317  || applyOperation<tensor>(expectedType, foNames, entryi)
318  );
319 
320  if (!ok)
321  {
322  Log << "Operation not applied between functions:" << nl
323  << flatOutput(foNames, FlatOutput::BareComma{}) << nl
324  << "with result names:" << nl
325  << flatOutput(entryi, FlatOutput::BareComma{})
326  << endl;
327  }
328  }
329 
330  Log << (nEntries == 0 ? " none" : "") << endl;
332  file()<< endl;
333 
334  return true;
335 }
336 
337 
339 {
340  return true;
341 }
342 
343 
344 // ************************************************************************* //
dictionary dict
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
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
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
virtual bool read(const dictionary &dict)
Read from dictionary.
Macros for easy insertion into run-time selection tables.
virtual bool write()
Calculate and write.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
virtual void writeCommented(Ostream &os, const string &str) const
Write a commented string to stream.
Definition: writeFile.C:313
static word scopedName(const std::string &scope, const word &name)
Create scope:name or scope_name string.
Definition: IOobjectI.H:40
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
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
addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, runTime)
static const word null
An empty word.
Definition: word.H:84
static const Enum< operationType > operationTypeNames_
Operation type names.
void writeHeaderValue(Ostream &os, const string &property, const Type &value) const
Write a (commented) header property and value pair.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
virtual bool read(const dictionary &dict)
Read.
Definition: writeFile.C:241
labelList f(nPoints)
List< word > wordList
List of word.
Definition: fileName.H:59
#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
virtual void writeFileHeader(const wordList &foNames, const List< wordList > &entries, const List< wordList > &types, Ostream &os) const
Output file header information.
multiFieldValue(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
#define Log
Definition: PDRblock.C:28
Base class for function objects, adding functionality to read/write state information (data required ...
messageStream Info
Information stream (stdout output on master, null elsewhere)
defineTypeNameAndDebug(surfaceFieldValue, 0)
static autoPtr< functionObject > New(const word &name, const Time &runTime, const dictionary &dict)
Select from dictionary, based on its "type" entry.
Base class for writing single files from the function objects.
Definition: writeFile.H:112
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
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 ...
virtual void writeTabbed(Ostream &os, const string &str) const
Write a tabbed string to stream.
Definition: writeFile.C:329