/*---------------------------------------------------------------------------*\ ========= | \\ / 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::applyToFace ( const label faceIn, label& zoneI, label& faceI ) const { const faceZoneMesh& fzm = this->owner().mesh().faceZones(); forAll(faceZoneIDs_, i) { const faceZone& fz = fzm[faceZoneIDs_[i]]; forAll(fz, j) { if (fz[j] == faceIn) { zoneI = i; faceI = j; return; } } } } 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 << "massFlux" << endl; } } } template void Foam::FacePostProcessing::write() { const fvMesh& mesh = this->owner().mesh(); const Time& time = mesh.time(); const faceZoneMesh& fzm = mesh.faceZones(); const scalar dt = time.deltaTValue(); totalTime_ += dt; const scalar alpha = (totalTime_ - dt)/totalTime_; const scalar beta = dt/totalTime_; forAll(faceZoneIDs_, zoneI) { massTotal_[zoneI] += mass_[zoneI]; massFlux_[zoneI] = alpha*massFlux_[zoneI] + beta*mass_[zoneI]/dt; } const label procI = Pstream::myProcNo(); Info<< "particleFaceFlux output:" << nl; List zoneMassTotal(mass_.size()); List zoneMassFlux(massFlux_.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 allProcMassFlux(Pstream::nProcs()); allProcMassFlux[procI] = massFlux_[zoneI]; Pstream::gatherList(allProcMassFlux); zoneMassFlux[zoneI] = ListListOps::combine ( allProcMassFlux, accessOp() ); const scalar sumMassFlux = sum(zoneMassFlux[zoneI]); 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; 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, "massFlux", zoneMassFlux[zoneI], false ); } } } if (resetOnWrite_) { forAll(faceZoneIDs_, zoneI) { massFlux_[zoneI] = 0.0; } 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_(), 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(); } else { outputDir_ = outputDir_/"postProcessing"/cloud::prefix/owner.name(); } DynamicList