diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
index b3aaac0dbf9fa2b525d96654f0fd494a470a449b..8dbf0ec5a89d2e0029fa2e20559bc397ab6cf153 100644
--- a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
+++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
@@ -27,8 +27,8 @@ License
 #include "volFields.H"
 #include "regionSplit.H"
 #include "fvcVolumeIntegrate.H"
-#include "Histogram.H"
 #include "mathematicalConstants.H"
+#include "stringListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -56,6 +56,281 @@ namespace Foam
 }
 
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::regionSizeDistribution::writeGraph
+(
+    const coordSet& coords,
+    const word& valueName,
+    const scalarField& values
+) const
+{
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+
+    const wordList valNames(1, valueName);
+
+    fileName outputPath;
+    if (Pstream::parRun())
+    {
+        outputPath = mesh.time().path()/".."/name_;
+    }
+    else
+    {
+        outputPath = mesh.time().path()/name_;
+    }
+
+    if (mesh.name() != fvMesh::defaultRegion)
+    {
+        outputPath = outputPath/mesh.name();
+    }
+
+    mkDir(outputPath/mesh.time().timeName());
+    OFstream str
+    (
+        outputPath
+      / mesh.time().timeName()
+      / formatterPtr_().getFileName(coords, valNames)
+    );
+    Info<< "Writing distribution of " << valueName << " to " << str.name()
+        << endl;
+
+    List<const scalarField*> valPtrs(1);
+    valPtrs[0] = &values;
+    formatterPtr_().write(coords, valNames, valPtrs, str);
+}
+
+
+void Foam::regionSizeDistribution::writeAlphaFields
+(
+    const regionSplit& regions,
+    const Map<label>& patchRegions,
+    const Map<scalar>& regionVolume,
+    const volScalarField& alpha
+) const
+{
+    const scalar maxDropletVol = 1.0/6.0*pow(maxDiam_, 3);
+
+    // Split alpha field
+    // ~~~~~~~~~~~~~~~~~
+    // Split into
+    //  - liquidCore            : region connected to inlet patches
+    //  - per region a volume   : for all other regions
+    //  - backgroundAlpha       : remaining alpha
+
+
+    // Construct field
+    volScalarField liquidCore
+    (
+        IOobject
+        (
+            alphaName_ + "_liquidCore",
+            obr_.time().timeName(),
+            obr_,
+            IOobject::NO_READ
+        ),
+        alpha,
+        fvPatchField<scalar>::calculatedType()
+    );
+
+    volScalarField backgroundAlpha
+    (
+        IOobject
+        (
+            alphaName_ + "_background",
+            obr_.time().timeName(),
+            obr_,
+            IOobject::NO_READ
+        ),
+        alpha,
+        fvPatchField<scalar>::calculatedType()
+    );
+
+
+    // Knock out any cell not in patchRegions
+    forAll(liquidCore, cellI)
+    {
+        label regionI = regions[cellI];
+        if (patchRegions.found(regionI))
+        {
+            backgroundAlpha[cellI] = 0;
+        }
+        else
+        {
+            liquidCore[cellI] = 0;
+
+            scalar regionVol = regionVolume[regionI];
+            if (regionVol < maxDropletVol)
+            {
+                backgroundAlpha[cellI] = 0;
+            }
+        }
+    }
+    liquidCore.correctBoundaryConditions();
+    backgroundAlpha.correctBoundaryConditions();
+
+    Info<< "Volume of liquid-core = "
+        << fvc::domainIntegrate(liquidCore).value()
+        << endl;
+    Info<< "Volume of background  = "
+        << fvc::domainIntegrate(backgroundAlpha).value()
+        << endl;
+
+    Info<< "Writing liquid-core field to " << liquidCore.name() << endl;
+    liquidCore.write();
+    Info<< "Writing background field to " << backgroundAlpha.name() << endl;
+    backgroundAlpha.write();
+}
+
+
+Foam::Map<Foam::label> Foam::regionSizeDistribution::findPatchRegions
+(
+    const polyMesh& mesh,
+    const regionSplit& regions
+) const
+{
+    // Mark all regions starting at patches
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    // Count number of patch faces (just for initial sizing)
+    const labelHashSet patchIDs(mesh.boundaryMesh().patchSet(patchNames_));
+
+    label nPatchFaces = 0;
+    forAllConstIter(labelHashSet, patchIDs, iter)
+    {
+        nPatchFaces += mesh.boundaryMesh()[iter.key()].size();
+    }
+
+
+    Map<label> patchRegions(nPatchFaces);
+    forAllConstIter(labelHashSet, patchIDs, iter)
+    {
+        const polyPatch& pp = mesh.boundaryMesh()[iter.key()];
+
+        // Collect all regions on the patch
+        const labelList& faceCells = pp.faceCells();
+
+        forAll(faceCells, i)
+        {
+            patchRegions.insert
+            (
+                regions[faceCells[i]],
+                Pstream::myProcNo()     // dummy value
+            );
+        }
+    }
+
+
+    // Make sure all the processors have the same set of regions
+    Pstream::mapCombineGather(patchRegions, minEqOp<label>());
+    Pstream::mapCombineScatter(patchRegions);
+
+    return patchRegions;
+}
+
+
+Foam::tmp<Foam::scalarField> Foam::regionSizeDistribution::divide
+(
+    const scalarField& num,
+    const scalarField& denom
+)
+{
+    tmp<scalarField> tresult(new scalarField(num.size()));
+    scalarField& result = tresult();
+
+    forAll(denom, i)
+    {
+        if (denom[i] != 0)
+        {
+            result[i] = num[i]/denom[i];
+        }
+        else
+        {
+            result[i] = 0.0;
+        }
+    }
+    return tresult;
+}
+
+
+void Foam::regionSizeDistribution::writeGraphs
+(
+    const word& fieldName,              // name of field
+    const labelList& indices,           // index of bin for each region
+    const scalarField& sortedField,     // per region field data
+    const scalarField& binCount,        // per bin number of regions
+    const coordSet& coords              // graph data for bins
+) const
+{
+    if (Pstream::master())
+    {
+        // Calculate per-bin average
+        scalarField binSum(nBins_, 0.0);
+        forAll(sortedField, i)
+        {
+            binSum[indices[i]] += sortedField[i];
+        }
+
+        scalarField binAvg(divide(binSum, binCount));
+
+        // Per bin deviation
+        scalarField binSqrSum(nBins_, 0.0);
+        forAll(sortedField, i)
+        {
+            binSqrSum[indices[i]] += Foam::sqr(sortedField[i]);
+        }
+        scalarField binDev
+        (
+            sqrt(divide(binSqrSum, binCount) - Foam::sqr(binAvg))
+        );
+
+        // Write average
+        writeGraph(coords, fieldName + "_sum", binSum);
+        // Write average
+        writeGraph(coords, fieldName + "_avg", binAvg);
+        // Write deviation
+        writeGraph(coords, fieldName + "_dev", binDev);
+    }
+}
+
+
+void Foam::regionSizeDistribution::writeGraphs
+(
+    const word& fieldName,              // name of field
+    const scalarField& cellField,       // per cell field data
+    const regionSplit& regions,         // per cell the region(=droplet)
+    const labelList& sortedRegions,     // valid regions in sorted order
+    const scalarField& sortedNormalisation,
+
+    const labelList& indices,           // per region index of bin
+    const scalarField& binCount,        // per bin number of regions
+    const coordSet& coords              // graph data for bins
+) const
+{
+    // Sum on a per-region basis. Parallel reduced.
+    Map<scalar> regionField(regionSum(regions, cellField));
+
+    // Extract in region order
+    scalarField sortedField
+    (
+        sortedNormalisation
+      * extractData
+        (
+            sortedRegions,
+            regionField
+        )
+    );
+
+    writeGraphs
+    (
+        fieldName,      // name of field
+        indices,        // index of bin for each region
+        sortedField,    // per region field data
+        binCount,       // per bin number of regions
+        coords          // graph data for bins
+    );
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::regionSizeDistribution::regionSizeDistribution
@@ -103,8 +378,11 @@ void Foam::regionSizeDistribution::read(const dictionary& dict)
         dict.lookup("field") >> alphaName_;
         dict.lookup("patches") >> patchNames_;
         dict.lookup("threshold") >> threshold_;
-        dict.lookup("volFraction") >> volFraction_;
+        dict.lookup("maxDiameter") >> maxDiam_;
+        minDiam_ = 0.0;
+        dict.readIfPresent("minDiameter", minDiam_);
         dict.lookup("nBins") >> nBins_;
+        dict.lookup("fields") >> fields_;
 
         word format(dict.lookup("setFormat"));
         formatterPtr_ = writer<scalar>::New(format);
@@ -163,14 +441,17 @@ void Foam::regionSizeDistribution::write()
            : obr_.lookupObject<volScalarField>(alphaName_)
         );
 
-        Info<< "Volume of alpha = "
+        Info<< "Volume of alpha          = "
             << fvc::domainIntegrate(alpha).value()
             << endl;
 
         const scalar meshVol = gSum(mesh.V());
-        Info<< "Mesh volume = " << meshVol << endl;
-        Info<< "Background region volume limit = " << volFraction_*meshVol
-            << endl;
+        const scalar maxDropletVol = 1.0/6.0*pow(maxDiam_, 3);
+        const scalar delta = (maxDiam_-minDiam_)/nBins_;
+
+        Info<< "Mesh volume              = " << meshVol << endl;
+        Info<< "Maximum droplet diameter = " << maxDiam_ << endl;
+        Info<< "Maximum droplet volume   = " << maxDropletVol << endl;
 
 
         // Determine blocked faces
@@ -260,325 +541,314 @@ void Foam::regionSizeDistribution::write()
         }
 
 
-        // Sum all regions
-        Map<Pair<scalar> > regionVolume(regions.nRegions()/Pstream::nProcs());
-        forAll(alpha, cellI)
-        {
-            scalar cellVol = mesh.V()[cellI];
-            scalar alphaVol = alpha[cellI]*cellVol;
+        // Determine regions connected to supplied patches
+        Map<label> patchRegions(findPatchRegions(mesh, regions));
 
-            label regionI = regions[cellI];
 
-            Map<Pair<scalar> >::iterator fnd = regionVolume.find(regionI);
-            if (fnd == regionVolume.end())
-            {
-                regionVolume.insert
-                (
-                    regionI,
-                    Pair<scalar>(cellVol, alphaVol)
-                );
-            }
-            else
-            {
-                fnd().first() += cellVol;
-                fnd().second() += alphaVol;
-            }
-        }
-        Pstream::mapCombineGather(regionVolume, ListPlusEqOp<scalar, 2>());
-        Pstream::mapCombineScatter(regionVolume);
 
+        // Sum all regions
+        const scalarField alphaVol = alpha.internalField()*mesh.V();
+        Map<scalar> allRegionVolume(regionSum(regions, mesh.V()));
+        Map<scalar> allRegionAlphaVolume(regionSum(regions, alphaVol));
+        Map<label> allRegionNumCells
+        (
+            regionSum
+            (
+                regions,
+                labelField(mesh.nCells(), 1.0)
+            )
+        );
 
         if (debug)
         {
             Info<< token::TAB << "Region"
                 << token::TAB << "Volume(mesh)"
                 << token::TAB << "Volume(" << alpha.name() << "):"
+                << token::TAB << "nCells"
                 << endl;
             scalar meshSumVol = 0.0;
             scalar alphaSumVol = 0.0;
+            label nCells = 0;
 
-            forAllConstIter(Map<Pair<scalar> >, regionVolume, iter)
+            Map<scalar>::const_iterator vIter = allRegionVolume.begin();
+            Map<scalar>::const_iterator aIter = allRegionAlphaVolume.begin();
+            Map<label>::const_iterator numIter = allRegionNumCells.begin();
+            for
+            (
+                ;
+                vIter != allRegionVolume.end()
+             && aIter != allRegionAlphaVolume.end();
+                ++vIter, ++aIter, ++numIter
+            )
             {
-                Info<< token::TAB << iter.key()
-                    << token::TAB << iter().first()
-                    << token::TAB << iter().second() << endl;
+                Info<< token::TAB << vIter.key()
+                    << token::TAB << vIter()
+                    << token::TAB << aIter()
+                    << token::TAB << numIter()
+                    << endl;
 
-                meshSumVol += iter().first();
-                alphaSumVol += iter().second();
+                meshSumVol += vIter();
+                alphaSumVol += aIter();
+                nCells += numIter();
             }
             Info<< token::TAB << "Total:"
                 << token::TAB << meshSumVol
-                << token::TAB << alphaSumVol << endl;
+                << token::TAB << alphaSumVol
+                << token::TAB << nCells
+                << endl;
             Info<< endl;
         }
 
 
 
-        // Mark all regions starting at patches
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-        // Count number of patch faces (just for initial sizing)
-        label nPatchFaces = 0;
-        forAll(patchNames_, i)
         {
-            const word& pName = patchNames_[i];
-            label patchI = mesh.boundaryMesh().findPatchID(pName);
-            if (patchI == -1)
-            {
-                WarningIn("regionSizeDistribution::write()")
-                    << "Cannot find patch " << pName << ". Valid patches are "
-                    << mesh.boundaryMesh().names()
-                    << endl;
-            }
-            else
+            Info<< "Patch connected regions (liquid core):" << endl;
+            Info<< token::TAB << "Region"
+                << token::TAB << "Volume(mesh)"
+                << token::TAB << "Volume(" << alpha.name() << "):"
+                << endl;
+            forAllConstIter(Map<label>, patchRegions, iter)
             {
-                nPatchFaces += mesh.boundaryMesh()[patchI].size();
+                label regionI = iter.key();
+                Info<< token::TAB << iter.key()
+                    << token::TAB << allRegionVolume[regionI]
+                    << token::TAB << allRegionAlphaVolume[regionI] << endl;
+
             }
+            Info<< endl;
         }
 
-        Map<label> keepRegions(nPatchFaces);
-        forAll(patchNames_, i)
         {
-            const word& pName = patchNames_[i];
+            Info<< "Background regions:" << endl;
+            Info<< token::TAB << "Region"
+                << token::TAB << "Volume(mesh)"
+                << token::TAB << "Volume(" << alpha.name() << "):"
+                << endl;
+            Map<scalar>::const_iterator vIter = allRegionVolume.begin();
+            Map<scalar>::const_iterator aIter = allRegionAlphaVolume.begin();
 
-            label patchI = mesh.boundaryMesh().findPatchID(pName);
-            if (patchI != -1)
+            for
+            (
+                ;
+                vIter != allRegionVolume.end()
+             && aIter != allRegionAlphaVolume.end();
+                ++vIter, ++aIter
+            )
             {
-                const polyPatch& pp = mesh.boundaryMesh()[patchI];
-
-                // Collect all regions on the patch
-                const labelList& faceCells = pp.faceCells();
-
-                forAll(faceCells, i)
+                if
+                (
+                   !patchRegions.found(vIter.key())
+                 && vIter() >= maxDropletVol
+                )
                 {
-                    keepRegions.insert
-                    (
-                        regions[faceCells[i]],
-                        Pstream::myProcNo()
-                    );
+                    Info<< token::TAB << vIter.key()
+                        << token::TAB << vIter()
+                        << token::TAB << aIter() << endl;
                 }
             }
+            Info<< endl;
         }
 
 
-        // Make sure all the processors have the same set of regions
-        Pstream::mapCombineGather(keepRegions, minEqOp<label>());
-        Pstream::mapCombineScatter(keepRegions);
 
-        Info<< "Patch connected regions (liquid core):" << endl;
-        forAllConstIter(Map<label>, keepRegions, iter)
-        {
-            label regionI = iter.key();
-            Pair<scalar>& vols = regionVolume[regionI];
-            Info<< token::TAB << iter.key()
-                << token::TAB << vols.first()
-                << token::TAB << vols.second() << endl;
+        // Split alpha field
+        // ~~~~~~~~~~~~~~~~~
+        // Split into
+        //  - liquidCore            : region connected to inlet patches
+        //  - per region a volume   : for all other regions
+        //  - backgroundAlpha       : remaining alpha
+        writeAlphaFields(regions, patchRegions, allRegionVolume, alpha);
 
-        }
-        Info<< endl;
 
-        Info<< "Background regions:" << endl;
-        forAllConstIter(Map<Pair<scalar> >, regionVolume, iter)
+        // Extract droplet-only allRegionVolume, i.e. delete liquid core
+        // (patchRegions) and background regions from maps.
+        // Note that we have to use mesh volume (allRegionVolume) and not
+        // allRegionAlphaVolume since background might not have alpha in it.
+        forAllIter(Map<scalar>, allRegionVolume, vIter)
         {
+            label regionI = vIter.key();
             if
             (
-               !keepRegions.found(iter.key())
-             && iter().first() >= volFraction_*meshVol
+                patchRegions.found(regionI)
+             || vIter() >= maxDropletVol
             )
             {
-                Info<< token::TAB << iter.key()
-                    << token::TAB << iter().first()
-                    << token::TAB << iter().second() << endl;
+                allRegionVolume.erase(vIter);
+                allRegionAlphaVolume.erase(regionI);
+                allRegionNumCells.erase(regionI);
             }
         }
-        Info<< endl;
 
+        if (allRegionVolume.size())
+        {
+            // Construct mids of bins for plotting
+            pointField xBin(nBins_);
 
-        // Split alpha field
-        // ~~~~~~~~~~~~~~~~~
-        // Split into
-        //  - liquidCore            : region connected to inlet patches
-        //  - per region a volume   : for all other regions
-        //  - backgroundAlpha       : remaining alpha
+            scalar x = 0.5*delta;
+            forAll(xBin, i)
+            {
+                xBin[i] = point(x, 0, 0);
+                x += delta;
+            }
 
+            const coordSet coords("diameter", "x", xBin, mag(xBin));
 
-        // Construct field
-        volScalarField liquidCore
-        (
-            IOobject
-            (
-                alphaName_ + "_liquidCore",
-                obr_.time().timeName(),
-                obr_,
-                IOobject::NO_READ
-            ),
-            alpha,
-            fvPatchField<scalar>::calculatedType()
-        );
 
-        volScalarField backgroundAlpha
-        (
-            IOobject
-            (
-                alphaName_ + "_background",
-                obr_.time().timeName(),
-                obr_,
-                IOobject::NO_READ
-            ),
-            alpha,
-            fvPatchField<scalar>::calculatedType()
-        );
+            // Get in region order the alpha*volume and diameter
+            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+            const labelList sortedRegions = allRegionAlphaVolume.sortedToc();
 
-        // Knock out any cell not in keepRegions
-        forAll(liquidCore, cellI)
-        {
-            label regionI = regions[cellI];
-            if (keepRegions.found(regionI))
+            scalarField sortedVols
+            (
+                extractData
+                (
+                    sortedRegions,
+                    allRegionAlphaVolume
+                )
+            );
+
+            // Calculate the diameters
+            scalarField sortedDiameters(sortedVols.size());
+            forAll(sortedDiameters, i)
             {
-                backgroundAlpha[cellI] = 0;
+                sortedDiameters[i] = Foam::cbrt
+                (
+                    sortedVols[i]
+                   *6/constant::mathematical::pi
+                );
             }
-            else
-            {
-                liquidCore[cellI] = 0;
 
-                scalar regionVol = regionVolume[regionI].first();
-                if (regionVol < volFraction_*meshVol)
-                {
-                    backgroundAlpha[cellI] = 0;
-                }
+            // Determine the bin index for all the diameters
+            labelList indices(sortedDiameters.size());
+            forAll(sortedDiameters, i)
+            {
+                indices[i] = (sortedDiameters[i]-minDiam_)/delta;
             }
-        }
-        liquidCore.correctBoundaryConditions();
-        backgroundAlpha.correctBoundaryConditions();
-
-        Info<< "Volume of liquid-core = "
-            << fvc::domainIntegrate(liquidCore).value()
-            << endl;
-
-        Info<< "Writing liquid-core field to " << liquidCore.name() << endl;
-        liquidCore.write();
-
-        Info<< "Volume of background = "
-            << fvc::domainIntegrate(backgroundAlpha).value()
-            << endl;
-
-        Info<< "Writing background field to " << backgroundAlpha.name() << endl;
-        backgroundAlpha.write();
 
+            // Calculate the counts per diameter bin
+            scalarField binCount(nBins_, 0.0);
+            forAll(sortedDiameters, i)
+            {
+                binCount[indices[i]] += 1.0;
+            }
 
+            // Write counts
+            if (Pstream::master())
+            {
+                writeGraph(coords, "count", binCount);
+            }
 
-        // Collect histogram
-        if (Pstream::master())
-        {
-            DynamicList<scalar> diameters(regionVolume.size());
-            forAllConstIter(Map<Pair<scalar> >, regionVolume, iter)
+            // Write to screen
             {
-                if (!keepRegions.found(iter.key()))
+                Info<< "Bins:" << endl;
+                Info<< token::TAB << "Bin"
+                    << token::TAB << "Min diameter"
+                    << token::TAB << "Count:"
+                    << endl;
+
+                scalar diam = 0.0;
+                forAll(binCount, binI)
                 {
-                    if (iter().first() < volFraction_*meshVol)
-                    {
-                        scalar v = iter().second();
-                      //scalar diam = Foam::cbrt(v*6/mathematicalConstant::pi);
-                        scalar diam =
-                            Foam::cbrt(v*6/constant::mathematical::pi);
-                        diameters.append(diam);
-                    }
+                    Info<< token::TAB << binI
+                        << token::TAB << diam
+                        << token::TAB << binCount[binI] << endl;
+                    diam += delta;
                 }
+                Info<< endl;
             }
 
-            if (diameters.size())
+
+            // Write average and deviation of droplet volume.
+            writeGraphs
+            (
+                "volume",           // name of field
+                indices,            // per region the bin index
+                sortedVols,         // per region field data
+                binCount,           // per bin number of regions
+                coords              // graph data for bins
+            );
+
+            // Collect some more field
             {
-                scalar maxDiam = max(diameters);
-                scalar minDiam = 0.0;
+                wordList scalarNames(obr_.names(volScalarField::typeName));
+                labelList selected = findStrings(fields_, scalarNames);
 
-                Info<< "Maximum diameter:" << maxDiam << endl;
+                forAll(selected, i)
+                {
+                    const word& fldName = scalarNames[selected[i]];
+                    Info<< "Scalar field " << fldName << endl;
 
-                Histogram<List<scalar> > bins
-                (
-                    minDiam,
-                    maxDiam,
-                    nBins_,
-                    diameters
-                );
+                    const scalarField& fld = obr_.lookupObject
+                    <
+                        volScalarField
+                    >(fldName).internalField();
 
-                /* 1.7.x
-                scalarField xBin(nBins_);
+                    writeGraphs
+                    (
+                        fldName,            // name of field
+                        alphaVol*fld,       // per cell field data
 
-                scalar dx = (maxDiam-minDiam)/nBins_;
-                scalar x = 0.5*dx;
-                forAll(bins.counts(), i)
-                {
-                    xBin[i] = x;
-                    x += dx;
+                        regions,            // per cell the region(=droplet)
+                        sortedRegions,      // valid regions in sorted order
+                        1.0/sortedVols,     // per region normalisation
+
+                        indices,            // index of bin for each region
+                        binCount,           // per bin number of regions
+                        coords              // graph data for bins
+                    );
                 }
+            }
+            {
+                wordList vectorNames(obr_.names(volVectorField::typeName));
+                labelList selected = findStrings(fields_, vectorNames);
 
-                scalarField normalisedCount(bins.counts().size());
-                forAll(bins.counts(), i)
+                forAll(selected, i)
                 {
-                    normalisedCount[i] = 1.0*bins.counts()[i];
-                }
+                    const word& fldName = vectorNames[selected[i]];
+                    Info<< "Vector field " << fldName << endl;
 
-                const coordSet coords
-                (
-                    "diameter",
-                    "x",
-                    xBin
-                );
-                */
+                    const vectorField& fld = obr_.lookupObject
+                    <
+                        volVectorField
+                    >(fldName).internalField();
 
-                pointField xBin(nBins_);
-                scalar dx = (maxDiam - minDiam)/nBins_;
-                scalar x = 0.5*dx;
-                forAll(bins.counts(), i)
-                {
-                    xBin[i] = point(x, 0, 0);
-                    x += dx;
-                }
 
-                scalarField normalisedCount(bins.counts().size());
-                forAll(bins.counts(), i)
-                {
-                    normalisedCount[i] = 1.0*bins.counts()[i];
-                }
+                    // Components
 
-                const coordSet coords
-                (
-                    "diameter",
-                    "x",
-                    xBin,
-                    mag(xBin)
-                );
-                const wordList valNames(1, "count");
+                    for (direction cmp = 0; cmp < vector::nComponents; cmp++)
+                    {
+                        writeGraphs
+                        (
+                            fldName + vector::componentNames[cmp],
+                            alphaVol*fld.component(cmp),// per cell field data
 
+                            regions,        // per cell the region(=droplet)
+                            sortedRegions,  // valid regions in sorted order
+                            1.0/sortedVols, // per region normalisation
 
-                fileName outputPath;
-                if (Pstream::parRun())
-                {
-                    outputPath = mesh.time().path()/".."/name_;
-                }
-                else
-                {
-                    outputPath = mesh.time().path()/name_;
-                }
+                            indices,        // index of bin for each region
+                            binCount,       // per bin number of regions
+                            coords          // graph data for bins
+                        );
+                    }
 
-                if (mesh.name() != fvMesh::defaultRegion)
-                {
-                    outputPath = outputPath/mesh.name();
-                }
+                    // Magnitude
+                    writeGraphs
+                    (
+                        fldName + "mag",    // name of field
+                        alphaVol*mag(fld),  // per cell field data
 
-                mkDir(outputPath/mesh.time().timeName());
-                OFstream str
-                (
-                    outputPath
-                  / mesh.time().timeName()
-                  / formatterPtr_().getFileName(coords, valNames)
-                );
-                Info<< "Writing distribution to " << str.name() << endl;
+                        regions,            // per cell the region(=droplet)
+                        sortedRegions,      // valid regions in sorted order
+                        1.0/sortedVols,     // per region normalisation
 
-                List<const scalarField*> valPtrs(1);
-                valPtrs[0] = &normalisedCount;
-                formatterPtr_().write(coords, valNames, valPtrs, str);
+                        indices,            // index of bin for each region
+                        binCount,           // per bin number of regions
+                        coords              // graph data for bins
+                    );
+                }
             }
         }
     }
diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H
index 033b5f9aeca13c2e81f26f3b0fe52d32b4b90b7d..7802733249ece4d57607f46282b78f976f795e2b 100644
--- a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H
+++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H
@@ -25,11 +25,67 @@ Class
     Foam::regionSizeDistribution
 
 Description
-    Looks up a field, interpolates it to the faces and determines a connected
-    region from a patch where the field is above a certain value.
-    - Writes a field containing all regions starting at given patch
-      ('liquid core')
-    - All other regions are summed for volume and a histogram is calculated.
+    Droplet size distribution calculation.
+
+    Looks up a void-fraction (alpha) field and splits the mesh into regions
+    based on where the field is below the threshold value. These
+    regions ("droplets") can now be analysed.
+
+    Regions:
+    - (debug) write regions as a volScalarField
+    - (debug) print for all regions the sum of volume and alpha*volume
+    - print the regions connected to a user-defined set of patches.
+      (in spray calculation these form the liquid core)
+    - print the regions with too large volume. These are the 'background'
+      regions.
+
+    Fields:
+    - write volScalarField alpha_liquidCore : alpha with outside liquid core
+                                              set to 0.
+                           alpha_background : alpha with outside background
+                                              set to 0.
+
+    Histogram:
+    - determine histogram of diameter (given minDiameter, maxDiameter, nBins)
+    - write graph of number of droplets per bin
+    - write graph of sum, average and deviation of droplet volume per bin
+    - write graph of sum, average and deviation of user-defined fields. For
+      volVectorFields these are those of the 3 components and the magnitude.
+
+    Sample input:
+
+    functions
+    {
+        regionSizeDistribution
+        {
+            type            regionSizeDistribution;
+
+            outputControl   timeStep;
+            outputInterval  1;
+
+            // Field to determine regions from
+            field           alpha;
+            // Patches that provide the liquid core
+            patches         (inlet);
+            // Delimit alpha regions
+            threshold       0.4;
+
+            // Fields to sample (no need to include alpha)
+            fields          (p U);
+
+            // Number of bins for histogram
+            nBins           100;
+            // Max droplet diameter
+            maxDiameter     0.5e-4;
+            //// Min droplet diameter (default is 0)
+            //minDiameter     0;
+
+            // Writing format
+            setFormat       gnuplot;
+        }
+    }
+
+
 
 SourceFiles
     regionSizeDistribution.C
@@ -41,6 +97,9 @@ SourceFiles
 
 #include "pointFieldFwd.H"
 #include "writer.H"
+#include "Map.H"
+#include "volFieldsFwd.H"
+#include "wordReList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -51,6 +110,8 @@ namespace Foam
 class objectRegistry;
 class dictionary;
 class mapPolyMesh;
+class regionSplit;
+class polyMesh;
 
 /*---------------------------------------------------------------------------*\
                            Class regionSizeDistribution Declaration
@@ -72,23 +133,85 @@ class regionSizeDistribution
         word alphaName_;
 
         //- Patches to walk from
-        wordList patchNames_;
+        wordReList patchNames_;
 
         //- Clip value
         scalar threshold_;
 
-        //- Background region volFraction
-        scalar volFraction_;
+        //- Maximum droplet diameter
+        scalar maxDiam_;
+
+        //- Minimum droplet diameter
+        scalar minDiam_;
 
         //- Mumber of bins
         label nBins_;
 
+        //- Names of fields to sample on regions
+        wordReList fields_;
+
         //- Output formatter to write
         autoPtr<writer<scalar> > formatterPtr_;
 
 
     // Private Member Functions
 
+        template<class Type>
+        Map<Type> regionSum(const regionSplit&, const Field<Type>&) const;
+
+        //- Get data in order
+        template<class Type>
+        List<Type> extractData(const UList<label>& keys, const Map<Type>&)
+        const;
+
+        void writeGraph
+        (
+            const coordSet& coords,
+            const word& valueName,
+            const scalarField& values
+        ) const;
+
+        //- Write volfields with the parts of alpha which are not
+        //  droplets (liquidCore, backGround)
+        void writeAlphaFields
+        (
+            const regionSplit& regions,
+            const Map<label>& keepRegions,
+            const Map<scalar>& regionVolume,
+            const volScalarField& alpha
+        ) const;
+
+        //- Mark all regions starting at patches
+        Map<label> findPatchRegions(const polyMesh&, const regionSplit&) const;
+
+        //- Helper: divide if denom != 0
+        static tmp<scalarField> divide(const scalarField&, const scalarField&);
+
+        //- Given per-region data calculate per-bin average/deviation and graph
+        void writeGraphs
+        (
+            const word& fieldName,              // name of field
+            const labelList& indices,           // index of bin for each region
+            const scalarField& sortedField,     // per region field data
+            const scalarField& binCount,        // per bin number of regions
+            const coordSet& coords              // graph data for bins
+        ) const;
+
+        //- Given per-cell data calculate per-bin average/deviation and graph
+        void writeGraphs
+        (
+            const word& fieldName,              // name of field
+            const scalarField& cellField,       // per cell field data
+
+            const regionSplit& regions,         // per cell the region(=droplet)
+            const labelList& sortedRegions,     // valid regions in sorted order
+            const scalarField& sortedNormalisation,
+
+            const labelList& indices,           // index of bin for each region
+            const scalarField& binCount,        // per bin number of regions
+            const coordSet& coords              // graph data for bins
+        ) const;
+
         //- Disallow default bitwise copy construct
         regionSizeDistribution(const regionSizeDistribution&);
 
@@ -156,6 +279,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+#   include "regionSizeDistributionTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #endif
 
 // ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistributionTemplates.C b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistributionTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..2f55434315f165816263af977965f0cf4db898d7
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistributionTemplates.C
@@ -0,0 +1,81 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "regionSizeDistribution.H"
+#include "regionSplit.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Type>
+Foam::Map<Type> Foam::regionSizeDistribution::regionSum
+(
+    const regionSplit& regions,
+    const Field<Type>& fld
+) const
+{
+    // Per region the sum of fld
+    Map<Type> regionToSum(regions.nRegions()/Pstream::nProcs());
+
+    forAll(fld, cellI)
+    {
+        label regionI = regions[cellI];
+
+        typename Map<Type>::iterator fnd = regionToSum.find(regionI);
+        if (fnd == regionToSum.end())
+        {
+            regionToSum.insert(regionI, fld[cellI]);
+        }
+        else
+        {
+            fnd() += fld[cellI];
+        }
+    }
+    Pstream::mapCombineGather(regionToSum, plusEqOp<Type>());
+    Pstream::mapCombineScatter(regionToSum);
+
+    return regionToSum;
+}
+
+
+// Get data in sortedToc order
+template<class Type>
+Foam::List<Type> Foam::regionSizeDistribution::extractData
+(
+    const UList<label>& keys,
+    const Map<Type>& regionData
+) const
+{
+    List<Type> sortedData(keys.size());
+
+    forAll(keys, i)
+    {
+        sortedData[i] = regionData[keys[i]];
+    }
+    return sortedData;
+}
+
+
+// ************************************************************************* //