/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- 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 . \*---------------------------------------------------------------------------*/ #include "FacePostProcessing.H" #include "Pstream.H" #include "ListListOps.H" #include "surfaceWriter.H" #include "globalIndex.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template void Foam::FacePostProcessing::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()) { const fileName logDir = outputDir_/this->owner().time().timeName(); // Create directory if does not exist mkDir(logDir); // Open new file at start up outputFilePtr_.set ( zoneI, new OFstream(logDir/(type() + '_' + zoneName + ".dat")) ); outputFilePtr_[zoneI] << "# Source : " << type() << nl << "# Face zone : " << zoneName << nl << "# Faces : " << nFaces << nl << "# Area : " << totArea << nl << "# Time" << tab << "mass" << tab << "massFlowRate" << endl; } } } template void Foam::FacePostProcessing::write() { const fvMesh& mesh = this->owner().mesh(); const Time& time = mesh.time(); const faceZoneMesh& fzm = mesh.faceZones(); scalar timeNew = time.value(); scalar timeElapsed = timeNew - timeOld_; totalTime_ += timeElapsed; const scalar alpha = (totalTime_ - timeElapsed)/totalTime_; const scalar beta = timeElapsed/totalTime_; forAll(faceZoneIDs_, zoneI) { massFlowRate_[zoneI] = alpha*massFlowRate_[zoneI] + beta*mass_[zoneI]/timeElapsed; massTotal_[zoneI] += mass_[zoneI]; } const label procI = Pstream::myProcNo(); Info<< type() << " output:" << nl; List zoneMassTotal(mass_.size()); List zoneMassFlowRate(massFlowRate_.size()); forAll(faceZoneIDs_, zoneI) { const word& zoneName = fzm[faceZoneIDs_[zoneI]].name(); scalarListList allProcMass(Pstream::nProcs()); allProcMass[procI] = massTotal_[zoneI]; Pstream::gatherList(allProcMass); zoneMassTotal[zoneI] = ListListOps::combine ( allProcMass, accessOp() ); const scalar sumMassTotal = sum(zoneMassTotal[zoneI]); scalarListList allProcMassFlowRate(Pstream::nProcs()); allProcMassFlowRate[procI] = massFlowRate_[zoneI]; Pstream::gatherList(allProcMassFlowRate); zoneMassFlowRate[zoneI] = ListListOps::combine ( allProcMassFlowRate, accessOp() ); const scalar sumMassFlowRate = sum(zoneMassFlowRate[zoneI]); Info<< " " << zoneName << ": total mass = " << sumMassTotal << "; average mass flow rate = " << sumMassFlowRate << nl; if (outputFilePtr_.set(zoneI)) { OFstream& os = outputFilePtr_[zoneI]; os << time.timeName() << token::TAB << sumMassTotal << token::TAB << sumMassFlowRate<< endl; } } Info<< endl; if (surfaceFormat_ != "none") { forAll(faceZoneIDs_, zoneI) { const faceZone& fZone = fzm[faceZoneIDs_[zoneI]]; labelList pointToGlobal; labelList uniqueMeshPointLabels; autoPtr globalPointsPtr = mesh.globalData().mergePoints ( fZone().meshPoints(), fZone().meshPointMap(), pointToGlobal, uniqueMeshPointLabels ); pointField uniquePoints(mesh.points(), uniqueMeshPointLabels); List allProcPoints(Pstream::nProcs()); allProcPoints[procI] = uniquePoints; Pstream::gatherList(allProcPoints); faceList faces(fZone().localFaces()); forAll(faces, i) { inplaceRenumber(pointToGlobal, faces[i]); } List allProcFaces(Pstream::nProcs()); allProcFaces[procI] = faces; Pstream::gatherList(allProcFaces); if (Pstream::master()) { pointField allPoints ( ListListOps::combine ( allProcPoints, accessOp() ) ); faceList allFaces ( ListListOps::combine ( allProcFaces, accessOp() ) ); autoPtr writer ( surfaceWriter::New(surfaceFormat_) ); writer->write ( outputDir_/time.timeName(), fZone.name(), allPoints, allFaces, "massTotal", zoneMassTotal[zoneI], false ); writer->write ( outputDir_/time.timeName(), fZone.name(), allPoints, allFaces, "massFlowRate", zoneMassFlowRate[zoneI], false ); } } } if (resetOnWrite_) { forAll(faceZoneIDs_, zoneI) { massFlowRate_[zoneI] = 0.0; } timeOld_ = timeNew; totalTime_ = 0.0; } forAll(mass_, zoneI) { mass_[zoneI] = 0.0; } // writeProperties(); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template Foam::FacePostProcessing::FacePostProcessing ( const dictionary& dict, CloudType& owner ) : CloudFunctionObject(dict, owner, typeName), faceZoneIDs_(), surfaceFormat_(this->coeffDict().lookup("surfaceFormat")), resetOnWrite_(this->coeffDict().lookup("resetOnWrite")), totalTime_(0.0), mass_(), massTotal_(), massFlowRate_(), log_(this->coeffDict().lookup("log")), outputFilePtr_(), outputDir_(owner.mesh().time().path()), timeOld_(owner.mesh().time().value()) { wordList faceZoneNames(this->coeffDict().lookup("faceZones")); mass_.setSize(faceZoneNames.size()); massTotal_.setSize(faceZoneNames.size()); massFlowRate_.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(); } else { outputDir_ = outputDir_/"postProcessing"/cloud::prefix/owner.name(); } DynamicList