diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
index 1068ea00965b75d90d5d52339b62f2fba8df0ec0..d5f76f5af212e35fab7b4c8213a7f97d0394957e 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
@@ -32,20 +32,28 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class CloudType>
-Foam::label Foam::FacePostProcessing<CloudType>::applyToFace
+void Foam::FacePostProcessing<CloudType>::applyToFace
 (
-    const label faceI
+    const label faceIn,
+    label& zoneI,
+    label& faceI
 ) const
 {
-    forAll(fZone_, i)
+    const faceZoneMesh& fzm = this->owner().mesh().faceZones();
+
+    forAll(faceZoneIDs_, i)
     {
-        if (fZone_[i] == faceI)
+        const faceZone& fz = fzm[faceZoneIDs_[i]];
+        forAll(fz, j)
         {
-            return i;
-        }
+            if (fz[j] == faceIn)
+            {
+                zoneI = i;
+                faceI = j;
+                return;
+            }
+        }        
     }
-
-    return -1;
 }
 
 
@@ -53,6 +61,7 @@ template<class CloudType>
 void Foam::FacePostProcessing<CloudType>::write()
 {
     const fvMesh& mesh = this->owner().mesh();
+    const faceZoneMesh& fzm = this->owner().mesh().faceZones();
     const scalar dt = this->owner().time().deltaTValue();
 
     totalTime_ += dt;
@@ -60,133 +69,159 @@ void Foam::FacePostProcessing<CloudType>::write()
     const scalar alpha = (totalTime_ - dt)/totalTime_;
     const scalar beta = dt/totalTime_;
 
-    massTotal_ += mass_;
-
-    massFlux_ = alpha*massFlux_ + beta*mass_/dt;
+    forAll(faceZoneIDs_, zoneI)
+    {
+        massTotal_[zoneI] += mass_[zoneI];
+        massFlux_[zoneI] = alpha*massFlux_[zoneI] + beta*mass_[zoneI]/dt;
+    }
 
     const label procI = Pstream::myProcNo();
 
-    scalarListList allProcMass(Pstream::nProcs());
-    allProcMass[procI] = massTotal_;
-    Pstream::gatherList(allProcMass);
-    scalarField allMass
-    (
-        ListListOps::combine<scalarList>
-        (
-            allProcMass, accessOp<scalarList>()
-        )
-    );
-
-    scalarListList allProcMassFlux(Pstream::nProcs());
-    allProcMassFlux[procI] = massFlux_;
-    Pstream::gatherList(allProcMassFlux);
-    scalarField allMassFlux
-    (
-        ListListOps::combine<scalarList>
-        (
-            allProcMassFlux, accessOp<scalarList>()
-        )
-    );
+    Info<< "particleFaceFlux output:" << nl;
 
-    Info<< "particleFaceFlux output:" << nl
-        << "    total mass      = " << sum(allMass) << nl
-        << "    average mass flux = " << sum(allMassFlux) << nl << endl;
+    List<scalarField> zoneMassTotal(mass_.size());
+    forAll(zoneMassTotal, zoneI)
+    {
+        scalarListList allProcMass(Pstream::nProcs());
+        allProcMass[procI] = massTotal_[zoneI];
+        Pstream::gatherList(allProcMass);
+        zoneMassTotal[zoneI] =
+            ListListOps::combine<scalarList>
+            (
+                allProcMass, accessOp<scalarList>()
+            );
 
+        const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
+        Info<< "    " << zoneName << " total mass      = "
+            << sum(zoneMassTotal[zoneI]) << nl;
+    }
 
-    if (surfaceFormat_ != "none")
+    List<scalarField> zoneMassFlux(massFlux_.size());
+    forAll(zoneMassFlux, zoneI)
     {
-        labelList pointToGlobal;
-        labelList uniqueMeshPointLabels;
-        autoPtr<globalIndex> globalPointsPtr =
-            mesh.globalData().mergePoints
+        scalarListList allProcMassFlux(Pstream::nProcs());
+        allProcMassFlux[procI] = massFlux_[zoneI];
+        Pstream::gatherList(allProcMassFlux);
+        zoneMassFlux[zoneI] =
+            ListListOps::combine<scalarList>
             (
-                fZone_().meshPoints(),
-                fZone_().meshPointMap(),
-                pointToGlobal,
-                uniqueMeshPointLabels
+                allProcMassFlux, accessOp<scalarList>()
             );
 
-        pointField uniquePoints(mesh.points(), uniqueMeshPointLabels);
-        List<pointField> allProcPoints(Pstream::nProcs());
-        allProcPoints[procI] = uniquePoints;
-        Pstream::gatherList(allProcPoints);
+        const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
+        Info<< "    " << zoneName << " average mass flux = "
+            << sum(zoneMassFlux[zoneI]) << nl;
+    }
+
+    Info<< endl;
+
+
+    if (surfaceFormat_ != "none")
+    {
+        fileName outputDir = mesh.time().path();
 
-        faceList faces(fZone_().localFaces());
-        forAll(faces, i)
+        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
         {
-            inplaceRenumber(pointToGlobal, faces[i]);
+            outputDir =
+                outputDir/"postProcessing"/cloud::prefix/
+                this->owner().name()/mesh.time().timeName();
         }
-        List<faceList> allProcFaces(Pstream::nProcs());
-        allProcFaces[procI] = faces;
-        Pstream::gatherList(allProcFaces);
 
-        if (Pstream::master())
+        forAll(faceZoneIDs_, zoneI)
         {
-            pointField allPoints
-            (
-                ListListOps::combine<pointField>
-                (
-                    allProcPoints, accessOp<pointField>()
-                )
-            );
+            const faceZone& fZone = fzm[faceZoneIDs_[zoneI]];
 
-            faceList allFaces
-            (
-                ListListOps::combine<faceList>
+            labelList pointToGlobal;
+            labelList uniqueMeshPointLabels;
+            autoPtr<globalIndex> globalPointsPtr =
+                mesh.globalData().mergePoints
                 (
-                    allProcFaces, accessOp<faceList>()
-                )
-            );
-
-            fileName outputDir = mesh.time().path();
-
-            if (Pstream::parRun())
+                    fZone().meshPoints(),
+                    fZone().meshPointMap(),
+                    pointToGlobal,
+                    uniqueMeshPointLabels
+                );
+
+            pointField uniquePoints(mesh.points(), uniqueMeshPointLabels);
+            List<pointField> allProcPoints(Pstream::nProcs());
+            allProcPoints[procI] = uniquePoints;
+            Pstream::gatherList(allProcPoints);
+
+            faceList faces(fZone().localFaces());
+            forAll(faces, i)
             {
-                // Put in undecomposed case (Note: gives problems for
-                // distributed data running)
-                outputDir =
-                    outputDir/".."/"postProcessing"/cloud::prefix/
-                    this->owner().name()/mesh.time().timeName();
+                inplaceRenumber(pointToGlobal, faces[i]);
             }
-            else
+            List<faceList> allProcFaces(Pstream::nProcs());
+            allProcFaces[procI] = faces;
+            Pstream::gatherList(allProcFaces);
+
+            if (Pstream::master())
             {
-                outputDir =
-                    outputDir/"postProcessing"/cloud::prefix/
-                    this->owner().name()/mesh.time().timeName();
-            }
+                pointField allPoints
+                (
+                    ListListOps::combine<pointField>
+                    (
+                        allProcPoints, accessOp<pointField>()
+                    )
+                );
 
-            autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_));
-            writer->write
-            (
-                outputDir,
-                "massTotal",
-                allPoints,
-                allFaces,
-                "massTotal",
-                allMass,
-                false
-            );
-            writer->write
-            (
-                outputDir,
-                "massFlux",
-                allPoints,
-                allFaces,
-                "massFlux",
-                allMassFlux,
-                false
-            );
+                faceList allFaces
+                (
+                    ListListOps::combine<faceList>
+                    (
+                        allProcFaces, accessOp<faceList>()
+                    )
+                );
+
+                autoPtr<surfaceWriter> writer(surfaceWriter::New(surfaceFormat_));
+                writer->write
+                (
+                    outputDir,
+                    fZone.name(),
+                    allPoints,
+                    allFaces,
+                    "massTotal",
+                    zoneMassTotal[zoneI],
+                    false
+                );
+
+                writer->write
+                (
+                    outputDir,
+                    fZone.name(),
+                    allPoints,
+                    allFaces,
+                    "massFlux",
+                    zoneMassFlux[zoneI],
+                    false
+                );
+            }
         }
     }
 
 
     if (resetOnWrite_)
     {
-        massFlux_ = 0.0;
+        forAll(faceZoneIDs_, zoneI)
+        {
+            massFlux_[zoneI] = 0.0;
+        }
         totalTime_ = 0.0;
     }
 
-    mass_ = 0.0;
+    forAll(mass_, zoneI)
+    {
+        mass_[zoneI] = 0.0;
+    }
 
     // writeProperties();
 }
@@ -202,7 +237,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
 )
 :
     CloudFunctionObject<CloudType>(dict, owner, typeName),
-    fZone_(owner.mesh().faceZones()[this->coeffDict().lookup("faceZone")]),
+    faceZoneIDs_(),
     surfaceFormat_(this->coeffDict().lookup("surfaceFormat")),
     resetOnWrite_(this->coeffDict().lookup("resetOnWrite")),
     totalTime_(0.0),
@@ -210,15 +245,32 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
     massTotal_(),
     massFlux_()
 {
-    label allFaces = returnReduce(fZone_().size(), sumOp<scalar>());
-    Info<< "        Number of faces = " << allFaces << endl;
+    wordList faceZoneNames(this->coeffDict().lookup("faceZones"));
+    mass_.setSize(faceZoneNames.size());
+    massTotal_.setSize(faceZoneNames.size());
+    massFlux_.setSize(faceZoneNames.size());
+
+    DynamicList<label> zoneIDs;
+    const faceZoneMesh& fzm = owner.mesh().faceZones();
+    forAll(faceZoneNames, i)
+    {
+        const word& zoneName = faceZoneNames[i];
+        label zoneI = fzm.findZoneID(zoneName);
+        if (zoneI != -1)
+        {
+            zoneIDs.append(zoneI);
+            const faceZone& fz = fzm[zoneI];
+            label nFaces = returnReduce(fz.size(), sumOp<label>());
+            mass_[i].setSize(nFaces, 0.0);
+            massTotal_[i].setSize(nFaces, 0.0);
+            massFlux_[i].setSize(nFaces, 0.0);
+            Info<< "        " << zoneName << " faces: " << nFaces;
+        }
+    }
 
-    mass_.setSize(fZone_.size(), 0.0);
+    faceZoneIDs_.transfer(zoneIDs);
 
     // readProperties(); AND initialise mass... fields
-
-    massTotal_.setSize(fZone_.size(), 0.0);
-    massFlux_.setSize(fZone_.size(), 0.0);
 }
 
 
@@ -229,7 +281,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
 )
 :
     CloudFunctionObject<CloudType>(pff),
-    fZone_(pff.fZone_.clone(pff.fZone_.zoneMesh())),
+    faceZoneIDs_(pff.faceZoneIDs_),
     surfaceFormat_(pff.surfaceFormat_),
     resetOnWrite_(pff.resetOnWrite_),
     totalTime_(pff.totalTime_),
@@ -266,11 +318,13 @@ void Foam::FacePostProcessing<CloudType>::postFace(const parcelType& p)
      || this->owner().solution().transient()
     )
     {
-        const label faceI = applyToFace(p.face());
+        label zoneI = -1;
+        label faceI = -1;
+        applyToFace(p.face(), zoneI, faceI);
 
-        if (faceI != -1)
+        if ((zoneI != -1) && (faceI != -1))
         {
-            mass_[faceI] += p.mass()*p.nParticle();
+            mass_[zoneI][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
index de239097e6e1fa26c7bd7265baf36b802b477d00..85a80b1a4ade6ed985f2f1a04bcbb21842251a73 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.H
@@ -64,8 +64,8 @@ class FacePostProcessing
             typedef typename CloudType::parcelType parcelType;
 
 
-        //- Face zone
-        const faceZone& fZone_;
+        //- Face zone IDs
+        labelList faceZoneIDs_;
 
         //- Surface output format
         const word surfaceFormat_;
@@ -77,19 +77,24 @@ class FacePostProcessing
         scalar totalTime_;
 
         //- Mass storage
-        scalarField mass_;
+        List<scalarField> mass_;
 
         //- Mass total storage
-        scalarField massTotal_;
+        List<scalarField> massTotal_;
 
         //- Mass flux storage
-        scalarField massFlux_;
+        List<scalarField> massFlux_;
 
 
     // Private Member Functions
 
-        //- Return index into massFlux_ list if valid face, else -1
-        label applyToFace(const label faceI) const;
+        //- Return index into storage lists if valid zone and face
+        void applyToFace
+        (
+            const label faceIn,
+            label& zoneI, label&
+            faceI
+        ) const;
 
 
 protected: