/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd. \\/ 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 "PatchPostProcessing.H" #include "Pstream.H" #include "stringListOps.H" #include "ListListOps.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template Foam::label Foam::PatchPostProcessing::applyToPatch ( const label globalPatchI ) const { forAll(patchIDs_, i) { if (patchIDs_[i] == globalPatchI) { return i; } } return -1; } // * * * * * * * * * * * * * protected Member Functions * * * * * * * * * * // template void Foam::PatchPostProcessing::write() { forAll(patchData_, i) { List > procData(Pstream::nProcs()); procData[Pstream::myProcNo()] = patchData_[i]; Pstream::gatherList(procData); if (Pstream::master()) { const fvMesh& mesh = this->owner().mesh(); fileName outputDir = mesh.time().path(); 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 { outputDir = outputDir/"postProcessing"/cloud::prefix/ this->owner().name()/mesh.time().timeName(); } // Create directory if it doesn't exist mkDir(outputDir); const word& patchName = mesh.boundaryMesh()[patchIDs_[i]].name(); OFstream patchOutFile ( outputDir/patchName + ".post", IOstream::ASCII, IOstream::currentVersion, mesh.time().writeCompression() ); List globalData; globalData = ListListOps::combine > ( procData, accessOp >() ); sort(globalData); string header("# Time currentProc " + parcelType::propHeader); patchOutFile<< header.c_str() << nl; forAll(globalData, dataI) { patchOutFile<< globalData[dataI].c_str() << nl; } } patchData_[i].clearStorage(); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template Foam::PatchPostProcessing::PatchPostProcessing ( const dictionary& dict, CloudType& owner ) : PostProcessingModel(dict, owner, typeName), maxStoredParcels_(readScalar(this->coeffDict().lookup("maxStoredParcels"))), patchIDs_(), patchData_() { const wordList allPatchNames = owner.mesh().boundaryMesh().names(); wordList patchName(this->coeffDict().lookup("patches")); labelHashSet uniquePatchIDs; forAllReverse(patchName, i) { labelList patchIDs = findStrings(patchName[i], allPatchNames); if (patchIDs.empty()) { WarningIn ( "Foam::PatchPostProcessing::PatchPostProcessing" "(" "const dictionary&, " "CloudType& " ")" ) << "Cannot find any patch names matching " << patchName[i] << endl; } uniquePatchIDs.insert(patchIDs); } patchIDs_ = uniquePatchIDs.toc(); if (debug) { forAll(patchIDs_, i) { const label patchI = patchIDs_[i]; const word& patchName = owner.mesh().boundaryMesh()[patchI].name(); Info<< "Post-process patch " << patchName << endl; } } patchData_.setSize(patchIDs_.size()); } template Foam::PatchPostProcessing::PatchPostProcessing ( const PatchPostProcessing& ppm ) : PostProcessingModel(ppm), maxStoredParcels_(ppm.maxStoredParcels_), patchIDs_(ppm.patchIDs_), patchData_(ppm.patchData_) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template Foam::PatchPostProcessing::~PatchPostProcessing() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template void Foam::PatchPostProcessing::postPatch ( const parcelType& p, const label patchI ) { const label localPatchI = applyToPatch(patchI); if (localPatchI != -1 && patchData_[localPatchI].size() < maxStoredParcels_) { OStringStream data; data<< this->owner().time().timeName() << ' ' << Pstream::myProcNo() << ' ' << p; patchData_[localPatchI].append(data.str()); } } template void Foam::PatchPostProcessing::postFace(const parcelType&) {} // ************************************************************************* //