diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C index 757c3a8aa694ea642a152c44a9a9d64c08bfa80f..cbdf299df7ce4f1fdc19c03ecdde00e379e5db41 100644 --- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C @@ -52,7 +52,47 @@ void Foam::FacePostProcessing<CloudType>::applyToFace faceI = j; return; } - } + } + } +} + + +template<class CloudType> +void Foam::FacePostProcessing<CloudType>::makeLogFile +( + const word& zoneName, + const label zoneI, + const label nFaces, + const scalar totArea +) +{ + // Create the output file if not already created + if (log_) + { + if (debug) + { + Info<< "Creating output file." << endl; + } + + if (Pstream::master()) + { + // Create directory if does not exist + mkDir(outputDir_); + + // Open new file at start up + outputFilePtr_.set + ( + zoneI, + new OFstream(outputDir_/(type() + '_' + zoneName + ".dat")) + ); + + outputFilePtr_[zoneI] + << "# Source : " << type() << nl + << "# Face zone : " << zoneName << nl + << "# Faces : " << nFaces << nl + << "# Area : " << totArea << nl + << "# Time" << tab << "mass" << tab << "massFlux" << endl; + } } } @@ -61,8 +101,9 @@ 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(); + const Time& time = mesh.time(); + const faceZoneMesh& fzm = mesh.faceZones(); + const scalar dt = time.deltaTValue(); totalTime_ += dt; @@ -80,8 +121,11 @@ void Foam::FacePostProcessing<CloudType>::write() Info<< "particleFaceFlux output:" << nl; List<scalarField> zoneMassTotal(mass_.size()); - forAll(zoneMassTotal, zoneI) + List<scalarField> zoneMassFlux(massFlux_.size()); + forAll(faceZoneIDs_, zoneI) { + const word& zoneName = fzm[faceZoneIDs_[zoneI]].name(); + scalarListList allProcMass(Pstream::nProcs()); allProcMass[procI] = massTotal_[zoneI]; Pstream::gatherList(allProcMass); @@ -90,15 +134,8 @@ void Foam::FacePostProcessing<CloudType>::write() ( allProcMass, accessOp<scalarList>() ); + const scalar sumMassTotal = sum(zoneMassTotal[zoneI]); - const word& zoneName = fzm[faceZoneIDs_[zoneI]].name(); - Info<< " " << zoneName << " total mass = " - << sum(zoneMassTotal[zoneI]) << nl; - } - - List<scalarField> zoneMassFlux(massFlux_.size()); - forAll(zoneMassFlux, zoneI) - { scalarListList allProcMassFlux(Pstream::nProcs()); allProcMassFlux[procI] = massFlux_[zoneI]; Pstream::gatherList(allProcMassFlux); @@ -107,10 +144,19 @@ void Foam::FacePostProcessing<CloudType>::write() ( allProcMassFlux, accessOp<scalarList>() ); + const scalar sumMassFlux = sum(zoneMassFlux[zoneI]); - const word& zoneName = fzm[faceZoneIDs_[zoneI]].name(); - Info<< " " << zoneName << " average mass flux = " - << sum(zoneMassFlux[zoneI]) << nl; + Info<< " " << zoneName + << ": total mass = " << sumMassTotal + << "; average mass flux = " << sumMassFlux + << nl; + + if (outputFilePtr_.set(zoneI)) + { + OFstream& os = outputFilePtr_[zoneI]; + os << time.timeName() << token::TAB << sumMassTotal << token::TAB + << sumMassFlux<< endl; + } } Info<< endl; @@ -125,14 +171,12 @@ void Foam::FacePostProcessing<CloudType>::write() // Put in undecomposed case (Note: gives problems for // distributed data running) outputDir = - outputDir/".."/"postProcessing"/cloud::prefix/ - this->owner().name()/mesh.time().timeName(); + outputDir/".."/"postProcessing"/cloud::prefix/time.timeName(); } else { outputDir = - outputDir/"postProcessing"/cloud::prefix/ - this->owner().name()/mesh.time().timeName(); + outputDir/"postProcessing"/cloud::prefix/time.timeName(); } forAll(faceZoneIDs_, zoneI) @@ -247,15 +291,36 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing totalTime_(0.0), mass_(), massTotal_(), - massFlux_() + massFlux_(), + log_(this->coeffDict().lookup("log")), + outputFilePtr_(), + outputDir_(owner.mesh().time().path()) { wordList faceZoneNames(this->coeffDict().lookup("faceZones")); mass_.setSize(faceZoneNames.size()); massTotal_.setSize(faceZoneNames.size()); massFlux_.setSize(faceZoneNames.size()); + outputFilePtr_.setSize(faceZoneNames.size()); + + if (Pstream::parRun()) + { + // Put in undecomposed case (Note: gives problems for + // distributed data running) + outputDir_ = + outputDir_/".."/"postProcessing"/cloud::prefix/ + owner.name()/owner.mesh().time().timeName(); + } + else + { + outputDir_ = + outputDir_/"postProcessing"/cloud::prefix/ + owner.name()/owner.mesh().time().timeName(); + } + DynamicList<label> zoneIDs; const faceZoneMesh& fzm = owner.mesh().faceZones(); + const surfaceScalarField& magSf = owner.mesh().magSf(); forAll(faceZoneNames, i) { const word& zoneName = faceZoneNames[i]; @@ -269,6 +334,15 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing massTotal_[i].setSize(nFaces, 0.0); massFlux_[i].setSize(nFaces, 0.0); Info<< " " << zoneName << " faces: " << nFaces; + + scalar totArea = 0.0; + forAll(fz, j) + { + totArea += magSf[fz[j]]; + } + totArea = returnReduce(totArea, sumOp<scalar>()); + + makeLogFile(zoneName, i, nFaces, totArea); } } @@ -291,7 +365,10 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing totalTime_(pff.totalTime_), mass_(pff.mass_), massTotal_(pff.massTotal_), - massFlux_(pff.massFlux_) + massFlux_(pff.massFlux_), + log_(pff.log_), + outputFilePtr_(), + outputDir_(pff.outputDir_) {} diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H index 85a80b1a4ade6ed985f2f1a04bcbb21842251a73..3782306777f230dfd61716939cbb466b39f04381 100644 --- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H @@ -85,9 +85,27 @@ class FacePostProcessing //- Mass flux storage List<scalarField> massFlux_; + //- Flag to indicate whether data should be written to file + Switch log_; + + //- Output file pointer per zone + PtrList<OFstream> outputFilePtr_; + + //- Output directory + fileName outputDir_; + // Private Member Functions + //- Helper function to create log files + void makeLogFile + ( + const word& zoneName, + const label zoneI, + const label nFaces, + const scalar totArea + ); + //- Return index into storage lists if valid zone and face void applyToFace (