diff --git a/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/Make/files b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/Make/files
new file mode 100644
index 0000000000..2556bea36c
--- /dev/null
+++ b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/Make/files
@@ -0,0 +1,4 @@
+VoFSurfaceFilm.C
+VoFPatchTransfer/VoFPatchTransfer.C
+
+LIB = $(FOAM_LIBBIN)/libVoFSurfaceFilm
diff --git a/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/Make/options b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/Make/options
new file mode 100644
index 0000000000..5cfbddf468
--- /dev/null
+++ b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/Make/options
@@ -0,0 +1,23 @@
+EXE_INC = \
+ -I../twoPhaseMixtureThermo \
+ -I$(LIB_SRC)/transportModels/lnInclude \
+ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
+ -I$(LIB_SRC)/twoPhaseModels/twoPhaseMixture/lnInclude \
+ -I$(LIB_SRC)/twoPhaseModels/interfaceProperties/lnInclude \
+ -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
+ -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+ -I$(LIB_SRC)/finiteVolume/lnInclude \
+ -I$(LIB_SRC)/meshTools/lnInclude
+
+LIB_LIBS = \
+ -ltwoPhaseMixtureThermo \
+ -lfluidThermophysicalModels \
+ -lspecie \
+ -ltwoPhaseMixture \
+ -ltwoPhaseProperties \
+ -linterfaceProperties \
+ -ltransportModels \
+ -lsurfaceFilmModels \
+ -lsurfaceFilmDerivedFvPatchFields \
+ -lfiniteVolume \
+ -lmeshTools
diff --git a/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/VoFPatchTransfer/VoFPatchTransfer.C b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/VoFPatchTransfer/VoFPatchTransfer.C
new file mode 100644
index 0000000000..70cd344d33
--- /dev/null
+++ b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/VoFPatchTransfer/VoFPatchTransfer.C
@@ -0,0 +1,345 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2017-2021 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "VoFPatchTransfer.H"
+#include "twoPhaseMixtureThermo.H"
+#include "thermoSingleLayer.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace surfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(VoFPatchTransfer, 0);
+addToRunTimeSelectionTable(transferModel, VoFPatchTransfer, dictionary);
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+VoFPatchTransfer::VoFPatchTransfer
+(
+ surfaceFilmRegionModel& film,
+ const dictionary& dict
+)
+:
+ transferModel(type(), film, dict),
+ deltaFactorToVoF_
+ (
+ coeffDict_.lookupOrDefault("deltaFactorToVoF", 1.0)
+ ),
+ deltaFactorToFilm_
+ (
+ coeffDict_.lookupOrDefault("deltaFactorToFilm", 0.5)
+ ),
+ alphaToVoF_
+ (
+ coeffDict_.lookupOrDefault("alphaToVoF", 0.5)
+ ),
+ alphaToFilm_
+ (
+ coeffDict_.lookupOrDefault("alphaToFilm", 0.1)
+ ),
+ transferRateCoeff_
+ (
+ coeffDict_.lookupOrDefault("transferRateCoeff", 0.1)
+ )
+{
+ const polyBoundaryMesh& pbm = film.regionMesh().boundaryMesh();
+ patchIDs_.setSize
+ (
+ pbm.size() - film.regionMesh().globalData().processorPatches().size()
+ );
+
+ if (coeffDict_.found("patches"))
+ {
+ const wordReList patchNames(coeffDict_.lookup("patches"));
+ const labelHashSet patchSet = pbm.patchSet(patchNames);
+
+ Info<< " applying to patches:" << nl;
+
+ label pidi = 0;
+ forAllConstIter(labelHashSet, patchSet, iter)
+ {
+ const label patchi = iter.key();
+ patchIDs_[pidi++] = patchi;
+ Info<< " " << pbm[patchi].name() << endl;
+ }
+ patchIDs_.setSize(pidi);
+ patchTransferredMasses_.setSize(pidi, 0);
+ }
+ else
+ {
+ Info<< " applying to all patches" << endl;
+
+ forAll(patchIDs_, patchi)
+ {
+ patchIDs_[patchi] = patchi;
+ }
+
+ patchTransferredMasses_.setSize(patchIDs_.size(), 0);
+ }
+
+ if (!patchIDs_.size())
+ {
+ FatalErrorInFunction
+ << "No patches selected"
+ << exit(FatalError);
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+VoFPatchTransfer::~VoFPatchTransfer()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
+
+void VoFPatchTransfer::correct
+(
+ scalarField& availableMass,
+ scalarField& massToTransfer,
+ vectorField& momentumToTransfer
+)
+{
+ NotImplemented;
+}
+
+
+void VoFPatchTransfer::correct
+(
+ scalarField& availableMass,
+ scalarField& massToTransfer,
+ vectorField& momentumToTransfer,
+ scalarField& energyToTransfer
+)
+{
+ // Do not correct if no patches selected
+ if (!patchIDs_.size()) return;
+
+ const thermoSingleLayer& film = filmType();
+
+ const scalarField& delta = film.delta();
+ const scalarField& rho = film.rho();
+ const scalarField& magSf = film.magSf();
+
+ const polyBoundaryMesh& pbm = film.regionMesh().boundaryMesh();
+
+
+ const twoPhaseMixtureThermo& thermo
+ (
+ film.primaryMesh().lookupObject
+ (
+ twoPhaseMixtureThermo::dictName
+ )
+ );
+
+ const volVectorField& UVoF
+ (
+ film.primaryMesh().lookupObject("U")
+ );
+
+ const volScalarField& alphaVoF = thermo.alpha1();
+ const volScalarField& rhoVoF = thermo.thermo1().rho()();
+ const volScalarField& heVoF = thermo.thermo1().he();
+ const volScalarField& TVoF = thermo.thermo1().T();
+ const volScalarField CpVoF(thermo.thermo1().Cp());
+
+ forAll(patchIDs_, pidi)
+ {
+ const label patchi = patchIDs_[pidi];
+ label primaryPatchi = -1;
+
+ forAll(film.intCoupledPatchIDs(), i)
+ {
+ const label filmPatchi = film.intCoupledPatchIDs()[i];
+
+ if (filmPatchi == patchi)
+ {
+ primaryPatchi = film.primaryPatchIDs()[i];
+ }
+ }
+
+ if (primaryPatchi != -1)
+ {
+ scalarField deltaCoeffs
+ (
+ film.primaryMesh().boundary()[primaryPatchi].deltaCoeffs()
+ );
+ film.toRegion(patchi, deltaCoeffs);
+
+ scalarField alphap(alphaVoF.boundaryField()[primaryPatchi]);
+ film.toRegion(patchi, alphap);
+
+ scalarField rhop(rhoVoF.boundaryField()[primaryPatchi]);
+ film.toRegion(patchi, rhop);
+
+ vectorField Up(UVoF.boundaryField()[primaryPatchi]);
+ film.toRegion(patchi, Up);
+
+ scalarField hp(heVoF.boundaryField()[primaryPatchi]);
+ film.toRegion(patchi, hp);
+
+ scalarField Tp(TVoF.boundaryField()[primaryPatchi]);
+ film.toRegion(patchi, Tp);
+
+ scalarField Cpp(CpVoF.boundaryField()[primaryPatchi]);
+ film.toRegion(patchi, Cpp);
+
+ scalarField Vp
+ (
+ film.primaryMesh().boundary()[primaryPatchi]
+ .patchInternalField(film.primaryMesh().V())
+ );
+ film.toRegion(patchi, Vp);
+
+ const polyPatch& pp = pbm[patchi];
+ const labelList& faceCells = pp.faceCells();
+
+ const vectorField& U = film.U();
+ const scalarField& he = film.thermo().he();
+
+ // Accumulate the total mass removed from patch
+ scalar dMassPatch = 0;
+
+ forAll(faceCells, facei)
+ {
+ const label celli = faceCells[facei];
+
+ scalar dMass = 0;
+
+ if
+ (
+ delta[celli] > 2*deltaFactorToVoF_/deltaCoeffs[facei]
+ || alphap[facei] > alphaToVoF_
+ )
+ {
+ dMass =
+ transferRateCoeff_*delta[celli]*rho[celli]*magSf[celli];
+
+ massToTransfer[celli] += dMass;
+ momentumToTransfer[celli] += dMass*U[celli];
+ energyToTransfer[celli] += dMass*he[celli];
+ }
+
+ if
+ (
+ alphap[facei] > 0
+ && delta[celli] < 2*deltaFactorToFilm_/deltaCoeffs[facei]
+ && alphap[facei] < alphaToFilm_
+ )
+ {
+ dMass =
+ -transferRateCoeff_*alphap[facei]*rhop[facei]*Vp[facei];
+
+ massToTransfer[celli] += dMass;
+ momentumToTransfer[celli] += dMass*Up[facei];
+ energyToTransfer[celli] += dMass*hp[facei];
+ }
+
+ availableMass[celli] -= dMass;
+ dMassPatch += dMass;
+ }
+
+ patchTransferredMasses_[pidi] += dMassPatch;
+ addToTransferredMass(dMassPatch);
+ }
+ }
+
+ transferModel::correct();
+
+ if (writeTime())
+ {
+ scalarField patchTransferredMasses0
+ (
+ getModelProperty
+ (
+ "patchTransferredMasses",
+ scalarField(patchTransferredMasses_.size(), 0)
+ )
+ );
+
+ scalarField patchTransferredMassTotals(patchTransferredMasses_);
+ Pstream::listCombineGather
+ (
+ patchTransferredMassTotals,
+ plusEqOp()
+ );
+ patchTransferredMasses0 += patchTransferredMassTotals;
+
+ setModelProperty
+ (
+ "patchTransferredMasses",
+ patchTransferredMasses0
+ );
+
+ patchTransferredMasses_ = 0;
+ }
+}
+
+
+void VoFPatchTransfer::patchTransferredMassTotals
+(
+ scalarField& patchMasses
+) const
+{
+ // Do not correct if no patches selected
+ if (!patchIDs_.size()) return;
+
+ scalarField patchTransferredMasses
+ (
+ getModelProperty
+ (
+ "patchTransferredMasses",
+ scalarField(patchTransferredMasses_.size(), 0)
+ )
+ );
+
+ scalarField patchTransferredMassTotals(patchTransferredMasses_);
+ Pstream::listCombineGather(patchTransferredMassTotals, plusEqOp());
+
+ forAll(patchIDs_, pidi)
+ {
+ const label patchi = patchIDs_[pidi];
+ patchMasses[patchi] +=
+ patchTransferredMasses[pidi] + patchTransferredMassTotals[pidi];
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace surfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/VoFPatchTransfer/VoFPatchTransfer.H b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/VoFPatchTransfer/VoFPatchTransfer.H
new file mode 100644
index 0000000000..0d022ecddb
--- /dev/null
+++ b/applications/solvers/multiphase/compressibleInterFoam/VoFSurfaceFilm/VoFPatchTransfer/VoFPatchTransfer.H
@@ -0,0 +1,146 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2017-2021 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 .
+
+Class
+ Foam::regionModels::surfaceFilmModels::VoFPatchTransfer
+
+Description
+ Transfer mass between the film and the VoF in the continuous phase.
+
+SourceFiles
+ VoFPatchTransfer.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef VoFPatchTransfer_H
+#define VoFPatchTransfer_H
+
+#include "transferModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace surfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+ Class VoFPatchTransfer Declaration
+\*---------------------------------------------------------------------------*/
+
+class VoFPatchTransfer
+:
+ public transferModel
+{
+protected:
+
+ //- Factor of the cell height above which the film is transferred
+ // to the VoF
+ scalar deltaFactorToVoF_;
+
+ //- Factor of the cell height below which the VoF may be transferred
+ // to the film
+ scalar deltaFactorToFilm_;
+
+ //- VoF limit above which all of the film is transferred to the VoF
+ scalar alphaToVoF_;
+
+ //- VoF limit below which the VoF may be transferred to the film
+ scalar alphaToFilm_;
+
+ //- Transfer rate coefficient
+ scalar transferRateCoeff_;
+
+ //- List of patch IDs at which the film is removed
+ labelList patchIDs_;
+
+ //- Transferred mass for each patch at which the film is removed
+ scalarField patchTransferredMasses_;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("VoFPatchTransfer");
+
+
+ // Constructors
+
+ //- Construct from surface film model
+ VoFPatchTransfer(surfaceFilmRegionModel& film, const dictionary& dict);
+
+ //- Disallow default bitwise copy construction
+ VoFPatchTransfer(const VoFPatchTransfer&) = delete;
+
+
+ //- Destructor
+ virtual ~VoFPatchTransfer();
+
+
+ // Member Functions
+
+ //- Correct
+ virtual void correct
+ (
+ scalarField& availableMass,
+ scalarField& massToTransfer,
+ vectorField& momentumToTransfer
+ );
+
+ //- Correct kinematic and thermodynamic transfers
+ virtual void correct
+ (
+ scalarField& availableMass,
+ scalarField& massToTransfer,
+ vectorField& momentumToTransfer,
+ scalarField& energyToTransfer
+ );
+
+ //- Accumulate the total mass injected for the patches into the
+ // scalarField provided
+ virtual void patchTransferredMassTotals
+ (
+ scalarField& patchMasses
+ ) const;
+
+
+ // Member Operators
+
+ //- Disallow default bitwise assignment
+ void operator=(const VoFPatchTransfer&) = delete;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace surfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //