sizeDistribution.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 OpenFOAM Foundation
9  Copyright (C) 2019-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 "sizeDistribution.H"
30 #include "sizeGroup.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 namespace functionObjects
38 {
39  defineTypeNameAndDebug(sizeDistribution, 0);
40  addToRunTimeSelectionTable(functionObject, sizeDistribution, dictionary);
41 }
42 }
43 
44 
45 const Foam::Enum
46 <
48 >
50 ({
51  {selectionModeTypes::rtCellZone, "cellZone"},
52  {selectionModeTypes::rtAll, "all"},
53 });
54 
55 
56 const Foam::Enum
57 <
59 >
61 ({
62  {functionTypes::ftNdf, "numberDensity"},
63  {functionTypes::ftVdf, "volumeDensity"},
64  {functionTypes::ftNc, "numberConcentration"},
65  {functionTypes::ftMom, "moments"},
66 });
67 
68 
69 const Foam::Enum
70 <
72 >
74 ({
75 
76  {abszissaTypes::atDiameter, "diameter"},
77  {abszissaTypes::atVolume, "volume"},
78 });
79 
80 
81 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
82 
84 (
85  const dictionary& dict
86 )
87 {
88  switch (functionType_)
89  {
90  case ftNdf:
91  {
92  break;
93  }
94 
95  case ftVdf:
96  {
97  break;
98  }
99 
100  case ftNc:
101  {
102  break;
103  }
104 
105  case ftMom:
106  {
107  break;
108  }
109 
110  default:
111  {
113  (
114  dict,
115  "functionType",
116  word::null,
118  ) << exit(FatalIOError);
119  }
120  }
121 
122  switch (abszissaType_)
123  {
124  case atDiameter:
125  {
126  break;
127  }
128 
129  case atVolume:
130  {
131  break;
132  }
133 
134  default:
135  {
137  (
138  dict,
139  "abszissaType",
140  word::null,
142  ) << exit(FatalIOError);
143  }
144  }
145 
147 
148  if (nCells_ == 0)
149  {
151  << type() << " " << name() << ": "
153  << '(' << selectionModeTypeName_ << "):" << nl
154  << " Selection has no cells" << exit(FatalIOError);
155  }
156 
157  volume_ = volume();
158 
159  Info<< type() << " " << name() << ":"
161  << '(' << selectionModeTypeName_ << "):" << nl
162  << " total cells = " << nCells_ << nl
163  << " total volume = " << volume_
164  << nl << endl;
165 }
166 
167 
169 {
170  switch (selectionModeType_)
171  {
172  case rtCellZone:
173  {
174  dict().readEntry("cellZone", selectionModeTypeName_);
175 
176  label zoneId =
177  mesh().cellZones().findZoneID(selectionModeTypeName_);
178 
179  if (zoneId < 0)
180  {
182  << "Unknown cellZone name: " << selectionModeTypeName_
183  << ". Valid cellZone names are: "
184  << mesh().cellZones().names()
185  << nl << exit(FatalIOError);
186  }
187 
188  cellId_ = mesh().cellZones()[zoneId];
189  nCells_ = returnReduce(cellId_.size(), sumOp<label>());
190  break;
191  }
192 
193  case rtAll:
194  {
195  cellId_ = identity(mesh().nCells());
196  nCells_ = returnReduce(cellId_.size(), sumOp<label>());
197  break;
198  }
199 
200  default:
201  {
203  (
204  dict_,
205  "selectionMode",
206  word::null,
207  selectionModeTypeNames_
208  ) << exit(FatalIOError);
209  }
210  }
211 }
212 
215 {
216  return gSum(filterField(mesh().V()));
217 }
218 
219 
221 {
222  List<scalarField> allValues(Pstream::nProcs());
223 
224  allValues[Pstream::myProcNo()] = field;
225 
226  Pstream::gatherList(allValues);
227 
228  if (Pstream::master())
229  {
230  field =
231  ListListOps::combine<scalarField>
232  (
233  allValues,
235  );
236  }
237 }
238 
239 
242 (
243  const scalarField& field
244 ) const
245 {
246  return tmp<scalarField>(new scalarField(field, cellId_));
247 }
248 
249 
251 (
252  const label i
253 )
254 {
255  OFstream& file = this->file();
256 
257  switch (functionType_)
258  {
259  case ftNdf:
260  {
261  writeHeader(file, "Number density function");
262  break;
263  }
264 
265  case ftVdf:
266  {
267  writeHeader(file, "Volume density function");
268  break;
269  }
270 
271  case ftNc:
272  {
273  writeHeader(file, "Number concentration");
274  break;
275  }
276 
277  case ftMom:
278  {
279  writeHeader(file, "Moments");
280  break;
281  }
282  }
283 
284  switch (abszissaType_)
285  {
286  case atVolume:
287  {
288  writeCommented(file, "Time/volume");
289  break;
290  }
291 
292  case atDiameter:
293  {
294  writeCommented(file, "Time/diameter");
295  break;
296  }
297  }
298 
299  switch (functionType_)
300  {
301  case ftMom:
302  {
303  for (label i = 0; i <= momentOrder_; i++)
304  {
305  file() << tab << i;
306  }
307 
308  break;
309  }
310  default:
311  {
312  forAll(popBal_.sizeGroups(), sizeGroupi)
313  {
314  const diameterModels::sizeGroup& fi =
315  popBal_.sizeGroups()[sizeGroupi];
316 
317  switch (abszissaType_)
318  {
319  case atDiameter:
320  {
321  file() << tab << fi.d().value();
322 
323  break;
324  }
325 
326  case atVolume:
327  {
328  file() << tab << fi.x().value();
329 
330  break;
331  }
332  }
333  }
334 
335  break;
336  }
337  }
338 
339  file << endl;
340 }
341 
342 
343 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
344 
346 (
347  const word& name,
348  const Time& runTime,
349  const dictionary& dict
350 )
351 :
353  writeFile(obr_, name),
354  dict_(dict),
355  selectionModeType_
356  (
357  selectionModeTypeNames_.get("selectionMode", dict)
358  ),
359  selectionModeTypeName_(),
360  functionType_(functionTypeNames_.get("functionType", dict)),
361  abszissaType_(abszissaTypeNames_.get("abszissaType", dict)),
362  nCells_(0),
363  cellId_(),
364  volume_(0.0),
365  writeVolume_(dict.getOrDefault("writeVolume", false)),
366  popBal_
367  (
368  obr_.lookupObject<Foam::diameterModels::populationBalanceModel>
369  (
370  dict.get<word>("populationBalance")
371  )
372  ),
373  N_(popBal_.sizeGroups().size()),
374  momentOrder_(dict.getOrDefault<label>("momentOrder", 0)),
375  normalize_(dict.getOrDefault("normalize", false)),
376  sumN_(0.0),
377  sumV_(0.0)
378 {
379  read(dict);
382 }
383 
384 
385 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
388 {}
389 
390 
391 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
392 
394 {
395  if (dict != dict_)
396  {
397  dict_ = dict;
398  }
399 
403  initialise(dict);
404 
405  return true;
406 }
407 
410 {
411  return true;
412 }
413 
414 
416 {
417  writeFileHeader();
418  writeCurrentTime(file());
419 
420  Log << type() << " " << name() << " write" << nl;
421 
422  scalarField V(filterField(mesh().V()));
423  combineFields(V);
424 
425  sumN_ = 0;
426  sumV_ = 0;
427 
428  forAll(N_, i)
429  {
430  const Foam::diameterModels::sizeGroup& fi = popBal_.sizeGroups()[i];
431 
432  const volScalarField& alpha = fi.VelocityGroup().phase();
433 
434  scalarField Ni(fi*alpha/fi.x());
435  scalarField values(filterField(Ni));
436  scalarField V(filterField(mesh().V()));
437 
438  // Combine onto master
439  combineFields(values);
440  combineFields(V);
441 
442  if (Pstream::master())
443  {
444  // Calculate volume-averaged number concentration
445  N_[i] = sum(V*values)/sum(V);
446  }
447 
448  sumN_ += N_[i];
449 
450  sumV_ += N_[i]*fi.x().value();
451  }
452 
453  if (Pstream::master())
454  {
455  switch (functionType_)
456  {
457  case ftMom:
458  {
459  for (label m = 0; m <= momentOrder_; m++)
460  {
461  scalar result(0.0);
462 
463  forAll(N_, i)
464  {
466  popBal_.sizeGroups()[i];
467 
468  switch (abszissaType_)
469  {
470  case atVolume:
471  {
472  result += pow(fi.x().value(), m)*N_[i];
473 
474  break;
475  }
476 
477  case atDiameter:
478  {
479  result += pow(fi.d().value(), m)*N_[i];
480 
481  break;
482  }
483  }
484  }
485 
486  file() << tab << result;
487  }
488 
489  break;
490  }
491 
492  default:
493  {
494  forAll(popBal_.sizeGroups(), i)
495  {
497  popBal_.sizeGroups()[i];
498 
499  scalar result(0.0);
500  scalar delta(0.0);
501 
502  switch (abszissaType_)
503  {
504  case atVolume:
505  {
506  delta = popBal_.v()[i+1].value()
507  - popBal_.v()[i].value();
508 
509  break;
510  }
511 
512  case atDiameter:
513  {
514  const scalar& formFactor =
515  fi.VelocityGroup().formFactor().value();
516 
517  delta =
518  pow
519  (
520  popBal_.v()[i+1].value()
521  /formFactor,
522  1.0/3.0
523  )
524  - pow
525  (
526  popBal_.v()[i].value()
527  /formFactor,
528  1.0/3.0
529  );
530 
531  break;
532  }
533  }
534 
535  switch (functionType_)
536  {
537  case ftNdf:
538  {
539  if (normalize_ == true)
540  {
541  result = N_[i]/delta/sumN_;
542  }
543  else
544  {
545  result = N_[i]/delta;
546  }
547 
548  break;
549  }
550 
551  case ftVdf:
552  {
553  if (normalize_ == true)
554  {
555  result = N_[i]*fi.x().value()/delta/sumV_;
556  }
557  else
558  {
559  result = N_[i]*fi.x().value()/delta;
560  }
561 
562  break;
563  }
564 
565  case ftNc:
566  {
567  if (normalize_ == true)
568  {
569  result = N_[i]/sumN_;
570  }
571  else
572  {
573  result = N_[i];
574  }
575 
576  break;
577  }
578 
579  default:
580  {
581  break;
582  }
583  }
584 
585  file()<< tab << result;
586  }
587  }
588  }
589  }
590  {
591  file()<< endl;
592  }
593 
594  Log << endl;
595 
596  return true;
597 }
598 
599 
600 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
scalar delta
scalar volume_
Total volume of the evaluated selection.
const Type & value() const noexcept
Return const reference to value.
dictionary dict
static const Enum< functionTypes > functionTypeNames_
Function type names.
defineTypeNameAndDebug(ObukhovLength, 0)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
scalar volume() const
Calculate and return volume of the evaluated cell zone.
rDeltaTY field()
const dimensionedScalar & x() const
Return representative volume of the sizeGroup.
Definition: sizeGroupI.H:52
static void writeHeader(Ostream &os, const word &fieldName)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
virtual void resetFile(const word &name)
Reset internal file pointer to new file with new name.
Definition: writeFile.C:165
static const Enum< abszissaTypes > abszissaTypeNames_
Abszissa type names.
Output to file stream, using an OSstream.
Definition: OFstream.H:49
void writeFileHeader(const label i=0)
Output file header information.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
void combineFields(scalarField &field)
Combine fields from all processor domains into single field.
engineTime & runTime
Object access operator or list access operator (default is pass-through)
Definition: UList.H:1004
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
constexpr char tab
The tab &#39;\t&#39; character(0x09)
Definition: Ostream.H:49
virtual bool read(const dictionary &dict)
Read from dictionary.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
void initialise(const dictionary &dict)
Initialise, e.g. cell addressing.
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.
const word & name() const noexcept
Return the name of this functionObject.
const dictionary & dict() const
Return the reference to the construction dictionary.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
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
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
static void gatherList(const List< commsStruct > &comms, List< T > &values, const int tag, const label comm)
Gather data, but keep individual values separate. Uses the specified communication schedule...
functionTypes functionType_
Function type.
const phaseModel & phase() const
Return the phase.
dynamicFvMesh & mesh
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
This class represents a single sizeGroup belonging to a velocityGroup. The main property of a sizeGro...
Definition: sizeGroup.H:92
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual const word & type() const =0
Runtime type information.
static const word null
An empty word.
Definition: word.H:84
const dimensionedScalar & formFactor() const
Return the form factor.
virtual autoPtr< OFstream > newFileAtStartTime(const word &name) const
Return autoPtr to a new file using the simulation start time.
Definition: writeFile.C:156
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
virtual bool read(const dictionary &dict)
Read.
Definition: writeFile.C:241
selectionModeTypes
Selection mode type enumeration.
sizeDistribution(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
label nCells_
Global number of cells.
selectionModeTypes selectionModeType_
Selection mode type.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
void setCellZoneCells()
Set cells to evaluate based on a cell zone.
word selectionModeTypeName_
Name of selection.
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
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
abszissaTypes abszissaType_
Abszissa type.
abszissaTypes
abszissa type enumeration
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool read(const dictionary &dict)
Read optional controls.
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const dimensionedScalar & d() const
Return representative diameter of the sizeGroup.
Definition: sizeGroupI.H:45
tmp< scalarField > filterField(const scalarField &field) const
Filter field according to cellIds.
static const Enum< selectionModeTypes > selectionModeTypeNames_
Selection mode type names.
A class for managing temporary objects.
Definition: HashPtrTable.H:50
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Base class for writing single files from the function objects.
Definition: writeFile.H:112
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:635
functionTypes
Function type enumeration.
const velocityGroup & VelocityGroup() const
Return const-reference to the velocityGroup.
Definition: sizeGroupI.H:38
Namespace for OpenFOAM.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...