cloudInfo.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 "cloudInfo.H"
30 #include "cloud.H"
31 #include "kinematicCloud.H"
32 #include "dictionary.H"
33 #include "mathematicalConstants.H"
34 #include "PstreamReduceOps.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 namespace functionObjects
42 {
43  defineTypeNameAndDebug(cloudInfo, 0);
44 
46  (
47  functionObject,
48  cloudInfo,
49  dictionary
50  );
51 }
52 }
53 
54 
55 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
56 
58 {
59  writeHeader(os, "Cloud information");
60  writeCommented(os, "Time");
61  writeTabbed(os, "nParcels");
62  writeTabbed(os, "mass");
63  writeTabbed(os, "Dmax");
64  writeTabbed(os, "D10");
65  writeTabbed(os, "D32");
66  os << endl;
67 }
68 
69 
70 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
71 
73 (
74  const word& name,
75  const Time& runTime,
76  const dictionary& dict
77 )
78 :
79  functionObjects::regionFunctionObject(name, runTime, dict),
80  functionObjects::logFiles(obr_, name, dict),
81  verbose_(false),
82  onExecute_(false)
83 {
84  read(dict);
85 }
86 
87 
88 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
89 
91 {
92  parcelSelect_.clear();
93  verbose_ = false;
94  onExecute_ = false;
95 
97  {
98  logFiles::resetNames(dict.get<wordList>("clouds"));
99 
100  Info<< type() << " " << name() << ": ";
101  if (names().size())
102  {
103  Info<< "applying to clouds:" << nl;
104  for (const word& cldName : names())
105  {
106  Info<< " " << cldName << nl;
107  }
108  Info<< endl;
109 
110  // Actions to define selection
111  parcelSelect_ = dict.subOrEmptyDict("selection");
112 
113  verbose_ = dict.getOrDefault("verbose", false);
114  onExecute_ = dict.getOrDefault("sampleOnExecute", false);
115  }
116  else
117  {
118  Info<< "no clouds to be processed" << nl << endl;
119  }
120 
121  if (writeToFile())
122  {
123  forAll(names(), cloudi)
124  {
125  writeFileHeader(files(cloudi));
126  }
127  }
128  }
129 
130  return true;
131 }
132 
133 
135 {
136  if (!request || names().empty())
137  {
138  return true;
139  }
140 
141  forAll(names(), cloudi)
142  {
143  // The reported quantities
144  label nTotParcels = 0;
145  scalar totMass = 0, Dmax = 0, D10 = 0, D32 = 0;
146  bool applyFilter = false;
147 
148  const word& cloudName = names()[cloudi];
149 
150  const auto* kinCloudPtr = obr_.cfindObject<kinematicCloud>(cloudName);
151 
152  if (!kinCloudPtr)
153  {
154  // Safety
155  continue;
156  }
157 
158  const auto& kinCloud = *kinCloudPtr;
159  const auto* plainCloudPtr = isA<cloud>(kinCloud);
160 
161  if (!parcelSelect_.empty() && plainCloudPtr)
162  {
163  const auto& plainCloud = *plainCloudPtr;
164 
165  // Filtering - simply use cloud methods
166 
167  objectRegistry obrTmp
168  (
169  IOobject
170  (
171  "tmp::cloudInfo::" + cloudName,
172  obr_.time().constant(),
173  obr_,
177  )
178  );
179 
180  plainCloud.writeObjects(obrTmp);
181 
182  // Apply output filter (for the current cloud)
183  applyFilter = calculateFilter(obrTmp, log);
184 
185  // Expected/required fields
186  const auto* diamFldPtr = obrTmp.cfindObject<IOField<scalar>>("d");
187  const auto* rhoFldPtr = obrTmp.cfindObject<IOField<scalar>>("rho");
188  const auto* nParticleFldPtr =
189  obrTmp.cfindObject<IOField<scalar>>("nParticle");
190 
191  do
192  {
193  #undef doLocalCode
194  #define doLocalCode(FldPtr, FldName) \
195  if (applyFilter && !FldPtr) \
196  { \
197  WarningInFunction \
198  << "Missing \"" << #FldName \
199  << "\" field - disabling filter" << nl; \
200  applyFilter = false; \
201  break; \
202  }
203 
204  doLocalCode(diamFldPtr, d);
205  doLocalCode(rhoFldPtr, rho);
206  doLocalCode(nParticleFldPtr, nParticle);
207  #undef doLocalCode
208  }
209  while (false);
210 
211  if (applyFilter)
212  {
213  // Filtered. Need to do everything by hand!
214 
215  const auto& diams = *diamFldPtr;
216  const auto& rhos = *rhoFldPtr;
217  const auto& nParts = *nParticleFldPtr;
218 
219  FixedList<scalar, 4> Dsums(Zero);
220 
221  for (const label particlei : parcelAddr_)
222  {
223  ++nTotParcels;
224 
225  const scalar d = diams[particlei];
226  const scalar rho = rhos[particlei];
227  const scalar np = nParts[particlei];
228 
229  totMass += np*rho*pow3(d);
230  Dmax = max(Dmax, d);
231 
232  Dsums[0] += np;
233  Dsums[1] += np*(d);
234  Dsums[2] += np*(sqr(d));
235  Dsums[3] += np*(pow3(d));
236  }
237 
238  reduce(nTotParcels, sumOp<label>());
239  reduce(totMass, sumOp<scalar>());
240  reduce(Dmax, maxOp<scalar>());
241  reduce(Dsums, sumOp<scalar>());
242 
243  totMass *= (constant::mathematical::pi/6.0);
244 
245  Dmax = max(0, Dmax);
246  D10 = Dsums[1]/(max(Dsums[0], VSMALL));
247  D32 = Dsums[3]/(max(Dsums[2], VSMALL));
248  }
249  }
250 
251  if (!applyFilter)
252  {
253  // No filter - use regular cloud methods
254  nTotParcels = returnReduce(kinCloud.nParcels(), sumOp<label>());
255  totMass = returnReduce(kinCloud.massInSystem(), sumOp<scalar>());
256 
257  Dmax = kinCloud.Dmax();
258  D10 = kinCloud.Dij(1, 0);
259  D32 = kinCloud.Dij(3, 2);
260  }
261 
262  Log << type() << " " << name() << " write:" << nl
263  << " number of parcels : " << nTotParcels << nl
264  << " mass in system : " << totMass << nl
265  << " maximum diameter : " << Dmax << nl
266  << " D10 diameter : " << D10 << nl
267  << " D32 diameter : " << D32 << nl
268  << endl;
269 
270  if ((request & ACTION_WRITE) && writeToFile())
271  {
272  auto& os = files(cloudi);
273 
274  writeCurrentTime(os);
275  os
276  << token::TAB << nTotParcels
277  << token::TAB << totMass
278  << token::TAB << Dmax
279  << token::TAB << D10
280  << token::TAB << D32
281  << endl;
282  }
283  }
284 
285  return true;
286 }
287 
288 
290 {
291  if (onExecute_)
292  {
293  return performAction(ACTION_ALL & ~ACTION_WRITE);
294  }
295 
296  return true;
297 }
298 
299 
301 {
302  return performAction(ACTION_ALL);
303 }
304 
305 
306 // ************************************************************************* //
Specialization of Foam::functionObject for a region and providing a reference to the region Foam::obj...
virtual bool execute()
Execute, currently does nothing.
Definition: cloudInfo.C:282
dictionary dict
defineTypeNameAndDebug(ObukhovLength, 0)
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
Inter-processor communication reduction functions.
dimensionedScalar log(const dimensionedScalar &ds)
virtual void writeHeader(Ostream &os, const string &str) const
Write a commented header to stream.
Definition: writeFile.C:339
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
Tab [isspace].
Definition: token.H:129
#define doLocalCode(FldPtr, FldName)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
dimensionedSymmTensor sqr(const dimensionedVector &dv)
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
Ignore writing from objectRegistry::writeObject()
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
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.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
virtual void writeFileHeader(Ostream &os) const
File header information.
Definition: cloudInfo.C:50
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
cloudInfo(const cloudInfo &)=delete
No copy construct.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
const word cloudName(propsDict.get< word >("cloud"))
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual bool read(const dictionary &dict)
Read the controls.
Definition: cloudInfo.C:83
constexpr scalar pi(M_PI)
virtual bool write()
Write.
Definition: cloudInfo.C:293
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
virtual bool read(const dictionary &dict)
Read.
Definition: writeFile.C:241
bool performAction(unsigned request)
Perform operation report/write.
Definition: cloudInfo.C:127
dimensionedScalar pow3(const dimensionedScalar &ds)
Nothing to be read.
#define Log
Definition: PDRblock.C:28
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool read(const dictionary &dict)
Read optional controls.
virtual void resetNames(const wordList &names)
Reset the list of names from a wordList.
Definition: logFiles.C:48
Do not request registration (bool: false)
Namespace for OpenFOAM.
functionObject base class for creating, maintaining and writing log files e.g. integrated or averaged...
Definition: logFiles.H:55
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127
virtual void writeTabbed(Ostream &os, const string &str) const
Write a tabbed string to stream.
Definition: writeFile.C:329