dataCloud.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) 2018-2024 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "dataCloud.H"
29 #include "Cloud.H"
30 #include "dictionary.H"
31 #include "fvMesh.H"
32 #include "pointList.H"
33 #include "OFstream.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 namespace functionObjects
41 {
42  defineTypeNameAndDebug(dataCloud, 0);
43  addToRunTimeSelectionTable(functionObject, dataCloud, dictionary);
44 }
45 }
46 
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 
49 bool Foam::functionObjects::dataCloud::writeCloud
50 (
51  const fileName& outputName,
52  const word& cloudName
53 )
54 {
55  applyFilter_ = false;
56 
57  const auto* cloudPtr = mesh_.findObject<cloud>(cloudName);
58  if (!cloudPtr)
59  {
60  return false;
61  }
62 
63  const auto& currCloud = *cloudPtr;
64 
65  objectRegistry obrTmp
66  (
67  IOobject
68  (
69  "tmp::dataCloud::" + cloudName,
70  mesh_.time().constant(),
71  mesh_,
75  )
76  );
77 
78  currCloud.writeObjects(obrTmp);
79 
80  const auto* pointsPtr = cloud::findIOPosition(obrTmp);
81 
82  if (!pointsPtr)
83  {
84  // This should be impossible
85  return false;
86  }
87 
88  applyFilter_ = calculateFilter(obrTmp, log);
89  Pstream::reduceOr(applyFilter_);
90 
91 
92  // Number of parcels (locally)
93  const label nParcels
94  (
95  applyFilter_ ? parcelAddr_.count() : pointsPtr->size()
96  );
97 
98  // Total number of parcels on all processes
99  const label nTotParcels = returnReduce(nParcels, sumOp<label>());
100 
101  if (applyFilter_)
102  {
103  // Report filtered/unfiltered count
104  Log << "After filtering using " << nTotParcels << '/'
105  << (returnReduce(pointsPtr->size(), sumOp<label>()))
106  << " parcels" << nl;
107  }
108 
109  if (!nTotParcels)
110  {
111  return false;
112  }
113 
114  if (UPstream::master())
115  {
116  Foam::mkDir(outputName.path());
117  }
118 
119  return
120  (
121  writeField<label>(outputName, obrTmp)
122  || writeField<scalar>(outputName, obrTmp)
123  || writeField<vector>(outputName, obrTmp)
124  );
125 }
126 
127 
128 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
129 
130 Foam::functionObjects::dataCloud::dataCloud
131 (
132  const word& name,
133  const Time& runTime,
134  const dictionary& dict
135 )
136 :
138  printf_(),
139  precision_(IOstream::defaultPrecision()),
140  applyFilter_(false),
141  selectClouds_(),
142  fieldName_(),
143  directory_()
144 {
145  read(dict);
146 }
147 
148 
149 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
150 
152 {
154 
155  const int padWidth = dict.getOrDefault<int>("width", 8);
156 
157  // Appropriate printf format - Enforce min/max sanity limits
158  if (padWidth < 1 || padWidth > 31)
159  {
160  printf_.clear();
161  }
162  else
163  {
164  printf_ = "%0" + std::to_string(padWidth) + "d";
165  }
166 
167  precision_ =
168  dict.getOrDefault("precision", IOstream::defaultPrecision());
169 
170 
171  selectClouds_.clear();
172  dict.readIfPresent("clouds", selectClouds_);
173  selectClouds_.uniq();
174 
175  if (selectClouds_.empty())
176  {
177  word cloudName;
178  if (dict.readIfPresent("cloud", cloudName))
179  {
180  selectClouds_.push_back(std::move(cloudName));
181  }
182  }
183 
184  dict.readEntry("field", fieldName_);
185 
186  // Actions to define selection
187  parcelSelect_ = dict.subOrEmptyDict("selection");
188 
189  // Output directory
190 
191  directory_.clear();
192  dict.readIfPresent("directory", directory_);
193 
194  if (directory_.size())
195  {
196  // User-defined output directory
197  directory_.expand();
198  if (!directory_.isAbsolute())
199  {
200  directory_ = time_.globalPath()/directory_;
201  }
202  }
203  else
204  {
205  // Standard postProcessing/ naming
206  directory_ = time_.globalPath()/functionObject::outputPrefix/name();
207  }
208  directory_.clean(); // Remove unneeded ".."
209 
210  return true;
211 }
212 
215 {
216  return true;
217 }
218 
219 
221 {
222  const wordList cloudNames
223  (
224  selectClouds_.empty()
225  ? mesh_.sortedNames<cloud>()
226  : mesh_.sortedNames<cloud>(selectClouds_)
227  );
228 
229  if (cloudNames.empty())
230  {
231  return true; // skip - not available
232  }
233 
234  const word timeDesc = "_" +
235  (
236  printf_.empty()
237  ? Foam::name(time_.timeIndex())
238  : word::printf(printf_, time_.timeIndex())
239  );
240 
241  Log << name() << " output Time: " << time_.timeName() << nl;
242 
243  // Each cloud separately
244  for (const word& cloudName : cloudNames)
245  {
246  // Legacy is not to be supported
247 
248  const fileName outputName
249  (
250  directory_/cloudName + timeDesc + ".dat"
251  );
252 
253  // writeCloud() includes mkDir (on master)
254 
255  if (writeCloud(outputName, cloudName))
256  {
257  Log << " cloud : "
258  << time_.relativePath(outputName) << endl;
259  }
260  }
261 
262  return true;
263 }
264 
265 
266 // ************************************************************************* //
static const IOField< point > * findIOPosition(const objectRegistry &obr)
Locate the "position" IOField within object registry.
Definition: cloud.H:188
dictionary dict
defineTypeNameAndDebug(ObukhovLength, 0)
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:420
A class for handling file names.
Definition: fileName.H:72
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
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
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:418
static void reduceOr(bool &value, const label communicator=worldComm)
Logical (or) reduction (MPI_AllReduce)
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
Ignore writing from objectRegistry::writeObject()
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
bitSet parcelAddr_
The filtered parcel addressing. Eg, for the current cloud.
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
virtual bool execute()
Execute, currently does nothing.
Definition: dataCloud.C:207
word outputName("finiteArea-edges.obj")
virtual bool write()
Write fields.
Definition: dataCloud.C:213
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:614
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
A cloud is a registry collection of lagrangian particles.
Definition: cloud.H:53
wordList sortedNames() const
The sorted names of all objects.
bool log
Flag to write log into Info.
bool calculateFilter(const objectRegistry &obrTmp, const bool log=true)
Calculate parcel selection filter.
static word printf(const char *fmt, const PrimitiveType &val)
Use a printf-style formatter for a primitive.
const word & constant() const noexcept
Return constant name.
Definition: TimePathsI.H:112
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
An IOstream is an abstract base class for all input/output systems; be they streams, files, token lists etc.
Definition: IOstream.H:82
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1094
Nothing to be read.
#define Log
Definition: PDRblock.C:28
static word outputPrefix
Directory prefix.
virtual bool read(const dictionary &dict)
Read optional controls.
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
virtual bool read(const dictionary &dict)
Read the dataCloud specification.
Definition: dataCloud.C:144
const fvMesh & mesh_
Reference to the fvMesh.
Do not request registration (bool: false)
Namespace for OpenFOAM.