diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
index 9e19beae34..783878f480 100644
--- a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
+++ b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
- \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
+ \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@@ -29,6 +29,7 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "FacePostProcessing.H"
+#include "ParticleCollector.H"
#include "ParticleErosion.H"
#include "ParticleTracks.H"
#include "ParticleTrap.H"
@@ -42,6 +43,7 @@ License
makeCloudFunctionObject(CloudType); \
\
makeCloudFunctionObjectType(FacePostProcessing, CloudType); \
+ makeCloudFunctionObjectType(ParticleCollector, CloudType); \
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C
new file mode 100644
index 0000000000..de22b5a044
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C
@@ -0,0 +1,668 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2012 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 "ParticleCollector.H"
+#include "Pstream.H"
+#include "surfaceWriter.H"
+#include "unitConversion.H"
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+template
+void Foam::ParticleCollector::makeLogFile
+(
+ const faceList& faces,
+ const Field& points,
+ const Field& area
+)
+{
+ // 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_.reset
+ (
+ new OFstream(logDir/(type() + ".dat"))
+ );
+
+ outputFilePtr_()
+ << "# Source : " << type() << nl
+ << "# Total area : " << sum(area) << nl
+ << "# Time";
+
+ forAll(faces, i)
+ {
+ word id = Foam::name(i);
+
+ outputFilePtr_()
+ << tab << "area[" << id << "]"
+ << tab << "mass[" << id << "]"
+ << tab << "massFlowRate[" << id << "]"
+ << endl;
+ }
+ }
+ }
+}
+
+
+template
+void Foam::ParticleCollector::initPolygons()
+{
+ mode_ = mtPolygon;
+
+ List > polygons(this->coeffDict().lookup("polygons"));
+ label nPoints = 0;
+ forAll(polygons, polyI)
+ {
+ label np = polygons[polyI].size();
+ if (np < 3)
+ {
+ FatalIOErrorIn
+ (
+ "Foam::ParticleCollector::initPolygons()",
+ this->coeffDict()
+ )
+ << "polygons must consist of at least 3 points"
+ << exit(FatalIOError);
+ }
+
+ nPoints += np;
+ }
+
+ label pointOffset = 0;
+ points_.setSize(nPoints);
+ faces_.setSize(polygons.size());
+ faceTris_.setSize(polygons.size());
+ area_.setSize(polygons.size());
+ forAll(faces_, faceI)
+ {
+ const Field& polyPoints = polygons[faceI];
+ face f(identity(polyPoints.size()) + pointOffset);
+ UIndirectList(points_, f) = polyPoints;
+ area_[faceI] = f.mag(points_);
+
+ DynamicList tris;
+ f.triangles(points_, tris);
+ faceTris_[faceI].transfer(tris);
+
+ faces_[faceI].transfer(f);
+
+ pointOffset += polyPoints.size();
+ }
+}
+
+
+template
+void Foam::ParticleCollector::initConcentricCircles()
+{
+ mode_ = mtConcentricCircle;
+
+ vector origin(this->coeffDict().lookup("origin"));
+
+ radius_ = this->coeffDict().lookup("radius");
+ nSector_ = readLabel(this->coeffDict().lookup("nSector"));
+
+ label nS = nSector_;
+
+ vector refDir;
+ if (nSector_ > 1)
+ {
+ refDir = this->coeffDict().lookup("refDir");
+ refDir -= normal_*(normal_ & refDir);
+ refDir /= mag(refDir);
+ }
+ else
+ {
+ // set 4 quadrants for single sector cases
+ nS = 4;
+
+ vector tangent = vector::zero;
+ scalar magTangent = 0.0;
+
+ Random rnd(1234);
+ while (magTangent < SMALL)
+ {
+ vector v = rnd.vector01();
+
+ tangent = v - (v & normal_)*normal_;
+ magTangent = mag(tangent);
+ }
+
+ refDir = tangent/magTangent;
+ }
+
+ scalar dTheta = 5.0;
+ scalar dThetaSector = 360.0/scalar(nS);
+ label intervalPerSector = max(1, ceil(dThetaSector/dTheta));
+ dTheta = dThetaSector/scalar(intervalPerSector);
+
+ label nPointPerSector = intervalPerSector + 1;
+
+ label nPointPerRadius = nS*(nPointPerSector - 1);
+ label nPoint = radius_.size()*nPointPerRadius;
+ label nFace = radius_.size()*nS;
+
+ // add origin
+ nPoint++;
+
+ points_.setSize(nPoint);
+ faces_.setSize(nFace);
+ area_.setSize(nFace);
+
+ coordSys_ = cylindricalCS("coordSys", origin, normal_, refDir, false);
+
+ List