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-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 "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_IF_MODIFIED,
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  Pstream::listCombineReduce(np, maxEqOp<label>());
108 
109  uniformPropsDict.add
110  (
111  "geometry",
112  cloud::geometryTypeNames[geometryType_]
113  );
114 
115  forAll(np, i)
116  {
117  word procName("processor" + Foam::name(i));
118  uniformPropsDict.add(procName, dictionary());
119  uniformPropsDict.subDict(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 valid = ioP.headerOk();
138  Istream& is = ioP.readStream(checkClass ? typeName : "", valid);
139  if (valid)
140  {
141  ioP.readData(is, *this);
142  ioP.close();
143  }
144 
145  if (!valid && debug)
146  {
147  Pout<< "Cannot read particle positions file:" << nl
148  << " " << ioP.objectPath() << 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(pMesh, cloudName),
173  polyMesh_(pMesh),
174  labels_(),
175  cellWallFacesPtr_(),
176  geometryType_(cloud::geometryType::COORDINATES)
177 {
178  checkPatches();
179 
180  (void)polyMesh_.tetBasePtIs();
181  (void)polyMesh_.oldCellCentres();
182 
183  initCloud(checkClass);
184 }
185 
186 
187 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
188 
189 template<class ParticleType>
191 (
192  const word& fieldName,
194 ) const
195 {
196  return IOobject
197  (
198  fieldName,
199  time().timeName(),
200  *this,
201  rOpt,
202  IOobject::NO_WRITE,
203  IOobject::NO_REGISTER
204  );
205 }
206 
207 
208 template<class ParticleType>
209 template<class DataType>
211 (
212  const Cloud<ParticleType>& c,
213  const IOField<DataType>& data
214 ) const
215 {
216  if (data.size() != c.size())
217  {
219  << "Size of " << data.name()
220  << " field " << data.size()
221  << " does not match the number of particles " << c.size()
222  << abort(FatalError);
223  }
224 }
225 
226 
227 template<class ParticleType>
228 template<class DataType>
230 (
231  const Cloud<ParticleType>& c,
232  const CompactIOField<Field<DataType>, DataType>& data
233 ) const
234 {
235  if (data.size() != c.size())
236  {
238  << "Size of " << data.name()
239  << " field " << data.size()
240  << " does not match the number of particles " << c.size()
241  << abort(FatalError);
242  }
243 }
244 
245 
246 template<class ParticleType>
247 template<class Type>
249 (
250  const IOobject& io,
251  const IOobject& ioNew
252 ) const
253 {
254  if (io.headerClassName() == IOField<Type>::typeName)
255  {
256  IOField<Type> fld(io);
257  auto* fldNewPtr = new IOField<Type>(ioNew, std::move(fld));
258  return fldNewPtr->store();
259  }
261  return false;
262 }
263 
264 
265 template<class ParticleType>
267 (
268  objectRegistry& obr,
269  const wordRes& selectFields,
270  const wordRes& excludeFields
271 ) const
272 {
273  IOobjectList cloudObjects
274  (
275  *this,
276  time().timeName(),
277  IOobject::NO_REGISTER
278  );
279 
280  const wordRes::filter pred(selectFields, excludeFields);
281 
282  forAllConstIters(cloudObjects, iter)
283  {
284  const IOobject& io = *(iter.val());
285  const word& fldName = io.name();
286 
287  if (!pred(fldName))
288  {
289  continue; // reject
290  }
291 
292  IOobject ioNew
293  (
294  fldName,
295  time().timeName(),
296  obr,
297  IOobject::NO_READ,
298  IOobject::NO_WRITE
299  );
300 
301  const bool stored
302  (
303  readStoreFile<label>(io, ioNew)
304  || readStoreFile<scalar>(io, ioNew)
305  || readStoreFile<vector>(io, ioNew)
306  || readStoreFile<sphericalTensor>(io, ioNew)
307  || readStoreFile<symmTensor>(io, ioNew)
308  || readStoreFile<tensor>(io, ioNew)
309  );
310 
311  if (!stored)
312  {
313  DebugInfo
314  << "Unhandled field:" << fldName
315  << " type:" << io.headerClassName() << endl;
316  }
317  }
318 }
319 
320 
321 template<class ParticleType>
323 {
325 }
326 
327 
328 template<class ParticleType>
330 (
331  IOstreamOption streamOpt,
332  const bool
333 ) const
334 {
335  writeCloudUniformProperties();
336 
337  writeFields();
338  return cloud::writeObject(streamOpt, this->size());
339 }
340 
341 
342 // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
343 
344 template<class ParticleType>
345 Foam::Ostream& Foam::operator<<(Ostream& os, const Cloud<ParticleType>& c)
346 {
347  c.writeData(os);
348 
349  os.check(FUNCTION_NAME);
350  return os;
351 }
352 
353 
354 // ************************************************************************* //
void readFromFiles(objectRegistry &obr, const wordRes &selectFields, const wordRes &excludeFields=wordRes::null()) const
Read from files into objectRegistry.
Definition: CloudIO.C:260
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
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:578
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:150
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
void checkFieldFieldIOobject(const Cloud< ParticleType > &c, const CompactIOField< Field< DataType >, DataType > &data) const
Check lagrangian data fieldfield.
Definition: CloudIO.C:223
Cloud(const polyMesh &mesh, const word &cloudName, const IDLList< ParticleType > &particles)
Construct from mesh and a list of particles.
Definition: Cloud.C:66
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
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:242
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:413
word timeName
Definition: getTimeIndex.H:3
wordRes excludeFields
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: CloudIO.C:323
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
const word cloudName(propsDict.get< word >("cloud"))
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:210
A cloud is a registry collection of lagrangian particles.
Definition: cloud.H:53
IOobject fieldIOobject(const word &fieldName, IOobjectOption::readOption rOpt) const
Helper to construct IOobject for field and current time.
Definition: CloudIO.C:184
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:47
const word & name() const
Name function is needed to disambiguate those inherited from regIOobject and dictionary.
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:55
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
Database for solution data, solver performance and other reduced data.
Definition: data.H:51
virtual void writeFields() const
Write the field data for the cloud of particles Dummy at.
Definition: CloudIO.C:315
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.
void checkFieldIOobject(const Cloud< ParticleType > &c, const IOField< DataType > &data) const
Check lagrangian data field.
Definition: CloudIO.C:204
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
List< label > labelList
A List of labels.
Definition: List.H:62
Registry of regIOobjects.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:166
A primitive field of type <T> with automated input and output.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157
readOption
Enumeration defining read preferences.