diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C index 1068ea00965b75d90d5d52339b62f2fba8df0ec0..d5f76f5af212e35fab7b4c8213a7f97d0394957e 100644 --- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C @@ -32,20 +32,28 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // 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 { - forAll(fZone_, i) + const faceZoneMesh& fzm = this->owner().mesh().faceZones(); + + forAll(faceZoneIDs_, i) { - if (fZone_[i] == faceI) + const faceZone& fz = fzm[faceZoneIDs_[i]]; + forAll(fz, j) { - return i; - } + if (fz[j] == faceIn) + { + zoneI = i; + faceI = j; + return; + } + } } - - return -1; } @@ -53,6 +61,7 @@ template<class CloudType> void Foam::FacePostProcessing<CloudType>::write() { const fvMesh& mesh = this->owner().mesh(); + const faceZoneMesh& fzm = this->owner().mesh().faceZones(); const scalar dt = this->owner().time().deltaTValue(); totalTime_ += dt; @@ -60,133 +69,159 @@ void Foam::FacePostProcessing<CloudType>::write() const scalar alpha = (totalTime_ - dt)/totalTime_; const scalar beta = dt/totalTime_; - massTotal_ += mass_; - - massFlux_ = alpha*massFlux_ + beta*mass_/dt; + forAll(faceZoneIDs_, zoneI) + { + massTotal_[zoneI] += mass_[zoneI]; + massFlux_[zoneI] = alpha*massFlux_[zoneI] + beta*mass_[zoneI]/dt; + } const label procI = Pstream::myProcNo(); - scalarListList allProcMass(Pstream::nProcs()); - allProcMass[procI] = massTotal_; - Pstream::gatherList(allProcMass); - scalarField allMass - ( - ListListOps::combine<scalarList> - ( - allProcMass, accessOp<scalarList>() - ) - ); - - scalarListList allProcMassFlux(Pstream::nProcs()); - allProcMassFlux[procI] = massFlux_; - Pstream::gatherList(allProcMassFlux); - scalarField allMassFlux - ( - ListListOps::combine<scalarList> - ( - allProcMassFlux, accessOp<scalarList>() - ) - ); + Info<< "particleFaceFlux output:" << nl; - Info<< "particleFaceFlux output:" << nl - << " total mass = " << sum(allMass) << nl - << " average mass flux = " << sum(allMassFlux) << nl << endl; + List<scalarField> zoneMassTotal(mass_.size()); + forAll(zoneMassTotal, zoneI) + { + scalarListList allProcMass(Pstream::nProcs()); + allProcMass[procI] = massTotal_[zoneI]; + Pstream::gatherList(allProcMass); + zoneMassTotal[zoneI] = + ListListOps::combine<scalarList> + ( + allProcMass, accessOp<scalarList>() + ); + const word& zoneName = fzm[faceZoneIDs_[zoneI]].name(); + Info<< " " << zoneName << " total mass = " + << sum(zoneMassTotal[zoneI]) << nl; + } - if (surfaceFormat_ != "none") + List<scalarField> zoneMassFlux(massFlux_.size()); + forAll(zoneMassFlux, zoneI) { - labelList pointToGlobal; - labelList uniqueMeshPointLabels; - autoPtr<globalIndex> globalPointsPtr = - mesh.globalData().mergePoints + scalarListList allProcMassFlux(Pstream::nProcs()); + allProcMassFlux[procI] = massFlux_[zoneI]; + Pstream::gatherList(allProcMassFlux); + zoneMassFlux[zoneI] = + ListListOps::combine<scalarList> ( - fZone_().meshPoints(), - fZone_().meshPointMap(), - pointToGlobal, - uniqueMeshPointLabels + allProcMassFlux, accessOp<scalarList>() ); - pointField uniquePoints(mesh.points(), uniqueMeshPointLabels); - List<pointField> allProcPoints(Pstream::nProcs()); - allProcPoints[procI] = uniquePoints; - Pstream::gatherList(allProcPoints); + const word& zoneName = fzm[faceZoneIDs_[zoneI]].name(); + Info<< " " << zoneName << " average mass flux = " + << sum(zoneMassFlux[zoneI]) << nl; + } + + Info<< endl; + + + if (surfaceFormat_ != "none") + { + fileName outputDir = mesh.time().path(); - faceList faces(fZone_().localFaces()); - forAll(faces, i) + if (Pstream::parRun()) + { + // Put in undecomposed case (Note: gives problems for + // distributed data running) + outputDir = + outputDir/".."/"postProcessing"/cloud::prefix/ + this->owner().name()/mesh.time().timeName(); + } + else { - inplaceRenumber(pointToGlobal, faces[i]); + outputDir = + outputDir/"postProcessing"/cloud::prefix/ + this->owner().name()/mesh.time().timeName(); } - List<faceList> allProcFaces(Pstream::nProcs()); - allProcFaces[procI] = faces; - Pstream::gatherList(allProcFaces); - if (Pstream::master()) + forAll(faceZoneIDs_, zoneI) { - pointField allPoints - ( - ListListOps::combine<pointField> - ( - allProcPoints, accessOp<pointField>() - ) - ); + const faceZone& fZone = fzm[faceZoneIDs_[zoneI]]; - faceList allFaces - ( - ListListOps::combine<faceList> + labelList pointToGlobal; + labelList uniqueMeshPointLabels; + autoPtr<globalIndex> globalPointsPtr = + mesh.globalData().mergePoints ( - allProcFaces, accessOp<faceList>() - ) - ); - - fileName outputDir = mesh.time().path(); - - if (Pstream::parRun()) + fZone().meshPoints(), + fZone().meshPointMap(), + pointToGlobal, + uniqueMeshPointLabels + ); + + pointField uniquePoints(mesh.points(), uniqueMeshPointLabels); + List<pointField> allProcPoints(Pstream::nProcs()); + allProcPoints[procI] = uniquePoints; + Pstream::gatherList(allProcPoints); + + faceList faces(fZone().localFaces()); + forAll(faces, i) { - // Put in undecomposed case (Note: gives problems for - // distributed data running) - outputDir = - outputDir/".."/"postProcessing"/cloud::prefix/ - this->owner().name()/mesh.time().timeName(); + inplaceRenumber(pointToGlobal, faces[i]); } - else + List<faceList> allProcFaces(Pstream::nProcs()); + allProcFaces[procI] = faces; + Pstream::gatherList(allProcFaces); + + if (Pstream::master()) { - outputDir = - outputDir/"postProcessing"/cloud::prefix/ - this->owner().name()/mesh.time().timeName(); - } + pointField allPoints + ( + ListListOps::combine<pointField> + ( + allProcPoints, accessOp<pointField>() + ) + ); - autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_)); - writer->write - ( - outputDir, - "massTotal", - allPoints, - allFaces, - "massTotal", - allMass, - false - ); - writer->write - ( - outputDir, - "massFlux", - allPoints, - allFaces, - "massFlux", - allMassFlux, - false - ); + faceList allFaces + ( + ListListOps::combine<faceList> + ( + allProcFaces, accessOp<faceList>() + ) + ); + + autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_)); + writer->write + ( + outputDir, + fZone.name(), + allPoints, + allFaces, + "massTotal", + zoneMassTotal[zoneI], + false + ); + + writer->write + ( + outputDir, + fZone.name(), + allPoints, + allFaces, + "massFlux", + zoneMassFlux[zoneI], + false + ); + } } } if (resetOnWrite_) { - massFlux_ = 0.0; + forAll(faceZoneIDs_, zoneI) + { + massFlux_[zoneI] = 0.0; + } totalTime_ = 0.0; } - mass_ = 0.0; + forAll(mass_, zoneI) + { + mass_[zoneI] = 0.0; + } // writeProperties(); } @@ -202,7 +237,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing ) : CloudFunctionObject<CloudType>(dict, owner, typeName), - fZone_(owner.mesh().faceZones()[this->coeffDict().lookup("faceZone")]), + faceZoneIDs_(), surfaceFormat_(this->coeffDict().lookup("surfaceFormat")), resetOnWrite_(this->coeffDict().lookup("resetOnWrite")), totalTime_(0.0), @@ -210,15 +245,32 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing massTotal_(), massFlux_() { - label allFaces = returnReduce(fZone_().size(), sumOp<scalar>()); - Info<< " Number of faces = " << allFaces << endl; + wordList faceZoneNames(this->coeffDict().lookup("faceZones")); + mass_.setSize(faceZoneNames.size()); + massTotal_.setSize(faceZoneNames.size()); + massFlux_.setSize(faceZoneNames.size()); + + 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; + } + } - mass_.setSize(fZone_.size(), 0.0); + faceZoneIDs_.transfer(zoneIDs); // 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), - fZone_(pff.fZone_.clone(pff.fZone_.zoneMesh())), + faceZoneIDs_(pff.faceZoneIDs_), surfaceFormat_(pff.surfaceFormat_), resetOnWrite_(pff.resetOnWrite_), totalTime_(pff.totalTime_), @@ -266,11 +318,13 @@ void Foam::FacePostProcessing<CloudType>::postFace(const parcelType& p) || 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(); } } } diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H index de239097e6e1fa26c7bd7265baf36b802b477d00..85a80b1a4ade6ed985f2f1a04bcbb21842251a73 100644 --- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H @@ -64,8 +64,8 @@ class FacePostProcessing typedef typename CloudType::parcelType parcelType; - //- Face zone - const faceZone& fZone_; + //- Face zone IDs + labelList faceZoneIDs_; //- Surface output format const word surfaceFormat_; @@ -77,19 +77,24 @@ class FacePostProcessing scalar totalTime_; //- Mass storage - scalarField mass_; + List<scalarField> mass_; //- Mass total storage - scalarField massTotal_; + List<scalarField> massTotal_; //- Mass flux storage - scalarField massFlux_; + List<scalarField> massFlux_; // Private Member Functions - //- Return index into massFlux_ list if valid face, else -1 - label applyToFace(const label faceI) const; + //- Return index into storage lists if valid zone and face + void applyToFace + ( + const label faceIn, + label& zoneI, label& + faceI + ) const; protected: