diff --git a/src/regionModels/surfaceFilmModels/Make/files b/src/regionModels/surfaceFilmModels/Make/files
index de4b1df758708d6fe4ce3e5b215ad95985c2e20d..e822c768809d7b35a332cc3dc407afacc311edde 100644
--- a/src/regionModels/surfaceFilmModels/Make/files
+++ b/src/regionModels/surfaceFilmModels/Make/files
@@ -77,5 +77,8 @@ $(PATCHFIELDS)/filmHeightInletVelocity/filmHeightInletVelocityFvPatchVectorField
 $(PATCHFIELDS)/inclinedFilmNusseltHeight/inclinedFilmNusseltHeightFvPatchScalarField.C
 $(PATCHFIELDS)/inclinedFilmNusseltInletVelocity/inclinedFilmNusseltInletVelocityFvPatchVectorField.C
 
+/* Function objects */
+FUNCTIONOBJECTS=functionObjects
+$(FUNCTIONOBJECTS)/filmFlux/filmFlux.C
 
 LIB = $(FOAM_LIBBIN)/libsurfaceFilmModels
diff --git a/src/regionModels/surfaceFilmModels/functionObjects/filmFlux/filmFlux.C b/src/regionModels/surfaceFilmModels/functionObjects/filmFlux/filmFlux.C
new file mode 100644
index 0000000000000000000000000000000000000000..73ff001d85b8531be09eb9936ee625daa390812c
--- /dev/null
+++ b/src/regionModels/surfaceFilmModels/functionObjects/filmFlux/filmFlux.C
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2019 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "filmFlux.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "surfaceInterpolate.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionObjects
+{
+    defineTypeNameAndDebug(filmFlux, 0);
+    addToRunTimeSelectionTable(functionObject, filmFlux, dictionary);
+}
+}
+
+
+const Foam::functionObjects::filmFlux::filmType&
+Foam::functionObjects::filmFlux::filmModel()
+{
+    return time_.objectRegistry::lookupObject<filmType>(filmName_);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::functionObjects::filmFlux::filmFlux
+(
+    const word& name,
+    const Time& runTime,
+    const dictionary& dict
+)
+:
+    stateFunctionObject(name, runTime),
+    filmName_("surfaceFilmProperties"),
+    resultName_(scopedName("filmFlux"))
+{
+    read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::functionObjects::filmFlux::read(const dictionary& dict)
+{
+    if (stateFunctionObject::read(dict))
+    {
+        dict.readIfPresent<word>("film", filmName_);
+        dict.readIfPresent<word>("result", resultName_);
+
+        return true;
+    }
+
+    return false;
+}
+
+
+bool Foam::functionObjects::filmFlux::execute()
+{
+    const auto& model = filmModel();
+
+    const fvMesh& filmMesh = model.regionMesh();
+
+    auto* resultPtr = filmMesh.getObjectPtr<surfaceScalarField>(resultName_);
+
+    if (!resultPtr)
+    {
+        resultPtr = new surfaceScalarField
+        (
+            IOobject
+            (
+                resultName_,
+                time_.timeName(),
+                filmMesh,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE
+            ),
+            filmMesh,
+            dimensionedScalar(dimMass/dimTime, Zero)
+        );
+
+        filmMesh.objectRegistry::store(resultPtr);
+    }
+
+    auto& result = *resultPtr;
+
+    const surfaceScalarField& phi = model.phi();
+    const volScalarField& magSf = model.magSf();
+    const volScalarField::Internal& vol = filmMesh.V();
+
+    volScalarField height
+    (
+        IOobject
+        (
+            "height",
+            time_.timeName(),
+            filmMesh,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE,
+            false
+        ),
+        filmMesh,
+        dimensionedScalar(dimLength, Zero),
+        zeroGradientFvPatchScalarField::typeName
+    );
+
+    auto& heightc = height.ref();
+
+    heightc = max(dimensionedScalar("eps", dimLength, ROOTVSMALL), vol/magSf());
+    height.correctBoundaryConditions();
+
+    result = phi/fvc::interpolate(height);
+
+    return true;
+}
+
+
+bool Foam::functionObjects::filmFlux::write()
+{
+    const auto& filmMesh = filmModel().regionMesh();
+
+    filmMesh.lookupObject<surfaceScalarField>(resultName_).write();
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/regionModels/surfaceFilmModels/functionObjects/filmFlux/filmFlux.H b/src/regionModels/surfaceFilmModels/functionObjects/filmFlux/filmFlux.H
new file mode 100644
index 0000000000000000000000000000000000000000..eefe461d879d4acb3ea2e7789b6345f980eb7015
--- /dev/null
+++ b/src/regionModels/surfaceFilmModels/functionObjects/filmFlux/filmFlux.H
@@ -0,0 +1,170 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2019 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::functionObjects::filmFlux
+
+Group
+    grpFieldFunctionObjects
+
+Description
+    Calculates the mass flux for surface film models.
+
+    Operands:
+    \table
+      Operand      | Type              | Location
+      input        | dictionary        | constant/\<surfaceFilmProperties\>
+      output file  | -                 | -
+      output field | surfaceScalarField   <!--
+                   -->                 | \<time\>/\<filmRegion\>/\<outField\>
+    \endtable
+
+Usage
+    Minimal example by using \c system/controlDict.functions:
+    \verbatim
+    filmFlux1
+    {
+        // Mandatory entries (unmodifiable)
+        type        filmFlux;
+
+        // Optional entries (runtime modifiable)
+        film        <surfaceFilmPropertiesDictionary>;
+        result      <resultName>;
+
+        // Optional (inherited) entries
+        ...
+    }
+    \endverbatim
+
+    where the entries mean:
+    \table
+      Property  | Description              | Type | Reqd | Dflt
+      type      | Type name: filmFlux      | word | yes  | -
+      film      | Name of surface film properties dictionary <!--
+                -->                        | dict | no   | surfaceFilmProperties
+      result    | Name of result field     | word | no   | filmFlux
+    \endtable
+
+    The inherited entries are elaborated in:
+     - \link stateFunctionObject.H \endlink
+
+    Usage by the \c postProcess utility is not available.
+
+See also
+  - Foam::functionObjects::stateFunctionObject
+
+SourceFiles
+    flux.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef functionObjects_filmFlux_H
+#define functionObjects_filmFlux_H
+
+#include "stateFunctionObject.H"
+#include "kinematicSingleLayer.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionObjects
+{
+
+/*---------------------------------------------------------------------------*\
+                          Class filmFlux Declaration
+\*---------------------------------------------------------------------------*/
+
+class filmFlux
+:
+    public stateFunctionObject
+{
+    // Private Data
+
+        typedef regionModels::surfaceFilmModels::kinematicSingleLayer filmType;
+
+        //- Film model name
+        word filmName_;
+
+        //- Name of derived flux field
+        word resultName_;
+
+
+    // Private Member Functions
+
+        //- Helper function to set the pointer to the film model
+        const filmType& filmModel();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("filmFlux");
+
+
+    // Constructors
+
+        //- Construct from Time and dictionary
+        filmFlux
+        (
+            const word& name,
+            const Time& runTime,
+            const dictionary& dict
+        );
+
+        //- No copy construct
+        filmFlux(const filmFlux&) = delete;
+
+        //- No copy assignment
+        void operator=(const filmFlux&) = delete;
+
+
+    //- Destructor
+    virtual ~filmFlux() = default;
+
+
+    // Member Functions
+
+        //- Read the field data
+        virtual bool read(const dictionary&);
+
+        //- Execute
+        virtual bool execute();
+
+        //- Write the field
+        virtual bool write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace functionObjects
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/rivuletPanel/system/controlDict b/tutorials/lagrangian/reactingParcelFoam/rivuletPanel/system/controlDict
index 33540ffc6e4ed86c117edcbfbb39200c7642631c..1a2bcd4b419beb74a38828bc6e7bab0eccb855db 100644
--- a/tutorials/lagrangian/reactingParcelFoam/rivuletPanel/system/controlDict
+++ b/tutorials/lagrangian/reactingParcelFoam/rivuletPanel/system/controlDict
@@ -63,6 +63,36 @@ functions
         internalField   yes;
         patches         ();
     }
+
+    filmFlux
+    {
+        type            filmFlux;
+        writeControl    writeTime;
+        result          myPhi; // optional
+    }
+
+    filmPatchFluxIn
+    {
+        type            surfaceFieldValue;
+        libs            (fieldFunctionObjects);
+        region          wallFilmRegion;
+        fields          (myPhi);
+        operation       sum;
+        regionType      patch;
+        name            inlet;
+        writeFields     no;
+    }
+    filmPatchFluxOut
+    {
+        type            surfaceFieldValue;
+        libs            (fieldFunctionObjects);
+        region          wallFilmRegion;
+        fields          (myPhi);
+        operation       sum;
+        regionType      patch;
+        name            outlet;
+        writeFields     no;
+    }
 }
 
 // ************************************************************************* //