CloudIO.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) 2011-2017, 2020 OpenFOAM Foundation
9  Copyright (C) 2017-2023 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 "Cloud.H"
30 #include "Time.H"
31 #include "IOPosition.H"
32 #include "IOdictionary.H"
33 #include "IOobjectList.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 template<class ParticleType>
39 
40 
41 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
42 
43 template<class ParticleType>
45 {
46  IOobject dictObj
47  (
48  cloudPropertiesName,
49  time().timeName(),
50  "uniform"/cloud::prefix/name(),
51  db(),
52  IOobject::MUST_READ,
53  IOobject::NO_WRITE,
54  IOobject::NO_REGISTER
55  );
56 
57  if (dictObj.typeHeaderOk<IOdictionary>(true))
58  {
59  const IOdictionary uniformPropsDict(dictObj);
60 
61  // Fall back to positions mode if the entry is not present for
62  // backwards compatibility
63  geometryType_ =
64  cloud::geometryTypeNames.getOrDefault
65  (
66  "geometry",
67  uniformPropsDict,
68  cloud::geometryType::POSITIONS
69  );
70 
71  const word procName("processor" + Foam::name(Pstream::myProcNo()));
72 
73  const dictionary* dictptr = uniformPropsDict.findDict(procName);
74 
75  if (dictptr)
76  {
77  dictptr->readEntry("particleCount", ParticleType::particleCount_);
78  }
79  }
80  else
81  {
82  ParticleType::particleCount_ = 0;
83  }
84 }
85 
86 
87 template<class ParticleType>
89 {
90  IOdictionary uniformPropsDict
91  (
92  IOobject
93  (
94  cloudPropertiesName,
95  time().timeName(),
96  "uniform"/cloud::prefix/name(),
97  db(),
98  IOobject::NO_READ,
99  IOobject::NO_WRITE,
100  IOobject::NO_REGISTER
101  )
102  );
103 
104  labelList np(Pstream::nProcs(), Zero);
105  np[Pstream::myProcNo()] = ParticleType::particleCount_;
106 
107  // FIXME: replace with Pstream::allGatherList(np);
108  Pstream::listCombineReduce(np, maxEqOp<label>());
109 
110  uniformPropsDict.add
111  (
112  "geometry",
113  cloud::geometryTypeNames[geometryType_]
114  );
115 
116  forAll(np, i)
117  {
118  const word procName("processor" + Foam::name(i));
119  uniformPropsDict.subDictOrAdd(procName).add("particleCount", np[i]);
120  }
121 
122  uniformPropsDict.writeObject
123  (
124  IOstreamOption(IOstreamOption::ASCII, time().writeCompression()),
125  true
126  );
127 }
128 
129 
130 template<class ParticleType>
131 void Foam::Cloud<ParticleType>::initCloud(const bool checkClass)
132 {
133  readCloudUniformProperties();
134 
135  IOPosition<Cloud<ParticleType>> ioP(*this, geometryType_);
136 
137  const bool haveFile = ioP.headerOk();
138  Istream& is = ioP.readStream(checkClass ? typeName : word::null, haveFile);
139  if (haveFile)
140  {
141  ioP.readData(is, *this);
142  ioP.close();
143  }
144 
145  if (!haveFile && debug)
146  {
147  Pout<< "Not reading particle positions file: "
148  << ioP.objectRelPath() << nl
149  << "Assuming the initial cloud contains 0 particles." << endl;
150  }
151 
152  // Always operate in coordinates mode after reading
153  geometryType_ = cloud::geometryType::COORDINATES;
154 
155  // Ask for the tetBasePtIs to trigger all processors to build
156  // them, otherwise, if some processors have no particles then
157  // there is a comms mismatch.
158  (void)polyMesh_.tetBasePtIs();
159 }
160 
161 
162 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
163 
164 template<class ParticleType>
166 (
167  const polyMesh& pMesh,
168  const word& cloudName,
169  const bool checkClass
170 )
171 :
172  Cloud<ParticleType>(pMesh, Foam::zero{}, cloudName)
173 {
174  initCloud(checkClass);
175 }
176 
177 
178 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
179 
180 template<class ParticleType>
182 (
183  const word& fieldName,
185 ) const
186 {
187  return IOobject
188  (
189  fieldName,
190  time().timeName(),
191  *this,
192  rOpt,
193  IOobjectOption::NO_WRITE,
194  IOobjectOption::NO_REGISTER
195  );
196 }
197 
198 
199 template<class ParticleType>
200 template<class DataType>
202 (
203  const Cloud<ParticleType>& c,
204  const IOField<DataType>& data
205 ) const
206 {
207  if (data.size() != c.size())
208  {
210  << "Size of " << data.name()
211  << " field " << data.size()
212  << " does not match the number of particles " << c.size()
213  << abort(FatalError);
214  }
215 }
216 
217 
218 template<class ParticleType>
219 template<class DataType>
221 (
222  const Cloud<ParticleType>& c,
223  const CompactIOField<Field<DataType>, DataType>& data
224 ) const
225 {
226  if (data.size() != c.size())
227  {
229  << "Size of " << data.name()
230  << " field " << data.size()
231  << " does not match the number of particles " << c.size()
232  << abort(FatalError);
233  }
234 }
235 
236 
237 template<class ParticleType>
238 template<class Type>
240 (
241  const IOobject& io,
242  const IOobject& ioNew
243 ) const
244 {
245  if (io.isHeaderClass<IOField<Type>>())
246  {
247  IOField<Type> fld(io);
248  auto* fldNewPtr = new IOField<Type>(ioNew, std::move(fld));
249  return fldNewPtr->store();
250  }
252  return false;
253 }
254 
255 
256 template<class ParticleType>
258 (
259  objectRegistry& obr,
260  const wordRes& selectFields,
261  const wordRes& excludeFields
262 ) const
263 {
264  IOobjectList cloudObjects
265  (
266  *this,
267  time().timeName(),
268  IOobject::NO_REGISTER
269  );
270 
271  const wordRes::filter pred(selectFields, excludeFields);
272 
273  forAllConstIters(cloudObjects, iter)
274  {
275  const IOobject& io = *(iter.val());
276  const word& fldName = io.name();
277 
278  if (!pred(fldName))
279  {
280  continue; // reject
281  }
282 
283  IOobject ioNew
284  (
285  fldName,
286  time().timeName(),
287  obr,
288  IOobject::NO_READ,
289  IOobject::NO_WRITE
290  );
291 
292  const bool stored
293  (
294  readStoreFile<label>(io, ioNew)
295  || readStoreFile<scalar>(io, ioNew)
296  || readStoreFile<vector>(io, ioNew)
297  || readStoreFile<sphericalTensor>(io, ioNew)
298  || readStoreFile<symmTensor>(io, ioNew)
299  || readStoreFile<tensor>(io, ioNew)
300  );
301 
302  if (!stored)
303  {
304  DebugInfo
305  << "Unhandled field:" << fldName
306  << " type:" << io.headerClassName() << endl;
307  }
308  }
309 }
310 
311 
312 template<class ParticleType>
314 {
316 }
317 
318 
319 template<class ParticleType>
321 (
322  IOstreamOption streamOpt,
323  const bool /* writeOnProc */
324 ) const
325 {
326  writeCloudUniformProperties();
327 
328  writeFields();
329  return cloud::writeObject(streamOpt, (this->size() > 0));
330 }
331 
332 
333 // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
334 
335 template<class ParticleType>
336 Foam::Ostream& Foam::operator<<(Ostream& os, const Cloud<ParticleType>& c)
337 {
338  c.writeData(os);
339 
340  os.check(FUNCTION_NAME);
341  return os;
342 }
343 
344 
345 // ************************************************************************* //
void readFromFiles(objectRegistry &obr, const wordRes &selectFields, const wordRes &excludeFields=wordRes::null()) const
Read from files into objectRegistry.
Definition: CloudIO.C:251
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
List of IOobjects with searching and retrieving facilities. Implemented as a HashTable, so the various sorted methods should be used if traversing in parallel.
Definition: IOobjectList.H:55
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
void checkFieldFieldIOobject(const Cloud< ParticleType > &c, const CompactIOField< Field< DataType >, DataType > &data) const
Check lagrangian data fieldfield.
Definition: CloudIO.C:214
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
A simple container for options an IOstream can normally have.
bool readStoreFile(const IOobject &io, const IOobject &ioNew) const
Helper function to store a cloud field on its registry.
Definition: CloudIO.C:233
static word cloudPropertiesName
Name of cloud properties dictionary.
Definition: Cloud.H:149
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
word timeName
Definition: getTimeIndex.H:3
wordRes excludeFields
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"))
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
Definition: CloudIO.C:314
A class for handling words, derived from Foam::string.
Definition: word.H:63
Functor wrapper of allow/deny lists of wordRe for filtering.
Definition: wordRes.H:216
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
Cloud(const polyMesh &mesh, const Foam::zero, const word &cloudName)
Construct without particles.
Definition: Cloud.C:57
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Base cloud calls templated on particle type.
Definition: Cloud.H:51
#define DebugInfo
Report an information message using Foam::Info.
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
virtual void writeFields() const
Write the field data for the cloud of particles Dummy at.
Definition: CloudIO.C:306
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const dimensionedScalar c
Speed of light in a vacuum.
IOobject fieldIOobject(const word &fieldName, IOobjectOption::readOption rOpt=IOobjectOption::NO_READ) const
Helper to construct IOobject for field and current time.
Definition: CloudIO.C:175
void checkFieldIOobject(const Cloud< ParticleType > &c, const IOField< DataType > &data) const
Check lagrangian data field.
Definition: CloudIO.C:195
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
List< label > labelList
A List of labels.
Definition: List.H:62
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
Registry of regIOobjects.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
A primitive field of type <T> with automated input and output.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127
readOption
Enumeration defining read preferences.