ENH: Added new particleZoneInfo cloud function object.
Reports cloud information for particles passing through a specified cell zone. Example usage: cloudFunctions { particleZoneInfo1 { type particleZoneInfo; cellZone leftFluid; // Optional entries //writer vtk; } } Results are written to file: - \<case\>/postProcessing/lagrangian/\<cloudName\>/\<functionName\>/\<time\> \# cellZone : leftFluid \# time : 1.0000000000e+00 \# \# origID origProc (x y z) time0 age d0 d mass0 mass Where - origID : particle ID - origProc : processor ID - (x y z) : Cartesian co-ordinates - time0 : time particle enters the cellZone - age : time spent in the cellZone - d0 : diameter on entry to the cellZone - d : current diameter - mass0 : mass on entry to the cellZone - mass : current mass If the optional \c writer entry is supplied, cloud data is written in the specified format. During the run, output statistics are reported after the cloud solution, e.g.: particleZoneInfo: Cell zone = leftFluid Contributions = 257 Here, 'Contributions' refers to the number of incremental particle-move contributions recorded during this time step. At write times, the output is extended, e.g.: particleZoneInfo: Cell zone = leftFluid Contributions = 822 Number of particles = 199 Written data to "postProcessing/lagrangian/reactingCloud1/ TUT: filter: add an example for the particleZoneInfo function object
This commit is contained in:
parent
8d90b16518
commit
5cb0dc9d8a
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,7 @@ License
|
||||
#include "ParticleErosion.H"
|
||||
#include "ParticleTracks.H"
|
||||
#include "ParticleTrap.H"
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "PatchCollisionDensity.H"
|
||||
#include "PatchInteractionFields.H"
|
||||
#include "PatchPostProcessing.H"
|
||||
@ -57,6 +58,7 @@ License
|
||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleZoneInfo, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchInteractionFields, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,7 @@ License
|
||||
#include "ParticleErosion.H"
|
||||
#include "ParticleTracks.H"
|
||||
#include "ParticleTrap.H"
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "PatchCollisionDensity.H"
|
||||
#include "PatchInteractionFields.H"
|
||||
#include "PatchPostProcessing.H"
|
||||
@ -60,6 +61,7 @@ License
|
||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleZoneInfo, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchInteractionFields, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,6 +36,7 @@ License
|
||||
#include "ParticleErosion.H"
|
||||
#include "ParticleTracks.H"
|
||||
#include "ParticleTrap.H"
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "PatchCollisionDensity.H"
|
||||
#include "PatchInteractionFields.H"
|
||||
#include "PatchPostProcessing.H"
|
||||
@ -58,6 +59,7 @@ License
|
||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleZoneInfo, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchInteractionFields, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||
|
@ -0,0 +1,458 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "DynamicField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
struct particleInfoCombineOp
|
||||
{
|
||||
void operator()(particleInfo& p1, const particleInfo& p2) const
|
||||
{
|
||||
// p2 not set
|
||||
if (p2.origID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// p1 not set - initialise with p2
|
||||
if (p1.origID == -1)
|
||||
{
|
||||
p1 = p2;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set initial values
|
||||
if (p2.time0 < p1.time0)
|
||||
{
|
||||
p1.time0 = p2.time0;
|
||||
p1.d0 = p2.d0;
|
||||
p1.mass0 = p2.mass0;
|
||||
}
|
||||
|
||||
// Accumulate age
|
||||
p1.age += p2.age;
|
||||
|
||||
// Set latest available values
|
||||
if (p2.isOlderThan(p1))
|
||||
{
|
||||
p1.position = p2.position;
|
||||
p1.d = p2.d;
|
||||
p1.mass = p2.mass;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Field<Type> getData
|
||||
(
|
||||
const Foam::UList<Foam::particleInfo>& data,
|
||||
Type Foam::particleInfo::* field
|
||||
)
|
||||
{
|
||||
Field<Type> result(data.size());
|
||||
|
||||
forAll(data, i)
|
||||
{
|
||||
result[i] = data[i].*field;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::Field<Type> getParData
|
||||
(
|
||||
const Foam::List<Foam::List<Foam::particleInfo>>& parData,
|
||||
Type Foam::particleInfo::* field
|
||||
)
|
||||
{
|
||||
DynamicField<Type> result;
|
||||
|
||||
for (const auto& particles : parData)
|
||||
{
|
||||
for (const auto& p : particles)
|
||||
{
|
||||
if (p.origID != -1)
|
||||
{
|
||||
result.append(p.*field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::writeWriter
|
||||
(
|
||||
const DynamicList<particleInfo>& data
|
||||
)
|
||||
{
|
||||
coordSet coords
|
||||
(
|
||||
"zoneParticles",
|
||||
"xyz",
|
||||
getData(data_, &particleInfo::position),
|
||||
scalarList(data.size(), Zero)
|
||||
);
|
||||
|
||||
writerPtr_->open(coords, this->baseTimeDir() / "zoneParticles");
|
||||
writerPtr_->beginTime(this->owner().time());
|
||||
|
||||
#undef writeLocal
|
||||
#define writeLocal(field) \
|
||||
writerPtr_->write(#field, getData(data, &particleInfo::field));
|
||||
|
||||
writeLocal(origID);
|
||||
writeLocal(origProc);
|
||||
writeLocal(time0);
|
||||
writeLocal(age);
|
||||
writeLocal(d0);
|
||||
writeLocal(d);
|
||||
writeLocal(mass0);
|
||||
writeLocal(mass);
|
||||
#undef writeLocal
|
||||
|
||||
writerPtr_->endTime();
|
||||
writerPtr_->close();
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::writeWriter
|
||||
(
|
||||
const List<List<particleInfo>>& procData
|
||||
)
|
||||
{
|
||||
vectorField points(getParData(procData, &particleInfo::position));
|
||||
|
||||
coordSet coords
|
||||
(
|
||||
"zoneParticles",
|
||||
"xyz",
|
||||
std::move(points),
|
||||
scalarList(points.size(), Zero)
|
||||
);
|
||||
|
||||
writerPtr_->open(coords, this->baseTimeDir() / "zoneParticles");
|
||||
writerPtr_->beginTime(this->owner().time());
|
||||
|
||||
#undef writeLocal
|
||||
#define writeLocal(field) \
|
||||
writerPtr_->write(#field, getParData(procData, &particleInfo::field));
|
||||
|
||||
writeLocal(origID);
|
||||
writeLocal(origProc);
|
||||
writeLocal(time0);
|
||||
writeLocal(age);
|
||||
writeLocal(d0);
|
||||
writeLocal(d);
|
||||
writeLocal(mass0);
|
||||
writeLocal(mass);
|
||||
#undef writeLocal
|
||||
|
||||
writerPtr_->endTime();
|
||||
writerPtr_->close();
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::writeFileHeader(Ostream& os) const
|
||||
{
|
||||
this->writeHeaderValue(os, "cellZone", cellZoneName_);
|
||||
this->writeHeaderValue(os, "time", this->owner().time().timeOutputValue());
|
||||
this->writeHeader(os, "");
|
||||
this->writeCommented(os, "origID");
|
||||
os << tab << "origProc"
|
||||
<< tab << "(x y z)"
|
||||
<< tab << "time0"
|
||||
<< tab << "age"
|
||||
<< tab << "d0"
|
||||
<< tab << "d"
|
||||
<< tab << "mass0"
|
||||
<< tab << "mass"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
bool Foam::ParticleZoneInfo<CloudType>::inZone(const label celli) const
|
||||
{
|
||||
return this->owner().mesh().cellZones()[cellZoneId_].whichCell(celli) != -1;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::label Foam::ParticleZoneInfo<CloudType>::getParticleID
|
||||
(
|
||||
const particleInfo& p
|
||||
) const
|
||||
{
|
||||
forAll(data_, i)
|
||||
{
|
||||
const auto& d = data_[i];
|
||||
if ((d.origProc == p.origProc) && (d.origID == p.origID))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ParticleZoneInfo<CloudType>::ParticleZoneInfo
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner,
|
||||
const word& modelName
|
||||
)
|
||||
:
|
||||
CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
|
||||
functionObjects::writeFile
|
||||
(
|
||||
owner,
|
||||
this->localPath(),
|
||||
typeName,
|
||||
this->coeffDict()
|
||||
),
|
||||
cellZoneName_(this->coeffDict().getWord("cellZone")),
|
||||
cellZoneId_(-1),
|
||||
data_(),
|
||||
movedParticles_(),
|
||||
maxIDs_(Pstream::nProcs(), Zero),
|
||||
writerPtr_
|
||||
(
|
||||
Pstream::master()
|
||||
? coordSetWriter::New
|
||||
(
|
||||
this->coeffDict().getWord("writer"),
|
||||
this->coeffDict().subOrEmptyDict("formatOptions")
|
||||
)
|
||||
: nullptr
|
||||
)
|
||||
{
|
||||
const auto& cellZones = owner.mesh().cellZones();
|
||||
|
||||
cellZoneId_ = cellZones.findZoneID(cellZoneName_);
|
||||
if (cellZoneId_ == -1)
|
||||
{
|
||||
FatalIOErrorInFunction(this->coeffDict())
|
||||
<< "Unable to find cellZone " << cellZoneName_
|
||||
<< ". Available cellZones are:" << cellZones.names()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
Info<< " Processing cellZone" << cellZoneName_ << " with id "
|
||||
<< cellZoneId_ << endl;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ParticleZoneInfo<CloudType>::ParticleZoneInfo
|
||||
(
|
||||
const ParticleZoneInfo<CloudType>& pzi
|
||||
)
|
||||
:
|
||||
CloudFunctionObject<CloudType>(pzi),
|
||||
writeFile(pzi),
|
||||
cellZoneName_(pzi.cellZoneName_),
|
||||
cellZoneId_(pzi.cellZoneId_),
|
||||
data_(pzi.data_),
|
||||
movedParticles_(pzi.movedParticles_),
|
||||
maxIDs_(Pstream::nProcs()),
|
||||
writerPtr_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::preEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::postEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
)
|
||||
{
|
||||
Info<< this->type() << ":" << nl
|
||||
<< " Cell zone = " << cellZoneName_ << nl
|
||||
<< " Contributions = "
|
||||
<< returnReduce(movedParticles_.size(), sumOp<label>())
|
||||
<< endl;
|
||||
|
||||
if (!this->writeTime())
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
for (const auto& p : movedParticles_)
|
||||
{
|
||||
const label id = getParticleID(p);
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
// New particle
|
||||
data_.append(p);
|
||||
maxIDs_[p.origProc] = max(maxIDs_[p.origProc], p.origID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add to existing particle
|
||||
data_[id] += p;
|
||||
}
|
||||
}
|
||||
|
||||
movedParticles_.clear();
|
||||
|
||||
// Calls write
|
||||
CloudFunctionObject<CloudType>::postEvolve(td);
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::postMove
|
||||
(
|
||||
parcelType& p,
|
||||
const scalar dt,
|
||||
const point&,
|
||||
bool&
|
||||
)
|
||||
{
|
||||
if (inZone(p.cell()))
|
||||
{
|
||||
particleInfo newData;
|
||||
newData.origID = p.origId();
|
||||
newData.origProc = p.origProc();
|
||||
newData.position = p.position();
|
||||
newData.time0 = this->owner().time().value() + dt;
|
||||
newData.age = dt;
|
||||
newData.d0 = p.d();
|
||||
newData.d = p.d();
|
||||
newData.mass0 = p.mass();
|
||||
newData.mass = newData.mass0;
|
||||
|
||||
movedParticles_.append(newData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::write()
|
||||
{
|
||||
autoPtr<OFstream> osPtr =
|
||||
this->createFile("particles", this->owner().time().timeOutputValue());
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
// Find number of particles per proc
|
||||
labelList allMaxIDs(maxIDs_);
|
||||
Pstream::listCombineGather(allMaxIDs, maxEqOp<label>());
|
||||
Pstream::scatterList(allMaxIDs);
|
||||
|
||||
List<List<particleInfo>> procParticles(Pstream::nProcs());
|
||||
forAll(procParticles, proci)
|
||||
{
|
||||
procParticles[proci].resize(allMaxIDs[proci] + 1);
|
||||
}
|
||||
|
||||
// Insert into bins for accumulation
|
||||
for (const auto& d : data_)
|
||||
{
|
||||
procParticles[d.origProc][d.origID] = d;
|
||||
}
|
||||
|
||||
for (auto& particles : procParticles)
|
||||
{
|
||||
Pstream::listCombineGather(particles, particleInfoCombineOp());
|
||||
}
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
writeWriter(procParticles);
|
||||
|
||||
auto& os = osPtr();
|
||||
writeFileHeader(os);
|
||||
|
||||
label nData = 0;
|
||||
for (const auto& particles : procParticles)
|
||||
{
|
||||
for (const auto& p : particles)
|
||||
{
|
||||
if (p.origID != -1)
|
||||
{
|
||||
os << p << endl;
|
||||
++nData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< " Number of particles = " << nData << nl
|
||||
<< " Written data to " << os.name() << endl;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeWriter(data_);
|
||||
|
||||
auto& os = osPtr();
|
||||
writeFileHeader(os);
|
||||
|
||||
for (const auto& p : data_)
|
||||
{
|
||||
os << p << nl;
|
||||
}
|
||||
|
||||
Info<< " Number of particles = " << data_.size() << nl
|
||||
<< " Written data to " << os.name() << endl;
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,334 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::ParticleZoneInfo
|
||||
|
||||
Group
|
||||
grpLagrangianIntermediateFunctionObjects
|
||||
|
||||
Description
|
||||
Reports cloud information for particles passing through a specified cell
|
||||
zone.
|
||||
|
||||
Usage
|
||||
Example usage:
|
||||
\verbatim
|
||||
cloudFunctions
|
||||
{
|
||||
particleZoneInfo1
|
||||
{
|
||||
// Mandatory entries
|
||||
type particleZoneInfo;
|
||||
cellZone leftFluid;
|
||||
|
||||
// Optional entries
|
||||
writer vtk;
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Results are written to file:
|
||||
- \<case\>/postProcessing/lagrangian/\<cloudName\>/\<functionName\>/\<time\>
|
||||
|
||||
\verbatim
|
||||
# cellZone : leftFluid
|
||||
# time : 1.0000000000e+00
|
||||
#
|
||||
# origID origProc (x y z) time0 age d0 d mass0 mass
|
||||
\endverbatim
|
||||
|
||||
Where
|
||||
- origID : particle ID
|
||||
- origProc : processor ID
|
||||
- (x y z) : Cartesian co-ordinates
|
||||
- time0 : time particle enters the cellZone
|
||||
- age : time spent in the cellZone
|
||||
- d0 : diameter on entry to the cellZone
|
||||
- d : current diameter
|
||||
- mass0 : mass on entry to the cellZone
|
||||
- mass : current mass
|
||||
|
||||
If the optional \c writer entry is supplied, cloud data is written in the
|
||||
specified format.
|
||||
|
||||
During the run, output statistics are reported after the cloud solution,
|
||||
e.g.:
|
||||
|
||||
\verbatim
|
||||
particleZoneInfo:
|
||||
Cell zone = leftFluid
|
||||
Contributions = 257
|
||||
\endverbatim
|
||||
|
||||
Here, 'Contributions' refers to the number of incremental particle-move
|
||||
contributions recorded during this time step. At write times, the output
|
||||
is extended, e.g.:
|
||||
|
||||
\verbatim
|
||||
particleZoneInfo:
|
||||
Cell zone = leftFluid
|
||||
Contributions = 822
|
||||
Number of particles = 199
|
||||
Written data to "postProcessing/lagrangian/reactingCloud1/
|
||||
\endverbatim
|
||||
|
||||
SourceFiles
|
||||
ParticleZoneInfo.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ParticleZoneInfo_H
|
||||
#define ParticleZoneInfo_H
|
||||
|
||||
#include "CloudFunctionObject.H"
|
||||
#include "writeFile.H"
|
||||
#include "coordSetWriter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
struct particleInfo Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
struct particleInfo
|
||||
{
|
||||
label origID = -1;
|
||||
label origProc = -1;
|
||||
vector position = Zero;
|
||||
scalar time0 = 0;
|
||||
scalar age = 0;
|
||||
scalar d0 = 0;
|
||||
scalar d = 0;
|
||||
scalar mass0 = 0;
|
||||
scalar mass = 0;
|
||||
|
||||
void operator+=(const particleInfo& p)
|
||||
{
|
||||
// Increment age
|
||||
age += p.age;
|
||||
|
||||
// Set current values
|
||||
position = p.position;
|
||||
d = p.d;
|
||||
mass = p.mass;
|
||||
}
|
||||
|
||||
scalar isOlderThan(const particleInfo& p) const
|
||||
{
|
||||
// Cannot just use time0 - particle may leave/re-enter and
|
||||
// so age is decoupled
|
||||
return (p.time0 + p.age) < (time0 + age);
|
||||
}
|
||||
|
||||
friend bool operator==(const particleInfo& a, const particleInfo& b)
|
||||
{
|
||||
return
|
||||
a.origID == b.origID
|
||||
&& a.origProc == b.origProc
|
||||
&& a.position == b.position
|
||||
&& a.time0 == b.time0
|
||||
&& a.age == b.age
|
||||
&& a.d0 == b.d0
|
||||
&& a.d == b.d
|
||||
&& a.mass0 == b.mass0
|
||||
&& a.mass == b.mass;
|
||||
}
|
||||
|
||||
friend bool operator!=(const particleInfo& a, const particleInfo& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Istream& operator>>(Istream& is, particleInfo& pi)
|
||||
{
|
||||
is >> pi.origID
|
||||
>> pi.origProc
|
||||
>> pi.position
|
||||
>> pi.time0
|
||||
>> pi.age
|
||||
>> pi.d0
|
||||
>> pi.d
|
||||
>> pi.mass0
|
||||
>> pi.mass;
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
friend Ostream& operator<<(Ostream& os, const particleInfo& pi)
|
||||
{
|
||||
os << pi.origID
|
||||
<< " " << pi.origProc
|
||||
<< " " << pi.position
|
||||
<< " " << pi.time0
|
||||
<< " " << pi.age
|
||||
<< " " << pi.d0
|
||||
<< " " << pi.d
|
||||
<< " " << pi.mass0
|
||||
<< " " << pi.mass;
|
||||
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ParticleZoneInfo Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class CloudType>
|
||||
class ParticleZoneInfo
|
||||
:
|
||||
public CloudFunctionObject<CloudType>,
|
||||
public functionObjects::writeFile
|
||||
|
||||
{
|
||||
// Private Data
|
||||
|
||||
// Typedefs
|
||||
|
||||
//- Convenience typedef for parcel type
|
||||
typedef typename CloudType::parcelType parcelType;
|
||||
|
||||
|
||||
//- Cell zone name
|
||||
word cellZoneName_;
|
||||
|
||||
//- Cell zone index
|
||||
label cellZoneId_;
|
||||
|
||||
//- Stored data
|
||||
DynamicList<particleInfo> data_;
|
||||
|
||||
//- Work storage
|
||||
DynamicList<particleInfo> movedParticles_;
|
||||
|
||||
//- Maximum particle ID per processor
|
||||
labelList maxIDs_;
|
||||
|
||||
//- Set writer
|
||||
autoPtr<coordSetWriter> writerPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Write output file header
|
||||
void writeFileHeader(Ostream& os) const;
|
||||
|
||||
//- Return true if celli is in the cellZone
|
||||
bool inZone(const label celli) const;
|
||||
|
||||
//- Return the index of the particle in the storage (data_)
|
||||
//- Returns -1 if not found
|
||||
label getParticleID(const particleInfo& p) const;
|
||||
|
||||
//- Write fields using writerPtr_ for serial runs
|
||||
void writeWriter(const DynamicList<particleInfo>& data);
|
||||
|
||||
//- Write fields using writerPtr_ for parallel runs
|
||||
void writeWriter(const List<List<particleInfo>>& procData);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("particleZoneInfo");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
ParticleZoneInfo
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner,
|
||||
const word& modelName
|
||||
);
|
||||
|
||||
//- Construct copy
|
||||
ParticleZoneInfo(const ParticleZoneInfo<CloudType>& pe);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<CloudFunctionObject<CloudType>> clone() const
|
||||
{
|
||||
return autoPtr<CloudFunctionObject<CloudType>>
|
||||
(
|
||||
new ParticleZoneInfo<CloudType>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~ParticleZoneInfo() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Pre-evolve hook
|
||||
virtual void preEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
);
|
||||
|
||||
//- Post-evolve hook
|
||||
virtual void postEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
);
|
||||
|
||||
//- Post-move hook
|
||||
virtual void postMove
|
||||
(
|
||||
parcelType& p,
|
||||
const scalar dt,
|
||||
const point& position0,
|
||||
bool& keepParticle
|
||||
);
|
||||
|
||||
//- Write
|
||||
virtual void write();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "ParticleZoneInfo.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -160,6 +160,13 @@ subModels
|
||||
|
||||
cloudFunctions
|
||||
{
|
||||
particleZoneInfo1
|
||||
{
|
||||
type particleZoneInfo;
|
||||
cellZone leftFluid;
|
||||
writer vtk;
|
||||
}
|
||||
|
||||
patchParticleHistogram1
|
||||
{
|
||||
type patchParticleHistogram;
|
||||
|
Loading…
Reference in New Issue
Block a user