From b05f27930218b55143d3f2a3a1a32490334b815e Mon Sep 17 00:00:00 2001
From: andy <andy>
Date: Wed, 11 May 2011 10:51:24 +0100
Subject: [PATCH] ENH: Added face post-processing for particle clouds

---
 .../LTSReactingParcelFoam/Make/options        |   6 +-
 .../lagrangian/coalChemistryFoam/Make/options |   4 +-
 .../Make/options                              |   6 +-
 .../Make/options                              |   4 +-
 .../Make/options                              |   4 +-
 .../reactingParcelFilmFoam/Make/options       |   4 +-
 .../reactingParcelFoam/Make/options           |   4 +-
 .../uncoupledKinematicParcelFoam/Make/options |   6 +-
 src/lagrangian/coalCombustion/Make/options    |   3 +-
 src/lagrangian/intermediate/Make/options      |   3 +-
 .../Templates/KinematicCloud/KinematicCloud.H |   3 +-
 .../include/makeParcelCloudFunctionObjects.H  |   2 +
 .../FacePostProcessing/FacePostProcessing.C   | 281 ++++++++++++++++++
 .../FacePostProcessing/FacePostProcessing.H   | 167 +++++++++++
 .../FacePostProcessing/FacePostProcessingI.H  |  34 +++
 15 files changed, 517 insertions(+), 14 deletions(-)
 create mode 100644 src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
 create mode 100644 src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H
 create mode 100644 src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessingI.H

diff --git a/applications/solvers/lagrangian/LTSReactingParcelFoam/Make/options b/applications/solvers/lagrangian/LTSReactingParcelFoam/Make/options
index 1ff1aaa6129..91ee4a594d0 100644
--- a/applications/solvers/lagrangian/LTSReactingParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/LTSReactingParcelFoam/Make/options
@@ -19,7 +19,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -42,4 +43,5 @@ EXE_LIBS = \
     -lradiationModels \
     -lODE \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lsampling
diff --git a/applications/solvers/lagrangian/coalChemistryFoam/Make/options b/applications/solvers/lagrangian/coalChemistryFoam/Make/options
index 75bbcab490e..f2f8d1e7587 100644
--- a/applications/solvers/lagrangian/coalChemistryFoam/Make/options
+++ b/applications/solvers/lagrangian/coalChemistryFoam/Make/options
@@ -20,6 +20,7 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude \
     -I$(FOAM_SOLVERS)/combustion/reactingFoam
 
 
@@ -45,4 +46,5 @@ EXE_LIBS = \
     -lradiationModels \
     -lregionModels \
     -lsurfaceFilmModels \
-    -lODE
+    -lODE \
+    -lsampling
diff --git a/applications/solvers/lagrangian/icoUncoupledKinematicParcelDyMFoam/Make/options b/applications/solvers/lagrangian/icoUncoupledKinematicParcelDyMFoam/Make/options
index f7bb7d2f2d2..07869335410 100644
--- a/applications/solvers/lagrangian/icoUncoupledKinematicParcelDyMFoam/Make/options
+++ b/applications/solvers/lagrangian/icoUncoupledKinematicParcelDyMFoam/Make/options
@@ -14,7 +14,8 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
 
 
 EXE_LIBS = \
@@ -33,4 +34,5 @@ EXE_LIBS = \
     -lsurfaceFilmModels \
     -ldynamicMesh \
     -ldynamicFvMesh \
-    -ltopoChangerFvMesh
+    -ltopoChangerFvMesh \
+    -lsampling
diff --git a/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options b/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options
index 1de2ec74de1..58d80278f82 100644
--- a/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options
@@ -12,6 +12,7 @@ EXE_INC = \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
 
 EXE_LIBS = \
     -llagrangian \
@@ -26,4 +27,5 @@ EXE_LIBS = \
     -lfiniteVolume \
     -lmeshTools \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lsampling
diff --git a/applications/solvers/lagrangian/porousExplicitSourceReactingParcelFoam/Make/options b/applications/solvers/lagrangian/porousExplicitSourceReactingParcelFoam/Make/options
index 386e25dd477..f2dffe2998b 100644
--- a/applications/solvers/lagrangian/porousExplicitSourceReactingParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/porousExplicitSourceReactingParcelFoam/Make/options
@@ -20,6 +20,7 @@ EXE_INC = \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude \
     -I$(FOAM_SOLVERS)/combustion/reactingFoam
 
 
@@ -44,4 +45,5 @@ EXE_LIBS = \
     -lradiationModels \
     -lODE \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lsampling
diff --git a/applications/solvers/lagrangian/reactingParcelFilmFoam/Make/options b/applications/solvers/lagrangian/reactingParcelFilmFoam/Make/options
index cd1c25ffea9..6e225cc0923 100644
--- a/applications/solvers/lagrangian/reactingParcelFilmFoam/Make/options
+++ b/applications/solvers/lagrangian/reactingParcelFilmFoam/Make/options
@@ -19,6 +19,7 @@ EXE_INC = \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude \
     -I$(FOAM_SOLVERS)/combustion/reactingFoam
 
 
@@ -39,4 +40,5 @@ EXE_LIBS = \
     -lradiationModels \
     -lsurfaceFilmModels \
     -llagrangianIntermediate \
-    -lODE
+    -lODE \
+    -lsampling
diff --git a/applications/solvers/lagrangian/reactingParcelFoam/Make/options b/applications/solvers/lagrangian/reactingParcelFoam/Make/options
index 1380c457e26..fc312bb5fa8 100644
--- a/applications/solvers/lagrangian/reactingParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/reactingParcelFoam/Make/options
@@ -19,6 +19,7 @@ EXE_INC = \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude \
     -I$(FOAM_SOLVERS)/combustion/reactingFoam
 
 
@@ -43,4 +44,5 @@ EXE_LIBS = \
     -lradiationModels \
     -lODE \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lsampling
diff --git a/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options b/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options
index d302015a314..7a7ddc04327 100644
--- a/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options
@@ -9,7 +9,8 @@ EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
 
 EXE_LIBS = \
     -llagrangian \
@@ -24,4 +25,5 @@ EXE_LIBS = \
     -lfiniteVolume \
     -lmeshTools \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lsampling
diff --git a/src/lagrangian/coalCombustion/Make/options b/src/lagrangian/coalCombustion/Make/options
index 640565da2e4..7253a9073d2 100644
--- a/src/lagrangian/coalCombustion/Make/options
+++ b/src/lagrangian/coalCombustion/Make/options
@@ -19,7 +19,8 @@ EXE_INC = \
     -I$(LIB_SRC)/turbulenceModels/LES/LESdeltas/lnInclude \
     -I$(LIB_SRC)/turbulenceModels/compressible/LES/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options
index 6290aae9da6..951d16cf589 100644
--- a/src/lagrangian/intermediate/Make/options
+++ b/src/lagrangian/intermediate/Make/options
@@ -19,7 +19,8 @@ EXE_INC = \
     -I$(LIB_SRC)/turbulenceModels/compressible/LES/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
index 70c1e73c85c..dcd61572269 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
@@ -29,10 +29,11 @@ Description
 
     - cloud function objects
 
-    - particle forces
+    - particle forces, e.g.
       - buoyancy
       - drag
       - pressure gradient
+      - ...
 
     - sub-models:
       - dispersion model
diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
index b576cb2c84a..0074e1c751f 100644
--- a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
+++ b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
@@ -28,6 +28,7 @@ License
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#include "FacePostProcessing.H"
 #include "ParticleTracks.H"
 #include "PatchPostProcessing.H"
 
@@ -37,6 +38,7 @@ License
                                                                               \
     makeCloudFunctionObject(CloudType);                                       \
                                                                               \
+    makeCloudFunctionObjectType(FacePostProcessing, CloudType);               \
     makeCloudFunctionObjectType(ParticleTracks, CloudType);                   \
     makeCloudFunctionObjectType(PatchPostProcessing, CloudType);
 
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
new file mode 100644
index 00000000000..b3cdad013e6
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
@@ -0,0 +1,281 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "FacePostProcessing.H"
+#include "Pstream.H"
+#include "ListListOps.H"
+#include "surfaceWriter.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::label Foam::FacePostProcessing<CloudType>::applyToFace
+(
+    const label faceI
+) const
+{
+    forAll(fZone_, i)
+    {
+        if (fZone_[i] == faceI)
+        {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+
+template<class CloudType>
+void Foam::FacePostProcessing<CloudType>::write()
+{
+    const fvMesh& mesh = this->owner().mesh();
+    const scalar dt = this->owner().time().deltaTValue();
+
+    totalTime_ += dt;
+
+    const scalar alpha = (totalTime_ - dt)/totalTime_;
+    const scalar beta = dt/totalTime_;
+
+    massTotal_ += mass_;
+
+    massFlux_ = alpha*massFlux_ + beta*mass_/dt;
+
+    const label procI = Pstream::myProcNo();
+
+    scalarListList allProcMass(Pstream::nProcs());
+    allProcMass[procI].setSize(massTotal_.size());
+    allProcMass[procI] = massTotal_;
+    Pstream::gatherList(allProcMass);
+    scalarList allMass
+    (
+        ListListOps::combine<scalarList>
+        (
+            allProcMass, accessOp<scalarList>()
+        )
+    );
+
+    scalarListList allProcMassFlux(Pstream::nProcs());
+    allProcMassFlux[procI].setSize(massFlux_.size());
+    allProcMassFlux[procI] = massFlux_;
+    Pstream::gatherList(allProcMassFlux);
+    scalarList allMassFlux
+    (
+        ListListOps::combine<scalarList>
+        (
+            allProcMassFlux, accessOp<scalarList>()
+        )
+    );
+
+    Info<< "particleFaceFlux output:" << nl
+        << "    total mass      = " << sum(allMass) << nl
+        << "    average mass flux = " << sum(allMassFlux) << nl << endl;
+
+
+    if (surfaceFormat_ != "none")
+    {
+        labelList pointToGlobal;
+        labelList uniqueMeshPointLabels;
+        autoPtr<globalIndex> globalPointsPtr =
+            mesh.globalData().mergePoints
+            (
+                fZone_().meshPoints(),
+                fZone_().meshPointMap(),
+                pointToGlobal,
+                uniqueMeshPointLabels
+            );
+
+        pointField uniquePoints(mesh.points(), uniqueMeshPointLabels);
+        List<pointField> allProcPoints(Pstream::nProcs());
+        allProcPoints[procI].setSize(uniquePoints.size());
+        allProcPoints[procI] = uniquePoints;
+        Pstream::gatherList(allProcPoints);
+        pointField allPoints
+        (
+            ListListOps::combine<pointField>
+            (
+                allProcPoints, accessOp<pointField>()
+            )
+        );
+
+        faceList faces(fZone_().localFaces());
+        forAll(faces, i)
+        {
+            inplaceRenumber(pointToGlobal, faces[i]);
+        }
+        List<faceList> allProcFaces(Pstream::nProcs());
+        allProcFaces[procI].setSize(faces.size());
+        allProcFaces[procI] = faces;
+        Pstream::gatherList(allProcFaces);
+        faceList allFaces
+        (
+            ListListOps::combine<faceList>
+            (
+                allProcFaces, accessOp<faceList>()
+            )
+        );
+
+
+        if (Pstream::master())
+        {
+            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();
+            }
+
+            autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_));
+            writer->write
+            (
+                outputDir,
+                "massTotal",
+                allPoints,
+                allFaces,
+                "massTotal",
+                massTotal_,
+                false
+            );
+            writer->write
+            (
+                outputDir,
+                "massFlux",
+                allPoints,
+                allFaces,
+                "massFlux",
+                massFlux_,
+                false
+            );
+        }
+    }
+
+
+    if (resetOnWrite_)
+    {
+        massFlux_ = 0.0;
+        totalTime_ = 0.0;
+    }
+
+    mass_ = 0.0;
+
+    // writeProperties();
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::FacePostProcessing<CloudType>::FacePostProcessing
+(
+    const dictionary& dict,
+    CloudType& owner
+)
+:
+    CloudFunctionObject<CloudType>(dict, owner, typeName),
+    fZone_(owner.mesh().faceZones()[this->coeffDict().lookup("faceZone")]),
+    surfaceFormat_(this->coeffDict().lookup("surfaceFormat")),
+    resetOnWrite_(this->coeffDict().lookup("resetOnWrite")),
+    totalTime_(0.0),
+    mass_(),
+    massTotal_(),
+    massFlux_()
+{
+    label allFaces = returnReduce(fZone_().size(), sumOp<scalar>());
+    Info<< "        Number of faces = " << allFaces << endl;
+
+    mass_.setSize(fZone_.size(), 0.0);
+
+    // readProperties(); AND initialise mass... fields
+
+    massTotal_.setSize(fZone_.size(), 0.0);
+    massFlux_.setSize(fZone_.size(), 0.0);
+}
+
+
+template<class CloudType>
+Foam::FacePostProcessing<CloudType>::FacePostProcessing
+(
+    const FacePostProcessing<CloudType>& pff
+)
+:
+    CloudFunctionObject<CloudType>(pff),
+    fZone_(pff.fZone_.clone(pff.fZone_.zoneMesh())),
+    surfaceFormat_(pff.surfaceFormat_),
+    resetOnWrite_(pff.resetOnWrite_),
+    totalTime_(pff.totalTime_),
+    mass_(pff.mass_),
+    massTotal_(pff.massTotal_),
+    massFlux_(pff.massFlux_)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::FacePostProcessing<CloudType>::~FacePostProcessing()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class CloudType>
+void Foam::FacePostProcessing<CloudType>::postPatch
+(
+    const parcelType&,
+    const label
+)
+{}
+
+
+template<class CloudType>
+void Foam::FacePostProcessing<CloudType>::postFace(const parcelType& p)
+{
+    if
+    (
+        this->owner().solution().output()
+     || this->owner().solution().transient()
+    )
+    {
+        const label faceI = applyToFace(p.face());
+
+        if (faceI != -1)
+        {
+            mass_[faceI] += p.mass()*p.nParticle();
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H
new file mode 100644
index 00000000000..de239097e6e
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H
@@ -0,0 +1,167 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::FacePostProcessing
+
+Description
+    Records particle face quantities on used-specified face zone
+
+    Currently supports:
+        accummulated mass
+        average mass flux
+
+SourceFiles
+    FacePostProcessing.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef FacePostProcessing_H
+#define FacePostProcessing_H
+
+#include "CloudFunctionObject.H"
+#include "faceZone.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                     Class FacePostProcessing Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class CloudType>
+class FacePostProcessing
+:
+    public CloudFunctionObject<CloudType>
+{
+    // Private Data
+
+        // Typedefs
+
+            //- Convenience typedef for parcel type
+            typedef typename CloudType::parcelType parcelType;
+
+
+        //- Face zone
+        const faceZone& fZone_;
+
+        //- Surface output format
+        const word surfaceFormat_;
+
+        //- Flag to indicate whether data should be reset/cleared on writing
+        Switch resetOnWrite_;
+
+        //- Total time
+        scalar totalTime_;
+
+        //- Mass storage
+        scalarField mass_;
+
+        //- Mass total storage
+        scalarField massTotal_;
+
+        //- Mass flux storage
+        scalarField massFlux_;
+
+
+    // Private Member Functions
+
+        //- Return index into massFlux_ list if valid face, else -1
+        label applyToFace(const label faceI) const;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Write post-processing info
+        void write();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("facePostProcessing");
+
+
+    // Constructors
+
+        //- Construct from dictionary
+        FacePostProcessing(const dictionary& dict, CloudType& owner);
+
+        //- Construct copy
+        FacePostProcessing(const FacePostProcessing<CloudType>& ppm);
+
+        //- Construct and return a clone
+        virtual autoPtr<CloudFunctionObject<CloudType> > clone() const
+        {
+            return autoPtr<CloudFunctionObject<CloudType> >
+            (
+                new FacePostProcessing<CloudType>(*this)
+            );
+        }
+
+
+    //- Destructor
+    virtual ~FacePostProcessing();
+
+
+    // Member Functions
+
+        // Access
+
+            //- Return const access to the reset on write flag
+            inline const Switch& resetOnWrite() const;
+
+
+        // Evaluation
+
+            //- Post-patch hook
+            virtual void postPatch(const parcelType& p, const label patchI);
+
+            //- Post-face hook
+            virtual void postFace(const parcelType& p);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "FacePostProcessingI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "FacePostProcessing.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessingI.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessingI.H
new file mode 100644
index 00000000000..8c264fc24aa
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessingI.H
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+template<class CloudType>
+inline const Foam::Switch&
+Foam::FacePostProcessing<CloudType>::resetOnWrite() const
+{
+    return resetOnWrite_;
+}
+
+
+// ************************************************************************* //
-- 
GitLab