mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Updated lagrangian FacePOstProcessing cloud function object
- Added support for multiple face zones
This commit is contained in:
@ -32,20 +32,28 @@ License
|
|||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class CloudType>
|
template<class CloudType>
|
||||||
Foam::label Foam::FacePostProcessing<CloudType>::applyToFace
|
void Foam::FacePostProcessing<CloudType>::applyToFace
|
||||||
(
|
(
|
||||||
const label faceI
|
const label faceIn,
|
||||||
|
label& zoneI,
|
||||||
|
label& faceI
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
forAll(fZone_, i)
|
const faceZoneMesh& fzm = this->owner().mesh().faceZones();
|
||||||
{
|
|
||||||
if (fZone_[i] == faceI)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
forAll(faceZoneIDs_, i)
|
||||||
|
{
|
||||||
|
const faceZone& fz = fzm[faceZoneIDs_[i]];
|
||||||
|
forAll(fz, j)
|
||||||
|
{
|
||||||
|
if (fz[j] == faceIn)
|
||||||
|
{
|
||||||
|
zoneI = i;
|
||||||
|
faceI = j;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -53,6 +61,7 @@ template<class CloudType>
|
|||||||
void Foam::FacePostProcessing<CloudType>::write()
|
void Foam::FacePostProcessing<CloudType>::write()
|
||||||
{
|
{
|
||||||
const fvMesh& mesh = this->owner().mesh();
|
const fvMesh& mesh = this->owner().mesh();
|
||||||
|
const faceZoneMesh& fzm = this->owner().mesh().faceZones();
|
||||||
const scalar dt = this->owner().time().deltaTValue();
|
const scalar dt = this->owner().time().deltaTValue();
|
||||||
|
|
||||||
totalTime_ += dt;
|
totalTime_ += dt;
|
||||||
@ -60,133 +69,159 @@ void Foam::FacePostProcessing<CloudType>::write()
|
|||||||
const scalar alpha = (totalTime_ - dt)/totalTime_;
|
const scalar alpha = (totalTime_ - dt)/totalTime_;
|
||||||
const scalar beta = dt/totalTime_;
|
const scalar beta = dt/totalTime_;
|
||||||
|
|
||||||
massTotal_ += mass_;
|
forAll(faceZoneIDs_, zoneI)
|
||||||
|
{
|
||||||
massFlux_ = alpha*massFlux_ + beta*mass_/dt;
|
massTotal_[zoneI] += mass_[zoneI];
|
||||||
|
massFlux_[zoneI] = alpha*massFlux_[zoneI] + beta*mass_[zoneI]/dt;
|
||||||
|
}
|
||||||
|
|
||||||
const label procI = Pstream::myProcNo();
|
const label procI = Pstream::myProcNo();
|
||||||
|
|
||||||
scalarListList allProcMass(Pstream::nProcs());
|
Info<< "particleFaceFlux output:" << nl;
|
||||||
allProcMass[procI] = massTotal_;
|
|
||||||
Pstream::gatherList(allProcMass);
|
|
||||||
scalarField allMass
|
|
||||||
(
|
|
||||||
ListListOps::combine<scalarList>
|
|
||||||
(
|
|
||||||
allProcMass, accessOp<scalarList>()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
scalarListList allProcMassFlux(Pstream::nProcs());
|
List<scalarField> zoneMassTotal(mass_.size());
|
||||||
allProcMassFlux[procI] = massFlux_;
|
forAll(zoneMassTotal, zoneI)
|
||||||
Pstream::gatherList(allProcMassFlux);
|
{
|
||||||
scalarField allMassFlux
|
scalarListList allProcMass(Pstream::nProcs());
|
||||||
(
|
allProcMass[procI] = massTotal_[zoneI];
|
||||||
ListListOps::combine<scalarList>
|
Pstream::gatherList(allProcMass);
|
||||||
(
|
zoneMassTotal[zoneI] =
|
||||||
allProcMassFlux, accessOp<scalarList>()
|
ListListOps::combine<scalarList>
|
||||||
)
|
(
|
||||||
);
|
allProcMass, accessOp<scalarList>()
|
||||||
|
);
|
||||||
|
|
||||||
Info<< "particleFaceFlux output:" << nl
|
const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
|
||||||
<< " total mass = " << sum(allMass) << nl
|
Info<< " " << zoneName << " total mass = "
|
||||||
<< " average mass flux = " << sum(allMassFlux) << nl << endl;
|
<< sum(zoneMassTotal[zoneI]) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<scalarField> zoneMassFlux(massFlux_.size());
|
||||||
|
forAll(zoneMassFlux, zoneI)
|
||||||
|
{
|
||||||
|
scalarListList allProcMassFlux(Pstream::nProcs());
|
||||||
|
allProcMassFlux[procI] = massFlux_[zoneI];
|
||||||
|
Pstream::gatherList(allProcMassFlux);
|
||||||
|
zoneMassFlux[zoneI] =
|
||||||
|
ListListOps::combine<scalarList>
|
||||||
|
(
|
||||||
|
allProcMassFlux, accessOp<scalarList>()
|
||||||
|
);
|
||||||
|
|
||||||
|
const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
|
||||||
|
Info<< " " << zoneName << " average mass flux = "
|
||||||
|
<< sum(zoneMassFlux[zoneI]) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
|
||||||
if (surfaceFormat_ != "none")
|
if (surfaceFormat_ != "none")
|
||||||
{
|
{
|
||||||
labelList pointToGlobal;
|
fileName outputDir = mesh.time().path();
|
||||||
labelList uniqueMeshPointLabels;
|
|
||||||
autoPtr<globalIndex> globalPointsPtr =
|
|
||||||
mesh.globalData().mergePoints
|
|
||||||
(
|
|
||||||
fZone_().meshPoints(),
|
|
||||||
fZone_().meshPointMap(),
|
|
||||||
pointToGlobal,
|
|
||||||
uniqueMeshPointLabels
|
|
||||||
);
|
|
||||||
|
|
||||||
pointField uniquePoints(mesh.points(), uniqueMeshPointLabels);
|
if (Pstream::parRun())
|
||||||
List<pointField> allProcPoints(Pstream::nProcs());
|
|
||||||
allProcPoints[procI] = uniquePoints;
|
|
||||||
Pstream::gatherList(allProcPoints);
|
|
||||||
|
|
||||||
faceList faces(fZone_().localFaces());
|
|
||||||
forAll(faces, i)
|
|
||||||
{
|
{
|
||||||
inplaceRenumber(pointToGlobal, faces[i]);
|
// Put in undecomposed case (Note: gives problems for
|
||||||
|
// distributed data running)
|
||||||
|
outputDir =
|
||||||
|
outputDir/".."/"postProcessing"/cloud::prefix/
|
||||||
|
this->owner().name()/mesh.time().timeName();
|
||||||
}
|
}
|
||||||
List<faceList> allProcFaces(Pstream::nProcs());
|
else
|
||||||
allProcFaces[procI] = faces;
|
|
||||||
Pstream::gatherList(allProcFaces);
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
{
|
||||||
pointField allPoints
|
outputDir =
|
||||||
(
|
outputDir/"postProcessing"/cloud::prefix/
|
||||||
ListListOps::combine<pointField>
|
this->owner().name()/mesh.time().timeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(faceZoneIDs_, zoneI)
|
||||||
|
{
|
||||||
|
const faceZone& fZone = fzm[faceZoneIDs_[zoneI]];
|
||||||
|
|
||||||
|
labelList pointToGlobal;
|
||||||
|
labelList uniqueMeshPointLabels;
|
||||||
|
autoPtr<globalIndex> globalPointsPtr =
|
||||||
|
mesh.globalData().mergePoints
|
||||||
(
|
(
|
||||||
allProcPoints, accessOp<pointField>()
|
fZone().meshPoints(),
|
||||||
)
|
fZone().meshPointMap(),
|
||||||
);
|
pointToGlobal,
|
||||||
|
uniqueMeshPointLabels
|
||||||
|
);
|
||||||
|
|
||||||
faceList allFaces
|
pointField uniquePoints(mesh.points(), uniqueMeshPointLabels);
|
||||||
(
|
List<pointField> allProcPoints(Pstream::nProcs());
|
||||||
ListListOps::combine<faceList>
|
allProcPoints[procI] = uniquePoints;
|
||||||
|
Pstream::gatherList(allProcPoints);
|
||||||
|
|
||||||
|
faceList faces(fZone().localFaces());
|
||||||
|
forAll(faces, i)
|
||||||
|
{
|
||||||
|
inplaceRenumber(pointToGlobal, faces[i]);
|
||||||
|
}
|
||||||
|
List<faceList> allProcFaces(Pstream::nProcs());
|
||||||
|
allProcFaces[procI] = faces;
|
||||||
|
Pstream::gatherList(allProcFaces);
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
pointField allPoints
|
||||||
(
|
(
|
||||||
allProcFaces, accessOp<faceList>()
|
ListListOps::combine<pointField>
|
||||||
)
|
(
|
||||||
);
|
allProcPoints, accessOp<pointField>()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
fileName outputDir = mesh.time().path();
|
faceList allFaces
|
||||||
|
(
|
||||||
|
ListListOps::combine<faceList>
|
||||||
|
(
|
||||||
|
allProcFaces, accessOp<faceList>()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (Pstream::parRun())
|
autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_));
|
||||||
{
|
writer->write
|
||||||
// Put in undecomposed case (Note: gives problems for
|
(
|
||||||
// distributed data running)
|
outputDir,
|
||||||
outputDir =
|
fZone.name(),
|
||||||
outputDir/".."/"postProcessing"/cloud::prefix/
|
allPoints,
|
||||||
this->owner().name()/mesh.time().timeName();
|
allFaces,
|
||||||
|
"massTotal",
|
||||||
|
zoneMassTotal[zoneI],
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
writer->write
|
||||||
|
(
|
||||||
|
outputDir,
|
||||||
|
fZone.name(),
|
||||||
|
allPoints,
|
||||||
|
allFaces,
|
||||||
|
"massFlux",
|
||||||
|
zoneMassFlux[zoneI],
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
outputDir =
|
|
||||||
outputDir/"postProcessing"/cloud::prefix/
|
|
||||||
this->owner().name()/mesh.time().timeName();
|
|
||||||
}
|
|
||||||
|
|
||||||
autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_));
|
|
||||||
writer->write
|
|
||||||
(
|
|
||||||
outputDir,
|
|
||||||
"massTotal",
|
|
||||||
allPoints,
|
|
||||||
allFaces,
|
|
||||||
"massTotal",
|
|
||||||
allMass,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
writer->write
|
|
||||||
(
|
|
||||||
outputDir,
|
|
||||||
"massFlux",
|
|
||||||
allPoints,
|
|
||||||
allFaces,
|
|
||||||
"massFlux",
|
|
||||||
allMassFlux,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (resetOnWrite_)
|
if (resetOnWrite_)
|
||||||
{
|
{
|
||||||
massFlux_ = 0.0;
|
forAll(faceZoneIDs_, zoneI)
|
||||||
|
{
|
||||||
|
massFlux_[zoneI] = 0.0;
|
||||||
|
}
|
||||||
totalTime_ = 0.0;
|
totalTime_ = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mass_ = 0.0;
|
forAll(mass_, zoneI)
|
||||||
|
{
|
||||||
|
mass_[zoneI] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
// writeProperties();
|
// writeProperties();
|
||||||
}
|
}
|
||||||
@ -202,7 +237,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
CloudFunctionObject<CloudType>(dict, owner, typeName),
|
CloudFunctionObject<CloudType>(dict, owner, typeName),
|
||||||
fZone_(owner.mesh().faceZones()[this->coeffDict().lookup("faceZone")]),
|
faceZoneIDs_(),
|
||||||
surfaceFormat_(this->coeffDict().lookup("surfaceFormat")),
|
surfaceFormat_(this->coeffDict().lookup("surfaceFormat")),
|
||||||
resetOnWrite_(this->coeffDict().lookup("resetOnWrite")),
|
resetOnWrite_(this->coeffDict().lookup("resetOnWrite")),
|
||||||
totalTime_(0.0),
|
totalTime_(0.0),
|
||||||
@ -210,15 +245,32 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
|
|||||||
massTotal_(),
|
massTotal_(),
|
||||||
massFlux_()
|
massFlux_()
|
||||||
{
|
{
|
||||||
label allFaces = returnReduce(fZone_().size(), sumOp<scalar>());
|
wordList faceZoneNames(this->coeffDict().lookup("faceZones"));
|
||||||
Info<< " Number of faces = " << allFaces << endl;
|
mass_.setSize(faceZoneNames.size());
|
||||||
|
massTotal_.setSize(faceZoneNames.size());
|
||||||
|
massFlux_.setSize(faceZoneNames.size());
|
||||||
|
|
||||||
mass_.setSize(fZone_.size(), 0.0);
|
DynamicList<label> zoneIDs;
|
||||||
|
const faceZoneMesh& fzm = owner.mesh().faceZones();
|
||||||
|
forAll(faceZoneNames, i)
|
||||||
|
{
|
||||||
|
const word& zoneName = faceZoneNames[i];
|
||||||
|
label zoneI = fzm.findZoneID(zoneName);
|
||||||
|
if (zoneI != -1)
|
||||||
|
{
|
||||||
|
zoneIDs.append(zoneI);
|
||||||
|
const faceZone& fz = fzm[zoneI];
|
||||||
|
label nFaces = returnReduce(fz.size(), sumOp<label>());
|
||||||
|
mass_[i].setSize(nFaces, 0.0);
|
||||||
|
massTotal_[i].setSize(nFaces, 0.0);
|
||||||
|
massFlux_[i].setSize(nFaces, 0.0);
|
||||||
|
Info<< " " << zoneName << " faces: " << nFaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
faceZoneIDs_.transfer(zoneIDs);
|
||||||
|
|
||||||
// readProperties(); AND initialise mass... fields
|
// readProperties(); AND initialise mass... fields
|
||||||
|
|
||||||
massTotal_.setSize(fZone_.size(), 0.0);
|
|
||||||
massFlux_.setSize(fZone_.size(), 0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -229,7 +281,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
CloudFunctionObject<CloudType>(pff),
|
CloudFunctionObject<CloudType>(pff),
|
||||||
fZone_(pff.fZone_.clone(pff.fZone_.zoneMesh())),
|
faceZoneIDs_(pff.faceZoneIDs_),
|
||||||
surfaceFormat_(pff.surfaceFormat_),
|
surfaceFormat_(pff.surfaceFormat_),
|
||||||
resetOnWrite_(pff.resetOnWrite_),
|
resetOnWrite_(pff.resetOnWrite_),
|
||||||
totalTime_(pff.totalTime_),
|
totalTime_(pff.totalTime_),
|
||||||
@ -266,11 +318,13 @@ void Foam::FacePostProcessing<CloudType>::postFace(const parcelType& p)
|
|||||||
|| this->owner().solution().transient()
|
|| this->owner().solution().transient()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const label faceI = applyToFace(p.face());
|
label zoneI = -1;
|
||||||
|
label faceI = -1;
|
||||||
|
applyToFace(p.face(), zoneI, faceI);
|
||||||
|
|
||||||
if (faceI != -1)
|
if ((zoneI != -1) && (faceI != -1))
|
||||||
{
|
{
|
||||||
mass_[faceI] += p.mass()*p.nParticle();
|
mass_[zoneI][faceI] += p.mass()*p.nParticle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,8 +64,8 @@ class FacePostProcessing
|
|||||||
typedef typename CloudType::parcelType parcelType;
|
typedef typename CloudType::parcelType parcelType;
|
||||||
|
|
||||||
|
|
||||||
//- Face zone
|
//- Face zone IDs
|
||||||
const faceZone& fZone_;
|
labelList faceZoneIDs_;
|
||||||
|
|
||||||
//- Surface output format
|
//- Surface output format
|
||||||
const word surfaceFormat_;
|
const word surfaceFormat_;
|
||||||
@ -77,19 +77,24 @@ class FacePostProcessing
|
|||||||
scalar totalTime_;
|
scalar totalTime_;
|
||||||
|
|
||||||
//- Mass storage
|
//- Mass storage
|
||||||
scalarField mass_;
|
List<scalarField> mass_;
|
||||||
|
|
||||||
//- Mass total storage
|
//- Mass total storage
|
||||||
scalarField massTotal_;
|
List<scalarField> massTotal_;
|
||||||
|
|
||||||
//- Mass flux storage
|
//- Mass flux storage
|
||||||
scalarField massFlux_;
|
List<scalarField> massFlux_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Return index into massFlux_ list if valid face, else -1
|
//- Return index into storage lists if valid zone and face
|
||||||
label applyToFace(const label faceI) const;
|
void applyToFace
|
||||||
|
(
|
||||||
|
const label faceIn,
|
||||||
|
label& zoneI, label&
|
||||||
|
faceI
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user