diff --git a/src/functionObjects/lagrangian/Make/files b/src/functionObjects/lagrangian/Make/files
index c7feb02e33ffcdbbcf385cd0be5ee13d40348ea1..8a65315b9adb9bfd649dd99e527e580e0e2331ea 100644
--- a/src/functionObjects/lagrangian/Make/files
+++ b/src/functionObjects/lagrangian/Make/files
@@ -4,5 +4,6 @@ icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C
 dsmcFields/dsmcFields.C
 
 vtkCloud/vtkCloud.C
+vtkCloud/parcelSelectionDetail.C
 
 LIB = $(FOAM_LIBBIN)/liblagrangianFunctionObjects
diff --git a/src/functionObjects/lagrangian/vtkCloud/parcelSelectionDetail.C b/src/functionObjects/lagrangian/vtkCloud/parcelSelectionDetail.C
new file mode 100644
index 0000000000000000000000000000000000000000..d436f7f9385590fbf94044bde8a2fcaac1680739
--- /dev/null
+++ b/src/functionObjects/lagrangian/vtkCloud/parcelSelectionDetail.C
@@ -0,0 +1,416 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 "parcelSelectionDetail.H"
+#include "scalarPredicates.H"
+#include "labelField.H"
+#include "scalarField.H"
+#include "pointField.H"
+#include "ListListOps.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::Enum
+<
+    Foam::Detail::parcelSelection::actionType
+>
+Foam::Detail::parcelSelection::actionNames
+({
+    { actionType::ALL, "all" },
+    { actionType::CLEAR, "clear" },
+    { actionType::INVERT, "invert" },
+    { actionType::ADD, "add" },
+    { actionType::SUBTRACT, "subtract" },
+    { actionType::SUBSET, "subset" },
+    { actionType::IGNORE, "ignore" },
+});
+
+
+const Foam::Enum
+<
+    Foam::Detail::parcelSelection::sourceType
+>
+Foam::Detail::parcelSelection::sourceNames
+({
+    { sourceType::FIELD, "field" },
+    { sourceType::STRIDE, "stride" },
+});
+
+
+const Foam::Enum
+<
+    Foam::Detail::parcelSelection::logicType
+> Foam::Detail::parcelSelection::logicNames
+({
+    { logicType::AND, "and" },
+    { logicType::OR, "or" },
+});
+
+
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    template<class Type, class Predicate, class AccessOp>
+    static void apply
+    (
+        bitSet& selection,
+        const Detail::parcelSelection::actionType action,
+        const Predicate& accept,
+        const UList<Type>& list,
+        const AccessOp& aop
+    )
+    {
+        using actionType = Detail::parcelSelection::actionType;
+
+        const label len = selection.size();
+
+        switch (action)
+        {
+            case actionType::ADD:
+            {
+                for (label parceli = 0; parceli < len; ++parceli)
+                {
+                    if (accept(aop(list[parceli])))
+                    {
+                        selection.set(parceli);
+                    }
+                }
+            }
+            break;
+
+            case actionType::SUBTRACT:
+            {
+                for (label parceli = 0; parceli < len; ++parceli)
+                {
+                    if (accept(aop(list[parceli])))
+                    {
+                        selection.unset(parceli);
+                    }
+                }
+            }
+            break;
+
+            case actionType::SUBSET:
+            {
+                for (const label parceli : selection)
+                {
+                    if (!accept(aop(list[parceli])))
+                    {
+                        selection.unset(parceli);
+                    }
+                }
+            }
+            break;
+
+            default:
+                break;
+        }
+    }
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::Detail::parcelSelection::parcelSelection()
+:
+    parcelSelect_(),
+    parcelAddr_()
+{}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+bool Foam::Detail::parcelSelection::calculateFilter
+(
+    const objectRegistry& obrTmp,
+    const bool log
+)
+{
+    if (parcelSelect_.empty())
+    {
+        parcelAddr_.clear();
+        return false;
+    }
+
+    // Start with all parcels unselected
+
+    // Number of parcels (locally)
+    const auto* pointsPtr = obrTmp.findObject<vectorField>("position");
+    label nParcels = pointsPtr->size();
+
+    parcelAddr_.reset();
+    parcelAddr_.resize(nParcels);
+
+    reduce(nParcels, sumOp<label>());
+
+    Log << "Applying parcel filtering to " << nParcels << " parcels" << nl;
+
+    if (!nParcels)
+    {
+        parcelAddr_.clear();
+        return false;
+    }
+
+    // The unary function type(s) for testing a scalar.
+    // Allocate 3 slots.
+    // 0 is the test
+    // 1,2 are for storage of composite tests (eg, and/or logic)
+    predicates::scalars tests(3);
+
+    for (const entry& dEntry : parcelSelect_)
+    {
+        if (!dEntry.isDict())
+        {
+            WarningInFunction
+                << "Ignoring non-dictionary entry "
+                << dEntry << endl;
+            continue;
+        }
+
+        const dictionary& dict = dEntry.dict();
+
+        // A very limited number of sources (stride, field)
+        // and actions (all add subtract subset) so handle manually
+
+        auto action = actionNames.get("action", dict);
+
+        // These ones we do directly
+        switch (action)
+        {
+            case actionType::ALL:
+                Log << "- select all" << nl;
+                parcelAddr_ = true;
+                continue;
+                break;
+
+            case actionType::CLEAR:
+                Log << "- clear" << nl;
+                parcelAddr_ = false;
+                continue;
+                break;
+
+            case actionType::INVERT:
+                Log << "- invert" << nl;
+                parcelAddr_.flip();
+                continue;
+                break;
+
+            case actionType::IGNORE:
+                continue;
+                break;
+
+            default:
+                break;
+        }
+
+        // The others need a source
+        // Need a source
+        const auto source = sourceNames.get("source", dict);
+
+        switch (source)
+        {
+            case sourceType::STRIDE:
+            {
+                const label stride = dict.get<label>("stride");
+
+                const labelField& ids =
+                    obrTmp.lookupObject<labelField>("origId");
+
+                Log << "- " << actionNames[action]
+                    << " stride " << stride << nl;
+
+                if (stride <= 0)
+                {
+                    WarningInFunction
+                        << nl
+                        << "Ignoring bad value for stride=" << stride << nl
+                        << endl;
+                }
+                else if (stride == 1)
+                {
+                    // More efficient handling of stride 1, but should
+                    // not really be using stride == 1.
+                    switch (action)
+                    {
+                        case actionType::ADD:
+                            parcelAddr_ = true;
+                            break;
+
+                        case actionType::SUBTRACT:
+                            parcelAddr_ = false;
+                            break;
+
+                        default:
+                            break;
+                    }
+                }
+                else
+                {
+                    // Using stride > 1
+                    apply
+                    (
+                        parcelAddr_,
+                        action,
+                        [=](const label id) -> bool { return !(id % stride); },
+                        ids,
+                        accessOp<label>()  // pass-through
+                    );
+                }
+            }
+            break;
+
+            case sourceType::FIELD:
+            {
+                const word fieldName(dict.get<word>("field"));
+
+                const auto* labelFld =
+                    obrTmp.findObject<labelField>(fieldName);
+
+                const auto* scalarFld =
+                    obrTmp.findObject<scalarField>(fieldName);
+
+                const auto* vectorFld =
+                    obrTmp.findObject<vectorField>(fieldName);
+
+
+                Log << "- " << actionNames[action] << " field " << fieldName;
+
+                if (!labelFld && !scalarFld && !vectorFld)
+                {
+                    WarningInFunction
+                        << nl
+                        << "No scalar/vector parcel field: " << fieldName
+                        << " ignoring selection" << nl
+                        << endl;
+                    continue;
+                }
+
+                const entry& e = dict.lookupEntry("accept", keyType::LITERAL);
+
+                ITstream& is = e.stream();
+
+                if (4 == is.size())
+                {
+                    // 4 tokens:
+                    //  -> (op val)
+
+                    Tuple2<word,scalar> expr1(is);
+                    e.checkITstream(is);
+
+                    tests.first() = predicates::scalars::operation(expr1);
+
+                    Log << " : " << expr1;
+                }
+                else if (9 == is.size())
+                {
+                    // 9 tokens:
+                    //  ->  (op val) and (op val)
+                    //  ->  (op val) or (op val)
+
+                    Tuple2<word,scalar> expr1(is);
+                    word logicName(is);
+                    Tuple2<word,scalar> expr2(is);
+                    e.checkITstream(is);
+
+                    logicType logic = logicNames[logicName];
+                    tests[1] = predicates::scalars::operation(expr1);
+                    tests[2] = predicates::scalars::operation(expr2);
+
+                    switch (logic)
+                    {
+                        case logicType::AND:
+                            tests.first() =
+                                predicates::scalars::andOp(tests[1], tests[2]);
+                            break;
+
+                        case logicType::OR:
+                            tests.first() =
+                                predicates::scalars::orOp(tests[1], tests[2]);
+                            break;
+                    }
+
+                    Log << " : " << expr1 << ' ' << logicName << ' ' << expr2;
+                }
+                else
+                {
+                    action = actionType::IGNORE;
+
+                    // Use the following to always provoke an error.
+                    e.checkITstream(is);
+                }
+
+                if (labelFld)
+                {
+                    apply
+                    (
+                        parcelAddr_,
+                        action,
+                        tests.first(),
+                        *labelFld,
+                        accessOp<label>()  // pass-through
+                    );
+                }
+                else if (scalarFld)
+                {
+                    apply
+                    (
+                        parcelAddr_,
+                        action,
+                        tests.first(),
+                        *scalarFld,
+                        accessOp<scalar>() // pass-through
+                    );
+                }
+                else if (vectorFld)
+                {
+                    apply
+                    (
+                        parcelAddr_,
+                        action,
+                        tests.first(),
+                        *vectorFld,
+                        [](const vector& val) -> scalar
+                        {
+                            return Foam::mag(val);
+                        }
+                    );
+                }
+
+                Log << endl;
+            }
+            break;
+
+            default:
+                break;
+        }
+    }
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/functionObjects/lagrangian/vtkCloud/parcelSelectionDetail.H b/src/functionObjects/lagrangian/vtkCloud/parcelSelectionDetail.H
new file mode 100644
index 0000000000000000000000000000000000000000..bf7f0f1276957baa50898b93fb5745e52fe6a903
--- /dev/null
+++ b/src/functionObjects/lagrangian/vtkCloud/parcelSelectionDetail.H
@@ -0,0 +1,221 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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::Detail::parcelSelection
+
+Description
+    Selection of parcels based on their objectRegistry entries.
+    Normally accessed via a dictionary entry.
+
+    Example sub-dictionary entry
+    \verbatim
+    selection
+    {
+        stride
+        {
+            // every 10th parcelId
+            action  add;
+            source  stride;
+            stride  10;
+        }
+        injector
+        {
+            // Only output from injectorID == 1
+            action  subset;
+            source  field;
+            field   typeId;
+            accept  (equal 1);
+        }
+        Umin
+        {
+            // Remove slow parcels
+            action  subtract;
+            source  field;
+            field   U;
+            accept  (less 1e-3);
+        }
+        diam
+        {
+            // Only particular diameter ranges
+            action  subset;
+            source  field;
+            field   d;
+            accept  (greater 1e-3) and (less 1e-3);
+        }
+    }
+    \endverbatim
+
+    \heading Entry type
+    \table
+        Property    | Description                           | Required | Default
+        action      | all/clear/invert add/subtract/subset/ignore | yes |
+        source      | field/stride                          | mostly  |
+    \endtable
+
+    \heading Stride source
+    \table
+        Property    | Description                           | Required | Default
+        stride      | The stride for the parcel id          | yes |
+    \endtable
+
+    \heading Field source
+    \table
+        Property    | Description                           | Required | Default
+        field       | The label/scalar/vector field name    | yes |
+        accept      | Acceptance or test criterion          | yes |
+    \endtable
+
+    The \c accept criterion has two forms:
+      -# single expression
+         - (expr)
+      -# composite expression
+         - (expr) or (expr)
+         - (expr) and (expr)
+
+    The expressions are a (op scalar) pair that form a unary scalar
+    predicate. The \a op is one of the following:
+    - lt, less
+    - le, lessEq
+    - gt, greater
+    - ge, greaterEq
+    - eq, equal
+    - neq, notEqual
+
+    For example,
+    \verbatim
+    accept  (less 10);
+    accept  (less 10) or (greater 100);
+    accept  (ge 10) and (le 20);
+    \endverbatim
+
+See also
+    Foam::predicates::scalars
+    Foam::functionObjects::vtkCloud
+
+SourceFiles
+    parcelSelectionDetail.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef parcelSelectionDetail_H
+#define parcelSelectionDetail_H
+
+#include "bitSet.H"
+#include "Enum.H"
+#include "objectRegistry.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Detail
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class Detail::parcelSelection Declaration
+\*---------------------------------------------------------------------------*/
+
+class parcelSelection
+{
+public:
+
+    //- Enumeration defining the valid selection actions
+    enum actionType
+    {
+        ALL,                //!< "all" - select all parcels
+        CLEAR,              //!< "clear" - clear the selection
+        INVERT,             //!< "invert" - invert the selection
+        ADD,                //!< "add" - parcel selection
+        SUBTRACT,           //!< "subtract" - remove parcel selection
+        SUBSET,             //!< "subset" - subset parcel selection
+        IGNORE,             //!< "ignore" - dummy no-op
+    };
+
+    //- Names for the actionType
+    static const Enum<actionType> actionNames;
+
+
+    //- Enumeration defining the valid sources
+    enum sourceType
+    {
+        FIELD,              //!< "field" - select based on field value
+        STRIDE              //!< "stride" - select based on stride (parcel id)
+    };
+
+    //- Names for the sourceType
+    static const Enum<sourceType> sourceNames;
+
+
+    //- Enumeration defining and/or logic
+    enum logicType { AND, OR };
+
+    //- Names for the logicType
+    static const Enum<logicType> logicNames;
+
+
+protected:
+
+    // Protected data
+
+        //- The filtered parcel addressing. Eg, for the current cloud.
+        dictionary parcelSelect_;
+
+        //- The filtered parcel addressing. Eg, for the current cloud.
+        bitSet parcelAddr_;
+
+
+    // Protected Member Functions
+
+        //- Calculate parcel selection filter.
+        //  \return True if the filter is applicable
+        bool calculateFilter
+        (
+            const objectRegistry& obrTmp,
+            const bool log = true
+        );
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        parcelSelection();
+
+
+    //- Destructor
+    virtual ~parcelSelection() = default;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Detail
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C
index 840e6da70c5b7c3287f90e3d3c9c94095963cb07..b5fd758a7c03b13d5758ccb203bb5da2f0b0f1f6 100644
--- a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C
+++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C
@@ -132,9 +132,23 @@ bool Foam::functionObjects::vtkCloud::writeCloud
         return false;
     }
 
+    applyFilter_ = calculateFilter(obrTmp, log);
+    reduce(applyFilter_, orOp<bool>());
+
+
+    // Number of parcels (locally)
+    label nParcels = (applyFilter_ ? parcelAddr_.count() : pointsPtr->size());
+
     // Total number of parcels on all processes
-    const label nTotParcels =
-        returnReduce(pointsPtr->size(), sumOp<label>());
+    const label nTotParcels = returnReduce(nParcels, sumOp<label>());
+
+    if (applyFilter_ && log)
+    {
+        // Report filtered/unfiltered count
+        Log << "After filtering using " << nTotParcels << '/'
+            << (returnReduce(pointsPtr->size(), sumOp<label>()))
+            << " parcels" << nl;
+    }
 
     if (pruneEmpty_ && !nTotParcels)
     {
@@ -216,7 +230,14 @@ bool Foam::functionObjects::vtkCloud::writeCloud
     }
 
 
-    vtk::writeListParallel(format.ref(), *pointsPtr);
+    if (applyFilter_)
+    {
+        vtk::writeListParallel(format.ref(), *pointsPtr, parcelAddr_);
+    }
+    else
+    {
+        vtk::writeListParallel(format.ref(), *pointsPtr);
+    }
 
 
     if (Pstream::master())
@@ -333,6 +354,7 @@ Foam::functionObjects::vtkCloud::vtkCloud
     printf_(),
     useVerts_(false),
     pruneEmpty_(false),
+    applyFilter_(false),
     selectClouds_(),
     selectFields_(),
     directory_(),
@@ -404,7 +426,6 @@ bool Foam::functionObjects::vtkCloud::read(const dictionary& dict)
     useVerts_ = dict.lookupOrDefault<bool>("cellData", false);
     pruneEmpty_ = dict.lookupOrDefault<bool>("prune", false);
 
-
     selectClouds_.clear();
     dict.readIfPresent("clouds", selectClouds_);
 
@@ -417,7 +438,10 @@ bool Foam::functionObjects::vtkCloud::read(const dictionary& dict)
 
     selectFields_.clear();
     dict.readIfPresent("fields", selectFields_);
+    selectFields_.uniq();
 
+    // Actions to define selection
+    parcelSelect_ = dict.subOrEmptyDict("selection");
 
     // Output directory
 
diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H
index 242d058d10ec6c6d22f0a333ba2db15c231e2650..256bbfa78237419bde6e80f5d198a5c91df60265 100644
--- a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H
+++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H
@@ -44,23 +44,56 @@ Description
         cloud           myCloud;
         fields          (T U rho);
         width           4;  // file-padding
+
+        selection
+        {
+            stride
+            {
+                // every 10th parcelId
+                action  add;
+                source  stride;
+                stride  10;
+            }
+            Umin
+            {
+                // Remove slow parcels
+                action  subtract;
+                source  field;
+                field   U;
+                accept  (less 1e-3);
+            }
+            diam
+            {
+                // Only particular diameter ranges
+                action  subset;
+                source  field;
+                field   d;
+                accept  (greater 1e-3) and (less 1e-3);
+            }
+        }
     }
     \endverbatim
 
-Usage
+    \heading Basic Usage
     \table
-        Property     | Description                      | Required    | Default
-        type         | Type name: vtkCloud              | yes         |
-        writeControl | Output control                   | recommended | timeStep
-        cloud        |                                  | no  | defaultCloud
-        clouds       | wordRe list of clouds            | no    |
-        fields       | wordRe list of fields            | no    |
-        prune        | Suppress writing of empty clouds | no    | false
+        Property     | Description                      | Required | Default
+        type         | Type name: vtkCloud              | yes |
+        clouds       | List of clouds (name or regex)   | no  |
+        cloud        | Cloud name                       | no  | defaultCloud
+        fields       | List of fields (name or regex)   | no  |
+        selection    | Parcel selection control         | no  | empty-dict
+    \endtable
+
+    \heading Output Options
+    \table
+        Property     | Description                      | Required | Default
+        format       | Format as ascii or binary        | no  | binary
+        precision    | Write precision in ascii         | no  | same as IOstream
+        directory    | The output directory name    | no | postProcessing/NAME
+        width        | Padding width for file name      | no  | 8
         cellData     | Emit cellData instead of pointData | no  | false
-        directory    | The output directory name     | no | postProcessing/NAME
-        width        | Padding width for file name      | no    | 8
-        format       | Format as ascii or binary        | no    | binary
-        precision    | Write precision in ascii         | no | same as IOstream
+        prune        | Suppress writing of empty clouds | no  | false
+        writeControl | Output control                   | recommended | timeStep
     \endtable
 
     The output filename and fields are added to the functionObjectProperties
@@ -77,7 +110,17 @@ Usage
     }
     \endverbatim
 
+Note
+    The selection dictionary can be used for finer control of the parcel
+    output. It contains a set of (add,subtract,subset,clear,invert)
+    selection actions and sources.
+    Omitting the selection dictionary is the same as specifying the
+    conversion of all parcels (in the selected clouds).
+    More syntax details are to be found in the corresponding
+    Foam::Detail::parcelSelection class.
+
 See also
+    Foam::Detail::parcelSelection
     Foam::functionObjects::ensightWrite
     Foam::functionObjects::vtkWrite
     Foam::functionObjects::fvMeshFunctionObject
@@ -93,6 +136,7 @@ SourceFiles
 #define functionObjects_vtkCloud_H
 
 #include "fvMeshFunctionObject.H"
+#include "parcelSelectionDetail.H"
 #include "foamVtkOutputOptions.H"
 #include "foamVtkSeriesWriter.H"
 #include "wordRes.H"
@@ -111,7 +155,8 @@ namespace functionObjects
 
 class vtkCloud
 :
-    public fvMeshFunctionObject
+    public fvMeshFunctionObject,
+    public Foam::Detail::parcelSelection
 {
     // Private data
 
@@ -127,6 +172,9 @@ class vtkCloud
         //- Suppress writing of empty clouds
         bool pruneEmpty_;
 
+        //- Apply output filter (for the current cloud)
+        bool applyFilter_;
+
         //- Requested names of clouds to process
         wordRes selectClouds_;
 
diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C
index f68b666c9b16717008b86d8f90d8e082cb95b738..aed94728c8ec0d859d7ea61e6813ea37353f39e7 100644
--- a/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C
+++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C
@@ -88,7 +88,14 @@ Foam::wordList Foam::functionObjects::vtkCloud::writeFields
             }
         }
 
-        vtk::writeListParallel(format.ref(), values);
+        if (applyFilter_)
+        {
+            vtk::writeListParallel(format.ref(), values, parcelAddr_);
+        }
+        else
+        {
+            vtk::writeListParallel(format.ref(), values);
+        }
 
         if (Pstream::master())
         {
diff --git a/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict b/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict
index 15290e5c12bfc004b8605e03e0a0f0ba0350e93e..e54c5d788b5948b91a14eb793300131942c40dac 100644
--- a/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict
+++ b/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict
@@ -54,6 +54,7 @@ maxDeltaT       1;
 functions
 {
     #include "vtkCloud"
+    #include "vtkWrite"
 }
 
 // ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkCloud b/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkCloud
index 808f9d36d9543a9f7c3227e63b7d8f4836285dc8..ce153de26ee2f60a0a3eeb30f1e9bfca926dd881 100644
--- a/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkCloud
+++ b/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkCloud
@@ -6,6 +6,9 @@ cloudWrite
     libs    ("liblagrangianFunctionObjects.so");
     log     true;
 
+    // Nothing happens before this anyhow
+    timeStart 0.5;
+
     writeControl    writeTime;
 
     // cloud   reactingCloud1;
@@ -15,16 +18,68 @@ cloudWrite
     fields  ( U T d "Y.*" );
 
     //- Output format (ascii | binary) - default = binary
-    // format  binary;
+    // format  ascii;
 
-    // format   ascii;
-    // writePrecision 12;
+    // precision   12;
 
-    //- Suppress writing of empty clouds - default = false
-    // prune   true;
+    // Suppress writing of empty clouds - default = false
+    prune   true;
 
-    //- Output directory name - default = "VTK"
+    //- Output directory name - Default postProcessing
     // directory       "VTK";
+
+    selection
+    {
+        all
+        {
+            action  all;
+        }
+
+        none
+        {
+            action  clear;
+        }
+
+        // Reduced number of output parcels
+        stride
+        {
+            action  add;
+            source  stride;
+            stride  4;
+        }
+
+        T
+        {
+            action  subset;
+            source  field;
+            field   T;
+            accept  (greater 280) and (less 300);
+        }
+
+        YH2O
+        {
+            action  subset;
+            source  field;
+            field   YH2O(l);
+            accept  (greater 0.5);
+        }
+
+        diameter
+        {
+            action  subset;
+            source  field;
+            field   d;
+            accept  (greater 1e-10);
+        }
+
+        Umin
+        {
+            action  subtract;
+            source  field;
+            field   U;
+            accept  (less 0.1);
+        }
+    }
 }
 
 
diff --git a/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkWrite b/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkWrite
new file mode 100644
index 0000000000000000000000000000000000000000..6e71e5f89efef72052fa29ed102c16f0018ddcbe
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/filter/system/vtkWrite
@@ -0,0 +1,35 @@
+// -*- C++ -*-
+// Minimal example of using the vtkWrite function object.
+vtkWrite
+{
+    type    vtkWrite;
+    libs    ("libutilityFunctionObjects.so");
+    log     true;
+
+    // Nothing happens before this anyhow
+    timeStart 0.4;
+    writeControl    writeTime;
+
+    boundary    false;
+
+    interpolate true;
+
+    fields  (U);
+    // format  ascii;
+
+    // Region of interest
+    selection
+    {
+        inletRegion
+        {
+            action  add;
+            source  zone;
+            zones   (leftFluid);
+        }
+    }
+
+    // Write cell ids as field - Default=true
+    writeIds    false;
+}
+
+// ************************************************************************* //