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-2021 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  false
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  false
101  )
102  );
103 
104  labelList np(Pstream::nProcs(), Zero);
105  np[Pstream::myProcNo()] = ParticleType::particleCount_;
106 
107  Pstream::listCombineGather(np, maxEqOp<label>());
108  Pstream::listCombineScatter(np);
109 
110  uniformPropsDict.add
111  (
112  "geometry",
113  cloud::geometryTypeNames[geometryType_]
114  );
115 
116  forAll(np, i)
117  {
118  word procName("processor" + Foam::name(i));
119  uniformPropsDict.add(procName, dictionary());
120  uniformPropsDict.subDict(procName).add("particleCount", np[i]);
121  }
122 
123  uniformPropsDict.writeObject
124  (
125  IOstreamOption(IOstream::ASCII, time().writeCompression()),
126  true
127  );
128 }
129 
130 
131 template<class ParticleType>
132 void Foam::Cloud<ParticleType>::initCloud(const bool checkClass)
133 {
134  readCloudUniformProperties();
135 
136  IOPosition<Cloud<ParticleType>> ioP(*this, geometryType_);
137 
138  const bool valid = ioP.headerOk();
139  Istream& is = ioP.readStream(checkClass ? typeName : "", valid);
140  if (valid)
141  {
142  ioP.readData(is, *this);
143  ioP.close();
144  }
145 
146  if (!valid && debug)
147  {
148  Pout<< "Cannot read particle positions file:" << nl
149  << " " << ioP.objectPath() << nl
150  << "Assuming the initial cloud contains 0 particles." << endl;
151  }
152 
153  // Always operate in coordinates mode after reading
154  geometryType_ = cloud::geometryType::COORDINATES;
155 
156  // Ask for the tetBasePtIs to trigger all processors to build
157  // them, otherwise, if some processors have no particles then
158  // there is a comms mismatch.
159  polyMesh_.tetBasePtIs();
160 }
161 
162 
163 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
164 
165 template<class ParticleType>
167 (
168  const polyMesh& pMesh,
169  const word& cloudName,
170  const bool checkClass
171 )
172 :
173  cloud(pMesh, cloudName),
174  polyMesh_(pMesh),
175  labels_(),
176  cellWallFacesPtr_(),
177  geometryType_(cloud::geometryType::COORDINATES)
178 {
179  checkPatches();
180 
181  polyMesh_.tetBasePtIs();
182  polyMesh_.oldCellCentres();
183 
184  initCloud(checkClass);
185 }
186 
187 
188 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
189 
190 template<class ParticleType>
192 (
193  const word& fieldName,
194  const IOobject::readOption r
195 ) const
196 {
197  return IOobject
198  (
199  fieldName,
200  time().timeName(),
201  *this,
202  r,
203  IOobject::NO_WRITE,
204  false
205  );
206 }
207 
208 
209 template<class ParticleType>
210 template<class DataType>
212 (
213  const Cloud<ParticleType>& c,
214  const IOField<DataType>& data
215 ) const
216 {
217  if (data.size() != c.size())
218  {
220  << "Size of " << data.name()
221  << " field " << data.size()
222  << " does not match the number of particles " << c.size()
223  << abort(FatalError);
224  }
225 }
226 
227 
228 template<class ParticleType>
229 template<class DataType>
231 (
232  const Cloud<ParticleType>& c,
233  const CompactIOField<Field<DataType>, DataType>& data
234 ) const
235 {
236  if (data.size() != c.size())
237  {
239  << "Size of " << data.name()
240  << " field " << data.size()
241  << " does not match the number of particles " << c.size()
242  << abort(FatalError);
243  }
244 }
245 
246 
247 template<class ParticleType>
248 template<class Type>
250 (
251  const IOobject& io,
252  const IOobject& ioNew
253 ) const
254 {
256  {
257  IOField<Type> fld(io);
258  auto* fldNewPtr = new IOField<Type>(ioNew, std::move(fld));
259  return fldNewPtr->store();
260  }
261 
262  return false;
263 }
264 
265 
266 template<class ParticleType>
268 (
269  objectRegistry& obr,
270  const wordRes& selectFields
271 ) const
272 {
273  IOobjectList cloudObjects
274  (
275  *this,
276  time().timeName(),
277  "",
278  IOobject::MUST_READ,
279  IOobject::NO_WRITE,
280  false
281  );
282 
283  forAllIters(cloudObjects, iter)
284  {
285  if (selectFields.size() && !selectFields.match(iter()->name()))
286  {
287  continue;
288  }
289 
290  IOobject ioNew
291  (
292  iter()->name(),
293  time().timeName(),
294  obr,
295  IOobject::NO_READ,
296  IOobject::NO_WRITE
297  );
298 
299  auto& object = *iter();
300 
301  const bool stored
302  (
303  readStoreFile<label>(object, ioNew)
304  || readStoreFile<scalar>(object, ioNew)
305  || readStoreFile<vector>(object, ioNew)
306  || readStoreFile<sphericalTensor>(object, ioNew)
307  || readStoreFile<symmTensor>(object, ioNew)
308  || readStoreFile<tensor>(object, ioNew)
309  );
310 
311  if (!stored)
312  {
313  DebugInfo
314  << "Unhandled field type " << iter()->headerClassName()
315  << 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>
346 {
347  c.writeData(os);
348 
349  os.check(FUNCTION_NAME);
350  return os;
351 }
352 
353 
354 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
IOPosition.H
Foam::Cloud::writeFields
virtual void writeFields() const
Write the field data for the cloud of particles Dummy at.
Definition: CloudIO.C:322
cloudName
const word cloudName(propsDict.get< word >("cloud"))
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::IOField
A primitive field of type <T> with automated input and output.
Definition: foamVtkLagrangianWriter.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::Cloud::readStoreFile
bool readStoreFile(const IOobject &io, const IOobject &ioNew) const
Helper function to store a cloud field on its registry.
Definition: CloudIO.C:250
Foam::Cloud::checkFieldIOobject
void checkFieldIOobject(const Cloud< ParticleType > &c, const IOField< DataType > &data) const
Check lagrangian data field.
Definition: CloudIO.C:212
Cloud.H
IOobjectList.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::CompactIOField
A Field of objects of type <T> with automated input and output using a compact storage....
Definition: CompactIOField.H:53
Foam::IOobject::headerClassName
const word & headerClassName() const noexcept
Return name of the class name read from header.
Definition: IOobjectI.H:83
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::baseIOdictionary::name
const word & name() const
Definition: baseIOdictionary.C:85
Foam::Cloud::fieldIOobject
IOobject fieldIOobject(const word &fieldName, const IOobject::readOption r) const
Helper to construct IOobject for field and current time.
Definition: CloudIO.C:192
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::wordRes::match
bool match(const std::string &text, bool literal=false) const
Smart match as literal or regex, stopping on the first match.
Definition: wordResI.H:91
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::Cloud::cloudPropertiesName
static word cloudPropertiesName
Name of cloud properties dictionary.
Definition: Cloud.H:127
Foam::Cloud::readFromFiles
void readFromFiles(objectRegistry &obr, const wordRes &selectFields) const
Read from files into objectRegistry.
Definition: CloudIO.C:268
fld
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))
Definition: gmvOutputLagrangian.H:23
forAllIters
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:223
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::IOobjectList
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:55
IOdictionary.H
Time.H
Foam::cloud
A cloud is a registry collection of lagrangian particles.
Definition: cloud.H:57
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:382
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Cloud
Base cloud calls templated on particle type.
Definition: Cloud.H:55
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::Cloud::Cloud
Cloud(const polyMesh &mesh, const word &cloudName, const IDLList< ParticleType > &particles)
Construct from mesh and a list of particles.
Definition: Cloud.C:73
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::IOobject::readOption
readOption
Enumeration defining the read options.
Definition: IOobject.H:183
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:55
Foam::writeFields
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
Foam::Cloud::checkFieldFieldIOobject
void checkFieldFieldIOobject(const Cloud< ParticleType > &c, const CompactIOField< Field< DataType >, DataType > &data) const
Check lagrangian data fieldfield.
Definition: CloudIO.C:231
Foam::Cloud::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: CloudIO.C:330