KinematicParcelIO.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 OpenFOAM Foundation
9  Copyright (C) 2016-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 "KinematicParcel.H"
30 #include "IOstreams.H"
31 #include "IOField.H"
32 #include "Cloud.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 template<class ParcelType>
39 
40 
41 template<class ParcelType>
43 (
44  sizeof(KinematicParcel<ParcelType>)
45  - offsetof(KinematicParcel<ParcelType>, active_)
46 );
47 
48 
49 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
50 
51 template<class ParcelType>
53 (
54  const polyMesh& mesh,
55  Istream& is,
56  bool readFields,
57  bool newFormat
58 )
59 :
60  ParcelType(mesh, is, readFields, newFormat),
61  active_(false),
62  typeId_(0),
63  nParticle_(0.0),
64  d_(0.0),
65  dTarget_(0.0),
66  U_(Zero),
67  rho_(0.0),
68  age_(0.0),
69  tTurb_(0.0),
70  UTurb_(Zero),
71  UCorrect_(Zero)
72 {
73  if (readFields)
74  {
75  if (is.format() == IOstreamOption::ASCII)
76  {
77  is >> active_
78  >> typeId_
79  >> nParticle_
80  >> d_
81  >> dTarget_
82  >> U_
83  >> rho_
84  >> age_
85  >> tTurb_
86  >> UTurb_
87  >> UCorrect_;
88  }
89  else if (!is.checkLabelSize<>() || !is.checkScalarSize<>())
90  {
91  // Non-native label or scalar size
92 
93  is.beginRawRead();
94 
95  readRawLabel(is, &active_);
96  readRawLabel(is, &typeId_);
97  readRawScalar(is, &nParticle_);
98  readRawScalar(is, &d_);
99  readRawScalar(is, &dTarget_);
100  readRawScalar(is, U_.data(), vector::nComponents);
101  readRawScalar(is, &rho_);
102  readRawScalar(is, &age_);
103  readRawScalar(is, &tTurb_);
104  readRawScalar(is, UTurb_.data(), vector::nComponents);
105  readRawScalar(is, UCorrect_.data(), vector::nComponents);
106 
107  is.endRawRead();
108  }
109  else
110  {
111  is.read(reinterpret_cast<char*>(&active_), sizeofFields);
112  }
113  }
115  is.check(FUNCTION_NAME);
116 }
117 
118 
119 template<class ParcelType>
120 template<class CloudType>
122 {
123  const bool readOnProc = c.size();
124 
126 
127  IOField<label> active
128  (
129  c.fieldIOobject("active", IOobject::MUST_READ),
130  readOnProc
131  );
132  c.checkFieldIOobject(c, active);
133 
134  IOField<label> typeId
135  (
136  c.fieldIOobject("typeId", IOobject::MUST_READ),
137  readOnProc
138  );
139  c.checkFieldIOobject(c, typeId);
140 
141  IOField<scalar> nParticle
142  (
143  c.fieldIOobject("nParticle", IOobject::MUST_READ),
144  readOnProc
145  );
146  c.checkFieldIOobject(c, nParticle);
147 
149  (
150  c.fieldIOobject("d", IOobject::MUST_READ),
151  readOnProc
152  );
153  c.checkFieldIOobject(c, d);
154 
155  IOField<scalar> dTarget
156  (
157  c.fieldIOobject("dTarget", IOobject::MUST_READ),
158  readOnProc
159  );
160  c.checkFieldIOobject(c, dTarget);
161 
163  (
164  c.fieldIOobject("U", IOobject::MUST_READ),
165  readOnProc
166  );
167  c.checkFieldIOobject(c, U);
168 
170  (
171  c.fieldIOobject("rho", IOobject::MUST_READ),
172  readOnProc
173  );
174  c.checkFieldIOobject(c, rho);
175 
176  IOField<scalar> age
177  (
178  c.fieldIOobject("age", IOobject::MUST_READ),
179  readOnProc
180  );
181  c.checkFieldIOobject(c, age);
182 
183  IOField<scalar> tTurb
184  (
185  c.fieldIOobject("tTurb", IOobject::MUST_READ),
186  readOnProc
187  );
188  c.checkFieldIOobject(c, tTurb);
189 
190  IOField<vector> UTurb
191  (
192  c.fieldIOobject("UTurb", IOobject::MUST_READ),
193  readOnProc
194  );
195  c.checkFieldIOobject(c, UTurb);
196 
197  IOField<vector> UCorrect
198  (
199  c.fieldIOobject("UCorrect", IOobject::MUST_READ),
200  readOnProc
201  );
202  c.checkFieldIOobject(c, UCorrect);
203 
204  label i = 0;
205 
207  {
208  p.active_ = active[i];
209  p.typeId_ = typeId[i];
210  p.nParticle_ = nParticle[i];
211  p.d_ = d[i];
212  p.dTarget_ = dTarget[i];
213  p.U_ = U[i];
214  p.rho_ = rho[i];
215  p.age_ = age[i];
216  p.tTurb_ = tTurb[i];
217  p.UTurb_ = UTurb[i];
218  p.UCorrect_ = UCorrect[i];
219 
220  ++i;
221  }
222 }
223 
224 
225 template<class ParcelType>
226 template<class CloudType>
228 {
230 
231  const label np = c.size();
232  const bool writeOnProc = c.size();
233 
234  IOField<label> active(c.fieldIOobject("active", IOobject::NO_READ), np);
235  IOField<label> typeId(c.fieldIOobject("typeId", IOobject::NO_READ), np);
236  IOField<scalar> nParticle
237  (
238  c.fieldIOobject("nParticle", IOobject::NO_READ),
239  np
240  );
241  IOField<scalar> d(c.fieldIOobject("d", IOobject::NO_READ), np);
242  IOField<scalar> dTarget(c.fieldIOobject("dTarget", IOobject::NO_READ), np);
243  IOField<vector> U(c.fieldIOobject("U", IOobject::NO_READ), np);
244  IOField<scalar> rho(c.fieldIOobject("rho", IOobject::NO_READ), np);
245  IOField<scalar> age(c.fieldIOobject("age", IOobject::NO_READ), np);
246  IOField<scalar> tTurb(c.fieldIOobject("tTurb", IOobject::NO_READ), np);
247  IOField<vector> UTurb(c.fieldIOobject("UTurb", IOobject::NO_READ), np);
248  IOField<vector> UCorrect(c.fieldIOobject("UCorrect", IOobject::NO_READ), np);
249 
250  label i = 0;
251 
252  for (const KinematicParcel<ParcelType>& p : c)
253  {
254  active[i] = p.active();
255  typeId[i] = p.typeId();
256  nParticle[i] = p.nParticle();
257  d[i] = p.d();
258  dTarget[i] = p.dTarget();
259  U[i] = p.U();
260  rho[i] = p.rho();
261  age[i] = p.age();
262  tTurb[i] = p.tTurb();
263  UTurb[i] = p.UTurb();
264  UCorrect[i] = p.UCorrect();
265 
266  ++i;
267  }
268 
269  active.write(writeOnProc);
270  typeId.write(writeOnProc);
271  nParticle.write(writeOnProc);
272  d.write(writeOnProc);
273  dTarget.write(writeOnProc);
274  U.write(writeOnProc);
275  rho.write(writeOnProc);
276  age.write(writeOnProc);
277  tTurb.write(writeOnProc);
278  UTurb.write(writeOnProc);
279  UCorrect.write(writeOnProc);
280 }
281 
282 
283 template<class ParcelType>
285 (
286  Ostream& os,
287  const wordRes& filters,
288  const word& delim,
289  const bool namesOnly
290 ) const
291 {
292  ParcelType::writeProperties(os, filters, delim, namesOnly);
293 
294  #undef writeProp
295  #define writeProp(Name, Value) \
296  ParcelType::writeProperty(os, Name, Value, namesOnly, delim, filters)
297 
298  writeProp("active", active_);
299  writeProp("typeId", typeId_);
300  writeProp("nParticle", nParticle_);
301  writeProp("d", d_);
302  writeProp("dTarget", dTarget_);
303  writeProp("U", U_);
304  writeProp("rho", rho_);
305  writeProp("age", age_);
306  writeProp("tTurb", tTurb_);
307  writeProp("UTurb", UTurb_);
308  writeProp("UCorrect", UCorrect_);
309 
310  #undef writeProp
311 }
312 
313 
314 template<class ParcelType>
315 template<class CloudType>
317 (
318  CloudType& c,
319  const objectRegistry& obr
320 )
321 {
322  ParcelType::readObjects(c, obr);
323 
324  if (!c.size()) return;
325 
326  const auto& active = cloud::lookupIOField<label>("active", obr);
327  const auto& typeId = cloud::lookupIOField<label>("typeId", obr);
328  const auto& nParticle = cloud::lookupIOField<scalar>("nParticle", obr);
329  const auto& d = cloud::lookupIOField<scalar>("d", obr);
330  const auto& dTarget = cloud::lookupIOField<scalar>("dTarget", obr);
331  const auto& U = cloud::lookupIOField<vector>("U", obr);
332  const auto& rho = cloud::lookupIOField<scalar>("rho", obr);
333  const auto& age = cloud::lookupIOField<scalar>("age", obr);
334  const auto& tTurb = cloud::lookupIOField<scalar>("tTurb", obr);
335  const auto& UTurb = cloud::lookupIOField<vector>("UTurb", obr);
336  const auto& UCorrect = cloud::lookupIOField<vector>("UCorrect", obr);
337 
338  label i = 0;
339 
341  {
342  p.active_ = active[i];
343  p.typeId_ = typeId[i];
344  p.nParticle_ = nParticle[i];
345  p.d_ = d[i];
346  p.dTarget_ = dTarget[i];
347  p.U_ = U[i];
348  p.rho_ = rho[i];
349  p.age_ = age[i];
350  p.tTurb_ = tTurb[i];
351  p.UTurb_ = UTurb[i];
352  p.UCorrect_ = UCorrect[i];
353 
354  ++i;
355  }
356 }
357 
358 
359 template<class ParcelType>
360 template<class CloudType>
362 (
363  const CloudType& c,
364  objectRegistry& obr
365 )
366 {
367  ParcelType::writeObjects(c, obr);
368 
369  const label np = c.size();
370 
371  auto& active = cloud::createIOField<label>("active", np, obr);
372  auto& typeId = cloud::createIOField<label>("typeId", np, obr);
373  auto& nParticle = cloud::createIOField<scalar>("nParticle", np, obr);
374  auto& d = cloud::createIOField<scalar>("d", np, obr);
375  auto& dTarget = cloud::createIOField<scalar>("dTarget", np, obr);
376  auto& U = cloud::createIOField<vector>("U", np, obr);
377  auto& rho = cloud::createIOField<scalar>("rho", np, obr);
378  auto& age = cloud::createIOField<scalar>("age", np, obr);
379  auto& tTurb = cloud::createIOField<scalar>("tTurb", np, obr);
380  auto&& UTurb = cloud::createIOField<vector>("UTurb", np, obr);
381  auto&& UCorrect = cloud::createIOField<vector>("UCorrect", np, obr);
382 
383  label i = 0;
384 
385  for (const KinematicParcel<ParcelType>& p : c)
386  {
387  active[i] = p.active();
388  typeId[i] = p.typeId();
389  nParticle[i] = p.nParticle();
390  d[i] = p.d();
391  dTarget[i] = p.dTarget();
392  U[i] = p.U();
393  rho[i] = p.rho();
394  age[i] = p.age();
395  tTurb[i] = p.tTurb();
396  UTurb[i] = p.UTurb();
397  UCorrect[i] = p.UCorrect();
398 
399  ++i;
400  }
401 }
402 
403 
404 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
405 
406 template<class ParcelType>
407 Foam::Ostream& Foam::operator<<
408 (
409  Ostream& os,
410  const KinematicParcel<ParcelType>& p
411 )
412 {
414  {
415  os << static_cast<const ParcelType&>(p)
416  << token::SPACE << bool(p.active())
417  << token::SPACE << p.typeId()
418  << token::SPACE << p.nParticle()
419  << token::SPACE << p.d()
420  << token::SPACE << p.dTarget()
421  << token::SPACE << p.U()
422  << token::SPACE << p.rho()
423  << token::SPACE << p.age()
424  << token::SPACE << p.tTurb()
425  << token::SPACE << p.UTurb()
426  << token::SPACE << p.UCorrect();
427  }
428  else
429  {
430  os << static_cast<const ParcelType&>(p);
431  os.write
432  (
433  reinterpret_cast<const char*>(&p.active_),
435  );
436  }
437 
439  return os;
440 }
441 
442 
443 // ************************************************************************* //
static void writeFields(const TrackCloudType &c)
Write.
DSMCCloud< dsmcParcel > CloudType
std::enable_if< std::is_floating_point< T >::value, bool >::type checkScalarSize() const noexcept
Check if the scalar byte-size associated with the stream is the same as the given type...
Definition: IOstream.H:379
virtual Ostream & write(const char c) override
Write character.
Definition: OBJstream.C:69
Kinematic parcel class with rotational motion (as spherical particles only) and one/two-way coupling ...
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
"ascii" (normal default)
scalar tTurb_
Time spent in turbulent eddy [s].
scalar age_
Age [s].
#define writeProp(Name, Value)
virtual bool endRawRead()=0
End of low-level raw binary read.
::Foam::direction nComponents(const expressions::valueTypeCode) noexcept
The number of components associated with given valueTypeCode.
Definition: exprTraits.C:40
KinematicParcel(const polyMesh &mesh, const barycentric &coordinates, const label celli, const label tetFacei, const label tetPti)
Construct from mesh, coordinates and topology.
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
scalar dTarget_
Target diameter [m].
virtual Istream & read(token &)=0
Return next token from stream.
dynamicFvMesh & mesh
scalar rho_
Density [kg/m3].
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const NameMatchPredicate &selectedFields, DynamicList< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type and store on the objectRegistry.
A class for handling words, derived from Foam::string.
Definition: word.H:63
static void writeObjects(const CloudType &c, objectRegistry &obr)
Write particle fields as objects into the obr registry.
label typeId_
Parcel type id.
Space [isspace].
Definition: token.H:131
void writeProperties(Ostream &os, const wordRes &filters, const word &delim, const bool namesOnly=false) const
Write individual parcel properties to stream.
vector UTurb_
Turbulent velocity fluctuation [m/s].
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
static void readFields(TrackCloudType &c)
Read.
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
static const std::size_t sizeofFields
Size in bytes of the fields.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
static void readObjects(CloudType &c, const objectRegistry &obr)
Read particle fields as objects from the obr registry.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
scalar nParticle_
Number of particles in Parcel.
label readRawLabel(Istream &is)
Read raw label from binary stream.
Definition: label.C:39
vector U_
Velocity of Parcel [m/s].
U
Definition: pEqn.H:72
virtual bool beginRawRead()=0
Start of low-level raw binary read.
const dimensionedScalar c
Speed of light in a vacuum.
Nothing to be read.
std::enable_if< std::is_integral< T >::value, bool >::type checkLabelSize() const noexcept
Check if the label byte-size associated with the stream is the same as the given type.
Definition: IOstream.H:368
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
label active_
Active flag - tracking inactive when active = false.
volScalarField & p
Registry of regIOobjects.
A class for handling character strings derived from std::string.
Definition: string.H:72
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:67
A primitive field of type <T> with automated input and output.
streamFormat format() const noexcept
Get the current stream format.
scalar d_
Diameter [m].
vector UCorrect_
Velocity correction due to collisions MPPIC [m/s].
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127