cloudSurfaceDistribution.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "cloud.H"
28 #include "faceSet.H"
29 #include "functionObject.H"
30 #include "hashedWordList.H"
31 #include "OSspecific.H"
32 #include "timeIOdictionary.H"
33 #include "unintegrable.H"
34 #include "writeFile.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 namespace functionObjects
42 {
45  (
49  );
50 }
51 }
52 
53 const Foam::NamedEnum
54 <
56  3
57 >
59 {"faceZone", "faceSet", "patch"};
60 
61 
62 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
63 
64 Foam::wordList Foam::functionObjects::cloudSurfaceDistribution::readFields
65 (
66  const dictionary& dict,
67  const word& key,
68  const wordList& defaultValue
69 )
70 {
71  const bool haveFields = dict.found(key + "s");
72  const bool haveField = dict.found(key);
73 
74  if (notNull(defaultValue) && !haveFields && !haveField)
75  {
76  return defaultValue;
77  }
78 
79  if (haveFields == haveField)
80  {
82  << "keywords " << key << "s and " << key << " both "
83  << (haveFields ? "" : "un") << "defined in "
84  << "dictionary " << dict.name()
85  << exit(FatalIOError);
86  }
87 
88  if (haveFields)
89  {
90  return dict.lookup<wordList>(key + "s");
91  }
92  else
93  {
94  return wordList(1, dict.lookup<word>(key));
95  }
96 }
97 
98 
100 Foam::functionObjects::cloudSurfaceDistribution::readSelectionType
101 (
102  const dictionary& dict
103 )
104 {
105  // Use the "select" entry if it is there
106  if (dict.found("select"))
107  {
108  return selectionTypeNames.read(dict.lookup("select"));
109  }
110 
111  // If there is only one of the possible keys (i.e., "faceZone", "faceSet",
112  // and "patch") present in the dictionary then infer the selection type
113  // from that key
114  const NamedEnum<selectionType, 3>::namesType& keys = selectionTypeNames;
115  label keyi = -1;
116  forAll(keys, i)
117  {
118  if (!dict.found(keys[i])) continue;
119 
120  keyi = keyi == -1 ? i : -labelMax;
121  }
122  if (keyi >= 0)
123  {
124  return selectionTypeNames[keys[keyi]];
125  }
126 
127  // Raise an error requesting a "select" entry
128  return selectionTypeNames.read(dict.lookup("select"));
129 }
130 
131 
132 const char* const*
133 Foam::functionObjects::cloudSurfaceDistribution::componentNames
134 (
135  const label fieldi
136 ) const
137 {
138  #define FIELD_RANGE_COMPONENT_NAMES(Type, GeoField) \
139  if (mesh().foundObject<GeoField<Type>>(fields_[fieldi])) \
140  { \
141  return pTraits<Type>::componentNames; \
142  }
143 
147 
148  return nullptr;
149 }
150 
151 
152 void Foam::functionObjects::cloudSurfaceDistribution::readCoeffs
153 (
154  const dictionary& dict,
155  const bool props
156 )
157 {
158  // Re-read the fields
159  const hashedWordList oldFields(fields_);
160  fields_ = readFields(dict, "field");
161 
162  // Determine if any fields are being continued
163  bool continued = false;
164  forAll(fields_, fieldi)
165  {
166  continued = continued || oldFields.found(fields_[fieldi]);
167  }
168 
169  // If we are continuing then the weight fields must not have changed
170  const wordList oldWeightFields(weightFields_);
171  weightFields_ = readFields(dict, "weightField", wordList());
172  if (continued && weightFields_ != oldWeightFields)
173  {
175  << "Cannot change weight fields at run-time"
176  << exit(FatalIOError);
177  }
178 
179  // If we are continuing then the surface must not have changed
180  const selectionType oldSelectionType = selectionType_;
181  selectionType_ = readSelectionType(dict);
182  const word oldSelectionName = selectionName_;
183  selectionName_ = dict.lookup<word>(selectionTypeNames[selectionType_]);
184  if
185  (
186  selectionType_ != oldSelectionType
187  || selectionName_ != oldSelectionName
188  )
189  {
191  << "Cannot change the selected surface at run-time"
192  << exit(FatalError);
193  }
194 
195  // If we are continuing then the number of bins must not have changed
196  const label oldNBins = nBins_;
197  nBins_ = dict.lookup<label>("nBins");
198  if (continued && nBins_ != oldNBins)
199  {
201  << "Cannot change the number of bins at run-time"
202  << exit(FatalIOError);
203  }
204 
205  // Re-read the formatter. This can change whenever.
206  if (!props)
207  {
208  formatter_ = setWriter::New(dict.lookup("setFormat"), dict);
209  }
210 
211  // If we have a new list of fields then we need to move any continuing
212  // data to its new location
213  if (fields_ != oldFields)
214  {
215  List<List<scalarField>> oldSums;
216  oldSums.transfer(sums_);
217  sums_.resize(fields_.size());
218 
219  List<List<Pair<scalar>>> oldRanges;
220  oldRanges.transfer(ranges_);
221  ranges_.resize(fields_.size());
222 
223  labelList oldNSamples;
224  oldNSamples.transfer(nSamples_);
225  nSamples_.resize(fields_.size());
226 
227  forAll(fields_, fieldi)
228  {
229  if (!oldFields.found(fields_[fieldi])) continue;
230 
231  const label oldFieldi = oldFields[fields_[fieldi]];
232 
233  sums_[fieldi].transfer(oldSums[oldFieldi]);
234  ranges_[fieldi].transfer(oldRanges[oldFieldi]);
235  nSamples_[fieldi] = oldNSamples[oldFieldi];
236  }
237  }
238 }
239 
240 
241 Foam::IOobject Foam::functionObjects::cloudSurfaceDistribution::propsDictIo
242 (
243  const IOobject::readOption r
244 ) const
245 {
246  return
247  IOobject
248  (
249  name() + "Properties",
250  mesh().time().name(),
251  "uniform",
252  mesh(),
253  r,
255  false
256  );
257 }
258 
259 
260 Foam::boolList Foam::functionObjects::cloudSurfaceDistribution::selected
261 (
262  const LagrangianSubScalarSubField& fraction
263 ) const
264 {
265  const Foam::cloud& c = cloud();
266 
267  const polyBoundaryMesh& pbm = c.mesh().mesh().boundaryMesh();
268 
269  const label patchi =
270  max
271  (
272  static_cast<label>(fraction.mesh().group())
273  - static_cast<label>(LagrangianGroup::onPatchZero),
274  -1
275  );
276 
277  const List<LagrangianState> states =
278  c.mesh().changing()
279  ? List<LagrangianState>(fraction.mesh().sub(c.mesh().states()))
280  : patchi != -1
281  ? List<LagrangianState>(fraction.size(), LagrangianState::onPatchZero)
282  : List<LagrangianState>(fraction.size(), LagrangianState::none);
283 
284  const SubField<label> facei = fraction.mesh().sub(c.mesh().facei());
285 
286  boolList result(facei.size(), false);
287 
288  switch (selectionType_)
289  {
290  case selectionType::faceZone:
291  {
292  const faceZone& z = c.mesh().mesh().faceZones()[selectionName_];
293  forAll(facei, subi)
294  {
295  if (states[subi] <= LagrangianState::inCell) continue;
296  result = z.lookupMap().found(facei[subi]);
297  }
298  break;
299  }
300  case selectionType::faceSet:
301  {
302  forAll(facei, subi)
303  {
304  if (states[subi] <= LagrangianState::inCell) continue;
305  result = selectionSet_.found(facei[subi]);
306  }
307  break;
308  }
309  case selectionType::patch:
310  {
311  result = patchi == pbm[selectionName_].index();
312  break;
313  }
314  }
315 
316  return result;
317 }
318 
319 
320 template<template<class> class GeoField>
321 bool Foam::functionObjects::cloudSurfaceDistribution::multiplyWeight
322 (
323  const LagrangianSubMesh& subMesh,
324  const label weightFieldi,
325  scalarField& weight
326 ) const
327 {
328  if (!mesh().foundObject<GeoField<scalar>>(weightFields_[weightFieldi]))
329  return false;
330 
331  const GeoField<scalar>& w =
332  mesh().lookupObject<GeoField<scalar>>(weightFields_[weightFieldi]);
333 
334  weight *= subMesh.sub(w.primitiveField());
335 
336  return true;
337 }
338 
339 
340 template<template<class> class GeoField, class Type>
341 bool Foam::functionObjects::cloudSurfaceDistribution::addField
342 (
343  const LagrangianSubMesh& subMesh,
344  const boolList& selected,
345  const scalarField& weight,
346  const label fieldi
347 )
348 {
349  if (!mesh().foundObject<GeoField<Type>>(fields_[fieldi])) return false;
350 
351  const GeoField<Type>& field =
352  mesh().lookupObject<GeoField<Type>>(fields_[fieldi]);
353 
354  // Allocate the data if needed
355  if (sums_[fieldi].empty())
356  {
357  sums_[fieldi].resize(pTraits<Type>::nComponents);
358  ranges_[fieldi].resize(pTraits<Type>::nComponents);
359 
360  for (direction d = 0; d < pTraits<Type>::nComponents; ++ d)
361  {
362  sums_[fieldi][d].resize(nBins_ + 1, scalar(0));
363  ranges_[fieldi][d] = Pair<scalar>(vGreat, -vGreat);
364  }
365 
366  nSamples_[fieldi] = 0;
367  }
368 
369  // Consider each component in turn
370  for (direction d = 0; d < pTraits<Type>::nComponents; ++ d)
371  {
372  Pair<scalar>& range = ranges_[fieldi][d];
373  const Pair<scalar> range0 = ranges_[fieldi][d];
374 
375  // Expand the range to include the new elements if necessary
376  bool rangeHasChanged = false;
377 
378  forAll(weight, subi)
379  {
380  if (!selected[subi]) continue;
381 
382  const scalar x = component(field[subMesh.start() + subi], d);
383 
384  if (x < range.first())
385  {
386  range.first() = x;
387  rangeHasChanged = true;
388  }
389 
390  if (x > range.second())
391  {
392  range.second() = x;
393  rangeHasChanged = true;
394  }
395  }
396 
397  // Synchronise
398  reduce(rangeHasChanged, orOp<bool>());
399  if (rangeHasChanged)
400  {
401  reduce(range.first(), minOp<scalar>());
402  reduce(range.second(), maxOp<scalar>());
403  }
404 
405  // If the range was expanded then re-sample the old sums onto the new
406  // discretisation of property space
407  if (rangeHasChanged && nSamples_[fieldi])
408  {
409  scalarList sum0;
410  sum0.transfer(sums_[fieldi][d]);
411  sums_[fieldi][d].resize(nBins_ + 1, scalar(0));
412 
413  forAll(sum0, nodei0)
414  {
415  const scalar x =
416  (1 - scalar(nodei0)/nBins_)*range0.first()
417  + scalar(nodei0)/nBins_*range0.second();
418  const scalar f =
419  (x - range.first())
420  /max(range.second() - range.first(), rootVSmall);
421  const label bini = min(max(floor(f*nBins_), 0), nBins_ - 1);
422  const scalar g = f*nBins_ - scalar(bini);
423 
424  sums_[fieldi][d][bini] += sum0[nodei0]*(1 - g);
425  sums_[fieldi][d][bini + 1] += sum0[nodei0]*g;
426  }
427  }
428 
429  // Add the new elements to the bins
430  forAll(weight, subi)
431  {
432  if (!selected[subi]) continue;
433 
434  const scalar x = component(field[subMesh.start() + subi], d);
435  const scalar f =
436  (x - range.first())
437  /max(range.second() - range.first(), rootVSmall);
438  const label bini = min(max(floor(f*nBins_), 0), nBins_ - 1);
439  const scalar g = f*nBins_ - scalar(bini);
440 
441  sums_[fieldi][d][bini] += weight[subi]*(1 - g);
442  sums_[fieldi][d][bini + 1] += weight[subi]*g;
443  }
444  }
445 
446  // Update the number of samples
447  forAll(weight, subi)
448  {
449  if (!selected[subi]) continue;
450 
451  nSamples_[fieldi] ++;
452  }
453 
454  return true;
455 }
456 
457 
458 void Foam::functionObjects::cloudSurfaceDistribution::writeDistribution
459 (
460  const word& fieldName,
461  const word& componentName,
462  const scalarField& x,
463  const scalarField& PDF,
464  const scalarField& CDF
465 ) const
466 {
467  if (!Pstream::master()) return;
468 
469  const fileName& outputPath =
470  time_.globalPath()
472  /(
474  ? mesh().mesh().name()
475  : word::null
476  )
477  /name()
478  /time_.name();
479 
480  mkDir(outputPath);
481 
482  const word fieldComponentName =
483  fieldName
484  + (componentName.empty() ? "" : "_")
485  + componentName;
486 
487  formatter_->write
488  (
489  outputPath,
490  fieldComponentName,
491  coordSet(true, fieldComponentName, x),
492  "PDF", PDF,
493  "CDF", CDF
494  );
495 }
496 
497 
498 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
499 
501 (
502  const word& name,
503  const Time& runTime,
504  const dictionary& dict
505 )
506 :
507  LagrangianMeshFunctionObject(name, runTime, dict, cloud::typeName),
509  (
510  static_cast<const LagrangianMeshFunctionObject&>(*this)
511  ),
512  fields_(),
513  weightFields_(readFields(dict, "weightField", wordList())),
514  selectionType_(readSelectionType(dict)),
515  selectionName_(dict.lookup<word>(selectionTypeNames[selectionType_])),
516  selectionSet_
517  (
518  selectionType_ == selectionType::faceSet
519  ? faceSet(mesh().mesh(), selectionName_)
520  : labelHashSet()
521  ),
522  nBins_(dict.lookup<label>("nBins")),
523  formatter_(),
524  sums_(),
525  ranges_(),
526  nSamples_()
527 {
528  // Restore from saved properties dictionary
530  (
531  this->propsDictIo(IOobject::MUST_READ)
532  );
533  if (propsDictIo.headerOk())
534  {
535  timeIOdictionary propsDict(propsDictIo);
536  readCoeffs(propsDict, true);
537  sums_ = propsDict.lookup<List<List<scalarField>>>("sums");
538  ranges_ = propsDict.lookup<List<List<Pair<scalar>>>>("ranges");
539  nSamples_ = propsDict.lookup<labelList>("nSamples");
540  }
541 
542  // Read the coefficients from the function object dictionary
543  readCoeffs(dict, false);
544 }
545 
546 
547 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
548 
550 {}
551 
552 
553 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
554 
556 (
557  const dictionary& dict
558 )
559 {
561  {
562  readCoeffs(dict, false);
563  return true;
564  }
565  else
566  {
567  return false;
568  }
569 }
570 
571 
573 {
574  return wordList::null();
575 }
576 
577 
579 {
580  return false;
581 }
582 
583 
585 {
586  return true;
587 }
588 
589 
591 (
592  const LagrangianSubScalarSubField& fraction
593 )
594 {}
595 
596 
598 (
599  const LagrangianSubScalarSubField& fraction
600 )
601 {
602  const LagrangianSubMesh& subMesh = fraction.mesh();
603 
604  if
605  (
606  selectionType_ == selectionType::patch
607  && subMesh.group() < LagrangianGroup::onPatchZero
608  ) return;
609 
610  // Identify which particles are to be included
611  const boolList selected(this->selected(fraction));
612 
613  // Construct the weights
614  scalarField weight(subMesh.size(), scalar(1));
615  forAll(weightFields_, weightFieldi)
616  {
617  #define MULTIPLY_WEIGHT(GeoField) \
618  && !multiplyWeight<GeoField>(subMesh, weightFieldi, weight)
619 
620  if
621  (
622  true
626  )
627  {
629  << "Weight field " << weightFields_[weightFieldi]
630  << " was not found" << exit(FatalError);
631  }
632  }
633 
634  // Add to the sums
635  forAll(fields_, fieldi)
636  {
637  #define ADD_FIELD(Type, GeoField) \
638  && !addField<GeoField, Type>(subMesh, selected, weight, fieldi)
639 
640  if
641  (
642  true
646  )
647  {
648  cannotFindObject(fields_[fieldi]);
649  }
650  }
651 }
652 
653 
655 {
656  forAll(sums_, fieldi)
657  {
658  // Quit if this PDF has nothing in it yet
659  if (returnReduce(nSamples_[fieldi], sumOp<label>()) == 0) continue;
660 
661  // Get the component names for this field
662  const char* const* componentNames = this->componentNames(fieldi);
663 
664  // Write each component's PDF
665  forAll(sums_[fieldi], d)
666  {
667  const scalarList& sum = sums_[fieldi][d];
668  const Pair<scalar>& range = ranges_[fieldi][d];
669 
670  // Write a single point if the distribution is uniform
671  if (range.first() == range.second())
672  {
673  writeDistribution
674  (
675  fields_[fieldi],
676  componentNames[d],
677  scalarField(1, range.first()),
678  scalarField(1, vGreat),
679  scalarField(1, scalar(1))
680  );
681  continue;
682  }
683 
684  // Construct the limits of the bins
685  scalarField x(nBins_ + 1);
686  forAll(sum, nodei)
687  {
688  const scalar f = scalar(nodei)/nBins_;
689  x[nodei] = (1 - f)*range.first() + f*range.second();
690  }
691 
692  // Convert the sum to a PDF by synchronising, normalising and
693  // correcting the ends (which have half the sample space of the
694  // interior points)
695  scalarField PDF(sum);
698  PDF /= Foam::sum(PDF)*(range.second() - range.first())/nBins_;
699  PDF.first() *= 2;
700  PDF.last() *= 2;
701 
702  // Write
703  writeDistribution
704  (
705  fields_[fieldi],
706  componentNames[d],
707  x,
708  PDF,
710  );
711  }
712  }
713 
714  if (!mesh().time().writeTime()) return true;
715 
717  propsDict.add("select", selectionTypeNames[selectionType_]);
718  propsDict.add(selectionTypeNames[selectionType_], selectionName_);
719  propsDict.add("fields", fields_);
720  propsDict.add("nBins", nBins_);
721  propsDict.add("sums", sums_);
722  propsDict.add("ranges", ranges_);
723  propsDict.add("nSamples", nSamples_);
724  propsDict.regIOobject::write();
725 
726  return true;
727 }
728 
729 
731 {
732  return true;
733 }
734 
735 
737 (
738  const polyTopoChangeMap& map
739 )
740 {
741  if (selectionType_ == selectionType::faceSet)
742  {
743  selectionSet_ = faceSet(mesh().mesh(), selectionName_);
744  }
745 }
746 
747 
749 (
750  const polyMeshMap&
751 )
752 {
753  if (selectionType_ == selectionType::faceSet)
754  {
755  selectionSet_ = faceSet(mesh().mesh(), selectionName_);
756  }
757 }
758 
759 
761 (
762  const polyDistributionMap&
763 )
764 {
765  if (selectionType_ == selectionType::faceSet)
766  {
767  selectionSet_ = faceSet(mesh().mesh(), selectionName_);
768  }
769 }
770 
771 
772 // ************************************************************************* //
scalar range
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const Mesh & mesh() const
Return mesh.
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
readOption
Enumeration defining the read options.
Definition: IOobject.H:117
const word & name() const
Return name.
Definition: IOobject.H:307
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
LagrangianGroup group() const
Return the group.
label size() const
Return size.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
static const List< word > & null()
Return a null List.
Definition: ListI.H:118
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:55
FixedList< word, nEnum > namesType
Definition: NamedEnum.H:64
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
T & first()
Return the first element of the list.
Definition: UListI.H:114
T & last()
Return the last element of the list.
Definition: UListI.H:128
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
Base class for clouds. Provides a basic evolution algorithm, models, and a database for caching deriv...
Definition: cloud.H:63
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
static tmp< scalarField > integrate(const scalarField &x, const scalarField &y)
Integrate the values y with respect to the coordinates x.
Definition: unintegrable.C:34
A list of face labels.
Definition: faceSet.H:51
Abstract base-class for Time/database functionObjects.
Base class for function objects relating to a Lagrangian mesh.
Base class for function objects that refer to a cloud. Provides hooks into the cloud solution process...
Function to generate a plot of the distribution of the values of particles that pass through a face-z...
cloudSurfaceDistribution(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
static const NamedEnum< selectionType, 3 > selectionTypeNames
Selection type names.
virtual wordList fields() const
Return the list of fields required.
virtual bool executeAtStart() const
Return false so this function does not execute at the start.
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
virtual void postCrossFaces(const LagrangianSubScalarSubField &fraction)
Hook following face crossings of a specific sub-mesh.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
virtual bool execute()
Do nothing. Everything happens in faces crossing hooks.
virtual void preCrossFaces(const LagrangianSubScalarSubField &fraction)
Hook before face crossings of a specific sub-mesh.
virtual void topoChange(const polyTopoChangeMap &map)
Update topology using the given map.
virtual bool read(const dictionary &)
Read parameters.
Function object that solves for the evolution of a cloud. Only provides one-way coupling with a finit...
virtual bool read(const dictionary &)
Read optional controls.
Reads fields from the time directories and adds them to the mesh database for further post-processing...
Definition: readFields.H:96
Writes run time, CPU time and clock time and optionally the CPU and clock times per time step.
static const word outputPrefix
Directory prefix.
Definition: writeFile.H:72
const polyMesh & mesh() const
Return reference to polyMesh.
Definition: fvMesh.H:443
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type and name.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:270
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
static autoPtr< setWriter > New(const word &writeType, const IOstream::streamFormat writeFormat=IOstream::ASCII, const IOstream::compressionType writeCompression=IOstream::UNCOMPRESSED)
Select given write options.
Definition: setWriter.C:286
timeIOdictionary derived from IOdictionary with globalFile set false to enable writing to processor t...
Templated form of IOobject providing type information for file reading and header type checking.
Definition: IOobject.H:530
bool headerOk()
Read header (uses typeGlobalFile to find file) and check.
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
#define ADD_FIELD(Type, GeoField)
#define MULTIPLY_WEIGHT(GeoField)
#define FIELD_RANGE_COMPONENT_NAMES(Type, GeoField)
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
const dimensionedScalar c
Speed of light in a vacuum.
defineTypeNameAndDebug(adjustTimeStepToCombustion, 0)
addToRunTimeSelectionTable(functionObject, adjustTimeStepToCombustion, dictionary)
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< word > wordList
A List of words.
Definition: fileName.H:54
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const HashSet< word > &selectedFields, LIFOStack< regIOobject * > &storedObjects)
Read the selected GeometricFields of the specified type.
Definition: ReadFields.C:244
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
LagrangianState
Lagrangian state enumeration.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void component(LagrangianPatchField< typename LagrangianPatchField< Type >::cmptType > &sf, const LagrangianPatchField< Type > &f, const direction d)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:64
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
DimensionedField< Type, LagrangianMesh > LagrangianInternalField
GeometricField< Type, LagrangianMesh, LagrangianPrimitiveDynamicField > LagrangianDynamicField
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
IOerror FatalIOError
LagrangianSubSubField< scalar > LagrangianSubScalarSubField
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
static const label labelMax
Definition: label.H:62
uint8_t direction
Definition: direction.H:45
GeometricField< Type, LagrangianMesh > LagrangianField
labelList f(nPoints)
dictionary dict
IOdictionary propsDict(systemDict("particleTracksDict", args, runTime))