diff --git a/applications/solvers/combustion/fireFoam/Make/options b/applications/solvers/combustion/fireFoam/Make/options
index 87e841be8e961efa3b08298d720e0ea60a3c7a6a..bdf679ccde3de4df4d170b0a7617a8c1c090d280 100644
--- a/applications/solvers/combustion/fireFoam/Make/options
+++ b/applications/solvers/combustion/fireFoam/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I${LIB_SRC}/sampling/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -22,7 +23,9 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/pyrolysisModels/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
-    -I$(LIB_SRC)/ODE/lnInclude
+    -I$(LIB_SRC)/ODE/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -49,4 +52,7 @@ EXE_LIBS = \
     -llagrangian \
     -llagrangianIntermediate \
     -llagrangianTurbulence \
-    -lODE
+    -lODE \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/compressible/rhoPimpleFoam/Make/options b/applications/solvers/compressible/rhoPimpleFoam/Make/options
index 2118219cfedb2db6300524c2b95e99bce09e215b..717240ffece6f320cfdde24dc7efbccfaa7e1512 100644
--- a/applications/solvers/compressible/rhoPimpleFoam/Make/options
+++ b/applications/solvers/compressible/rhoPimpleFoam/Make/options
@@ -8,7 +8,8 @@ EXE_INC = \
     -I$(LIB_SRC)/transportModels/compressible/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
+    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
+    -I$(LIB_SRC)/regionFaModels\lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -23,4 +24,5 @@ EXE_LIBS = \
     -ldynamicFvMesh \
     -ltopoChangerFvMesh \
     -lsampling \
-    -latmosphericModels
+    -latmosphericModels \
+    -lregionFaModels
diff --git a/applications/solvers/compressible/rhoSimpleFoam/Make/options b/applications/solvers/compressible/rhoSimpleFoam/Make/options
index 806154972b40e2e0f8132a43ec092ca23a9bc326..dd872bce900fe839d9b203a1a109b535cfaba2d4 100644
--- a/applications/solvers/compressible/rhoSimpleFoam/Make/options
+++ b/applications/solvers/compressible/rhoSimpleFoam/Make/options
@@ -7,6 +7,7 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
+    -I$(LIB_SRC)/regionFaModels\lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -18,4 +19,5 @@ EXE_LIBS = \
     -lspecie \
     -lturbulenceModels \
     -lcompressibleTurbulenceModels \
-    -latmosphericModels
+    -latmosphericModels \
+    -lregionFaModels
diff --git a/applications/solvers/heatTransfer/buoyantPimpleFoam/Make/options b/applications/solvers/heatTransfer/buoyantPimpleFoam/Make/options
index 519e80ffe203fb43f849053b715fe529d7d06318..d3224df41105b82035c83bea3875732e7ff50d32 100644
--- a/applications/solvers/heatTransfer/buoyantPimpleFoam/Make/options
+++ b/applications/solvers/heatTransfer/buoyantPimpleFoam/Make/options
@@ -6,7 +6,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
+    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
+    -I$(LIB_SRC)/regionFaModels\lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -19,4 +20,5 @@ EXE_LIBS = \
     -lspecie \
     -lturbulenceModels \
     -lcompressibleTurbulenceModels \
-    -latmosphericModels
+    -latmosphericModels \
+    -lregionFaModels
diff --git a/applications/solvers/heatTransfer/buoyantSimpleFoam/Make/options b/applications/solvers/heatTransfer/buoyantSimpleFoam/Make/options
index 40ada6b54aa5bd65082cf6faa00060fed61311a1..322b0c4488739682ad05e0e9330dcad1a1632b3b 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleFoam/Make/options
+++ b/applications/solvers/heatTransfer/buoyantSimpleFoam/Make/options
@@ -6,7 +6,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
+    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
+    -I$(LIB_SRC)/regionFaModels\lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -19,4 +20,5 @@ EXE_LIBS = \
     -lradiationModels \
     -lturbulenceModels \
     -lcompressibleTurbulenceModels \
-    -latmosphericModels
+    -latmosphericModels \
+    -lregionFaModels
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options b/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options
index 4a527e03e6f100ccacf25e3589ab54c2cd9ca215..0a16d78b2f065e3fdea0435bf11252630aee4190 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options
@@ -18,7 +18,8 @@ EXE_INC = \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-    -I$(LIB_SRC)/regionModels/regionModel/lnInclude
+    -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
+    -I$(LIB_SRC)/regionFaModels\lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -36,4 +37,5 @@ EXE_LIBS = \
     -lturbulenceModels \
     -lcompressibleTurbulenceModels \
     -lradiationModels \
-    -lregionModels
+    -lregionModels \
+    -lregionFaModels
diff --git a/applications/solvers/incompressible/pimpleFoam/Make/options b/applications/solvers/incompressible/pimpleFoam/Make/options
index 584c27112d3b73aa78e32ab6b41ac67d13d5ff78..2525075dd7594908a10db7d3c7af31c64e57829a 100644
--- a/applications/solvers/incompressible/pimpleFoam/Make/options
+++ b/applications/solvers/incompressible/pimpleFoam/Make/options
@@ -7,7 +7,8 @@ EXE_INC = \
     -I$(LIB_SRC)/transportModels \
     -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels\lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -20,4 +21,5 @@ EXE_LIBS = \
     -ldynamicMesh \
     -ldynamicFvMesh \
     -ltopoChangerFvMesh \
-    -latmosphericModels
+    -latmosphericModels \
+    -lregionFaModels
diff --git a/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/MPPICDyMFoam/Make/options b/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/MPPICDyMFoam/Make/options
index 03b1e8a243c96d25a7b22adc506a8e1e785779e0..eca5c04b54a5adf54905cecc9070fef72773f272 100644
--- a/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/MPPICDyMFoam/Make/options
+++ b/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/MPPICDyMFoam/Make/options
@@ -3,6 +3,7 @@ EXE_INC = \
     -I../.. \
     -I../../DPMTurbulenceModels \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -19,7 +20,9 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicMesh/lnInclude
+    -I$(LIB_SRC)/dynamicMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -39,4 +42,7 @@ EXE_LIBS = \
     -ldynamicMesh \
     -ldynamicFvMesh \
     -ltopoChangerFvMesh \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/Make/options b/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/Make/options
index 14fd3e8bf1fcf5cb972f43f7e38bae954c95c550..a1f3342a0da5cb570a42b13fbba3c598706cf20f 100644
--- a/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/Make/options
+++ b/applications/solvers/lagrangian/DPMFoam/DPMDyMFoam/Make/options
@@ -2,6 +2,7 @@ EXE_INC = \
     -I.. \
     -I../DPMTurbulenceModels \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -18,7 +19,9 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -38,4 +41,7 @@ EXE_LIBS = \
     -ldynamicMesh \
     -ldynamicFvMesh \
     -ltopoChangerFvMesh \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/DPMFoam/MPPICFoam/Make/options b/applications/solvers/lagrangian/DPMFoam/MPPICFoam/Make/options
index 419d56725ab9ad2ed651dc9643bd1e303fa70471..2b9bf8a79b4ee4cd2509fc1c4e6580126f3a8372 100644
--- a/applications/solvers/lagrangian/DPMFoam/MPPICFoam/Make/options
+++ b/applications/solvers/lagrangian/DPMFoam/MPPICFoam/Make/options
@@ -2,6 +2,7 @@ EXE_INC = \
     -I.. \
     -I../DPMTurbulenceModels \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -17,6 +18,8 @@ EXE_INC = \
     -I$(LIB_SRC)/TurbulenceModels/phaseIncompressible/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -33,4 +36,7 @@ EXE_LIBS = \
     -lDPMTurbulenceModels \
     -lregionModels \
     -lsurfaceFilmModels \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/DPMFoam/Make/options b/applications/solvers/lagrangian/DPMFoam/Make/options
index e16be0b44486904d69d6c4ae78aff2dc7f9efa26..8d87d5e8fdca31672cc14eb39b91d30f3d583184 100644
--- a/applications/solvers/lagrangian/DPMFoam/Make/options
+++ b/applications/solvers/lagrangian/DPMFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I./DPMTurbulenceModels \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -14,7 +15,9 @@ EXE_INC = \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -31,4 +34,7 @@ EXE_LIBS = \
     -lDPMTurbulenceModels \
     -lregionModels \
     -lsurfaceFilmModels \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/coalChemistryFoam/Make/options b/applications/solvers/lagrangian/coalChemistryFoam/Make/options
index 3b3ee4cabc5d5919ed6374b2f764ec5a0503d995..3fa33f636406c0abd76db7d393566a91abe5b867 100644
--- a/applications/solvers/lagrangian/coalChemistryFoam/Make/options
+++ b/applications/solvers/lagrangian/coalChemistryFoam/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
@@ -17,6 +18,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/combustionModels/lnInclude \
     -I$(FOAM_SOLVERS)/combustion/reactingFoam \
@@ -44,4 +47,7 @@ EXE_LIBS = \
     -lsurfaceFilmModels \
     -lODE \
     -lcombustionModels \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options b/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options
index 96f149372627e9910949cf7672fd4dcf43bd69da..1c5d6ac4c7d69d51d9fe56a055725973eba0e91b 100644
--- a/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -13,7 +14,9 @@ EXE_INC = \
     -I$(LIB_SRC)/transportModels \
     -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -30,4 +33,7 @@ EXE_LIBS = \
     -lincompressibleTurbulenceModels \
     -lincompressibleTransportModels \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/icoUncoupledKinematicParcelDyMFoam/Make/options b/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/icoUncoupledKinematicParcelDyMFoam/Make/options
index 61823c498cad71493c3623dc0e49ccd1efc723e8..5efb8a48e420305228c5b25ca2cdaa21c07dd6e8 100644
--- a/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/icoUncoupledKinematicParcelDyMFoam/Make/options
+++ b/applications/solvers/lagrangian/icoUncoupledKinematicParcelFoam/icoUncoupledKinematicParcelDyMFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I.. \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -16,7 +17,9 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -36,4 +39,7 @@ EXE_LIBS = \
     -lsurfaceFilmModels \
     -ldynamicMesh \
     -ldynamicFvMesh \
-    -ltopoChangerFvMesh
+    -ltopoChangerFvMesh \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/Make/files b/applications/solvers/lagrangian/kinematicParcelFoam/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..a63fc64fa7371272e4c6f383b3181174750ea186
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/Make/files
@@ -0,0 +1,3 @@
+kinematicParcelFoam.C
+
+EXE = $(FOAM_APPBIN)/kinematicParcelFoam
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/Make/options b/applications/solvers/lagrangian/kinematicParcelFoam/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..d7531a9d7329069b1949e9b3b63f9c0a30817c69
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/Make/options
@@ -0,0 +1,42 @@
+EXE_INC = \
+    -I$(FOAM_SOLVERS)/lagrangian/reactingParcelFoam \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
+    -I$(LIB_SRC)/transportModels \
+    -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
+    -I$(LIB_SRC)/dynamicMesh/lnInclude \
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
+    -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
+    -I$(LIB_SRC)/lagrangian/basic/lnInclude \
+    -I$(LIB_SRC)/lagrangian/intermediate/lnInclude
+
+
+EXE_LIBS = \
+    -lfiniteVolume \
+    -lfvOptions \
+    -lmeshTools \
+    -lsampling \
+    -lturbulenceModels \
+    -lincompressibleTurbulenceModels \
+    -lincompressibleTransportModels \
+    -ldynamicMesh \
+    -ldynamicFvMesh \
+    -ltopoChangerFvMesh \
+    -latmosphericModels \
+    -lregionModels \
+    -lsurfaceFilmModels \
+    -lsurfaceFilmDerivedFvPatchFields \
+    -llagrangian \
+    -llagrangianIntermediate \
+    -llagrangianTurbulence \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/UEqn.H b/applications/solvers/lagrangian/kinematicParcelFoam/UEqn.H
new file mode 100644
index 0000000000000000000000000000000000000000..0e4177b8e1f9a7ae88fc9a8b1446b6d8c4bddf77
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/UEqn.H
@@ -0,0 +1,22 @@
+    MRF.correctBoundaryVelocity(U);
+
+    fvVectorMatrix UEqn
+    (
+        fvm::ddt(U) + fvm::div(phi, U)
+      + MRF.DDt(U)
+      + turbulence->divDevReff(U)
+     ==
+        parcels.SU(U, true)
+      + fvOptions(U)
+    );
+
+    UEqn.relax();
+
+    fvOptions.constrain(UEqn);
+
+    if (pimple.momentumPredictor())
+    {
+        solve(UEqn == -fvc::grad(p));
+
+        fvOptions.correct(U);
+    }
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/createClouds.H b/applications/solvers/lagrangian/kinematicParcelFoam/createClouds.H
new file mode 100644
index 0000000000000000000000000000000000000000..c2d9dd8d6b7e8fc51bb5d9c36790607b5405a2f2
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/createClouds.H
@@ -0,0 +1,16 @@
+const word kinematicCloudName
+(
+    args.getOrDefault<word>("cloud", "kinematicCloud")
+);
+
+Info<< "Constructing kinematicCloud " << kinematicCloudName << endl;
+
+basicKinematicCloud parcels
+(
+    kinematicCloudName,
+    rhoInf,
+    U,
+    muc,
+    g
+);
+
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/createFieldRefs.H b/applications/solvers/lagrangian/kinematicParcelFoam/createFieldRefs.H
new file mode 100644
index 0000000000000000000000000000000000000000..7a0c96f0719c1d63baab10cf04c99babd911bf38
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/createFieldRefs.H
@@ -0,0 +1 @@
+regionModels::surfaceFilmModel& surfaceFilm = tsurfaceFilm();
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/createFields.H b/applications/solvers/lagrangian/kinematicParcelFoam/createFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..0182144d86e85803af9663c0c508d439831f1119
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/createFields.H
@@ -0,0 +1,85 @@
+#include "readGravitationalAcceleration.H"
+
+Info<< "Reading field p\n" << endl;
+volScalarField p
+(
+    IOobject
+    (
+        "p",
+        runTime.timeName(),
+        mesh,
+        IOobject::MUST_READ,
+        IOobject::AUTO_WRITE
+    ),
+    mesh
+);
+
+Info<< "\nReading field U\n" << endl;
+volVectorField U
+(
+    IOobject
+    (
+        "U",
+        runTime.timeName(),
+        mesh,
+        IOobject::MUST_READ,
+        IOobject::AUTO_WRITE
+    ),
+    mesh
+);
+
+#include "createPhi.H"
+
+singlePhaseTransportModel laminarTransport(U, phi);
+
+dimensionedScalar rhoInfValue
+(
+    "rhoInf",
+    dimDensity,
+    laminarTransport
+);
+
+volScalarField rhoInf
+(
+    IOobject
+    (
+        "rho",
+        runTime.timeName(),
+        mesh,
+        IOobject::NO_READ,
+        IOobject::NO_WRITE
+    ),
+    mesh,
+    rhoInfValue
+);
+
+volScalarField muc
+(
+    IOobject
+    (
+        "muc",
+        runTime.timeName(),
+        mesh,
+        IOobject::NO_READ,
+        IOobject::NO_WRITE
+    ),
+    rhoInf*laminarTransport.nu()
+);
+
+Info<< "Creating turbulence model\n" << endl;
+autoPtr<incompressible::turbulenceModel> turbulence
+(
+    incompressible::turbulenceModel::New(U, phi, laminarTransport)
+);
+
+label pRefCell = 0;
+scalar pRefValue = 0.0;
+setRefCell(p, pimple.dict(), pRefCell, pRefValue);
+mesh.setFluxRequired(p.name());
+
+#include "createMRF.H"
+#include "createClouds.H"
+#include "createSurfaceFilmModel.H"
+#include "createFvOptions.H"
+
+
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/kinematicParcelFoam.C b/applications/solvers/lagrangian/kinematicParcelFoam/kinematicParcelFoam.C
new file mode 100644
index 0000000000000000000000000000000000000000..8fa73e53e5300734a3434346d563c5b2d53f92cb
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/kinematicParcelFoam.C
@@ -0,0 +1,155 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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/>.
+
+Application
+    kinematicParcelFoam
+
+Group
+    grpLagrangianSolvers
+
+Description
+    Transient solver for incompressible, turbulent flow with kinematic,
+    particle cloud, and surface film modelling.
+
+\*---------------------------------------------------------------------------*/
+
+#include "fvCFD.H"
+#include "dynamicFvMesh.H"
+#include "singlePhaseTransportModel.H"
+#include "turbulentTransportModel.H"
+#include "surfaceFilmModel.H"
+#include "basicKinematicCloud.H"
+#include "fvOptions.H"
+#include "pimpleControl.H"
+#include "CorrectPhi.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+int main(int argc, char *argv[])
+{
+    argList::addNote
+    (
+        "Transient solver for incompressible, turbulent flow"
+        " with kinematic particle clouds"
+        " and surface film modelling."
+    );
+
+    #define CREATE_MESH createMeshesPostProcess.H
+    #include "postProcess.H"
+
+    #include "addCheckCaseOptions.H"
+    #include "setRootCaseLists.H"
+    #include "createTime.H"
+    #include "createDynamicFvMesh.H"
+    #include "initContinuityErrs.H"
+    #include "createDyMControls.H"
+    #include "createFields.H"
+    #include "createFieldRefs.H"
+    #include "createRegionControls.H"
+    #include "createUfIfPresent.H"
+
+    turbulence->validate();
+
+    #include "CourantNo.H"
+    #include "setInitialDeltaT.H"
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+    Info<< "\nStarting time loop\n" << endl;
+
+    while (runTime.run())
+    {
+        #include "readDyMControls.H"
+        #include "CourantNo.H"
+        #include "setMultiRegionDeltaT.H"
+
+        ++runTime;
+
+        Info<< "Time = " << runTime.timeName() << nl << endl;
+
+        // Store the particle positions
+        parcels.storeGlobalPositions();
+
+        // Do any mesh changes
+        mesh.update();
+
+        if (solvePrimaryRegion && mesh.changing())
+        {
+            MRF.update();
+
+            if (correctPhi)
+            {
+                // Calculate absolute flux
+                // from the mapped surface velocity
+                phi = mesh.Sf() & Uf();
+
+                #include "../../incompressible/pimpleFoam/correctPhi.H"
+
+                // Make the fluxes relative to the mesh-motion
+                fvc::makeRelative(phi, U);
+            }
+
+            if (checkMeshCourantNo)
+            {
+                #include "meshCourantNo.H"
+            }
+        }
+
+        parcels.evolve();
+        surfaceFilm.evolve();
+
+        if (solvePrimaryRegion)
+        {
+            // --- PIMPLE loop
+            while (pimple.loop())
+            {
+                #include "UEqn.H"
+
+                // --- Pressure corrector loop
+                while (pimple.correct())
+                {
+                    #include "pEqn.H"
+                }
+
+                if (pimple.turbCorr())
+                {
+                    laminarTransport.correct();
+                    turbulence->correct();
+                }
+            }
+        }
+
+        runTime.write();
+
+        runTime.printExecutionTime(Info);
+    }
+
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/solvers/lagrangian/kinematicParcelFoam/pEqn.H b/applications/solvers/lagrangian/kinematicParcelFoam/pEqn.H
new file mode 100644
index 0000000000000000000000000000000000000000..631df1b4a8262b981a7ef8aed567b431e102f3f5
--- /dev/null
+++ b/applications/solvers/lagrangian/kinematicParcelFoam/pEqn.H
@@ -0,0 +1,62 @@
+
+volScalarField rAU(1.0/UEqn.A());
+volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p));
+
+surfaceScalarField phiHbyA("phiHbyA", fvc::flux(HbyA));
+
+if (pimple.ddtCorr())
+{
+    phiHbyA += MRF.zeroFilter(fvc::interpolate(rAU)*fvc::ddtCorr(U, phi, Uf));
+}
+else
+{
+    phiHbyA += MRF.zeroFilter(fvc::interpolate(rAU));
+}
+
+MRF.makeRelative(phiHbyA);
+
+if (p.needReference())
+{
+    fvc::makeRelative(phiHbyA, U);
+    adjustPhi(phiHbyA, U, p);
+    fvc::makeAbsolute(phiHbyA, U);
+}
+
+
+// Update the pressure BCs to ensure flux consistency
+constrainPressure(p, U, phiHbyA, rAU, MRF);
+
+// Non-orthogonal pressure corrector loop
+while (pimple.correctNonOrthogonal())
+{
+    fvScalarMatrix pEqn
+    (
+        fvm::laplacian(rAU, p)
+     ==
+        fvc::div(phiHbyA)
+    );
+
+    pEqn.setReference(pRefCell, pRefValue);
+
+    pEqn.solve(mesh.solver(p.select(pimple.finalInnerIter())));
+
+    if (pimple.finalNonOrthogonalIter())
+    {
+        phi = phiHbyA - pEqn.flux();
+    }
+}
+
+#include "continuityErrs.H"
+
+p.relax();
+
+U = HbyA - rAU*fvc::grad(p);
+U.correctBoundaryConditions();
+fvOptions.correct(U);
+
+// Correct rhoUf if the mesh is moving
+fvc::correctUf(Uf, U, phi);
+
+// Make the fluxes relative to the mesh motion
+fvc::makeRelative(phi, U);
+
diff --git a/applications/solvers/lagrangian/reactingParcelFoam/Make/options b/applications/solvers/lagrangian/reactingParcelFoam/Make/options
index 34adc463ddd4aa9eab07373eecfb2c97a402be34..70ec7ed080301c7ed9ab73b2919c28f443a4eab1 100644
--- a/applications/solvers/lagrangian/reactingParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/reactingParcelFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I../reactingParcelFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
@@ -18,6 +19,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
@@ -48,4 +51,7 @@ EXE_LIBS = \
     -llagrangianIntermediate \
     -llagrangianTurbulence \
     -lODE \
-    -lcombustionModels
+    -lcombustionModels \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/reactingParcelFoam/createFields.H b/applications/solvers/lagrangian/reactingParcelFoam/createFields.H
index eee7772c2337c58ec3ec48548e6eecdb3674631d..6984cc617819b8b05a9d6244b701446e671915ba 100644
--- a/applications/solvers/lagrangian/reactingParcelFoam/createFields.H
+++ b/applications/solvers/lagrangian/reactingParcelFoam/createFields.H
@@ -11,7 +11,11 @@ basicSpecieMixture& composition = thermo.composition();
 PtrList<volScalarField>& Y = composition.Y();
 
 const word inertSpecie(thermo.get<word>("inertSpecie"));
-if (!composition.species().found(inertSpecie))
+if
+(
+    !composition.species().found(inertSpecie)
+  && composition.species().size() > 0
+)
 {
     FatalIOErrorIn(args.executable().c_str(), thermo)
         << "Inert specie " << inertSpecie << " not found in available species "
diff --git a/applications/solvers/lagrangian/reactingParcelFoam/reactingHeterogenousParcelFoam/Make/options b/applications/solvers/lagrangian/reactingParcelFoam/reactingHeterogenousParcelFoam/Make/options
index 9afe29d4427dff0f4f09faf022f54e07cc78542d..d307b5260ca3536af293ff9b5a9ae6d83467de5e 100644
--- a/applications/solvers/lagrangian/reactingParcelFoam/reactingHeterogenousParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/reactingParcelFoam/reactingHeterogenousParcelFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I.. \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/sampling/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
@@ -18,6 +19,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
@@ -47,4 +50,7 @@ EXE_LIBS = \
     -llagrangianIntermediate \
     -llagrangianTurbulence \
     -lODE \
-    -lcombustionModels
+    -lcombustionModels \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/reactingParcelFoam/simpleReactingParcelFoam/Make/options b/applications/solvers/lagrangian/reactingParcelFoam/simpleReactingParcelFoam/Make/options
index fee9c9890eec68b7e867889ab1d9ef752db4edef..6b2a7257298379cf4614e12c4389a815e3f73bb5 100644
--- a/applications/solvers/lagrangian/reactingParcelFoam/simpleReactingParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/reactingParcelFoam/simpleReactingParcelFoam/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -19,6 +20,8 @@ EXE_INC = \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
     -I$(LIB_SRC)/combustionModels/lnInclude \
     -I$(FOAM_SOLVERS)/combustion/reactingFoam
 
@@ -43,4 +46,7 @@ EXE_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -lcombustionModels \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/simpleCoalParcelFoam/Make/options b/applications/solvers/lagrangian/simpleCoalParcelFoam/Make/options
index 0942257a8ef6bbb494bd993e308f751af617ca5e..8612aedf9cf40077d192aaac1c049682e4c73949 100644
--- a/applications/solvers/lagrangian/simpleCoalParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/simpleCoalParcelFoam/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/fvOptions/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -20,7 +21,9 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/combustionModels/lnInclude \
-    -I$(LIB_SRC)/sampling/lnInclude
+    -I$(LIB_SRC)/sampling/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -43,4 +46,7 @@ EXE_LIBS = \
     -lsurfaceFilmModels \
     -lcombustionModels \
     -lsampling \
-    -lcoalCombustion
+    -lcoalCombustion \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/sprayFoam/Make/options b/applications/solvers/lagrangian/sprayFoam/Make/options
index 3e7fecf2e146e8a6a6f1c0d99c12a5f8732923d6..1d711963065977bb1901fc5f7d15de35ca88726c 100644
--- a/applications/solvers/lagrangian/sprayFoam/Make/options
+++ b/applications/solvers/lagrangian/sprayFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I../reactingParcelFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I${LIB_SRC}/sampling/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -20,6 +21,8 @@ EXE_INC = \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
     -I$(LIB_SRC)/combustionModels/lnInclude
 
 EXE_LIBS = \
@@ -44,4 +47,7 @@ EXE_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -lcombustionModels \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/sprayFoam/engineFoam/Make/options b/applications/solvers/lagrangian/sprayFoam/engineFoam/Make/options
index e036f2a908de73012db5d88cfafd2df723f5d78f..7a8c521c90e6887924111c0951a4fb37a053d37e 100644
--- a/applications/solvers/lagrangian/sprayFoam/engineFoam/Make/options
+++ b/applications/solvers/lagrangian/sprayFoam/engineFoam/Make/options
@@ -3,6 +3,7 @@ EXE_INC = \
     -I.. \
     -I../../reactingParcelFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I${LIB_SRC}/sampling/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -23,7 +24,9 @@ EXE_INC = \
     -I$(LIB_SRC)/engine/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-    -I$(LIB_SRC)/combustionModels/lnInclude
+    -I$(LIB_SRC)/combustionModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -48,4 +51,7 @@ EXE_LIBS = \
     -lengine \
     -lregionModels \
     -lsurfaceFilmModels \
-    -lcombustionModels
+    -lcombustionModels \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/sprayFoam/simpleSprayFoam/Make/options b/applications/solvers/lagrangian/sprayFoam/simpleSprayFoam/Make/options
index 565af71908d457cd86e1fc56784898c2f2c1f3d3..151225cb0787a77e84500d3c4bd65d67ddb84b3e 100644
--- a/applications/solvers/lagrangian/sprayFoam/simpleSprayFoam/Make/options
+++ b/applications/solvers/lagrangian/sprayFoam/simpleSprayFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I$(FOAM_SOLVERS)/lagrangian/reactingParcelFoam/simpleReactingParcelFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -20,7 +21,9 @@ EXE_INC = \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-    -I$(LIB_SRC)/combustionModels/lnInclude
+    -I$(LIB_SRC)/combustionModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -44,4 +47,7 @@ EXE_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -lcombustionModels \
-    -lsampling
+    -lsampling \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/sprayFoam/sprayDyMFoam/Make/options b/applications/solvers/lagrangian/sprayFoam/sprayDyMFoam/Make/options
index cd6c9ef7b8724679dbc836d8fecc8f3d057a9cf1..c7501564d2e2554734d0f14dd4f7c9ac89a1262a 100644
--- a/applications/solvers/lagrangian/sprayFoam/sprayDyMFoam/Make/options
+++ b/applications/solvers/lagrangian/sprayFoam/sprayDyMFoam/Make/options
@@ -3,6 +3,7 @@ EXE_INC = \
     -I../../reactingParcelFoam \
     -I../../../compressible/rhoPimpleFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I${LIB_SRC}/meshTools/lnInclude \
     -I${LIB_SRC}/sampling/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
@@ -25,7 +26,9 @@ EXE_INC = \
     -I$(LIB_SRC)/combustionModels/lnInclude \
     -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/meshTools/lnInclude
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -51,4 +54,7 @@ EXE_LIBS = \
     -lcombustionModels \
     -ldynamicFvMesh \
     -ltopoChangerFvMesh \
-    -ldynamicMesh
+    -ldynamicMesh \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options b/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options
index 1bab76259cceaef4f808ce6d5ca7d095fc01bb29..18c419a4957c16295e35d99e3ae159665f7c0a9c 100644
--- a/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options
+++ b/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -11,7 +12,9 @@ EXE_INC = \
     -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude \
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -27,4 +30,7 @@ EXE_LIBS = \
     -lturbulenceModels \
     -lcompressibleTurbulenceModels \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/uncoupledKinematicParcelDyMFoam/Make/options b/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/uncoupledKinematicParcelDyMFoam/Make/options
index f41d858bf783ad4d90eec48da2c900dd5cd47882..067d0c0311530f0d108996be2e3bee3062086c04 100644
--- a/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/uncoupledKinematicParcelDyMFoam/Make/options
+++ b/applications/solvers/lagrangian/uncoupledKinematicParcelFoam/uncoupledKinematicParcelDyMFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I.. \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
@@ -14,7 +15,9 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -33,4 +36,7 @@ EXE_LIBS = \
     -lsurfaceFilmModels \
     -ldynamicMesh \
     -ldynamicFvMesh \
-    -ltopoChangerFvMesh
+    -ltopoChangerFvMesh \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
diff --git a/applications/solvers/multiphase/MPPICInterFoam/Make/options b/applications/solvers/multiphase/MPPICInterFoam/Make/options
index 337f90f68680feeb34224b67591d2f606a850683..078ccece8658fbaf466e1579149da47e70dc2f96 100644
--- a/applications/solvers/multiphase/MPPICInterFoam/Make/options
+++ b/applications/solvers/multiphase/MPPICInterFoam/Make/options
@@ -2,6 +2,7 @@ EXE_INC = \
     -I../VoF \
     -I$(FOAM_SOLVERS)/multiphase/interFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/fvOptions/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
@@ -20,7 +21,9 @@ EXE_INC = \
     -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
     -I$(LIB_SRC)/TurbulenceModels/phaseCompressible/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
@@ -38,3 +41,4 @@ EXE_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -lcompressibleTwoPhaseMixtureTurbulenceModels
+
diff --git a/src/Allwmake b/src/Allwmake
index e488f9397822ef92eef76442a0ac7560ed00db3f..0af702324ec94173a950030338fdca03eedbee5e 100755
--- a/src/Allwmake
+++ b/src/Allwmake
@@ -83,14 +83,18 @@ wmake $targetType ODE
 thermophysicalModels/Allwmake $targetType $*
 TurbulenceModels/Allwmake $targetType $*
 wmake $targetType combustionModels
+
+wmakeLnInclude -u regionFaModels
+wmakeLnInclude -u faOptions
 regionModels/Allwmake $targetType $*
-lagrangian/Allwmake $targetType $*
 
 wmake $targetType fvOptions
 wmake $targetType faOptions
 wmake $targetType fvMotionSolver
 wmake $targetType regionFaModels
 
+lagrangian/Allwmake $targetType $*
+
 wmake $targetType overset
 
 # snappyHexMesh uses overset voxelMesh
diff --git a/src/faOptions/corrections/limitVelocity/limitVelocity.C b/src/faOptions/corrections/limitVelocity/limitVelocity.C
new file mode 100644
index 0000000000000000000000000000000000000000..fa2f484fab0d5a7d0206a512dd73d3652dd2988e
--- /dev/null
+++ b/src/faOptions/corrections/limitVelocity/limitVelocity.C
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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 "limitVelocity.H"
+#include "areaFields.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace fa
+{
+    defineTypeNameAndDebug(limitVelocity, 0);
+    addToRunTimeSelectionTable
+    (
+        option,
+        limitVelocity,
+        dictionary
+    );
+}
+}
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fa::limitVelocity::limitVelocity
+(
+    const word& name,
+    const word& modelType,
+    const dictionary& dict,
+    const fvPatch& patch
+)
+:
+    faceSetOption(name, modelType, dict, patch),
+    UName_(coeffs_.getOrDefault<word>("U", "U")),
+    max_(coeffs_.get<scalar>("max"))
+{
+    fieldNames_.setSize(1, UName_);
+    applied_.setSize(1, false);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::fa::limitVelocity::read(const dictionary& dict)
+{
+    if (faceSetOption::read(dict))
+    {
+        coeffs_.readEntry("max", max_);
+
+        return true;
+    }
+
+    return false;
+}
+
+
+void Foam::fa::limitVelocity::correct(areaVectorField& U)
+{
+    const scalar maxSqrU = sqr(max_);
+
+    vectorField& Uif = U.primitiveFieldRef();
+
+    for (const label facei : faces_)
+    {
+        const scalar magSqrUi = magSqr(Uif[facei]);
+
+        if (magSqrUi > maxSqrU)
+        {
+            Uif[facei] *= sqrt(maxSqrU/max(magSqrUi, SMALL));
+        }
+    }
+
+    // handle boundaries in the case of 'all'
+    if (selectionMode_ == smAll)
+    {
+        areaVectorField::Boundary& Ubf = U.boundaryFieldRef();
+
+        forAll(Ubf, patchi)
+        {
+            faPatchVectorField& Up = Ubf[patchi];
+
+            if (!Up.fixesValue())
+            {
+                forAll(Up, facei)
+                {
+                    const scalar magSqrUi = magSqr(Up[facei]);
+
+                    if (magSqrUi > maxSqrU)
+                    {
+                        Up[facei] *= sqrt(maxSqrU/max(magSqrUi, SMALL));
+                    }
+                }
+            }
+        }
+    }
+
+    // We've changed internal values so give boundary conditions opportunity
+    // to correct.
+    U.correctBoundaryConditions();
+}
+
+
+// ************************************************************************* //
diff --git a/src/faOptions/corrections/limitVelocity/limitVelocity.H b/src/faOptions/corrections/limitVelocity/limitVelocity.H
new file mode 100644
index 0000000000000000000000000000000000000000..e5da8a400aa3eae97679086f84278943f0ab433b
--- /dev/null
+++ b/src/faOptions/corrections/limitVelocity/limitVelocity.H
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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::fa::limitVelocity
+
+Description
+    Limits the maximum velocity magnitude to the specified \c max value.
+
+Usage
+    Minimal example by using \c constant/faOptions:
+    \verbatim
+    <faOption>
+    {
+        // Mandatory entries
+        type            limitVelocity;
+        active          yes;
+        selectionMode   all;
+        max             <maxValue>;
+
+        // Optional entries
+        U               <UName>;
+
+        // Inherited entries
+        ...
+    }
+    \endverbatim
+
+    where the entries mean:
+    \table
+      Property  | Description                   | Type   | Reqd  | Deflt
+      type      | Type name: limitVelocity      | word   | yes   | -
+      max       | Maximum velocity limit [m/s]  | scalar | yes   | -
+      U         | Name of operand velocity field | word  | no    | U
+    \endtable
+
+    The inherited entries are elaborated in:
+     - \link fvOption.H \endlink
+     - \link faceSetOption.H \endlink
+
+SourceFiles
+    limitVelocity.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef limitVelocity_H
+#define limitVelocity_H
+
+#include "faceSetOption.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace fa
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class limitVelocity Declaration
+\*---------------------------------------------------------------------------*/
+
+class limitVelocity
+:
+    public faceSetOption
+{
+protected:
+
+    // Protected Data
+
+        //- Name of operand velocity field
+        word UName_;
+
+        //- Maximum velocity magnitude
+        scalar max_;
+
+
+private:
+
+    // Private Member Functions
+
+        //- No copy construct
+        limitVelocity(const limitVelocity&) = delete;
+
+        //- No copy assignment
+        void operator=(const limitVelocity&) = delete;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("limitVelocity");
+
+
+    // Constructors
+
+        //- Construct from components
+        limitVelocity
+        (
+            const word& name,
+            const word& modelType,
+            const dictionary& dict,
+            const fvPatch& patch
+        );
+
+
+    //- Destructor
+    virtual ~limitVelocity() = default;
+
+
+    // Member Functions
+
+        //- Read dictionary
+        virtual bool read(const dictionary& dict);
+
+        //- Correct the velocity field
+        virtual void correct(areaVectorField& U);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.C b/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.C
index e812353649570f35381c5241a26ce3bd99fe2657..01bc10a050b376ff64f7a7da10ff64b58356d8dd 100644
--- a/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.C
+++ b/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2016-2017 Wikki Ltd
-    Copyright (C) 2020 OpenCFD Ltd.
+    Copyright (C) 2020-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -65,6 +65,36 @@ Foam::tmp<Foam::Field<Type>> Foam::volSurfaceMapping::mapToSurface
 }
 
 
+template<class Type>
+Foam::tmp<Foam::Field<Type>> Foam::volSurfaceMapping::mapToSurface
+(
+    const Field<Type>& f
+) const
+{
+    const labelList& faceLabels = mesh_.faceLabels();
+
+    auto tresult = tmp<Field<Type>>::New(faceLabels.size(), Zero);
+    auto& result = tresult.ref();
+
+    const polyMesh& pMesh = mesh_();
+    const polyBoundaryMesh& bm = pMesh.boundaryMesh();
+    label patchID, faceID;
+
+    forAll(faceLabels, i)
+    {
+        if (faceLabels[i] < pMesh.nFaces())
+        {
+            patchID = bm.whichPatch(faceLabels[i]);
+            faceID = bm[patchID].whichFace(faceLabels[i]);
+
+            result[i] = f[faceID];
+        }
+    }
+
+    return tresult;
+}
+
+
 template<class Type>
 Foam::tmp<Foam::Field<Type>> Foam::volSurfaceMapping::mapInternalToSurface
 (
@@ -151,6 +181,19 @@ void Foam::volSurfaceMapping::mapToField
     const GeometricField<Type, faPatchField, areaMesh>& af,
     Field<Type>& f
 ) const
+{
+    const Field<Type>& afi = af.internalField();
+
+    mapToField(afi, f);
+}
+
+
+template<class Type>
+void Foam::volSurfaceMapping::mapToField
+(
+    const Field<Type>& af,
+    Field<Type>& f
+) const
 {
     const labelList& faceLabels = mesh_.faceLabels();
 
@@ -158,15 +201,13 @@ void Foam::volSurfaceMapping::mapToField
     const polyBoundaryMesh& bm = pMesh.boundaryMesh();
     label patchID, faceID;
 
-    const Field<Type>& afi = af.internalField();
-
     forAll(faceLabels, i)
     {
         if (faceLabels[i] < pMesh.nFaces())
         {
             patchID = bm.whichPatch(faceLabels[i]);
             faceID = bm[patchID].whichFace(faceLabels[i]);
-            f[faceID] = afi[i];
+            f[faceID] = af[i];
         }
     }
 }
diff --git a/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.H b/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.H
index 5b428f099c19df902ad6e9ba5fe28e0f9ea5e6f6..f5908f04a41db680ac01ded0feb144c2fc18e6b0 100644
--- a/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.H
+++ b/src/finiteArea/interpolation/volSurfaceMapping/volSurfaceMapping.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2016-2017 Wikki Ltd
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -42,6 +42,7 @@ SourceFiles
 #define volSurfaceMapping_H
 
 #include "faMesh.H"
+#include "volMesh.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -85,7 +86,7 @@ public:
 
     // Member Functions
 
-        //- Map droplet cloud sources to surface
+        //- Map Boundary field to surface
         template<class Type>
         tmp<Field<Type>> mapToSurface
         (
@@ -93,6 +94,9 @@ public:
             GeometricField<Type, fvPatchField, volMesh>::Boundary& df
         ) const;
 
+        //- Map vol Field to surface Field
+        template<class Type>
+        tmp<Field<Type>> mapToSurface(const Field<Type>& f) const;
 
         //- Map patch internal field to surface
         template<class Type>
@@ -118,14 +122,23 @@ public:
             typename GeometricField<Type, fvPatchField, volMesh>::Boundary& bf
         ) const;
 
-        //- Map surface field to field assumes Field
-        //- faces in the same order as Boundary
+        //- Map surface field to field
+        //  Assumes Field faces in the same order as Boundary
         template<class Type>
         void mapToField
         (
             const GeometricField<Type, faPatchField, areaMesh>& af,
             Field<Type>& f
         ) const;
+
+        //- Map surface field to volume field
+        //  Assumes Field faces in the same order as Boundary
+        template<class Type>
+        void mapToField
+        (
+            const Field<Type>& af,
+            Field<Type>& f
+        ) const;
 };
 
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
index 1592f3f38289f2819f8c58fadb15795dd1c0301a..7a9c170d7a3123ca17baab91476c75cbf2b9f600 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -92,46 +93,50 @@ movingWallVelocityFvPatchVectorField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::movingWallVelocityFvPatchVectorField::updateCoeffs()
+Foam::tmp<Foam::vectorField>
+Foam::movingWallVelocityFvPatchVectorField::Uwall() const
 {
-    if (updated())
-    {
-        return;
-    }
-
     const fvMesh& mesh = internalField().mesh();
+    const fvPatch& p = patch();
+    const polyPatch& pp = p.patch();
+    const pointField& oldPoints = mesh.oldPoints();
 
-    if (mesh.moving())
+    vectorField oldFc(pp.size());
+
+    forAll(oldFc, i)
     {
-        const fvPatch& p = patch();
-        const polyPatch& pp = p.patch();
-        const pointField& oldPoints = mesh.oldPoints();
+        oldFc[i] = pp[i].centre(oldPoints);
+    }
+
+    const scalar deltaT = mesh.time().deltaTValue();
 
-        vectorField oldFc(pp.size());
+    const vectorField Up((pp.faceCentres() - oldFc)/deltaT);
 
-        forAll(oldFc, i)
-        {
-            oldFc[i] = pp[i].centre(oldPoints);
-        }
+    const auto& U = static_cast<const volVectorField&>(internalField());
 
-        const scalar deltaT = mesh.time().deltaTValue();
+    tmp<scalarField> phip =
+        p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
 
-        const vectorField Up((pp.faceCentres() - oldFc)/deltaT);
+    const vectorField n(p.nf());
+    const scalarField& magSf = p.magSf();
+    tmp<scalarField> Un = phip/(magSf + VSMALL);
 
-        const volVectorField& U =
-            static_cast<const volVectorField&>(internalField());
+    return (Up + n*(Un - (n & Up)));
+}
 
-        scalarField phip
-        (
-            p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U))
-        );
 
-        const vectorField n(p.nf());
-        const scalarField& magSf = p.magSf();
-        tmp<scalarField> Un = phip/(magSf + VSMALL);
+void Foam::movingWallVelocityFvPatchVectorField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
 
+    const fvMesh& mesh = internalField().mesh();
 
-        vectorField::operator=(Up + n*(Un - (n & Up)));
+    if (mesh.moving())
+    {
+        vectorField::operator=(Uwall()());
     }
 
     fixedValueFvPatchVectorField::updateCoeffs();
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.H
index bd272e93176d02215bebbf3fccf562e6c1b4f9de..9b5b05cd7ec3d74e68863b3d8bec9ac96cb5facd 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/movingWallVelocity/movingWallVelocityFvPatchVectorField.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2015 OpenCFD Ltd.
+    Copyright (C) 2015-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -71,7 +71,6 @@ class movingWallVelocityFvPatchVectorField
 :
     public fixedValueFvPatchVectorField
 {
-
 public:
 
     //- Runtime type information
@@ -140,7 +139,10 @@ public:
         }
 
 
-    // Member functions
+    // Member Functions
+
+        //- Return wall velocity field
+        tmp<vectorField> Uwall() const;
 
         //- Update the coefficients associated with the patch field
         virtual void updateCoeffs();
diff --git a/src/functionObjects/lagrangian/Make/options b/src/functionObjects/lagrangian/Make/options
index 26e35a3df73e14e78aca28901840bca8e23b391e..c1d04b6d1498f3db5ef3e271c4535bcb46dc767a 100644
--- a/src/functionObjects/lagrangian/Make/options
+++ b/src/functionObjects/lagrangian/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
     -I$(LIB_SRC)/fileFormats/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/conversion/lnInclude \
@@ -9,7 +10,9 @@ EXE_INC = \
     -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
     -I$(LIB_SRC)/lagrangian/DSMC/lnInclude \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
+    -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
@@ -21,4 +24,8 @@ LIB_LIBS = \
     -llagrangianIntermediate \
     -llagrangianTurbulence \
     -lregionModels \
-    -lsurfaceFilmModels
+    -lsurfaceFilmModels \
+    -lregionFaModels \
+    -lfiniteArea \
+    -lfaOptions
+
diff --git a/src/lagrangian/coalCombustion/Make/options b/src/lagrangian/coalCombustion/Make/options
index 25ee31bf7dfc939af4f6adaeb43280e93cc02261..594770817691aa072cb71de3748c523f137b9385 100644
--- a/src/lagrangian/coalCombustion/Make/options
+++ b/src/lagrangian/coalCombustion/Make/options
@@ -18,7 +18,10 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
@@ -41,4 +44,6 @@ LIB_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -ldynamicMesh \
-    -ldynamicFvMesh
+    -ldynamicFvMesh \
+    -lregionFaModels \
+    -lfiniteArea
diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options
index d972d5b0345590520cdb943aa98de8f2c2e29f10..74eb95ca4c0e8adf79c358849f15e9692f3d53f0 100644
--- a/src/lagrangian/intermediate/Make/options
+++ b/src/lagrangian/intermediate/Make/options
@@ -16,7 +16,10 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
@@ -36,4 +39,6 @@ LIB_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -ldynamicMesh \
-    -ldynamicFvMesh
+    -ldynamicFvMesh \
+    -lregionFaModels \
+    -lfiniteArea
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
index 788aa175e88f35202c2b02f628c451bbfd088696..288c7ec747ff90e8791b2982698329a242d33a17 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
@@ -534,8 +534,12 @@ public:
                     inline const volScalarField::Internal&
                         UCoeff() const;
 
-                    //- Return tmp momentum source term
-                    inline tmp<fvVectorMatrix> SU(volVectorField& U) const;
+                    //- Return tmp momentum source term (compressible)
+                    inline tmp<fvVectorMatrix> SU
+                    (
+                        volVectorField& U,
+                        bool incompressible = false
+                    ) const;
 
 
         // Check
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H
index 6e4a017bdbe6c66c0dd9554abc4c2b9673108c79..b3e903aa94287f2dfcea121d852ff06623e7e3ad 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H
@@ -468,7 +468,8 @@ Foam::KinematicCloud<CloudType>::UCoeff() const
 
 template<class CloudType>
 inline Foam::tmp<Foam::fvVectorMatrix>
-Foam::KinematicCloud<CloudType>::SU(volVectorField& U) const
+Foam::KinematicCloud<CloudType>::SU(volVectorField& U, bool incompressible)
+const
 {
     if (debug)
     {
@@ -478,18 +479,29 @@ Foam::KinematicCloud<CloudType>::SU(volVectorField& U) const
             << max(UCoeff()).value() << endl;
     }
 
+    dimensionSet dim(dimForce);
+    if (incompressible)
+    {
+        dim.reset(dimForce/dimDensity);
+    }
+
     if (solution_.coupled())
     {
         if (solution_.semiImplicit("U"))
         {
-            const volScalarField::Internal
+            volScalarField::Internal
                 Vdt(mesh_.V()*this->db().time().deltaT());
 
+            if (incompressible)
+            {
+                Vdt.dimensions() *= dimDensity;
+            }
+
             return UTrans()/Vdt - fvm::Sp(UCoeff()/Vdt, U) + UCoeff()/Vdt*U;
         }
         else
         {
-            tmp<fvVectorMatrix> tfvm(new fvVectorMatrix(U, dimForce));
+            tmp<fvVectorMatrix> tfvm(new fvVectorMatrix(U, dim));
             fvVectorMatrix& fvm = tfvm.ref();
 
             fvm.source() = -UTrans()/(this->db().time().deltaT());
@@ -498,7 +510,7 @@ Foam::KinematicCloud<CloudType>::SU(volVectorField& U) const
         }
     }
 
-    return tmp<fvVectorMatrix>::New(U, dimForce);
+    return tmp<fvVectorMatrix>::New(U, dim);
 }
 
 
diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelSurfaceFilmModels.H b/src/lagrangian/intermediate/parcels/include/makeParcelSurfaceFilmModels.H
index 7e2b1f9c734f1260cee2ec5eb4d330c4b74f32d6..de67215d6a25e79de6fcb23a1d16405330b02d6a 100644
--- a/src/lagrangian/intermediate/parcels/include/makeParcelSurfaceFilmModels.H
+++ b/src/lagrangian/intermediate/parcels/include/makeParcelSurfaceFilmModels.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -31,14 +32,15 @@ License
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #include "NoSurfaceFilm.H"
+#include "KinematicSurfaceFilm.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #define makeParcelSurfaceFilmModels(CloudType)                                 \
                                                                                \
     makeSurfaceFilmModel(CloudType);                                           \
-    makeSurfaceFilmModelType(NoSurfaceFilm, CloudType);
-
+    makeSurfaceFilmModelType(NoSurfaceFilm, CloudType);                        \
+    makeSurfaceFilmModelType(KinematicSurfaceFilm, CloudType);
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/lagrangian/intermediate/parcels/include/makeReactingParcelSurfaceFilmModels.H b/src/lagrangian/intermediate/parcels/include/makeReactingParcelSurfaceFilmModels.H
index 67dfb49a75a1505621b627d0af7ca2244f6f5ab3..cdd181b25519502957c37cf9c90bc8d84911f98c 100644
--- a/src/lagrangian/intermediate/parcels/include/makeReactingParcelSurfaceFilmModels.H
+++ b/src/lagrangian/intermediate/parcels/include/makeReactingParcelSurfaceFilmModels.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,6 +33,7 @@ License
 
 #include "NoSurfaceFilm.H"
 #include "ThermoSurfaceFilm.H"
+#include "KinematicSurfaceFilm.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -39,7 +41,8 @@ License
                                                                                \
     makeSurfaceFilmModel(CloudType);                                           \
     makeSurfaceFilmModelType(NoSurfaceFilm, CloudType);                        \
-    makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType);
+    makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType);                    \
+    makeSurfaceFilmModelType(KinematicSurfaceFilm, CloudType);
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/lagrangian/intermediate/parcels/include/makeThermoParcelSurfaceFilmModels.H b/src/lagrangian/intermediate/parcels/include/makeThermoParcelSurfaceFilmModels.H
index 57e4cfc68951abd3b6463be1e83aa2883c3f2c44..4ba044be132fb9b693c286f1b87ad02809fce13e 100644
--- a/src/lagrangian/intermediate/parcels/include/makeThermoParcelSurfaceFilmModels.H
+++ b/src/lagrangian/intermediate/parcels/include/makeThermoParcelSurfaceFilmModels.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,6 +33,7 @@ License
 
 #include "NoSurfaceFilm.H"
 #include "ThermoSurfaceFilm.H"
+#include "KinematicSurfaceFilm.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -40,7 +42,8 @@ License
     makeSurfaceFilmModel(CloudType);                                           \
                                                                                \
     makeSurfaceFilmModelType(NoSurfaceFilm, CloudType);                        \
-    makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType);
+    makeSurfaceFilmModelType(ThermoSurfaceFilm, CloudType);                    \
+    makeSurfaceFilmModelType(KinematicSurfaceFilm, CloudType);
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/lagrangian/intermediate/phaseProperties/phaseProperties/phaseProperties.C b/src/lagrangian/intermediate/phaseProperties/phaseProperties/phaseProperties.C
index 35076e8718b5bb075ba22286361d3b3e447ad96a..a610389b9146494e007fafc0643ea73e68775226 100644
--- a/src/lagrangian/intermediate/phaseProperties/phaseProperties/phaseProperties.C
+++ b/src/lagrangian/intermediate/phaseProperties/phaseProperties/phaseProperties.C
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2015 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -85,11 +86,11 @@ void Foam::phaseProperties::reorder(const wordList& specieNames)
 
         if (!found)
         {
-            FatalErrorInFunction
+            WarningInFunction
                 << "Could not find specie " << names0[i]
                 << " in list " <<  names_
                 << " for phase " << phaseTypeNames[phase_]
-                << exit(FatalError);
+                << nl;
         }
     }
 }
@@ -114,11 +115,11 @@ void Foam::phaseProperties::setCarrierIds
         }
         if (carrierIds_[i] == -1)
         {
-            FatalErrorInFunction
+            WarningInFunction
                 << "Could not find carrier specie " << names_[i]
                 << " in species list" <<  nl
                 << "Available species are: " << nl << carrierNames << nl
-                << exit(FatalError);
+                << nl;
         }
     }
 }
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C
index 923af2c0023a054f432bfecec6e2c5f2df92c0be..94e4961ca8bc39cfd61aac318d4f7bb591bf0dba 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C
@@ -5,8 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2016-2020 OpenCFD Ltd.
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/KinematicSurfaceFilm/KinematicSurfaceFilm.C b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/KinematicSurfaceFilm/KinematicSurfaceFilm.C
new file mode 100644
index 0000000000000000000000000000000000000000..a08e87e5c53304f9a56c70d7171f625966a4cb9e
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/KinematicSurfaceFilm/KinematicSurfaceFilm.C
@@ -0,0 +1,823 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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 "KinematicSurfaceFilm.H"
+#include "surfaceFilmRegionModel.H"
+#include "liquidFilmModel.H"
+#include "addToRunTimeSelectionTable.H"
+#include "unitConversion.H"
+#include "Pstream.H"
+
+using namespace Foam::constant::mathematical;
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::wordList Foam::KinematicSurfaceFilm<CloudType>::interactionTypeNames_
+{
+    "absorb", "bounce", "splashBai"
+};
+
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+template<class CloudType>
+typename Foam::KinematicSurfaceFilm<CloudType>::interactionType
+Foam::KinematicSurfaceFilm<CloudType>::interactionTypeEnum(const word& it) const
+{
+    forAll(interactionTypeNames_, i)
+    {
+        if (interactionTypeNames_[i] == it)
+        {
+            return interactionType(i);
+        }
+    }
+
+    FatalErrorInFunction
+        << "Unknown interaction type " << it
+        << ". Valid interaction types include: " << interactionTypeNames_
+        << abort(FatalError);
+
+    return interactionType(0);
+}
+
+
+template<class CloudType>
+Foam::word Foam::KinematicSurfaceFilm<CloudType>::interactionTypeStr
+(
+    const interactionType& it
+) const
+{
+    if (it >= interactionTypeNames_.size())
+    {
+        FatalErrorInFunction
+            << "Unknown interaction type enumeration" << abort(FatalError);
+    }
+
+    return interactionTypeNames_[it];
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::vector Foam::KinematicSurfaceFilm<CloudType>::tangentVector
+(
+    const vector& v
+) const
+{
+    vector tangent(Zero);
+    scalar magTangent = 0.0;
+
+    while (magTangent < SMALL)
+    {
+        const vector vTest(rndGen_.sample01<vector>());
+        tangent = vTest - (vTest & v)*v;
+        magTangent = mag(tangent);
+    }
+
+    return tangent/magTangent;
+}
+
+
+template<class CloudType>
+Foam::vector Foam::KinematicSurfaceFilm<CloudType>::splashDirection
+(
+    const vector& tanVec1,
+    const vector& tanVec2,
+    const vector& nf
+) const
+{
+    // Azimuthal angle [rad]
+    const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
+
+    // Ejection angle [rad]
+    const scalar thetaSi = degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
+
+    // Direction vector of new parcel
+    const scalar alpha = sin(thetaSi);
+    const scalar dcorr = cos(thetaSi);
+    const vector normal(alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi)));
+    vector dirVec(dcorr*nf);
+    dirVec += normal;
+
+    return dirVec/mag(dirVec);
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::initFilmModels()
+{
+    const fvMesh& mesh = this->owner().mesh();
+
+    // set up filmModel pointer
+    if (!filmModel_)
+    {
+        filmModel_ =
+            const_cast<regionFilm*>
+            (
+                mesh.time().objectRegistry::template findObject
+                <
+                    regionFilm
+                >
+                (
+                    "surfaceFilmProperties"
+                )
+            );
+    }
+
+    if (areaFilms_.size() == 0)
+    {
+        // set up areaFilms
+        const wordList names =
+            mesh.time().objectRegistry::template
+                sortedNames<regionModels::regionFaModel>();
+
+        forAll(names, i)
+        {
+            const regionModels::regionFaModel* regionFa =
+                mesh.time().objectRegistry::template findObject
+                <
+                    regionModels::regionFaModel
+                >(names[i]);
+
+            if (regionFa && isA<areaFilm>(*regionFa))
+            {
+                areaFilm& film =
+                    const_cast<areaFilm&>(refCast<const areaFilm>(*regionFa));
+                areaFilms_.append(&film);
+            }
+        }
+    }
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::init(bool binitThermo)
+{
+    if (binitThermo)
+    {
+        this->coeffDict().readEntry("pRef", pRef_);
+        this->coeffDict().readEntry("TRef", TRef_);
+        thermo_ = new liquidMixtureProperties(this->coeffDict().subDict("thermo"));
+    }
+}
+
+
+template<class CloudType>
+template<class filmType>
+void Foam::KinematicSurfaceFilm<CloudType>::absorbInteraction
+(
+    filmType& film,
+    const parcelType& p,
+    const polyPatch& pp,
+    const label facei,
+    const scalar mass,
+    bool& keepParticle
+)
+{
+    if (debug)
+    {
+        Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
+    }
+
+    // Patch face normal
+    const vector& nf = pp.faceNormals()[facei];
+
+    // Patch velocity
+    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
+
+    // Relative parcel velocity
+    const vector Urel(p.U() - Up);
+
+    // Parcel normal velocity
+    const vector Un(nf*(Urel & nf));
+
+    // Parcel tangential velocity
+    const vector Ut(Urel - Un);
+
+    film.addSources
+    (
+        pp.index(),
+        facei,
+        mass,                             // mass
+        mass*Ut,                          // tangential momentum
+        mass*mag(Un),                     // impingement pressure
+        0                                 // energy
+    );
+
+    this->nParcelsTransferred()++;
+
+    this->totalMassTransferred() += mass;
+
+    keepParticle = false;
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::bounceInteraction
+(
+    parcelType& p,
+    const polyPatch& pp,
+    const label facei,
+    bool& keepParticle
+) const
+{
+    if (debug)
+    {
+        Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
+    }
+
+    // Patch face normal
+    const vector& nf = pp.faceNormals()[facei];
+
+    // Patch velocity
+    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
+
+    // Relative parcel velocity
+    const vector Urel(p.U() - Up);
+
+    // Flip parcel normal velocity component
+    p.U() -= 2.0*nf*(Urel & nf);
+
+    keepParticle = true;
+}
+
+
+template<class CloudType>
+template<class filmType>
+void Foam::KinematicSurfaceFilm<CloudType>::drySplashInteraction
+(
+    filmType& filmModel,
+    const scalar sigma,
+    const scalar mu,
+    const parcelType& p,
+    const polyPatch& pp,
+    const label facei,
+    bool& keepParticle
+)
+{
+    if (debug)
+    {
+        Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
+    }
+
+    // Patch face velocity and normal
+    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
+    const vector& nf = pp.faceNormals()[facei];
+
+    // Local pressure
+    //const scalar pc = thermo_.thermo().p()[p.cell()];
+
+    // Retrieve parcel properties
+    const scalar m = p.mass()*p.nParticle();
+    const scalar rho = p.rho();
+    const scalar d = p.d();
+    const vector Urel(p.U() - Up);
+    const vector Un(nf*(Urel & nf));
+
+    // Laplace number
+    const scalar La = rho*sigma*d/sqr(mu);
+
+    // Weber number
+    const scalar We = rho*magSqr(Un)*d/sigma;
+
+    // Critical Weber number
+    const scalar Wec = Adry_*pow(La, -0.183);
+
+    if (We < Wec) // Adhesion - assume absorb
+    {
+        absorbInteraction<filmType>
+            (filmModel, p, pp, facei, m, keepParticle);
+    }
+    else // Splash
+    {
+        // Ratio of incident mass to splashing mass
+        const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
+        splashInteraction<filmType>
+            (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
+    }
+}
+
+
+template<class CloudType>
+template<class filmType>
+void Foam::KinematicSurfaceFilm<CloudType>::wetSplashInteraction
+(
+    filmType& filmModel,
+    const scalar sigma,
+    const scalar mu,
+    parcelType& p,
+    const polyPatch& pp,
+    const label facei,
+    bool& keepParticle
+)
+{
+    if (debug)
+    {
+        Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
+    }
+
+    // Patch face velocity and normal
+    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
+    const vector& nf = pp.faceNormals()[facei];
+
+    // Retrieve parcel properties
+    const scalar m = p.mass()*p.nParticle();
+    const scalar rho = p.rho();
+    const scalar d = p.d();
+    vector& U = p.U();
+    const vector Urel(p.U() - Up);
+    const vector Un(nf*(Urel & nf));
+    const vector Ut(Urel - Un);
+
+    // Laplace number
+    const scalar La = rho*sigma*d/sqr(mu);
+
+    // Weber number
+    const scalar We = rho*magSqr(Un)*d/sigma;
+
+    // Critical Weber number
+    const scalar Wec = Awet_*pow(La, -0.183);
+
+    if (We < 2) // Adhesion - assume absorb
+    {
+        absorbInteraction<filmType>
+            (filmModel, p, pp, facei, m, keepParticle);
+    }
+    else if ((We >= 2) && (We < 20)) // Bounce
+    {
+        // Incident angle of impingement
+        const scalar theta = piByTwo - acos(U/mag(U) & nf);
+
+        // Restitution coefficient
+        const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
+
+        // Update parcel velocity
+        U = -epsilon*(Un) + 5.0/7.0*(Ut);
+
+        keepParticle = true;
+        return;
+    }
+    else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
+    {
+        absorbInteraction<filmType>
+            (filmModel, p, pp, facei, m, keepParticle);
+    }
+    else    // Splash
+    {
+        // Ratio of incident mass to splashing mass
+        // splash mass can be > incident mass due to film entrainment
+        const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
+        splashInteraction<filmType>
+            (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
+    }
+}
+
+
+template<class CloudType>
+template<class filmType>
+void Foam::KinematicSurfaceFilm<CloudType>::splashInteraction
+(
+    filmType& filmModel,
+    const parcelType& p,
+    const polyPatch& pp,
+    const label facei,
+    const scalar mRatio,
+    const scalar We,
+    const scalar Wec,
+    const scalar sigma,
+    bool& keepParticle
+)
+{
+    // Patch face velocity and normal
+    const fvMesh& mesh = this->owner().mesh();
+    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
+    const vector& nf = pp.faceNormals()[facei];
+
+    // Determine direction vectors tangential to patch normal
+    const vector tanVec1(tangentVector(nf));
+    const vector tanVec2(nf^tanVec1);
+
+    // Retrieve parcel properties
+    const scalar np = p.nParticle();
+    const scalar m = p.mass()*np;
+    const scalar d = p.d();
+    const vector Urel(p.U() - Up);
+    const vector Un(nf*(Urel & nf));
+    const vector Ut(Urel - Un);
+    const vector& posC = mesh.C()[p.cell()];
+    const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
+
+    // Total mass of (all) splashed parcels
+    const scalar mSplash = m*mRatio;
+
+    // Number of splashed particles per incoming particle
+    const scalar Ns = 5.0*(We/Wec - 1.0);
+
+    // Average diameter of splashed particles
+    const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
+
+    // Cumulative diameter splash distribution
+    const scalar dMax = 0.9*cbrt(mRatio)*d;
+    const scalar dMin = 0.1*dMax;
+    const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
+
+    // Surface energy of secondary parcels [J]
+    scalar ESigmaSec = 0;
+
+    // Sample splash distribution to determine secondary parcel diameters
+    scalarList dNew(parcelsPerSplash_);
+    scalarList npNew(parcelsPerSplash_);
+    forAll(dNew, i)
+    {
+        const scalar y = rndGen_.sample01<scalar>();
+        dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
+        npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
+        ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
+    }
+
+    // Incident kinetic energy [J]
+    const scalar EKIn = 0.5*m*magSqr(Un);
+
+    // Incident surface energy [J]
+    const scalar ESigmaIn = np*sigma*p.areaS(d);
+
+    // Dissipative energy
+    const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
+
+    // Total energy [J]
+    const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
+
+    // Switch to absorb if insufficient energy for splash
+    if (EKs <= 0)
+    {
+        absorbInteraction<filmType>
+            (filmModel, p, pp, facei, m, keepParticle);
+        return;
+    }
+
+    // Helper variables to calculate magUns0
+    const scalar logD = log(d);
+    const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
+    scalar coeff1 = 0.0;
+    forAll(dNew, i)
+    {
+        coeff1 += sqr(log(dNew[i]) - logD);
+    }
+
+    // Magnitude of the normal velocity of the first splashed parcel
+    const scalar magUns0 =
+        sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
+
+    // Set splashed parcel properties
+    forAll(dNew, i)
+    {
+        const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
+
+        // Create a new parcel by copying source parcel
+        parcelType* pPtr = new parcelType(p);
+
+        pPtr->origId() = pPtr->getNewParticleID();
+
+        pPtr->origProc() = Pstream::myProcNo();
+
+        if (splashParcelType_ >= 0)
+        {
+            pPtr->typeId() = splashParcelType_;
+        }
+
+        // Perturb new parcels towards the owner cell centre
+        pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
+
+        pPtr->nParticle() = npNew[i];
+
+        pPtr->d() = dNew[i];
+
+        pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
+
+        // Apply correction to velocity for 2-D cases
+        meshTools::constrainDirection(mesh, mesh.solutionD(), pPtr->U());
+
+        // Add the new parcel
+        this->owner().addParticle(pPtr);
+
+        nParcelsSplashed_++;
+    }
+
+    // Transfer remaining part of parcel to film 0 - splashMass can be -ve
+    // if entraining from the film
+    const scalar mDash = m - mSplash;
+    absorbInteraction<filmType>
+        (filmModel, p, pp, facei, mDash, keepParticle);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::KinematicSurfaceFilm<CloudType>::KinematicSurfaceFilm
+(
+    const dictionary& dict,
+    CloudType& owner,
+    const word& type,
+    bool initThermo
+)
+:
+    SurfaceFilmModel<CloudType>(dict, owner, type),
+    rndGen_(owner.rndGen()),
+    thermo_(nullptr),
+    filmModel_(nullptr),
+    areaFilms_(0),
+    interactionType_
+    (
+        interactionTypeEnum(this->coeffDict().getWord("interactionType"))
+    ),
+    deltaWet_(0.0),
+    splashParcelType_(0),
+    parcelsPerSplash_(0),
+    Adry_(0.0),
+    Awet_(0.0),
+    Cf_(0.0),
+    nParcelsSplashed_(0)
+{
+    Info<< "    Applying " << interactionTypeStr(interactionType_)
+        << " interaction model" << endl;
+
+    if (interactionType_ == itSplashBai)
+    {
+        this->coeffDict().readEntry("deltaWet", deltaWet_);
+        splashParcelType_ =
+            this->coeffDict().getOrDefault("splashParcelType", -1);
+        parcelsPerSplash_ =
+            this->coeffDict().getOrDefault("parcelsPerSplash", 2);
+        this->coeffDict().readEntry("Adry", Adry_);
+        this->coeffDict().readEntry("Awet", Awet_);
+        this->coeffDict().readEntry("Cf", Cf_);
+        init(initThermo);
+    }
+}
+
+
+template<class CloudType>
+Foam::KinematicSurfaceFilm<CloudType>::KinematicSurfaceFilm
+(
+    const KinematicSurfaceFilm<CloudType>& sfm,
+    bool initThermo
+)
+:
+    SurfaceFilmModel<CloudType>(sfm),
+    rndGen_(sfm.rndGen_),
+    thermo_(nullptr),
+    filmModel_(nullptr),
+    areaFilms_(0),
+    interactionType_(sfm.interactionType_),
+    deltaWet_(sfm.deltaWet_),
+    splashParcelType_(sfm.splashParcelType_),
+    parcelsPerSplash_(sfm.parcelsPerSplash_),
+    Adry_(sfm.Adry_),
+    Awet_(sfm.Awet_),
+    Cf_(sfm.Cf_),
+    nParcelsSplashed_(sfm.nParcelsSplashed_)
+{
+    if (interactionType_ == itSplashBai)
+    {
+        init(initThermo);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class CloudType>
+bool Foam::KinematicSurfaceFilm<CloudType>::transferParcel
+(
+    parcelType& p,
+    const polyPatch& pp,
+    bool& keepParticle
+)
+{
+    const label patchi = pp.index();
+
+    bool bInteraction(false);
+
+    initFilmModels();
+
+    // Check the singleLayer film models
+    if (filmModel_)
+    {
+        if (filmModel_->isRegionPatch(patchi))
+        {
+            const label facei = pp.whichFace(p.face());
+
+            switch (interactionType_)
+            {
+                case itBounce:
+                {
+                    bounceInteraction(p, pp, facei, keepParticle);
+
+                    break;
+                }
+                case itAbsorb:
+                {
+                    const scalar m = p.nParticle()*p.mass();
+
+                    absorbInteraction<regionFilm>
+                        (*filmModel_, p, pp, facei, m, keepParticle);
+
+                    break;
+                }
+                case itSplashBai:
+                {
+                    bool dry = this->deltaFilmPatch_[patchi][facei] < deltaWet_;
+
+                    const scalarField X(thermo_->size(), 1);
+                    const scalar mu = thermo_->mu(pRef_, TRef_, X);
+                    const scalar sigma = thermo_->sigma(pRef_, TRef_, X);
+
+                    if (dry)
+                    {
+                        drySplashInteraction<regionFilm>
+                            (*filmModel_, sigma, mu, p, pp, facei, keepParticle);
+                    }
+                    else
+                    {
+                        wetSplashInteraction<regionFilm>
+                            (*filmModel_, sigma, mu, p, pp, facei, keepParticle);
+                    }
+
+                    break;
+                }
+                default:
+                {
+                    FatalErrorInFunction
+                        << "Unknown interaction type enumeration"
+                        << abort(FatalError);
+                }
+            }
+
+            // Transfer parcel/parcel interactions complete
+            bInteraction = true;
+        }
+    }
+
+
+    for (areaFilm& film : areaFilms_)
+    {
+        if (patchi == film.patchID())
+        {
+            const label facei = pp.whichFace(p.face());
+
+            switch (interactionType_)
+            {
+                // It only supports absorp model
+                case itAbsorb:
+                {
+                    const scalar m = p.nParticle()*p.mass();
+
+                    absorbInteraction<areaFilm>
+                    (
+                        film, p, pp, facei, m, keepParticle
+                    );
+                    break;
+                }
+                case itBounce:
+                {
+                    bounceInteraction(p, pp, facei, keepParticle);
+
+                    break;
+                }
+                case itSplashBai:
+                {
+                    bool dry = film.h()[facei] < deltaWet_;
+
+                    regionModels::areaSurfaceFilmModels::liquidFilmModel& liqFilm =
+                        refCast
+                        <   regionModels::areaSurfaceFilmModels::liquidFilmModel
+                        >(film);
+
+                    const scalarField X(liqFilm.thermo().size(), 1);
+                    const scalar pRef = film.pRef();
+                    const scalar TRef = liqFilm.Tref();
+
+                    const scalar mu = liqFilm.thermo().mu(pRef, TRef, X);
+                    const scalar sigma =
+                        liqFilm.thermo().sigma(pRef, TRef, X);
+
+                    if (dry)
+                    {
+                        drySplashInteraction<areaFilm>
+                            (film, sigma, mu, p, pp, facei, keepParticle);
+                    }
+                    else
+                    {
+                        wetSplashInteraction<areaFilm>
+                            (film, sigma, mu, p, pp, facei, keepParticle);
+                    }
+
+                    break;
+                }
+                default:
+                {
+                    FatalErrorInFunction
+                        << "Unknown interaction type enumeration"
+                        << abort(FatalError);
+                }
+            }
+            // Transfer parcel/parcel interactions complete
+            bInteraction = true;
+        }
+    }
+
+    // Parcel not interacting with film
+    return bInteraction;
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::cacheFilmFields
+(
+    const label filmPatchi,
+    const label primaryPatchi,
+    const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel
+)
+{
+    SurfaceFilmModel<CloudType>::cacheFilmFields
+    (
+        filmPatchi,
+        primaryPatchi,
+        filmModel
+    );
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::cacheFilmFields
+(
+    const label filmPatchi,
+    const areaFilm& filmModel
+)
+{
+    SurfaceFilmModel<CloudType>::cacheFilmFields
+    (
+        filmPatchi,
+        filmModel
+    );
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::setParcelProperties
+(
+    parcelType& p,
+    const label filmFacei
+) const
+{
+    SurfaceFilmModel<CloudType>::setParcelProperties(p, filmFacei);
+}
+
+
+template<class CloudType>
+void Foam::KinematicSurfaceFilm<CloudType>::info(Ostream& os)
+{
+    SurfaceFilmModel<CloudType>::info(os);
+
+    label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
+    label nSplashTotal =
+        nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
+
+    os  << "      - new splash parcels          = " << nSplashTotal << endl;
+
+    if (this->writeTime())
+    {
+        this->setModelProperty("nParcelsSplashed", nSplashTotal);
+        nParcelsSplashed_ = 0;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/KinematicSurfaceFilm/KinematicSurfaceFilm.H b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/KinematicSurfaceFilm/KinematicSurfaceFilm.H
new file mode 100644
index 0000000000000000000000000000000000000000..55d3fb5610a0a34eb6fca65636d8acde13614c2b
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/KinematicSurfaceFilm/KinematicSurfaceFilm.H
@@ -0,0 +1,365 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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::KinematicSurfaceFilm
+
+Group
+    grpLagrangianIntermediateSurfaceFilmSubModels
+
+Description
+    Kinematic parcel surface film model.
+
+    Responsible for:
+    - injecting parcelss from the film model into the cloud, e.g. for dripping
+    - parcel interaction with the film, e.g absorb, bounce, splash
+
+SourceFiles
+    KinematicSurfaceFilm.C
+    KinematicSurfaceFilmI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef KinematicSurfaceFilm_H
+#define KinematicSurfaceFilm_H
+
+#include "SurfaceFilmModel.H"
+#include "UPtrList.H"
+#include "liquidMixtureProperties.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+//Forward declaration of classes
+namespace regionModels
+{
+    namespace surfaceFilmModels
+    {
+        class surfaceFilmRegionModel;
+    }
+}
+
+namespace regionModels
+{
+    namespace areaSurfaceFilmModels
+    {
+        class liquidFilmBase;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+                      Class KinematicSurfaceFilm Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class CloudType>
+class KinematicSurfaceFilm
+:
+    public SurfaceFilmModel<CloudType>
+{
+public:
+
+    // Public Data
+
+        //- Options for the interaction types
+        enum interactionType
+        {
+            itAbsorb,
+            itBounce,
+            itSplashBai
+        };
+
+        //- Names for interactionType
+        static wordList interactionTypeNames_;
+
+
+    // Public Member Functions
+
+        //- Return interaction type enum from word
+        interactionType interactionTypeEnum(const word& it) const;
+
+        //- Return word from interaction type enum
+        word interactionTypeStr(const interactionType& it) const;
+
+
+protected:
+
+    // Protected Data
+
+        //- Convenience typedef to the cloud's parcel type
+        typedef typename CloudType::parcelType parcelType;
+
+        typedef typename
+            regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm;
+
+        typedef typename
+            regionModels::surfaceFilmModels::surfaceFilmRegionModel regionFilm;
+
+        //- Reference to the cloud random number generator
+        Random& rndGen_;
+
+
+        // Region Film thermo
+
+            //- Region Film liquid thermo
+            liquidMixtureProperties* thermo_;
+
+            //- Region Film reference pressure
+            scalar pRef_;
+
+            //- Region Film reference temperature
+            scalar TRef_;
+
+            //- Pointer to filmModel
+            regionFilm* filmModel_;
+
+
+        // Area Films
+
+            //- UPointers to area films
+            UPtrList<areaFilm> areaFilms_;
+
+
+        // Interaction model data
+
+            //- Interaction type enumeration
+            interactionType interactionType_;
+
+            //- Film thickness beyond which patch is assumed to be wet
+            scalar deltaWet_;
+
+            //- Splash parcel type label - id assigned to identify parcel for
+            //  post-processing. If not specified, defaults to originating cloud
+            //  type
+            label splashParcelType_;
+
+            //- Number of new parcels resulting from splash event
+            label parcelsPerSplash_;
+
+
+            // Surface roughness coefficient typically in the range 1300 - 5200
+            // and decreases with increasing surface roughness
+
+                //- Dry surface roughness coefficient
+                //  = 2630 for dry interaction (ref. Bai)
+                scalar Adry_;
+
+                //- Wet surface roughness coefficient
+                //  = 1320 for wet interaction (ref. Bai)
+                scalar Awet_;
+
+
+            //- Skin friction typically in the range 0.6 < Cf < 0.8
+            scalar Cf_;
+
+            //- Counter for number of new splash parcels
+            label nParcelsSplashed_;
+
+
+    // Protected Member Functions
+
+        //- Return a vector tangential to input vector, v
+        vector tangentVector(const vector& v) const;
+
+        //- Return splashed parcel direction
+        vector splashDirection
+        (
+            const vector& tanVec1,
+            const vector& tanVec2,
+            const vector& nf
+        ) const;
+
+        //- Initialise thermo
+        void init(bool binitThermo);
+
+        //- Initialise pointers of films
+        void initFilmModels();
+
+
+        // Injection from sheet (ejection) helper functions
+
+            //- Cache the film fields in preparation for injection
+            virtual void cacheFilmFields
+            (
+                const label primaryPatchi,
+                const areaFilm&
+            );
+
+            //- Cache the film fields in preparation for injection
+            virtual void cacheFilmFields
+            (
+                const label filmPatchi,
+                const label primaryPatchi,
+                const regionModels::surfaceFilmModels::surfaceFilmRegionModel&
+            );
+
+            //- Set the individual parcel properties
+            virtual void setParcelProperties
+            (
+                parcelType& p,
+                const label filmFacei
+            ) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("kinematicSurfaceFilm");
+
+
+    // Constructors
+
+        //- Construct from components
+        KinematicSurfaceFilm
+        (
+            const dictionary& dict,
+            CloudType& owner,
+            const word& type = typeName,
+            bool initThermo = true
+        );
+
+        //- Construct copy
+        KinematicSurfaceFilm
+        (
+            const KinematicSurfaceFilm<CloudType>& sfm,
+            bool initThermo = true
+        );
+
+        //- Construct and return a clone using supplied owner cloud
+        virtual autoPtr<SurfaceFilmModel<CloudType>> clone() const
+        {
+            return autoPtr<SurfaceFilmModel<CloudType>>
+            (
+                new KinematicSurfaceFilm<CloudType>(*this)
+            );
+        }
+
+
+    //- Destructor
+    virtual ~KinematicSurfaceFilm() = default;
+
+
+    // Member Functions
+
+        // Interaction models
+
+            //- Absorb parcel into film
+            template<class filmType>
+            void absorbInteraction
+            (
+                filmType&,
+                const parcelType& p,
+                const polyPatch& pp,
+                const label facei,
+                const scalar mass,
+                bool& keepParticle
+            );
+
+            //- Bounce parcel (flip parcel normal velocity)
+            void bounceInteraction
+            (
+                parcelType& p,
+                const polyPatch& pp,
+                const label facei,
+                bool& keepParticle
+            ) const;
+
+            //- Parcel interaction with dry surface
+            template<class filmType>
+            void drySplashInteraction
+            (
+                filmType&,
+                const scalar sigma,
+                const scalar mu,
+                const parcelType& p,
+                const polyPatch& pp,
+                const label facei,
+                bool& keepParticle
+            );
+
+            //- Parcel interaction with wetted surface
+            template<class filmType>
+            void wetSplashInteraction
+            (
+                filmType&,
+                const scalar sigma,
+                const scalar mu,
+                parcelType& p,
+                const polyPatch& pp,
+                const label facei,
+                bool& keepParticle
+            );
+
+            //- Bai parcel splash interaction model
+            template<class filmType>
+            void splashInteraction
+            (
+                filmType&,
+                const parcelType& p,
+                const polyPatch& pp,
+                const label facei,
+                const scalar mRatio,
+                const scalar We,
+                const scalar Wec,
+                const scalar sigma,
+                bool& keepParticle
+            );
+
+
+        // Evaluation
+
+            //- Transfer parcel from cloud to surface film
+            //  Returns true if parcel is to be transferred
+            virtual bool transferParcel
+            (
+                parcelType& p,
+                const polyPatch& pp,
+                bool& keepParticle
+            );
+
+
+        // I-O
+
+            //- Write surface film info to stream
+            virtual void info(Ostream& os);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "KinematicSurfaceFilm.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
index 5ef693076de29917888cc2252304077a92ddd5bd..d9e474202b8cd257aaf6c4a5dc0a172c5c12e11d 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
@@ -27,8 +27,9 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "SurfaceFilmModel.H"
-#include "surfaceFilmRegionModel.H"
 #include "mathematicalConstants.H"
+#include "surfaceFilmRegionModel.H"
+#include "liquidFilmBase.H"
 
 using namespace Foam::constant;
 
@@ -40,13 +41,16 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel(CloudType& owner)
     CloudSubModelBase<CloudType>(owner),
     g_(owner.g()),
     ejectedParcelType_(0),
+    injectionOffset_(1.1),
+    minDiameter_(0),
     massParcelPatch_(0),
     diameterParcelPatch_(0),
     UFilmPatch_(0),
     rhoFilmPatch_(0),
     deltaFilmPatch_(0),
     nParcelsTransferred_(0),
-    nParcelsInjected_(0)
+    nParcelsInjected_(0),
+    totalMassTransferred_(0)
 {}
 
 
@@ -62,7 +66,15 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel
     g_(owner.g()),
     ejectedParcelType_
     (
-        this->coeffDict().getOrDefault("ejectedParcelType", -1)
+        this->coeffDict().template getOrDefault<label>("ejectedParcelType", -1)
+    ),
+    injectionOffset_
+    (
+        this->coeffDict().template getOrDefault<scalar>("injectionOffset", 1.1)
+    ),
+    minDiameter_
+    (
+        this->coeffDict().template getOrDefault<scalar>("minDiameter", -1)
     ),
     massParcelPatch_(0),
     diameterParcelPatch_(0),
@@ -70,7 +82,8 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel
     rhoFilmPatch_(0),
     deltaFilmPatch_(owner.mesh().boundary().size()),
     nParcelsTransferred_(0),
-    nParcelsInjected_(0)
+    nParcelsInjected_(0),
+    totalMassTransferred_()
 {}
 
 
@@ -83,13 +96,16 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel
     CloudSubModelBase<CloudType>(sfm),
     g_(sfm.g_),
     ejectedParcelType_(sfm.ejectedParcelType_),
+    injectionOffset_(sfm.injectionOffset_),
+    minDiameter_(sfm.minDiameter_),
     massParcelPatch_(sfm.massParcelPatch_),
     diameterParcelPatch_(sfm.diameterParcelPatch_),
     UFilmPatch_(sfm.UFilmPatch_),
     rhoFilmPatch_(sfm.rhoFilmPatch_),
     deltaFilmPatch_(sfm.deltaFilmPatch_),
     nParcelsTransferred_(sfm.nParcelsTransferred_),
-    nParcelsInjected_(sfm.nParcelsInjected_)
+    nParcelsInjected_(sfm.nParcelsInjected_),
+    totalMassTransferred_(sfm.totalMassTransferred_)
 {}
 
 
@@ -102,6 +118,63 @@ Foam::SurfaceFilmModel<CloudType>::~SurfaceFilmModel()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<class CloudType>
+template<class CloudTrackType>
+void Foam::SurfaceFilmModel<CloudType>::injectParticles
+(
+    const label primaryPatchi,
+    const labelList& injectorCellsPatch,
+    CloudTrackType& cloud
+)
+{
+    const fvMesh& mesh = this->owner().mesh();
+    const vectorField& Cf = mesh.C().boundaryField()[primaryPatchi];
+    const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchi];
+    const scalarField& magSf =
+        mesh.magSf().boundaryField()[primaryPatchi];
+
+    forAll(injectorCellsPatch, j)
+    {
+        if (diameterParcelPatch_[j] > 0)
+        {
+            const label celli = injectorCellsPatch[j];
+
+            const scalar offset =
+                max
+                (
+                    diameterParcelPatch_[j],
+                    deltaFilmPatch_[primaryPatchi][j]
+                );
+            const point pos = Cf[j] - injectionOffset_*offset*Sf[j]/magSf[j];
+
+            // Create a new parcel
+            parcelType* pPtr =
+                new parcelType(this->owner().pMesh(), pos, celli);
+
+            // Check/set new parcel thermo properties
+            cloud.setParcelThermoProperties(*pPtr, 0.0);
+
+            setParcelProperties(*pPtr, j);
+
+            if (pPtr->nParticle() > 0.001)
+            {
+                // Check new parcel properties
+                cloud.checkParcelProperties(*pPtr, 0.0, false);
+
+                // Add the new parcel to the cloud
+                cloud.addParticle(pPtr);
+
+                nParcelsInjected_++;
+            }
+            else
+            {
+                // TODO: cache mass and re-distribute?
+                delete pPtr;
+            }
+        }
+    }
+}
+
 template<class CloudType>
 template<class TrackCloudType>
 void Foam::SurfaceFilmModel<CloudType>::inject(TrackCloudType& cloud)
@@ -111,76 +184,77 @@ void Foam::SurfaceFilmModel<CloudType>::inject(TrackCloudType& cloud)
         return;
     }
 
+    const fvMesh& mesh = this->owner().mesh();
+    const polyBoundaryMesh& pbm = mesh.boundaryMesh();
+
     // Retrieve the film model from the owner database
-    const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel =
-        this->owner().mesh().time().objectRegistry::template lookupObject
+    const regionModels::surfaceFilmModels::surfaceFilmRegionModel* filmModel =
+        mesh.time().objectRegistry::template findObject
         <regionModels::surfaceFilmModels::surfaceFilmRegionModel>
         (
             "surfaceFilmProperties"
         );
 
-    if (!filmModel.active())
+    // Check the singleLayer type of films
+    if (filmModel && filmModel->active())
     {
-        return;
-    }
 
-    const labelList& filmPatches = filmModel.intCoupledPatchIDs();
-    const labelList& primaryPatches = filmModel.primaryPatchIDs();
+        const labelList& filmPatches = filmModel->intCoupledPatchIDs();
+        const labelList& primaryPatches = filmModel->primaryPatchIDs();
 
-    const fvMesh& mesh = this->owner().mesh();
-    const polyBoundaryMesh& pbm = mesh.boundaryMesh();
+        forAll(filmPatches, i)
+        {
+            const label filmPatchi = filmPatches[i];
+            const label primaryPatchi = primaryPatches[i];
 
-    forAll(filmPatches, i)
-    {
-        const label filmPatchi = filmPatches[i];
-        const label primaryPatchi = primaryPatches[i];
+            const labelList& injectorCellsPatch = pbm[primaryPatchi].faceCells();
 
-        const labelList& injectorCellsPatch = pbm[primaryPatchi].faceCells();
+            cacheFilmFields(filmPatchi, primaryPatchi, *filmModel);
 
-        cacheFilmFields(filmPatchi, primaryPatchi, filmModel);
+            injectParticles(primaryPatchi, injectorCellsPatch, cloud);
+        }
+    }
 
-        const vectorField& Cf = mesh.C().boundaryField()[primaryPatchi];
-        const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchi];
-        const scalarField& magSf = mesh.magSf().boundaryField()[primaryPatchi];
+    // Check finite area films
+    wordList names =
+        mesh.time().objectRegistry::template
+            sortedNames<regionModels::regionFaModel>();
 
-        forAll(injectorCellsPatch, j)
+    forAll (names, i)
+    {
+        const regionModels::regionFaModel* regionFa =
+            mesh.time().objectRegistry::template cfindObject
+            <
+                regionModels::regionFaModel
+            >(names[i]);
+
+        // Check that it is a type areaFilm
+        if (regionFa && isA<areaFilm>(*regionFa) && regionFa->active())
         {
-            if (diameterParcelPatch_[j] > 0)
-            {
-                const label celli = injectorCellsPatch[j];
-
-                const scalar offset =
-                    max
-                    (
-                        diameterParcelPatch_[j],
-                        deltaFilmPatch_[primaryPatchi][j]
-                    );
-                const point pos = Cf[j] - 1.1*offset*Sf[j]/magSf[j];
-
-                // Create a new parcel
-                parcelType* pPtr =
-                    new parcelType(this->owner().pMesh(), pos, celli);
+            areaFilm& film =
+                const_cast<areaFilm&>(refCast<const areaFilm>(*regionFa));
 
-                // Check/set new parcel thermo properties
-                cloud.setParcelThermoProperties(*pPtr, 0.0);
+            const label patchId = regionFa->patchID();
 
-                setParcelProperties(*pPtr, j);
+            const labelList& injectorCellsPatch = pbm[patchId].faceCells();
 
-                if (pPtr->nParticle() > 0.001)
-                {
-                    // Check new parcel properties
-    //                cloud.checkParcelProperties(*pPtr, 0.0, true);
-                    cloud.checkParcelProperties(*pPtr, 0.0, false);
+            cacheFilmFields(patchId, film);
 
-                    // Add the new parcel to the cloud
-                    cloud.addParticle(pPtr);
+            injectParticles(patchId, injectorCellsPatch, cloud);
 
-                    nParcelsInjected_++;
-                }
-                else
+            forAll(injectorCellsPatch, facei)
+            {
+                if (diameterParcelPatch_[facei] > 0)
                 {
-                    // TODO: cache mass and re-distribute?
-                    delete pPtr;
+                    film.addSources
+                    (
+                        patchId,
+                        facei,
+                       -massParcelPatch_[facei],    // mass
+                        Zero,                       // tangential momentum
+                        Zero,                       // impingement
+                        Zero                        // energy
+                    );
                 }
             }
         }
@@ -215,6 +289,39 @@ void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields
 }
 
 
+template<class CloudType>
+void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields
+(
+    const label filmPatchi,
+    const regionModels::areaSurfaceFilmModels::liquidFilmBase& filmModel
+)
+{
+    const volSurfaceMapping& map = filmModel.region().vsm();
+
+    massParcelPatch_.setSize(filmModel.Uf().size(), Zero);
+
+    const scalarField& massParcelPatch =
+        filmModel.cloudMassTrans().boundaryField()[filmPatchi];
+
+    map.mapToField(massParcelPatch, massParcelPatch_);
+
+    const scalarField&  diameterParcelPatch =
+        filmModel.cloudDiameterTrans().boundaryField()[filmPatchi];
+
+    diameterParcelPatch_.setSize(filmModel.Uf().size(), Zero);
+    map.mapToField(diameterParcelPatch, diameterParcelPatch_);
+
+    UFilmPatch_.setSize(filmModel.Uf().size(), vector::zero);
+    map.mapToField(filmModel.Uf(), UFilmPatch_);
+
+    rhoFilmPatch_.setSize(UFilmPatch_.size(), Zero);
+    map.mapToField(filmModel.rho(), rhoFilmPatch_);
+
+    deltaFilmPatch_[filmPatchi].setSize(UFilmPatch_.size(), Zero);
+    map.mapToField(filmModel.h(), deltaFilmPatch_[filmPatchi]);
+}
+
+
 template<class CloudType>
 void Foam::SurfaceFilmModel<CloudType>::setParcelProperties
 (
@@ -230,6 +337,14 @@ void Foam::SurfaceFilmModel<CloudType>::setParcelProperties
 
     p.nParticle() = massParcelPatch_[filmFacei]/p.rho()/vol;
 
+    if (minDiameter_ != -1)
+    {
+        if (p.d() < minDiameter_)
+        {
+            p.nParticle() = 0;
+        }
+    }
+
     if (ejectedParcelType_ >= 0)
     {
         p.typeId() = ejectedParcelType_;
@@ -246,22 +361,33 @@ void Foam::SurfaceFilmModel<CloudType>::info(Ostream& os)
     label nInject0 =
         this->template getModelProperty<label>("nParcelsInjected");
 
+    scalar massTransferred0 =
+        this->template getModelProperty<scalar>("massTransferred");
+
     label nTransTotal =
         nTrans0 + returnReduce(nParcelsTransferred_, sumOp<label>());
 
     label nInjectTotal =
         nInject0 + returnReduce(nParcelsInjected_, sumOp<label>());
 
+    scalar massTransferredTotal =
+        massTransferred0 + returnReduce(totalMassTransferred_, sumOp<scalar>());
+
+
     os  << "    Surface film:" << nl
         << "      - parcels absorbed            = " << nTransTotal << nl
+        << "      - mass absorbed               = " << massTransferredTotal << nl
         << "      - parcels ejected             = " << nInjectTotal << endl;
 
     if (this->writeTime())
     {
         this->setModelProperty("nParcelsTransferred", nTransTotal);
         this->setModelProperty("nParcelsInjected", nInjectTotal);
+        this->setModelProperty("massTransferred", massTransferredTotal);
+
         nParcelsTransferred_ = 0;
         nParcelsInjected_ = 0;
+        totalMassTransferred_ = 0;
     }
 }
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H
index ed232999065c5470add13bed5ac797f4797df9e5..410dd63e239f02b661c0b03a7de2368ae378476a 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -46,6 +47,7 @@ SourceFiles
 #include "runTimeSelectionTables.H"
 #include "CloudSubModelBase.H"
 
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
@@ -60,6 +62,15 @@ namespace regionModels
     }
 }
 
+namespace regionModels
+{
+    namespace areaSurfaceFilmModels
+    {
+        class liquidFilmBase;
+    }
+}
+
+
 /*---------------------------------------------------------------------------*\
                       Class SurfaceFilmModel Declaration
 \*---------------------------------------------------------------------------*/
@@ -76,6 +87,9 @@ protected:
         //- Convenience typedef to the cloud's parcel type
         typedef typename CloudType::parcelType parcelType;
 
+        typedef typename
+            regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm;
+
         //- Gravitational acceleration constant
         const dimensionedVector& g_;
 
@@ -84,23 +98,29 @@ protected:
         //  type
         label ejectedParcelType_;
 
+        //- Injection offset position
+        scalar injectionOffset_;
+
+        //- Minimum diameter particle injection
+        scalar minDiameter_;
+
 
         // Cached injector fields per film patch
 
             //- Parcel mass / patch face
-            scalarList massParcelPatch_;
+            scalarField massParcelPatch_;
 
             //- Parcel diameter / patch face
-            scalarList diameterParcelPatch_;
+            scalarField diameterParcelPatch_;
 
             //- Film velocity / patch face
-            List<vector> UFilmPatch_;
+            Field<vector> UFilmPatch_;
 
             //- Film density / patch face
-            scalarList rhoFilmPatch_;
+            scalarField rhoFilmPatch_;
 
             //- Film height of all film patches / patch face
-            scalarListList deltaFilmPatch_;
+            Field<scalarField> deltaFilmPatch_;
 
 
         // Counters
@@ -112,6 +132,12 @@ protected:
             label nParcelsInjected_;
 
 
+        // Total mass info
+
+            //- Total mass transferred to the film
+            scalar totalMassTransferred_;
+
+
     // Protected functions
 
         //- Cache the film fields in preparation for injection
@@ -122,6 +148,22 @@ protected:
             const regionModels::surfaceFilmModels::surfaceFilmRegionModel&
         );
 
+        //- Cache the finite area film fields in preparation for injection
+        virtual void cacheFilmFields
+        (
+            const label primaryPatchi,
+            const areaFilm&
+        );
+
+        //- Inject particles in cloud
+        template<class TrackCloudType>
+        void injectParticles
+        (
+            const label primaryPatchi,
+            const labelList& injectorCellsPatch,
+            TrackCloudType& cloud
+        );
+
         //- Set the individual parcel properties
         virtual void setParcelProperties
         (
@@ -204,6 +246,12 @@ public:
             //  the film model
             inline label& nParcelsInjected();
 
+            //- Return non-const total mass transferred
+            inline scalar& totalMassTransferred();
+
+            //- Return consr access to mass transferred
+            inline scalar totalMassTransferred() const;
+
 
         // Member Functions
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModelI.H b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModelI.H
index 67420350c65c91a706c4716423e97e1236ea293d..4240d00ea3307cafe243596c936566c5a841bbeb 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModelI.H
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModelI.H
@@ -63,5 +63,18 @@ Foam::label Foam::SurfaceFilmModel<CloudType>::nParcelsInjected() const
     return nParcelsInjected_;
 }
 
+template<class CloudType>
+Foam::scalar& Foam::SurfaceFilmModel<CloudType>::totalMassTransferred()
+{
+    return totalMassTransferred_;
+}
+
+
+template<class CloudType>
+Foam::scalar Foam::SurfaceFilmModel<CloudType>::totalMassTransferred() const
+{
+    return totalMassTransferred_;
+}
+
 
 // ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C
index d45be7e0427a3851c074e7f28ab6c540394ce4dd..045cc208fb4fd7fd350903fe1e021dd011cbeb7c 100644
--- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C
+++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,451 +27,6 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ThermoSurfaceFilm.H"
-#include "addToRunTimeSelectionTable.H"
-#include "unitConversion.H"
-#include "Pstream.H"
-
-using namespace Foam::constant::mathematical;
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-template<class CloudType>
-Foam::wordList Foam::ThermoSurfaceFilm<CloudType>::interactionTypeNames_
-{
-    "absorb", "bounce", "splashBai"
-};
-
-
-// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
-
-template<class CloudType>
-typename Foam::ThermoSurfaceFilm<CloudType>::interactionType
-Foam::ThermoSurfaceFilm<CloudType>::interactionTypeEnum(const word& it) const
-{
-    forAll(interactionTypeNames_, i)
-    {
-        if (interactionTypeNames_[i] == it)
-        {
-            return interactionType(i);
-        }
-    }
-
-    FatalErrorInFunction
-        << "Unknown interaction type " << it
-        << ". Valid interaction types include: " << interactionTypeNames_
-        << abort(FatalError);
-
-    return interactionType(0);
-}
-
-
-template<class CloudType>
-Foam::word Foam::ThermoSurfaceFilm<CloudType>::interactionTypeStr
-(
-    const interactionType& it
-) const
-{
-    if (it >= interactionTypeNames_.size())
-    {
-        FatalErrorInFunction
-            << "Unknown interaction type enumeration" << abort(FatalError);
-    }
-
-    return interactionTypeNames_[it];
-}
-
-
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-template<class CloudType>
-Foam::vector Foam::ThermoSurfaceFilm<CloudType>::tangentVector
-(
-    const vector& v
-) const
-{
-    vector tangent = Zero;
-    scalar magTangent = 0.0;
-
-    while (magTangent < SMALL)
-    {
-        vector vTest = rndGen_.sample01<vector>();
-        tangent = vTest - (vTest & v)*v;
-        magTangent = mag(tangent);
-    }
-
-    return tangent/magTangent;
-}
-
-
-template<class CloudType>
-Foam::vector Foam::ThermoSurfaceFilm<CloudType>::splashDirection
-(
-    const vector& tanVec1,
-    const vector& tanVec2,
-    const vector& nf
-) const
-{
-    // Azimuthal angle [rad]
-    const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
-
-    // Ejection angle [rad]
-    const scalar thetaSi = degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
-
-    // Direction vector of new parcel
-    const scalar alpha = sin(thetaSi);
-    const scalar dcorr = cos(thetaSi);
-    const vector normal = alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi));
-    vector dirVec = dcorr*nf;
-    dirVec += normal;
-
-    return dirVec/mag(dirVec);
-}
-
-
-template<class CloudType>
-void Foam::ThermoSurfaceFilm<CloudType>::absorbInteraction
-(
-    regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
-    const parcelType& p,
-    const polyPatch& pp,
-    const label facei,
-    const scalar mass,
-    bool& keepParticle
-)
-{
-    if (debug)
-    {
-        Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
-    }
-
-    // Patch face normal
-    const vector& nf = pp.faceNormals()[facei];
-
-    // Patch velocity
-    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
-
-    // Relative parcel velocity
-    const vector Urel = p.U() - Up;
-
-    // Parcel normal velocity
-    const vector Un = nf*(Urel & nf);
-
-    // Parcel tangential velocity
-    const vector Ut = Urel - Un;
-
-    filmModel.addSources
-    (
-        pp.index(),
-        facei,
-        mass,                           // mass
-        mass*Ut,                        // tangential momentum
-        mass*mag(Un),                   // impingement pressure
-        mass*p.hs()                     // energy
-    );
-
-    this->nParcelsTransferred()++;
-
-    keepParticle = false;
-}
-
-
-template<class CloudType>
-void Foam::ThermoSurfaceFilm<CloudType>::bounceInteraction
-(
-    parcelType& p,
-    const polyPatch& pp,
-    const label facei,
-    bool& keepParticle
-) const
-{
-    if (debug)
-    {
-        Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
-    }
-
-    // Patch face normal
-    const vector& nf = pp.faceNormals()[facei];
-
-    // Patch velocity
-    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
-
-    // Relative parcel velocity
-    const vector Urel = p.U() - Up;
-
-    // Flip parcel normal velocity component
-    p.U() -= 2.0*nf*(Urel & nf);
-
-    keepParticle = true;
-}
-
-
-template<class CloudType>
-void Foam::ThermoSurfaceFilm<CloudType>::drySplashInteraction
-(
-    regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
-    const parcelType& p,
-    const polyPatch& pp,
-    const label facei,
-    bool& keepParticle
-)
-{
-    if (debug)
-    {
-        Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
-    }
-
-    const liquidProperties& liq = thermo_.liquids().properties()[0];
-
-    // Patch face velocity and normal
-    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
-    const vector& nf = pp.faceNormals()[facei];
-
-    // Local pressure
-    const scalar pc = thermo_.thermo().p()[p.cell()];
-
-    // Retrieve parcel properties
-    const scalar m = p.mass()*p.nParticle();
-    const scalar rho = p.rho();
-    const scalar d = p.d();
-    const scalar sigma = liq.sigma(pc, p.T());
-    const scalar mu = liq.mu(pc, p.T());
-    const vector Urel = p.U() - Up;
-    const vector Un = nf*(Urel & nf);
-
-    // Laplace number
-    const scalar La = rho*sigma*d/sqr(mu);
-
-    // Weber number
-    const scalar We = rho*magSqr(Un)*d/sigma;
-
-    // Critical Weber number
-    const scalar Wec = Adry_*pow(La, -0.183);
-
-    if (We < Wec) // Adhesion - assume absorb
-    {
-        absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
-    }
-    else // Splash
-    {
-        // Ratio of incident mass to splashing mass
-        const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
-        splashInteraction
-            (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
-    }
-}
-
-
-template<class CloudType>
-void Foam::ThermoSurfaceFilm<CloudType>::wetSplashInteraction
-(
-    regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
-    parcelType& p,
-    const polyPatch& pp,
-    const label facei,
-    bool& keepParticle
-)
-{
-    if (debug)
-    {
-        Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
-    }
-
-    const liquidProperties& liq = thermo_.liquids().properties()[0];
-
-    // Patch face velocity and normal
-    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
-    const vector& nf = pp.faceNormals()[facei];
-
-    // Local pressure
-    const scalar pc = thermo_.thermo().p()[p.cell()];
-
-    // Retrieve parcel properties
-    const scalar m = p.mass()*p.nParticle();
-    const scalar rho = p.rho();
-    const scalar d = p.d();
-    vector& U = p.U();
-    const scalar sigma = liq.sigma(pc, p.T());
-    const scalar mu = liq.mu(pc, p.T());
-    const vector Urel = p.U() - Up;
-    const vector Un = nf*(Urel & nf);
-    const vector Ut = Urel - Un;
-
-    // Laplace number
-    const scalar La = rho*sigma*d/sqr(mu);
-
-    // Weber number
-    const scalar We = rho*magSqr(Un)*d/sigma;
-
-    // Critical Weber number
-    const scalar Wec = Awet_*pow(La, -0.183);
-
-    if (We < 2) // Adhesion - assume absorb
-    {
-        absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
-    }
-    else if ((We >= 2) && (We < 20)) // Bounce
-    {
-        // Incident angle of impingement
-        const scalar theta = piByTwo - acos(U/mag(U) & nf);
-
-        // Restitution coefficient
-        const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
-
-        // Update parcel velocity
-        U = -epsilon*(Un) + 5.0/7.0*(Ut);
-
-        keepParticle = true;
-        return;
-    }
-    else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
-    {
-        absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
-    }
-    else    // Splash
-    {
-        // Ratio of incident mass to splashing mass
-        // splash mass can be > incident mass due to film entrainment
-        const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
-        splashInteraction
-            (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
-    }
-}
-
-
-template<class CloudType>
-void Foam::ThermoSurfaceFilm<CloudType>::splashInteraction
-(
-    regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel,
-    const parcelType& p,
-    const polyPatch& pp,
-    const label facei,
-    const scalar mRatio,
-    const scalar We,
-    const scalar Wec,
-    const scalar sigma,
-    bool& keepParticle
-)
-{
-    // Patch face velocity and normal
-    const fvMesh& mesh = this->owner().mesh();
-    const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
-    const vector& nf = pp.faceNormals()[facei];
-
-    // Determine direction vectors tangential to patch normal
-    const vector tanVec1 = tangentVector(nf);
-    const vector tanVec2 = nf^tanVec1;
-
-    // Retrieve parcel properties
-    const scalar np = p.nParticle();
-    const scalar m = p.mass()*np;
-    const scalar d = p.d();
-    const vector Urel = p.U() - Up;
-    const vector Un = nf*(Urel & nf);
-    const vector Ut = Urel - Un;
-    const vector& posC = mesh.C()[p.cell()];
-    const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
-
-    // Total mass of (all) splashed parcels
-    const scalar mSplash = m*mRatio;
-
-    // Number of splashed particles per incoming particle
-    const scalar Ns = 5.0*(We/Wec - 1.0);
-
-    // Average diameter of splashed particles
-    const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
-
-    // Cumulative diameter splash distribution
-    const scalar dMax = 0.9*cbrt(mRatio)*d;
-    const scalar dMin = 0.1*dMax;
-    const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
-
-    // Surface energy of secondary parcels [J]
-    scalar ESigmaSec = 0;
-
-    // Sample splash distribution to determine secondary parcel diameters
-    scalarList dNew(parcelsPerSplash_);
-    scalarList npNew(parcelsPerSplash_);
-    forAll(dNew, i)
-    {
-        const scalar y = rndGen_.sample01<scalar>();
-        dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
-        npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
-        ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
-    }
-
-    // Incident kinetic energy [J]
-    const scalar EKIn = 0.5*m*magSqr(Un);
-
-    // Incident surface energy [J]
-    const scalar ESigmaIn = np*sigma*p.areaS(d);
-
-    // Dissipative energy
-    const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
-
-    // Total energy [J]
-    const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
-
-    // Switch to absorb if insufficient energy for splash
-    if (EKs <= 0)
-    {
-        absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
-        return;
-    }
-
-    // Helper variables to calculate magUns0
-    const scalar logD = log(d);
-    const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
-    scalar coeff1 = 0.0;
-    forAll(dNew, i)
-    {
-        coeff1 += sqr(log(dNew[i]) - logD);
-    }
-
-    // Magnitude of the normal velocity of the first splashed parcel
-    const scalar magUns0 =
-        sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
-
-    // Set splashed parcel properties
-    forAll(dNew, i)
-    {
-        const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
-
-        // Create a new parcel by copying source parcel
-        parcelType* pPtr = new parcelType(p);
-
-        pPtr->origId() = pPtr->getNewParticleID();
-
-        pPtr->origProc() = Pstream::myProcNo();
-
-        if (splashParcelType_ >= 0)
-        {
-            pPtr->typeId() = splashParcelType_;
-        }
-
-        // Perturb new parcels towards the owner cell centre
-        pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
-
-        pPtr->nParticle() = npNew[i];
-
-        pPtr->d() = dNew[i];
-
-        pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
-
-        // Apply correction to velocity for 2-D cases
-        meshTools::constrainDirection(mesh, mesh.solutionD(), pPtr->U());
-
-        // Add the new parcel
-        this->owner().addParticle(pPtr);
-
-        nParcelsSplashed_++;
-    }
-
-    // Transfer remaining part of parcel to film 0 - splashMass can be -ve
-    // if entraining from the film
-    const scalar mDash = m - mSplash;
-    absorbInteraction(filmModel, p, pp, facei, mDash, keepParticle);
-}
-
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -482,41 +37,14 @@ Foam::ThermoSurfaceFilm<CloudType>::ThermoSurfaceFilm
     CloudType& owner
 )
 :
-    SurfaceFilmModel<CloudType>(dict, owner, typeName),
-    rndGen_(owner.rndGen()),
+    KinematicSurfaceFilm<CloudType>(dict, owner, typeName,  false),
     thermo_
     (
         owner.db().objectRegistry::template lookupObject<SLGThermo>("SLGThermo")
     ),
     TFilmPatch_(0),
-    CpFilmPatch_(0),
-    interactionType_
-    (
-        interactionTypeEnum(this->coeffDict().getWord("interactionType"))
-    ),
-    deltaWet_(0.0),
-    splashParcelType_(0),
-    parcelsPerSplash_(0),
-    Adry_(0.0),
-    Awet_(0.0),
-    Cf_(0.0),
-    nParcelsSplashed_(0)
-{
-    Info<< "    Applying " << interactionTypeStr(interactionType_)
-        << " interaction model" << endl;
-
-    if (interactionType_ == itSplashBai)
-    {
-        this->coeffDict().readEntry("deltaWet", deltaWet_);
-        splashParcelType_ =
-            this->coeffDict().getOrDefault("splashParcelType", -1);
-        parcelsPerSplash_ =
-            this->coeffDict().getOrDefault("parcelsPerSplash", 2);
-        this->coeffDict().readEntry("Adry", Adry_);
-        this->coeffDict().readEntry("Awet", Awet_);
-        this->coeffDict().readEntry("Cf", Cf_);
-    }
-}
+    CpFilmPatch_(0)
+{}
 
 
 template<class CloudType>
@@ -525,26 +53,10 @@ Foam::ThermoSurfaceFilm<CloudType>::ThermoSurfaceFilm
     const ThermoSurfaceFilm<CloudType>& sfm
 )
 :
-    SurfaceFilmModel<CloudType>(sfm),
-    rndGen_(sfm.rndGen_),
+    KinematicSurfaceFilm<CloudType>(sfm, false),
     thermo_(sfm.thermo_),
     TFilmPatch_(sfm.TFilmPatch_),
-    CpFilmPatch_(sfm.CpFilmPatch_),
-    interactionType_(sfm.interactionType_),
-    deltaWet_(sfm.deltaWet_),
-    splashParcelType_(sfm.splashParcelType_),
-    parcelsPerSplash_(sfm.parcelsPerSplash_),
-    Adry_(sfm.Adry_),
-    Awet_(sfm.Awet_),
-    Cf_(sfm.Cf_),
-    nParcelsSplashed_(sfm.nParcelsSplashed_)
-{}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-template<class CloudType>
-Foam::ThermoSurfaceFilm<CloudType>::~ThermoSurfaceFilm()
+    CpFilmPatch_(sfm.CpFilmPatch_)
 {}
 
 
@@ -558,68 +70,134 @@ bool Foam::ThermoSurfaceFilm<CloudType>::transferParcel
     bool& keepParticle
 )
 {
-    // Retrieve the film model from the owner database
-    regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel =
-        const_cast<regionModels::surfaceFilmModels::surfaceFilmRegionModel&>
-        (
-            this->owner().db().time().objectRegistry::template
-                lookupObject
-                <regionModels::surfaceFilmModels::surfaceFilmRegionModel>
-                (
-                    "surfaceFilmProperties"
-                )
-        );
-
     const label patchi = pp.index();
 
-    if (filmModel.isRegionPatch(patchi))
-    {
-        const label facei = pp.whichFace(p.face());
+    this->initFilmModels();
 
-        switch (interactionType_)
+    bool bInteraction(false);
+
+    // Check the singleLayer film models
+    if (this->filmModel_)
+    {
+        if (this->filmModel_->isRegionPatch(patchi))
         {
-            case itBounce:
-            {
-                bounceInteraction(p, pp, facei, keepParticle);
+            const label facei = pp.whichFace(p.face());
 
-                break;
-            }
-            case itAbsorb:
+            switch (this->interactionType_)
             {
-                const scalar m = p.nParticle()*p.mass();
-                absorbInteraction(filmModel, p, pp, facei, m, keepParticle);
+                case KinematicSurfaceFilm<CloudType>::itBounce:
+                {
+                    this->bounceInteraction(p, pp, facei, keepParticle);
 
-                break;
-            }
-            case itSplashBai:
-            {
-                bool dry = this->deltaFilmPatch_[patchi][facei] < deltaWet_;
+                    break;
+                }
+                case KinematicSurfaceFilm<CloudType>::itAbsorb:
+                {
+                    const scalar m = p.nParticle()*p.mass();
+
+                    this->absorbInteraction //<regionFilm>
+                        (*(this->filmModel_), p, pp, facei, m, keepParticle);
 
-                if (dry)
+                    break;
+                }
+                case KinematicSurfaceFilm<CloudType>::itSplashBai:
                 {
-                    drySplashInteraction(filmModel, p, pp, facei, keepParticle);
+                    // Local pressure
+                    const scalar pc = thermo_.thermo().p()[p.cell()];
+                    const liquidProperties& liq = thermo_.liquids().properties()[0];
+                    const scalar sigma = liq.sigma(pc, p.T());
+                    const scalar mu = liq.mu(pc, p.T());
+
+                    bool dry = this->deltaFilmPatch_[patchi][facei] < this->deltaWet_;
+
+                    if (dry)
+                    {
+                        this->drySplashInteraction //<CloudType, regionFilm>
+                            (*(this->filmModel_), sigma, mu, p, pp, facei, keepParticle);
+                    }
+                    else
+                    {
+                        this->wetSplashInteraction //<regionFilm>
+                            (*(this->filmModel_), sigma, mu, p, pp, facei, keepParticle);
+                    }
+
+                    break;
                 }
-                else
+                default:
                 {
-                    wetSplashInteraction(filmModel, p, pp, facei, keepParticle);
+                    FatalErrorInFunction
+                        << "Unknown interaction type enumeration"
+                        << abort(FatalError);
                 }
-
-                break;
             }
-            default:
+
+            // Transfer parcel/parcel interactions complete
+            bInteraction = true;
+        }
+    }
+
+    for (areaFilm& film : this->areaFilms_)
+    {
+        if (patchi == film.patchID())
+        {
+            const label facei = pp.whichFace(p.face());
+
+            switch (this->interactionType_)
             {
-                FatalErrorInFunction
-                    << "Unknown interaction type enumeration"
-                    << abort(FatalError);
+                // It only supports absorp model
+                case KinematicSurfaceFilm<CloudType>::itAbsorb:
+                {
+                    const scalar m = p.nParticle()*p.mass();
+
+                    this->absorbInteraction //<areaFilm>
+                    (
+                        film, p, pp, facei, m, keepParticle
+                    );
+                    break;
+                }
+                case KinematicSurfaceFilm<CloudType>::itBounce:
+                {
+                    this->bounceInteraction(p, pp, facei, keepParticle);
+
+                    break;
+                }
+                case KinematicSurfaceFilm<CloudType>::itSplashBai:
+                {
+                    // Local pressure
+                    const scalar pc = thermo_.thermo().p()[p.cell()];
+                    const liquidProperties& liq = thermo_.liquids().properties()[0];
+                    const scalar sigma = liq.sigma(pc, p.T());
+                    const scalar mu = liq.mu(pc, p.T());
+
+                    bool dry = film.h()[facei] < this->deltaWet_;
+
+                    if (dry)
+                    {
+                        this->drySplashInteraction //<areaFilm>
+                            (film, sigma, mu, p, pp, facei, keepParticle);
+                    }
+                    else
+                    {
+                        this->wetSplashInteraction //<areaFilm>
+                            (film, sigma, mu, p, pp, facei, keepParticle);
+                    }
+
+                    break;
+                }
+                default:
+                {
+                    FatalErrorInFunction
+                        << "Unknown interaction type enumeration"
+                        << abort(FatalError);
+                }
             }
+            // Transfer parcel/parcel interactions complete
+            bInteraction = true;
         }
-
-        // Transfer parcel/parcel interactions complete
-        return true;
     }
 
     // Parcel not interacting with film
-    return false;
+    return bInteraction;
 }
 
 
@@ -631,7 +209,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
     const regionModels::surfaceFilmModels::surfaceFilmRegionModel& filmModel
 )
 {
-    SurfaceFilmModel<CloudType>::cacheFilmFields
+    KinematicSurfaceFilm<CloudType>::cacheFilmFields
     (
         filmPatchi,
         primaryPatchi,
@@ -646,6 +224,27 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
 }
 
 
+template<class CloudType>
+void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
+(
+    const label filmPatchi,
+    const areaFilm& filmModel
+)
+{
+    KinematicSurfaceFilm<CloudType>::cacheFilmFields
+    (
+        filmPatchi,
+        filmModel
+    );
+    const volSurfaceMapping& map = filmModel.region().vsm();
+
+    TFilmPatch_.setSize(filmModel.Tf().size(), Zero);
+    map.mapToField(filmModel.Tf(), TFilmPatch_);
+    CpFilmPatch_.setSize(filmModel.Tf().size(), Zero);
+    map.mapToField(filmModel.Cp(), CpFilmPatch_);
+}
+
+
 template<class CloudType>
 void Foam::ThermoSurfaceFilm<CloudType>::setParcelProperties
 (
@@ -653,7 +252,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::setParcelProperties
     const label filmFacei
 ) const
 {
-    SurfaceFilmModel<CloudType>::setParcelProperties(p, filmFacei);
+    KinematicSurfaceFilm<CloudType>::setParcelProperties(p, filmFacei);
 
     // Set parcel properties
     p.T() = TFilmPatch_[filmFacei];
@@ -664,19 +263,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::setParcelProperties
 template<class CloudType>
 void Foam::ThermoSurfaceFilm<CloudType>::info(Ostream& os)
 {
-    SurfaceFilmModel<CloudType>::info(os);
-
-    label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
-    label nSplashTotal =
-        nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
-
-    os  << "      - new splash parcels          = " << nSplashTotal << endl;
-
-    if (this->writeTime())
-    {
-        this->setModelProperty("nParcelsSplashed", nSplashTotal);
-        nParcelsSplashed_ = 0;
-    }
+    KinematicSurfaceFilm<CloudType>::info(os);
 }
 
 
diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H
index 186e951dbb32190560873aff17158b149be85e98..51eaed0d87c725ba6c64f2713e54b4196f67637f 100644
--- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H
+++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
+    Copyright (C) 2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,19 +33,6 @@ Group
 Description
     Thermo parcel surface film model.
 
-    Responsible for:
-    - injecting parcelss from the film model into the cloud, e.g. for dripping
-    - parcel interaction with the film, e.g absorb, bounce, splash
-
-    Splash model references:
-
-        Bai and Gosman, `Mathematical modelling of wall films formed by
-        impinging sprays', SAE 960626, 1996
-
-        Bai et al, `Modelling of gasoline spray impingement', Atom. Sprays,
-        vol 12, pp 1-27, 2002
-
-
 SourceFiles
     ThermoSurfaceFilm.C
     ThermoSurfaceFilmI.H
@@ -54,7 +42,8 @@ SourceFiles
 #ifndef ThermoSurfaceFilm_H
 #define ThermoSurfaceFilm_H
 
-#include "SurfaceFilmModel.H"
+#include "KinematicSurfaceFilm.H"
+#include "UPtrList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -68,42 +57,20 @@ namespace Foam
 template<class CloudType>
 class ThermoSurfaceFilm
 :
-    public SurfaceFilmModel<CloudType>
+    public KinematicSurfaceFilm<CloudType>
 {
-public:
-
-    // Public data
-
-        //  Interaction type enumerations
-        enum interactionType
-        {
-            itAbsorb,
-            itBounce,
-            itSplashBai
-        };
-
-        //- Word descriptions of interaction type names
-        static wordList interactionTypeNames_;
-
-
-    // Public Member Functions
-
-        // Return interaction type enum from word
-        interactionType interactionTypeEnum(const word& it) const;
-
-        // Return word from interaction type enum
-        word interactionTypeStr(const interactionType& it) const;
-
-
 protected:
 
-    // Protected data
+    // Protected Data
 
         //- Convenience typedef to the cloud's parcel type
         typedef typename CloudType::parcelType parcelType;
 
-        //- Reference to the cloud random number generator
-        Random& rndGen_;
+        typedef typename
+            regionModels::areaSurfaceFilmModels::liquidFilmBase areaFilm;
+
+        typedef typename
+            regionModels::surfaceFilmModels::surfaceFilmRegionModel regionFilm;
 
         //- Reference to the cloud thermo package
         const SLGThermo& thermo_;
@@ -112,128 +79,28 @@ protected:
         // Cached injector fields per film patch
 
             //- Film temperature / patch face
-            scalarList TFilmPatch_;
+            scalarField TFilmPatch_;
 
             //- Film specific heat capacity / patch face
-            scalarList CpFilmPatch_;
-
-
-        // Interaction model data
-
-            //- Interaction type enumeration
-            interactionType interactionType_;
-
-            //- Film thickness beyond which patch is assumed to be wet
-            scalar deltaWet_;
-
-            //- Splash parcel type label - id assigned to identify parcel for
-            //  post-processing. If not specified, defaults to originating cloud
-            //  type
-            label splashParcelType_;
-
-            //- Number of new parcels resulting from splash event
-            label parcelsPerSplash_;
-
-
-            // Surface roughness coefficient typically in the range 1300 - 5200
-            // and decreases with increasing surface roughness
-
-                //- Dry surface roughness coefficient
-                //  = 2630 for dry interaction (ref. Bai)
-                scalar Adry_;
-
-                //- Wet surface roughness coefficient
-                //  = 1320 for wet interaction (ref. Bai)
-                scalar Awet_;
-
-
-            //- Skin friction typically in the range 0.6 < Cf < 0.8
-            scalar Cf_;
-
-            //- Counter for number of new splash parcels
-            label nParcelsSplashed_;
+            scalarField CpFilmPatch_;
 
 
     // Protected Member Functions
 
-        //- Return a vector tangential to input vector, v
-        vector tangentVector(const vector& v) const;
-
-        //- Return splashed parcel direction
-        vector splashDirection
-        (
-            const vector& tanVec1,
-            const vector& tanVec2,
-            const vector& nf
-        ) const;
-
-
-        // Interaction models
-
-            //- Absorb parcel into film
-            void absorbInteraction
-            (
-                regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
-                const parcelType& p,
-                const polyPatch& pp,
-                const label facei,
-                const scalar mass,
-                bool& keepParticle
-            );
-
-            //- Bounce parcel (flip parcel normal velocity)
-            void bounceInteraction
-            (
-                parcelType& p,
-                const polyPatch& pp,
-                const label facei,
-                bool& keepParticle
-            ) const;
-
-            //- Parcel interaction with dry surface
-            void drySplashInteraction
-            (
-                regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
-                const parcelType& p,
-                const polyPatch& pp,
-                const label facei,
-                bool& keepParticle
-            );
-
-            //- Parcel interaction with wetted surface
-            void wetSplashInteraction
-            (
-                regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
-                parcelType& p,
-                const polyPatch& pp,
-                const label facei,
-                bool& keepParticle
-            );
+        // Injection from sheet (ejection) helper functions
 
-            //- Bai parcel splash interaction model
-            void splashInteraction
+            virtual void cacheFilmFields
             (
-                regionModels::surfaceFilmModels::surfaceFilmRegionModel&,
-                const parcelType& p,
-                const polyPatch& pp,
-                const label facei,
-                const scalar mRatio,
-                const scalar We,
-                const scalar Wec,
-                const scalar sigma,
-                bool& keepParticle
+                const label primaryPatchi,
+                const areaFilm&
             );
 
-
-        // Injection from sheet (ejection) helper functions
-
             //- Cache the film fields in preparation for injection
             virtual void cacheFilmFields
             (
                 const label filmPatchi,
                 const label primaryPatchi,
-                const regionModels::surfaceFilmModels::surfaceFilmRegionModel&
-                    filmModel
+                const regionFilm&
             );
 
             //- Set the individual parcel properties
@@ -269,7 +136,7 @@ public:
 
 
     //- Destructor
-    virtual ~ThermoSurfaceFilm();
+    virtual ~ThermoSurfaceFilm() = default;
 
 
     // Member Functions
diff --git a/src/lagrangian/spray/Make/options b/src/lagrangian/spray/Make/options
index d595ada329b1a9965c39d7994b43dc7260be42f6..443d427398f16ebecef895d4549b1801342f586a 100644
--- a/src/lagrangian/spray/Make/options
+++ b/src/lagrangian/spray/Make/options
@@ -20,7 +20,10 @@ EXE_INC = \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
@@ -44,4 +47,6 @@ LIB_LIBS = \
     -lregionModels \
     -lsurfaceFilmModels \
     -ldynamicMesh \
-    -ldynamicFvMesh
+    -ldynamicFvMesh \
+    -lregionFaModels \
+    -lfiniteArea
diff --git a/src/lagrangian/turbulence/Make/options b/src/lagrangian/turbulence/Make/options
index 7be9fe24ee3e03f04493320be429481c72dc17c9..e2fc84c325a18d7cc42ef1efe3dd87bd74d1def7 100644
--- a/src/lagrangian/turbulence/Make/options
+++ b/src/lagrangian/turbulence/Make/options
@@ -18,7 +18,10 @@ EXE_INC = \
     -I$(LIB_SRC)/transportModels \
     -I$(LIB_SRC)/regionModels/regionModel/lnInclude \
     -I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-    -I$(LIB_SRC)/dynamicFvMesh/lnInclude
+    -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
+    -I$(LIB_SRC)/regionFaModels/lnInclude \
+    -I$(LIB_SRC)/finiteArea/lnInclude \
+    -I$(LIB_SRC)/faOptions/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
@@ -40,4 +43,6 @@ LIB_LIBS = \
     -lincompressibleTransportModels \
     -lregionModels \
     -lsurfaceFilmModels \
-    -ldynamicFvMesh
+    -ldynamicFvMesh \
+    -lregionFaModels \
+    -lfiniteArea
diff --git a/src/regionFaModels/KirchhoffShell/KirchhoffShell.C b/src/regionFaModels/KirchhoffShell/KirchhoffShell.C
index 577a5262e118505b142a7a3c7774bf198f92f9eb..39c64de6a0715fd897efc14bb6bff079f8edcf03 100644
--- a/src/regionFaModels/KirchhoffShell/KirchhoffShell.C
+++ b/src/regionFaModels/KirchhoffShell/KirchhoffShell.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -44,14 +44,15 @@ defineTypeNameAndDebug(KirchhoffShell, 0);
 
 addToRunTimeSelectionTable(vibrationShellModel, KirchhoffShell, dictionary);
 
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-bool KirchhoffShell::read(const dictionary& dict)
+bool KirchhoffShell::init(const dictionary& dict)
 {
     this->solution().readEntry("nNonOrthCorr", nNonOrthCorr_);
     return true;
 }
 
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 void KirchhoffShell::solveDisplacement()
 {
@@ -249,16 +250,11 @@ KirchhoffShell::KirchhoffShell
         dimensionedScalar(inv(pow3(dimLength)), Zero)
     )
 {
-    init();
+    init(dict);
 }
 
-
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
-void KirchhoffShell::init()
-{}
-
-
 void KirchhoffShell::preEvolveRegion()
 {}
 
@@ -306,11 +302,9 @@ const tmp<areaScalarField> KirchhoffShell::rho() const
     );
 }
 
-
 void KirchhoffShell::info()
 {}
 
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace regionModels
diff --git a/src/regionFaModels/KirchhoffShell/KirchhoffShell.H b/src/regionFaModels/KirchhoffShell/KirchhoffShell.H
index 0a7762bedb4c102c7d84ec81673ca2b5aca96365..24fe3c7a9782cb8fea59c63ed0f3989af556befc 100644
--- a/src/regionFaModels/KirchhoffShell/KirchhoffShell.H
+++ b/src/regionFaModels/KirchhoffShell/KirchhoffShell.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -33,10 +33,10 @@ Usage
     \verbatim
     <patchName>
     {
-        // Mandatory/Optional (inherited) entries
+        // Mandatory/Optional entries
         ...
 
-        // Mandatory entries (unmodifiable)
+        // Mandatory entries
         vibrationShellModel   KirchhoffShell;
         f0                    0.04;
         f1                    0.0;
@@ -46,7 +46,7 @@ Usage
 
     where the entries mean:
     \table
-      Property   | Description                         | Type  | Reqd | Dflt
+      Property   | Description                         | Type  | Reqd | Deflt
       vibrationShellModel | Type name: KirchhoffShell  | word  | yes  | -
       f0         | Damping coefficient [1/s]           | scalar | yes | -
       f1         | Damping coefficient [1/s]           | scalar | yes | -
@@ -94,8 +94,8 @@ class KirchhoffShell
 
     // Private Member Functions
 
-        //- Initialize KirchhoffShell
-        void init();
+        //- Initialise KirchhoffShell
+        bool init(const dictionary& dict);
 
 
 protected:
@@ -140,10 +140,6 @@ protected:
 
     // Protected Member Functions
 
-        //- Read control parameters from dictionary
-        virtual bool read(const dictionary& dict);
-
-
         // Equations
 
             //- Solve energy equation
diff --git a/src/regionFaModels/Make/files b/src/regionFaModels/Make/files
index 3a3b9a4adddcd3f2bc9b9f3dd700bd6740cb2f91..a4f1d35563bc26b110e6173657eff081ab203104 100644
--- a/src/regionFaModels/Make/files
+++ b/src/regionFaModels/Make/files
@@ -13,4 +13,33 @@ KirchhoffShell/KirchhoffShell.C
 derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C
 derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C
 
+/* Sub-Model */
+
+liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C
+liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C
+liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C
+
+liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.C
+liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.C
+liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModelNew.C
+
+liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C
+
+liquidFilm/subModels/kinematic/force/forceList/forceList.C
+liquidFilm/subModels/kinematic/force/force/force.C
+liquidFilm/subModels/kinematic/force/force/forceNew.C
+liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.C
+liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.C
+
+liquidFilm/subModels/filmSubModelBase.C
+
+liquidFilm/liquidFilmBase.C
+liquidFilm/liquidFilmBaseNew.C
+
+liquidFilm/liquidFilmModel/liquidFilmModel.C
+liquidFilm/kinematicThinFilm/kinematicThinFilm.C
+derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C
+
+functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C
+
 LIB = $(FOAM_LIBBIN)/libregionFaModels
diff --git a/src/regionFaModels/Make/options b/src/regionFaModels/Make/options
index cd4795b38d01292372b3c1514abe9745dcfa97ad..4f1bfd3c8df2b55d65f5357f3cdb4fa05e3a2fa7 100644
--- a/src/regionFaModels/Make/options
+++ b/src/regionFaModels/Make/options
@@ -5,7 +5,13 @@ EXE_INC = \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/thermophysicalProperties/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude
+    -I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
+    -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
+    -I$(LIB_SRC)/transportModels/compressible/lnInclude \
+    -I$(LIB_SRC)/transportModels
 
 LIB_LIBS = \
     -lfiniteVolume \
@@ -13,4 +19,5 @@ LIB_LIBS = \
     -lmeshTools \
     -lthermophysicalProperties \
     -lspecie \
-    -lfaOptions
+    -lfaOptions \
+    -ldistributionModels
diff --git a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C
new file mode 100644
index 0000000000000000000000000000000000000000..e2fe02f80fe3d55ad89af703000828bc7565eba4
--- /dev/null
+++ b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C
@@ -0,0 +1,200 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "velocityFilmShellFvPatchVectorField.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
+(
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF
+)
+:
+    mixedFvPatchField<vector>(p, iF),
+    baffle_(),
+    dict_(dictionary::null),
+    curTimeIndex_(-1),
+    zeroWallVelocity_(true)
+{
+    refValue() = 0;
+    refGrad() = 0;
+    valueFraction() = 1;
+}
+
+
+velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
+(
+    const velocityFilmShellFvPatchVectorField& ptf,
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    mixedFvPatchField<vector>
+    (
+        ptf,
+        p,
+        iF,
+        mapper
+    ),
+    baffle_(),
+    dict_(ptf.dict_),
+    curTimeIndex_(-1),
+    zeroWallVelocity_(true)
+{}
+
+
+velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
+(
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF,
+    const dictionary& dict
+)
+:
+    mixedFvPatchField<vector>(p, iF),
+    baffle_(nullptr),
+    dict_(dict),
+    curTimeIndex_(-1),
+    zeroWallVelocity_(dict.getOrDefault<bool>("zeroWallVelocity", true))
+{
+    fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
+
+    typedef regionModels::areaSurfaceFilmModels::liquidFilmBase baffle;
+
+    if (dict.found("refValue"))
+    {
+        // Full restart
+        refValue() = vectorField("refValue", dict, p.size());
+        refGrad() = vectorField("refGradient", dict, p.size());
+        valueFraction() = scalarField("valueFraction", dict, p.size());
+    }
+    else
+    {
+        // Start from user entered data. Assume fixedValue.
+        refValue() = *this;
+        refGrad() = vector::zero;
+        valueFraction() = 1;
+    }
+
+    if (!baffle_)
+    {
+        baffle_.reset(baffle::New(p, dict).ptr());
+    }
+}
+
+
+velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField
+(
+    const velocityFilmShellFvPatchVectorField& ptf,
+    const DimensionedField<vector, volMesh>& iF
+)
+:
+    mixedFvPatchField<vector>(ptf, iF),
+    baffle_(),
+    dict_(ptf.dict_),
+    curTimeIndex_(-1),
+    zeroWallVelocity_(true)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+void velocityFilmShellFvPatchVectorField::updateCoeffs()
+{
+    if (this->updated())
+    {
+        return;
+    }
+
+    // Execute the change to the openFraction only once per time-step
+    if (curTimeIndex_ != this->db().time().timeIndex())
+    {
+        baffle_->evolve();
+
+        volVectorField::Boundary& vfb =
+            db().lookupObjectRef<volVectorField>
+            (
+                this->internalField().name()
+            ).boundaryFieldRef();
+
+        baffle_->vsm().mapToVolume(baffle_->Us(), vfb);
+
+        refGrad() = Zero;
+        valueFraction() = 1;
+
+        if (zeroWallVelocity_)
+        {
+            refValue() = Zero;
+        }
+        else
+        {
+            refValue() = vfb[patch().index()];
+        }
+        curTimeIndex_ = this->db().time().timeIndex();
+    }
+
+    mixedFvPatchField<vector>::updateCoeffs();
+}
+
+
+void velocityFilmShellFvPatchVectorField::write(Ostream& os) const
+{
+    mixedFvPatchField<vector>::write(os);
+
+    // Remove value and type already written by mixedFvPatchField
+    dict_.remove("value");
+    dict_.remove("type");
+    dict_.remove("refValue");
+    dict_.remove("refGradient");
+    dict_.remove("valueFraction");
+    dict_.write(os, false);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makePatchTypeField
+(
+    fvPatchVectorField,
+    velocityFilmShellFvPatchVectorField
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H
new file mode 100644
index 0000000000000000000000000000000000000000..66ba8205ee435516c2b14b927747b405cc398480
--- /dev/null
+++ b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H
@@ -0,0 +1,226 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::compressible::velocityFilmShellFvPatchVectorField
+
+Group
+    grpLiquidFilmBoundaryConditions
+
+Description
+
+Usage
+    Example of the boundary condition specification:
+    \verbatim
+    <patchName>
+    {
+        type                velocityFilmShell;
+
+        active              true;
+        infoOutput          true;
+
+        U                   U;
+        pRef                1e5;
+        T0                  300;
+
+        deltaWet            1e-4;
+        h0                  1e-8;
+
+        zeroWallVelocity    true;
+
+        thermo
+        {
+            H2O;
+        }
+
+        turbulence          laminar;
+
+        laminarCoeffs
+        {
+            friction        ManningStrickler;   // Wall friction model
+            n               0.005;              // Manning number
+            Cf              0.9;                // Gas friction
+        }
+
+        injectionModels
+        (
+            curvatureSeparation
+        );
+
+        forces ();
+
+        curvatureSeparationCoeffs
+        {
+            definedPatchRadii  0;
+        }
+
+        region              film;
+        liquidFilmModel     kinematicThinFilm;
+
+        value               uniform (0 0 0);
+    }
+    \endverbatim
+
+    where the entries mean:
+    \table
+      Property    | Description                        | Type | Reqd | Deflt
+      type        | Type name: velocityFilmShell       | word | yes  | -
+      U           | Name of the primary U              | word | yes  | -
+      pRef        | Reference pressure for thermo    | scalar | yes  | -
+      T0          | Film initial temperature         | scalar | no   | READ
+      thermo      | Flow thermo                     | wordRes | yes  | -
+      zeroWallVelocity    | Flag to fix zero U for primary flow <!--
+                  -->                                  | bool | no   | true
+      turbulence  | Type of film turbulence model      | word | yes  | -
+      injectionModels   | Lagrangian injection         |      | no   | -
+      forces      | Film force models               | wordRes | no   | -
+      deltaWet    | Wet film thickness               | scalar | no   | 1e-4
+      h0          | Numerical minimum thickness      | scalar | no   | 1e-7
+      region      | Name of the 2D region            | word   | yes  | -
+      liquidFilmModel     | Film model               | word   | yes  | -
+    \endtable
+
+SourceFiles
+    velocityFilmShellFvPatchVectorField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef velocityFilmShellFvPatchVectorField_H
+#define velocityFilmShellFvPatchVectorField_H
+
+#include "autoPtr.H"
+#include "liquidFilmBase.H"
+#include "mixedFvPatchFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+             Class velocityFilmShellFvPatchVectorField Declaration
+\*---------------------------------------------------------------------------*/
+
+class velocityFilmShellFvPatchVectorField
+:
+    public mixedFvPatchField<vector>
+{
+    // Private Data
+
+        //- Thermal baffle
+        autoPtr<regionModels::areaSurfaceFilmModels::liquidFilmBase> baffle_;
+
+        //- Dictionary
+        mutable dictionary dict_;
+
+        //- Time index to evolve the film
+        label curTimeIndex_;
+
+        //- Zero wall velocity. Fix U to zero or to film U
+        bool zeroWallVelocity_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("velocityFilmShell");
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        velocityFilmShellFvPatchVectorField
+        (
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        velocityFilmShellFvPatchVectorField
+        (
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given
+        //- velocityFilmShellFvPatchVectorField onto a new patch
+        velocityFilmShellFvPatchVectorField
+        (
+            const velocityFilmShellFvPatchVectorField&,
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchVectorField> clone() const
+        {
+            return tmp<fvPatchVectorField>
+            (
+                new velocityFilmShellFvPatchVectorField(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        velocityFilmShellFvPatchVectorField
+        (
+            const velocityFilmShellFvPatchVectorField&,
+            const DimensionedField<vector, volMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvPatchVectorField> clone
+        (
+            const DimensionedField<vector, volMesh>& iF
+        ) const
+        {
+            return tmp<fvPatchVectorField>
+            (
+                new velocityFilmShellFvPatchVectorField(*this, iF)
+            );
+        }
+
+
+    // Member Functions
+
+        //- Update the coefficients associated with the patch field
+        virtual void updateCoeffs();
+
+        //- Write
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..3b5e95ffd1fae6229d36057b019e06bcf4b264e3
--- /dev/null
+++ b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.C
@@ -0,0 +1,163 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "setTimeStepFaRegionsFunctionObject.H"
+#include "addToRunTimeSelectionTable.H"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionObjects
+{
+    defineTypeNameAndDebug(setTimeStepFaRegionsFunctionObject, 0);
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        setTimeStepFaRegionsFunctionObject,
+        dictionary
+    );
+}
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::functionObjects::
+setTimeStepFaRegionsFunctionObject::
+setTimeStepFaRegionsFunctionObject
+(
+    const word& name,
+    const Time& runTime,
+    const dictionary& dict
+)
+:
+    timeFunctionObject(name, runTime)
+{
+    read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::adjustTimeStep()
+{
+    // Wanted timestep
+    scalar newDeltaT = regionDeltaT();
+
+    static label index = -1;
+
+    if ((time_.timeIndex() != index) && (newDeltaT < time_.deltaTValue()))
+    {
+        // Store current time so we don't get infinite recursion (since
+        // setDeltaT calls adjustTimeStep() again)
+        index = time_.timeIndex();
+
+        // Set time, allow deltaT to be adjusted for writeInterval purposes
+        const_cast<Time&>(time_).setDeltaT(newDeltaT, false);
+
+        return true;
+    }
+
+    return false;
+}
+
+
+bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::read
+(
+    const dictionary& dict
+)
+{
+    if (timeFunctionObject::read(dict))
+    {
+        // Ensure that adjustTimeStep is active
+        if (!time_.controlDict().lookupOrDefault<bool>("adjustTimeStep", false))
+        {
+            FatalIOErrorInFunction(dict)
+                << "Need to set 'adjustTimeStep' true to allow timestep control"
+                << nl
+                << exit(FatalIOError);
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+
+Foam::scalar Foam::functionObjects::setTimeStepFaRegionsFunctionObject::
+regionDeltaT() const
+{
+    const wordList names(time_.sortedNames<regionFaModel>());
+
+    scalar Co = 0.0;
+
+    forAll (names, i)
+    {
+        const auto* regionFa = time_.cfindObject<regionFaModel>(names[i]);
+
+        if (regionFa)
+        {
+            const scalar regionCo = regionFa->CourantNumber();
+            if (regionCo > Co)
+            {
+                Co = regionCo;
+            }
+        }
+    }
+
+    if (names.size() > 0)
+    {
+        const scalar regionFaMaxCo =
+            time_.controlDict().get<scalar>("regionFaMaxCo");
+
+        const scalar maxDeltaTFact = regionFaMaxCo/(Co + SMALL);
+        const scalar deltaTFact =
+            min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
+
+        return deltaTFact*time_.deltaTValue();
+    }
+
+    return time_.deltaTValue();
+}
+
+
+bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::execute()
+{
+    return true;
+}
+
+
+bool Foam::functionObjects::setTimeStepFaRegionsFunctionObject::write()
+{
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..6c61535720b9f129e55f0e1de44d85db5ad5bc7c
--- /dev/null
+++ b/src/regionFaModels/functionObjects/setTimeStep/setTimeStepFaRegionsFunctionObject.H
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::setTimeStepFaRegionsFunctionObject
+
+Group
+    grpUtilitiesFunctionObjects
+
+Description
+    This function object controls the time step for classes of the type
+    \c regionFaModel. It reads \c regionFaMaxCo entry from \c controlDict
+    and evaluate the time step based on the finite area Courant Number.
+
+    Can only be used with solvers using \c adjustTimeStep control (e.g.
+    \c pimpleFoam). It makes no attempt to co-operate with other time step
+    'controllers', e.g. \c maxCo, other functionObjects. Supports \c enabled
+    flag but none of the other options \c timeStart, \c timeEnd, \c writeControl
+    etc.
+
+Usage
+    Example of function object specification to manipulate the time step:
+    \verbatim
+    setTimeStep1
+    {
+        // Mandatory entries
+        type        setTimeStepFaRegion;
+
+        // Inherited entries
+        ...
+    }
+    \endverbatim
+
+    where the entries mean:
+    \table
+      Property     | Description                    | Type | Reqd | Deflt
+      type         | Type name: setTimeStepFaRegion | word | yes  | -
+      enabled      | On/off switch                  | bool | no   | yes
+    \endtable
+
+    The inherited entries are elaborated in:
+     - \link timeFunctionObject.H \endlink
+     - \link regionFaModel.H \endlink
+
+SourceFiles
+    setTimeStepFaRegionsFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef functionObjects_setTimeStepFaRegionsFunctionObject_H
+#define functionObjects_setTimeStepFaRegionsFunctionObject_H
+
+#include "timeFunctionObject.H"
+#include "regionFaModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+using namespace Foam::regionModels;
+
+namespace Foam
+{
+namespace functionObjects
+{
+
+/*---------------------------------------------------------------------------*\
+                Class setTimeStepFaRegionsFunctionObject Declaration
+\*---------------------------------------------------------------------------*/
+
+class setTimeStepFaRegionsFunctionObject
+:
+    public functionObjects::timeFunctionObject
+{
+    // Private Member Functions
+
+        //- No copy construct
+        setTimeStepFaRegionsFunctionObject
+        (
+            const setTimeStepFaRegionsFunctionObject&
+        ) = delete;
+
+        //- No copy assignment
+        void operator=(const setTimeStepFaRegionsFunctionObject&) = delete;
+
+        //- Return minimum deltaT from fa regions
+        scalar regionDeltaT() const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("setTimeStepFaRegion");
+
+
+    // Constructors
+
+        //- Construct from components
+        setTimeStepFaRegionsFunctionObject
+        (
+            const word& name,
+            const Time& runTime,
+            const dictionary& dict
+        );
+
+
+    // Destructor
+    virtual ~setTimeStepFaRegionsFunctionObject() = default;
+
+
+    // Member Functions
+
+        //- Called at the end of Time::adjustDeltaT() if adjustTime is true
+        virtual bool adjustTimeStep();
+
+        //- Read and set the function object if its data have changed
+        virtual bool read(const dictionary& dict);
+
+        //- Execute does nothing
+        virtual bool execute();
+
+        //- Write does nothing
+        virtual bool write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace functionObjects
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C
new file mode 100644
index 0000000000000000000000000000000000000000..1fc4b873ab7170332fb2aa0e5bbe1aea9d8a79c6
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.C
@@ -0,0 +1,190 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "kinematicThinFilm.H"
+#include "addToRunTimeSelectionTable.H"
+#include "uniformDimensionedFields.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(kinematicThinFilm, 0);
+addToRunTimeSelectionTable(liquidFilmBase, kinematicThinFilm, dictionary);
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+kinematicThinFilm::kinematicThinFilm
+(
+    const word& modelType,
+    const fvPatch& patch,
+    const dictionary& dict
+)
+:
+    liquidFilmModel(modelType, patch, dict)
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void kinematicThinFilm::preEvolveRegion()
+{
+    rhoSp_.storePrevIter();
+    USp_.storePrevIter();
+    pnSp_.storePrevIter();
+
+    // Update mass exchange sources
+    liquidFilmModel::preEvolveRegion();
+
+    // gas pressure map from primary region
+    ppf_ = pg();
+}
+
+
+void kinematicThinFilm::evolveRegion()
+{
+    if (debug)
+    {
+        InfoInFunction << endl;
+    }
+
+    const areaVectorField& ns = regionMesh().faceAreaNormals();
+
+    const areaVectorField gs(g_ - ns*(ns & g_));
+
+    phi2s_ = fac::interpolate(h_)*phif_;
+
+    for (int oCorr=1; oCorr<=nOuterCorr_; oCorr++)
+    {
+        pf_.storePrevIter();
+
+        faVectorMatrix UsEqn
+        (
+            fam::ddt(h_, Uf_)
+          + fam::div(phi2s_, Uf_)
+          ==
+            gs*h_
+          + turbulence_->Su(Uf_)
+          + faOptions()(h_, Uf_, sqr(dimVelocity))
+          + forces_.correct(Uf_)
+          + USp_
+        );
+
+        UsEqn.relax();
+
+        faOptions().constrain(UsEqn);
+
+        if (momentumPredictor_)
+        {
+            solve(UsEqn == - fac::grad(pf_*h_)/rho_ + pf_*fac::grad(h_)/rho_);
+        }
+
+        for (int corr=1; corr<=nCorr_; corr++)
+        {
+            areaScalarField UsA(UsEqn.A());
+
+            Uf_ = UsEqn.H()/UsA;
+            Uf_.correctBoundaryConditions();
+            faOptions().correct(Uf_);
+
+            phif_ =
+                (fac::interpolate(Uf_) & regionMesh().Le())
+                - fac::interpolate(1.0/(rho_*UsA))
+                * fac::lnGrad(pf_*h_)*regionMesh().magLe()
+                + fac::interpolate(pf_/(rho_*UsA))
+                * fac::lnGrad(h_)*regionMesh().magLe();
+
+            for (int nFilm=1; nFilm<=nFilmCorr_; nFilm++)
+            {
+                faScalarMatrix hEqn
+                (
+                    fam::ddt(h_)
+                  + fam::div(phif_, h_)
+                 ==
+                    faOptions()(rho_, h_, dimVelocity)
+                  + rhoSp_
+                );
+
+                hEqn.relax();
+                faOptions().constrain(hEqn);
+                hEqn.solve();
+                faOptions().correct(h_);
+
+                if (nFilm == nFilmCorr_)
+                {
+                    phi2s_ = hEqn.flux();
+                }
+            }
+
+            // Bound h_
+            h_ = max(h_, h0_);
+
+            pf_ = rho_*gn_*h_ - sigma_*fac::laplacian(h_) + pnSp_ + ppf_;
+            pf_.correctBoundaryConditions();
+            pf_.relax();
+
+            Uf_ -= (1.0/(rho_*UsA))*fac::grad(pf_*h_)
+                - (pf_/(rho_*UsA))*fac::grad(h_);
+            Uf_.correctBoundaryConditions();
+            faOptions().correct(Uf_);
+        }
+    }
+
+     Info<< "Film h min/max   = " << min(h_).value() << ", "
+        << max(h_).value() << endl;
+
+     Info<< "Film U min/max   = " << max(mag(Uf_)).value() << endl;
+}
+
+
+void kinematicThinFilm::postEvolveRegion()
+{
+    // Reset sources
+    liquidFilmModel::postEvolveRegion();
+
+    // Correct thermo
+    correctThermoFields();
+
+    // Correct turbulence
+    turbulence_->correct();
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H
new file mode 100644
index 0000000000000000000000000000000000000000..bad60d49548336a46e13ce4f2140c635624b2707
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/kinematicThinFilm/kinematicThinFilm.H
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionFaModels::kinematicThinFilm
+
+Description
+    Thin film model.
+
+SourceFiles
+    kinematicThinFilm.C
+    kinematicThinFilmI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef kinematicThinFilm_H
+#define kinematicThinFilm_H
+
+#include "volFieldsFwd.H"
+#include "liquidFilmModel.H"
+#include "faMesh.H"
+#include "filmTurbulenceModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class kinematicThinFilm Declaration
+\*---------------------------------------------------------------------------*/
+
+class kinematicThinFilm
+:
+    public liquidFilmModel
+{
+public:
+
+    //- Runtime type information
+    TypeName("kinematicThinFilm");
+
+
+    // Constructors
+
+        //- Construct from components and dict
+        kinematicThinFilm
+        (
+            const word& modelType,
+            const fvPatch& patch,
+            const dictionary& dict
+        );
+
+        //- No copy construct
+        kinematicThinFilm(const kinematicThinFilm&) = delete;
+
+        //- No copy assignment
+        void operator=(const kinematicThinFilm&) = delete;
+
+
+    //- Destructor
+    virtual ~kinematicThinFilm() = default;
+
+
+    // Member Functions
+
+        // Evolution
+
+            //- Pre-evolve film
+            virtual void preEvolveRegion();
+
+            //- Evolve the film
+            virtual void evolveRegion();
+
+            //- Post-evolve film
+            virtual void postEvolveRegion();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/liquidFilmBase.C b/src/regionFaModels/liquidFilm/liquidFilmBase.C
new file mode 100644
index 0000000000000000000000000000000000000000..5ae39554858c9408d6e33e6e98e1db7145ed9722
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/liquidFilmBase.C
@@ -0,0 +1,560 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "liquidFilmBase.H"
+#include "faMesh.H"
+#include "gravityMeshObject.H"
+#include "movingWallVelocityFvPatchVectorField.H"
+#include "turbulentFluidThermoModel.H"
+#include "turbulentTransportModel.H"
+#include "calculatedFvPatchFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(liquidFilmBase, 0);
+
+defineRunTimeSelectionTable(liquidFilmBase, dictionary);
+
+const Foam::word liquidFilmName("liquidFilm");
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+liquidFilmBase::liquidFilmBase
+(
+    const word& modelType,
+    const fvPatch& p,
+    const dictionary& dict
+)
+:
+    regionFaModel(p, liquidFilmName, modelType, dict, true),
+
+    momentumPredictor_
+    (
+        this->solution().subDict("PIMPLE").get<bool>("momentumPredictor")
+    ),
+    nOuterCorr_
+    (
+        this->solution().subDict("PIMPLE").get<label>("nOuterCorr")
+    ),
+    nCorr_(this->solution().subDict("PIMPLE").get<label>("nCorr")),
+    nFilmCorr_
+    (
+        this->solution().subDict("PIMPLE").get<label>("nFilmCorr")
+    ),
+
+    h0_("h0", dimLength, 1e-7, dict),
+
+    deltaWet_("deltaWet", dimLength, 1e-4, dict),
+
+    UName_(dict.get<word>("U")),
+
+    pName_(dict.lookupOrDefault<word>("p",  word::null)),
+
+    pRef_(dict.get<scalar>("pRef")),
+
+    h_
+    (
+        IOobject
+        (
+            "hf_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::MUST_READ,
+            IOobject::AUTO_WRITE
+        ),
+        regionMesh()
+    ),
+
+    Uf_
+    (
+        IOobject
+        (
+            "Uf_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::MUST_READ,
+            IOobject::AUTO_WRITE
+        ),
+        regionMesh()
+    ),
+    pf_
+    (
+        IOobject
+        (
+            "pf_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimPressure, Zero)
+    ),
+    ppf_
+    (
+        IOobject
+        (
+            "ppf_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimPressure, Zero)
+    ),
+    phif_
+    (
+        IOobject
+        (
+            "phif_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::READ_IF_PRESENT,
+            IOobject::AUTO_WRITE
+        ),
+        fac::interpolate(Uf_) & regionMesh().Le()
+    ),
+
+    phi2s_
+    (
+        IOobject
+        (
+            "phi2s_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::READ_IF_PRESENT,
+            IOobject::AUTO_WRITE
+        ),
+        fac::interpolate(h_*Uf_) & regionMesh().Le()
+    ),
+
+
+    gn_
+    (
+        IOobject
+        (
+            "gn",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimAcceleration, Zero)
+    ),
+
+    g_(meshObjects::gravity::New(primaryMesh().time())),
+
+    massSource_
+    (
+        IOobject
+        (
+            "massSource",
+            primaryMesh().time().timeName(),
+            primaryMesh()
+        ),
+        primaryMesh(),
+        dimensionedScalar(dimMass, Zero),
+        calculatedFvPatchField<scalar>::typeName
+    ),
+
+    momentumSource_
+    (
+        IOobject
+        (
+            "momentumSource",
+            primaryMesh().time().timeName(),
+            primaryMesh()
+        ),
+        primaryMesh(),
+        dimensionedVector(dimPressure, Zero),
+        calculatedFvPatchField<vector>::typeName
+    ),
+
+    pnSource_
+    (
+        IOobject
+        (
+            "pnSource",
+            primaryMesh().time().timeName(),
+            primaryMesh()
+        ),
+        primaryMesh(),
+        dimensionedScalar(dimPressure, Zero),
+        calculatedFvPatchField<scalar>::typeName
+    ),
+
+    energySource_
+    (
+        IOobject
+        (
+            "energySource",
+            primaryMesh().time().timeName(),
+            primaryMesh()
+        ),
+        primaryMesh(),
+        dimensionedScalar(dimEnergy, Zero),
+        calculatedFvPatchField<scalar>::typeName
+    ),
+
+    addedMassTotal_(0),
+
+    faOptions_(Foam::fa::options::New(p))
+{
+    const areaVectorField& ns = regionMesh().faceAreaNormals();
+
+    gn_ = g_ & ns;
+
+    if (!faOptions_.optionList::size())
+    {
+        Info << "No finite area options present" << endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+liquidFilmBase::~liquidFilmBase()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+scalar liquidFilmBase::CourantNumber() const
+{
+    scalar CoNum = 0.0;
+    scalar velMag = 0.0;
+
+    edgeScalarField SfUfbyDelta
+    (
+        regionMesh().edgeInterpolation::deltaCoeffs()*mag(phif_)
+    );
+
+    CoNum =
+        max(SfUfbyDelta/regionMesh().magLe()).value()*time().deltaT().value();
+
+    velMag = max(mag(phif_)/regionMesh().magLe()).value();
+
+    reduce(CoNum, maxOp<scalar>());
+    reduce(velMag, maxOp<scalar>());
+
+    Info<< "Max film Courant Number: " << CoNum
+        << " Film velocity magnitude: " << velMag << endl;
+
+    return CoNum;
+}
+
+
+Foam::tmp<Foam::areaVectorField> liquidFilmBase::Uw() const
+{
+    tmp<areaVectorField> tUw
+    (
+        new areaVectorField
+        (
+            IOobject
+            (
+                "tUw",
+                primaryMesh().time().timeName(),
+                primaryMesh()
+            ),
+            regionMesh(),
+            dimensionedVector(dimVelocity, Zero)
+        )
+    );
+
+    areaVectorField& Uw = tUw.ref();
+
+    const polyPatch& pp = primaryMesh().boundaryMesh()[patch_.index()];
+
+    if
+    (
+        primaryMesh().moving()
+     && isA<movingWallVelocityFvPatchVectorField>(pp)
+    )
+    {
+        const movingWallVelocityFvPatchVectorField& wpp =
+            refCast<const movingWallVelocityFvPatchVectorField>(pp);
+
+        tmp<vectorField> tUwall = wpp.Uwall();
+
+         // Map Up to area
+        tmp<vectorField> UsWall = vsmPtr_->mapToSurface(tUwall());
+
+        const vectorField& nHat =
+            regionMesh().faceAreaNormals().internalField();
+
+        Uw.primitiveFieldRef() = UsWall() - nHat*(UsWall() & nHat);
+    }
+
+    return tUw;
+}
+
+
+Foam::tmp<Foam::areaVectorField> liquidFilmBase::Us() const
+{
+    tmp<areaVectorField> tUs
+    (
+        new areaVectorField
+        (
+            IOobject
+            (
+                "tUs",
+                primaryMesh().time().timeName(),
+                primaryMesh()
+            ),
+            regionMesh(),
+            dimensionedVector(dimVelocity, Zero)
+        )
+    );
+
+    // Uf quadratic profile
+    tUs.ref() = Foam::sqrt(2.0)*Uf_;
+
+    return tUs;
+}
+
+
+Foam::tmp<Foam::areaVectorField> liquidFilmBase::Up() const
+{
+    const label patchi = patch_.index();
+
+    const volVectorField& Uprimary =
+        primaryMesh().lookupObject<volVectorField>(UName_);
+
+    const fvPatchVectorField& Uw = Uprimary.boundaryField()[patchi];
+
+    tmp<areaVectorField> tUp
+    (
+        new areaVectorField
+        (
+            IOobject
+            (
+                "tUp",
+                primaryMesh().time().timeName(),
+                primaryMesh()
+            ),
+            regionMesh(),
+            dimensionedVector(dimVelocity, Zero)
+        )
+    );
+
+    areaVectorField& Up = tUp.ref();
+
+    scalarField hp(patch_.size(), Zero);
+
+    // map areas h to hp on primary
+    vsmPtr_->mapToField(h_, hp);
+
+    const vectorField& nHat = regionMesh().faceAreaNormals().internalField();
+
+    // U tangential on primary
+    const vectorField Ust(-Uw.snGrad()*hp);
+
+    // Map U tang to surface
+    Up.primitiveFieldRef() = vsmPtr_->mapToSurface(Ust);
+
+    // U tangent on surface
+    Up.primitiveFieldRef() -= nHat*(Up.primitiveField() & nHat);
+
+    return tUp;
+}
+
+
+tmp<areaScalarField> liquidFilmBase::pg() const
+{
+    tmp<areaScalarField> tpg
+    (
+        new areaScalarField
+        (
+            IOobject
+            (
+                "tpg",
+                primaryMesh().time().timeName(),
+                primaryMesh()
+            ),
+            regionMesh(),
+            dimensionedScalar(dimPressure, Zero)
+        )
+    );
+
+    areaScalarField& pfg = tpg.ref();
+
+    if (pName_ != word::null)
+    {
+        const volScalarField& pp =
+            primaryMesh().lookupObject<volScalarField>(pName_);
+
+        volScalarField::Boundary& pw =
+            const_cast<volScalarField::Boundary&>(pp.boundaryField());
+
+        //pw -= pRef_;
+
+        pfg.primitiveFieldRef() = vsmPtr_->mapInternalToSurface<scalar>(pw)();
+    }
+    return tpg;
+}
+
+
+tmp<areaScalarField> liquidFilmBase::alpha() const
+{
+    tmp<areaScalarField> talpha
+    (
+        new areaScalarField
+        (
+            IOobject
+            (
+                "talpha",
+                primaryMesh().time().timeName(),
+                primaryMesh()
+            ),
+            regionMesh(),
+            dimensionedScalar(dimless, Zero)
+        )
+    );
+    areaScalarField& alpha = talpha.ref();
+
+    alpha = pos0(h_ - deltaWet_);
+
+    return talpha;
+}
+
+
+void liquidFilmBase::addSources
+(
+    const label patchi,
+    const label facei,
+    const scalar massSource,
+    const vector& momentumSource,
+    const scalar pressureSource,
+    const scalar energySource
+)
+{
+    massSource_.boundaryFieldRef()[patchi][facei] += massSource;
+    pnSource_.boundaryFieldRef()[patchi][facei] += pressureSource;
+    momentumSource_.boundaryFieldRef()[patchi][facei] += momentumSource;
+}
+
+
+void liquidFilmBase::preEvolveRegion()
+{
+    regionFaModel::preEvolveRegion();
+}
+
+
+void liquidFilmBase::postEvolveRegion()
+{
+    if (debug && primaryMesh().time().writeTime())
+    {
+        massSource_.write();
+        pnSource_.write();
+        momentumSource_.write();
+    }
+
+    massSource_.boundaryFieldRef() = Zero;
+    pnSource_.boundaryFieldRef() = Zero;
+    momentumSource_.boundaryFieldRef() = Zero;
+
+    regionFaModel::postEvolveRegion();
+}
+
+
+Foam::fa::options& liquidFilmBase::faOptions()
+{
+     return faOptions_;
+}
+
+
+const areaVectorField& liquidFilmBase::Uf() const
+{
+     return Uf_;
+}
+
+
+const areaScalarField& liquidFilmBase::gn() const
+{
+     return gn_;
+}
+
+
+const uniformDimensionedVectorField& liquidFilmBase::g() const
+{
+    return g_;
+}
+
+
+const areaScalarField& liquidFilmBase::h() const
+{
+     return h_;
+}
+
+
+const edgeScalarField& liquidFilmBase::phif() const
+{
+    return phif_;
+}
+
+
+const edgeScalarField& liquidFilmBase::phi2s() const
+{
+    return phi2s_;
+}
+
+
+const dimensionedScalar& liquidFilmBase::h0() const
+{
+     return h0_;
+}
+
+
+const regionFaModel& liquidFilmBase::region() const
+{
+    return *this;
+}
+
+
+scalar liquidFilmBase::pRef()
+{
+    return pRef_;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/liquidFilmBase.H b/src/regionFaModels/liquidFilm/liquidFilmBase.H
new file mode 100644
index 0000000000000000000000000000000000000000..8bbce9f9b5213acb2d24a4c7b13fe89613ba4eb1
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/liquidFilmBase.H
@@ -0,0 +1,331 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::liquidFilmBase
+
+Description
+    Base class for thermal 2D shells
+
+SourceFiles
+    liquidFilmBase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef liquidFilmBase_H
+#define liquidFilmBase_H
+
+#include "runTimeSelectionTables.H"
+#include "autoPtr.H"
+#include "faCFD.H"
+#include "volFieldsFwd.H"
+#include "uniformDimensionedFields.H"
+#include "regionFaModel.H"
+#include "faOptions.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class liquidFilmBase Declaration
+\*---------------------------------------------------------------------------*/
+
+class liquidFilmBase
+:
+    public regionFaModel
+{
+protected:
+
+    // Protected Data
+
+        // Solution parameters
+
+            //- Momentum predictor
+            Switch momentumPredictor_;
+
+            //- Number of outer correctors
+            label nOuterCorr_;
+
+            //- Number of PISO-like correctors
+            label nCorr_;
+
+            //- Number of film thickness correctors
+            label nFilmCorr_;
+
+            //- Cumulative continuity error
+            scalar cumulativeContErr_;
+
+            //- Smallest numerical thickness
+            dimensionedScalar h0_;
+
+            //- Delta wet for sub-models
+            dimensionedScalar deltaWet_;
+
+
+        //- Name of the velocity field
+        word UName_;
+
+        //- Name of the pressure field
+        word pName_;
+
+        //- Reference absolute pressure
+        scalar pRef_;
+
+
+        // Fields
+
+            //- Film hight
+            areaScalarField h_;
+
+            //- Film velocity
+            areaVectorField Uf_;
+
+            //- Film pressure
+            areaScalarField pf_;
+
+             //- Primary region pressure
+            areaScalarField ppf_;
+
+            //- Film momentum flux
+            edgeScalarField phif_;
+
+            //- Film height flux
+            edgeScalarField phi2s_;
+
+            //- Normal gravity field
+            areaScalarField gn_;
+
+            //- Gravity
+            uniformDimensionedVectorField g_;
+
+
+        // Mass exchanage fields from the primary region (lagragian)
+
+            //- Mass
+            volScalarField massSource_;
+
+            //- Momentum
+            volVectorField momentumSource_;
+
+            //- Normal pressure by particles
+            volScalarField pnSource_;
+
+            //- Energy
+            volScalarField energySource_;
+
+            //- Total mass added
+            scalar addedMassTotal_;
+
+
+        //- faOptions
+        Foam::fa::options& faOptions_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("liquidFilmBase");
+
+
+    // Declare runtime constructor selection tables
+
+         declareRunTimeSelectionTable
+         (
+             autoPtr,
+             liquidFilmBase,
+             dictionary,
+             (
+                const word& modelType,
+                const fvPatch& patch,
+                const dictionary& dict
+             ),
+             (modelType, patch, dict)
+         );
+
+
+    // Constructors
+
+
+        //- Construct from type name and mesh and dict
+        liquidFilmBase
+        (
+            const word& modelType,
+            const fvPatch& patch,
+            const dictionary& dict
+        );
+
+        //- No copy construct
+        liquidFilmBase(const liquidFilmBase&) = delete;
+
+        //- No copy assignment
+        void operator=(const liquidFilmBase&) = delete;
+
+
+    // Selectors
+
+        //- Return a reference to the selected model using dictionary
+        static autoPtr<liquidFilmBase> New
+        (
+            const fvPatch& patch,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~liquidFilmBase();
+
+
+    // Member Functions
+
+        //- Courant number evaluation
+        virtual scalar CourantNumber() const;
+
+
+        // Helper functions
+
+            //- Wall velocity
+            tmp<areaVectorField> Uw() const;
+
+            //- Film surface film velocity
+            tmp<areaVectorField> Us() const;
+
+            //- Primary region velocity at film hight. Assume the film to be
+            // in the viscous sub-layer
+            tmp<areaVectorField> Up() const;
+
+            //- Map primary static pressure
+            tmp<areaScalarField> pg() const;
+
+            //- Wet indicator using h0
+            tmp<areaScalarField> alpha() const;
+
+
+        // Access functions
+
+            //- Return faOptions
+            Foam::fa::options& faOptions();
+
+            //- Access const reference Uf
+            const areaVectorField& Uf() const;
+
+            //- Access const reference gn
+            const areaScalarField& gn() const;
+
+            //- Gravity
+            const uniformDimensionedVectorField& g() const;
+
+            //- Access const reference h
+            const areaScalarField& h() const;
+
+            //- Access to momentum flux
+            const edgeScalarField& phif() const;
+
+            //- Access continuity flux
+            const edgeScalarField& phi2s() const;
+
+
+            //- Return h0
+            const dimensionedScalar& h0() const;
+
+            //- Access to this region
+            const regionFaModel& region() const;
+
+            //- Access to pRef
+            scalar pRef();
+
+
+            // Transfer fields - to the primary region (lagragian injection)
+
+                //- Return mass transfer source - Eulerian phase only
+                //virtual tmp<volScalarField> primaryMassTrans() const = 0;
+
+                //- Return the film mass available for transfer to cloud
+                virtual const volScalarField& cloudMassTrans() const = 0;
+
+                //- Return the parcel diameters originating from film to cloud
+                virtual const volScalarField& cloudDiameterTrans() const = 0;
+
+
+
+        // Evolution
+
+            //- Pre-evolve film
+            virtual void preEvolveRegion();
+
+            //- Post-evolve film
+            virtual void postEvolveRegion();
+
+
+        // Thermo variables
+
+             //- Access const reference mu
+            virtual const areaScalarField& mu() const = 0;
+
+            //- Access const reference rho
+            virtual const areaScalarField& rho() const = 0;
+
+            //- Access const reference sigma
+            virtual const areaScalarField& sigma() const = 0;
+
+            //- Access const reference Tf
+            virtual const areaScalarField& Tf() const = 0;
+
+            //- Access const reference Cp
+            virtual const areaScalarField& Cp() const = 0;
+
+
+        // External hook to add sources and mass exchange variables
+
+
+            //- Add sources
+            virtual void addSources
+            (
+                const label patchi,            // patchi on primary region
+                const label facei,             // facei of patchi
+                const scalar massSource,       // [kg]
+                const vector& momentumSource,  // [kg.m/s] (tang'l momentum)
+                const scalar pressureSource,   // [kg.m/s] (normal momentum)
+                const scalar energySource = 0  // [J]
+            );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/liquidFilmBaseNew.C b/src/regionFaModels/liquidFilm/liquidFilmBaseNew.C
new file mode 100644
index 0000000000000000000000000000000000000000..738345c437be65e664641889dc2ef68f7f498043
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/liquidFilmBaseNew.C
@@ -0,0 +1,71 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "liquidFilmBase.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+autoPtr<liquidFilmBase> liquidFilmBase::New
+(
+    const fvPatch& p,
+    const dictionary& dict
+)
+{
+    word modelType = dict.get<word>("liquidFilmModel");
+
+    auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
+
+    if (!cstrIter.found())
+    {
+        FatalErrorInFunction
+            << "Unknown liquidFilmBase type "
+            << modelType << nl << nl
+            << "Valid liquidFilmBase types :" << nl
+            << dictionaryConstructorTablePtr_->sortedToc()
+            << exit(FatalError);
+    }
+
+    return autoPtr<liquidFilmBase>(cstrIter()(modelType, p, dict));
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.C b/src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.C
new file mode 100644
index 0000000000000000000000000000000000000000..15a4149e013fe98d169d17f967e905f08d685eb6
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.C
@@ -0,0 +1,381 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "liquidFilmModel.H"
+#include "addToRunTimeSelectionTable.H"
+#include "uniformDimensionedFields.H"
+#include "gravityMeshObject.H"
+#include "volFields.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(liquidFilmModel, 0);
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void liquidFilmModel::correctThermoFields()
+{
+    scalarField X(thermo_.size(), 1);
+
+    forAll (rho_, faceI)
+    {
+        rho_[faceI] = thermo_.rho(pRef_, Tf_[faceI], X);
+        mu_[faceI] = thermo_.mu(pRef_, Tf_[faceI], X);
+        sigma_[faceI] = thermo_.sigma(pRef_, Tf_[faceI], X);
+        Cp_[faceI] = thermo_.Cp(pRef_, Tf_[faceI], X);
+    }
+
+    forAll (regionMesh().boundary(), patchI)
+    {
+        const scalarField& patchTf = Tf_.boundaryFieldRef()[patchI];
+
+        scalarField& patchRho = rho_.boundaryFieldRef()[patchI];
+        scalarField& patchmu = mu_.boundaryFieldRef()[patchI];
+        scalarField& patchsigma = sigma_.boundaryFieldRef()[patchI];
+        scalarField& patchCp = Cp_.boundaryFieldRef()[patchI];
+
+        forAll(patchRho, edgeI)
+        {
+            patchRho[edgeI] = thermo_.rho(pRef_, patchTf[edgeI], X);
+            patchmu[edgeI] = thermo_.mu(pRef_, patchTf[edgeI], X);
+            patchsigma[edgeI] = thermo_.sigma(pRef_, patchTf[edgeI], X);
+            patchCp[edgeI] = thermo_.Cp(pRef_, patchTf[edgeI], X);
+        }
+    }
+
+    //Initialize pf_
+    pf_ = rho_*gn_*h_ - sigma_*fac::laplacian(h_);
+}
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+liquidFilmModel::liquidFilmModel
+(
+    const word& modelType,
+    const fvPatch& patch,
+    const dictionary& dict
+)
+:
+    liquidFilmBase(modelType, patch, dict),
+
+    thermo_(dict.subDict("thermo")),
+
+    rho_
+    (
+        IOobject
+        (
+            "rhof",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimDensity, Zero)
+    ),
+    mu_
+    (
+        IOobject
+        (
+            "muf",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimViscosity, Zero)
+    ),
+    Tf_
+    (
+        IOobject
+        (
+            "Tf_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::READ_IF_PRESENT,
+            IOobject::AUTO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimTemperature, Zero)
+    ),
+    Cp_
+    (
+        IOobject
+        (
+            "Cp_" + regionName_,
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimEnergy/dimTemperature, Zero)
+    ),
+    sigma_
+    (
+        IOobject
+        (
+            "sigmaf",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimMass/sqr(dimTime), Zero)
+    ),
+    hRho_
+    (
+        IOobject
+        (
+            h_.name() + "*" + rho_.name(),
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(h_.dimensions()*rho_.dimensions(), Zero)
+    ),
+    rhoSp_
+    (
+        IOobject
+        (
+            "rhoSp",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        regionMesh(),
+        dimensionedScalar(dimVelocity, Zero)
+    ),
+    USp_
+    (
+        IOobject
+        (
+            "USp",
+            primaryMesh().time().timeName(),
+            primaryMesh()
+        ),
+        regionMesh(),
+        dimensionedVector(sqr(dimVelocity), Zero)
+    ),
+    pnSp_
+    (
+        IOobject
+        (
+            "pnSp",
+            primaryMesh().time().timeName(),
+            primaryMesh()
+        ),
+        regionMesh(),
+        dimensionedScalar(dimPressure, Zero)
+    ),
+    cloudMassTrans_
+    (
+        IOobject
+        (
+            "cloudMassTrans",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        primaryMesh(),
+        dimensionedScalar(dimMass, Zero),
+        calculatedFvPatchField<scalar>::typeName
+    ),
+
+    cloudDiameterTrans_
+    (
+        IOobject
+        (
+            "cloudDiameterTrans",
+            primaryMesh().time().timeName(),
+            primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        primaryMesh(),
+        dimensionedScalar(dimLength, Zero),
+        calculatedFvPatchField<scalar>::typeName
+    ),
+
+    turbulence_(filmTurbulenceModel::New(*this, dict)),
+
+    availableMass_(regionMesh().faces().size(), Zero),
+
+    injection_(*this, dict),
+
+    forces_(*this, dict)
+{
+
+    if (dict.found("T0"))
+    {
+        Tref_ = dict.get<scalar>("T0");
+        Tf_ = dimensionedScalar("T0", dimTemperature, dict);
+    }
+    correctThermoFields();
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const areaScalarField& liquidFilmModel::mu() const
+{
+     return mu_;
+}
+
+
+const areaScalarField& liquidFilmModel::rho() const
+{
+     return rho_;
+}
+
+
+const areaScalarField& liquidFilmModel::sigma() const
+{
+     return sigma_;
+}
+
+
+const areaScalarField& liquidFilmModel::Tf() const
+{
+     return Tf_;
+}
+
+
+const areaScalarField& liquidFilmModel::Cp() const
+{
+     return Cp_;
+}
+
+
+const liquidMixtureProperties& liquidFilmModel::thermo() const
+{
+    return thermo_;
+}
+
+
+scalar liquidFilmModel::Tref() const
+{
+    return Tref_;
+}
+
+
+const volScalarField& liquidFilmModel::cloudMassTrans() const
+{
+    return cloudMassTrans_;
+}
+
+
+const volScalarField& liquidFilmModel::cloudDiameterTrans() const
+{
+    return cloudDiameterTrans_;
+}
+
+
+void liquidFilmModel::preEvolveRegion()
+{
+    liquidFilmBase::preEvolveRegion();
+
+
+
+    cloudMassTrans_ == dimensionedScalar(dimMass, Zero);
+    cloudDiameterTrans_ == dimensionedScalar(dimLength, Zero);
+
+    const scalar deltaT = primaryMesh().time().deltaTValue();
+    const scalarField rAreaDeltaT(scalar(1)/deltaT/regionMesh().S().field());
+
+    // Map the total mass, mom and pnSource from particles
+    rhoSp_.primitiveFieldRef() =
+        vsm().mapToSurface(massSource_.boundaryField()[patchID()]);
+    // [kg.m/s]
+    USp_.primitiveFieldRef() =
+        vsm().mapToSurface(momentumSource_.boundaryField()[patchID()]);
+
+    pnSp_.primitiveFieldRef() =
+        vsm().mapToSurface(pnSource_.boundaryField()[patchID()]);
+
+
+    // Calculate rate per area
+    rhoSp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
+    USp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
+    pnSp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
+
+    rhoSp_.relax();
+    pnSp_.relax();
+    USp_.relax();
+}
+
+
+void liquidFilmModel::postEvolveRegion()
+{
+    availableMass_ = (h() - h0_)*rho()*regionMesh().S();
+    injection_.correct(availableMass_, cloudMassTrans_, cloudDiameterTrans_);
+    liquidFilmBase::postEvolveRegion();
+}
+
+
+void liquidFilmModel::info()
+{
+    Info<< "\nSurface film: " << type() << " on patch: " << patchID() << endl;
+
+    const DimensionedField<scalar, areaMesh>& sf = regionMesh().S();
+
+    Info<< indent << "min/max(mag(Uf))    = "
+        << gMin(mag(Uf_.field())) << ", "
+        << gMax(mag(Uf_.field())) << nl
+        << indent << "min/max(delta)     = "
+        << gMin(h_.field()) << ", " << gMax(h_.field()) << nl
+        << indent << "coverage           = "
+        << gSum(alpha()().field()*mag(sf.field()))/gSum(mag(sf.field())) <<  nl
+        << indent << "total mass         = "
+        << gSum(availableMass_) << nl;
+
+    injection_.info(Info);
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.H b/src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.H
new file mode 100644
index 0000000000000000000000000000000000000000..ac326001b567e750c20a2e0f3721574c1a0b68b6
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/liquidFilmModel/liquidFilmModel.H
@@ -0,0 +1,237 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionFaModels::liquidFilmModel
+
+Description
+    Thin Model Film model.
+
+
+SourceFiles
+    liquidFilmModel.C
+    kinematicThinFilmI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef liquidFilmModel_H
+#define liquidFilmModel_H
+
+#include "volFieldsFwd.H"
+#include "liquidFilmBase.H"
+#include "faMesh.H"
+#include "filmTurbulenceModel.H"
+#include "liquidMixtureProperties.H"
+#include "injectionModelList.H"
+#include "faCFD.H"
+#include "forceList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class liquidFilmModel Declaration
+\*---------------------------------------------------------------------------*/
+
+class liquidFilmModel
+:
+    public liquidFilmBase
+{
+protected:
+
+    // Thermo properties
+
+        //- Liquid thermo
+        liquidMixtureProperties thermo_;
+
+        //- Reference tempararure
+        scalar Tref_;
+
+
+    // Fields
+
+        //- Density [kg/m3]
+        areaScalarField rho_;
+
+        //- Dynamic viscosity [Pa.s]
+        areaScalarField mu_;
+
+        //- Film temperature
+        areaScalarField Tf_;
+
+        //- Film Heat capacity
+        areaScalarField Cp_;
+
+        //- Surface tension [m/s2]
+        areaScalarField sigma_;
+
+        //- Film rho*height
+        areaScalarField hRho_;
+
+
+    // Mass exchange sources
+
+        //- Mass source
+        areaScalarField rhoSp_;
+
+        //- Momentum source
+        areaVectorField USp_;
+
+        //- Normal pressure by particles
+        areaScalarField pnSp_;
+
+
+    // Transfer fields
+
+        //- Film mass  for transfer to cloud
+        volScalarField cloudMassTrans_;
+
+        //- Parcel diameters originating from film to cloud
+        volScalarField cloudDiameterTrans_;
+
+
+    // General properties
+
+        //- Turbulence model
+        autoPtr<filmTurbulenceModel> turbulence_;
+
+
+        // Sub-models
+
+            //- Available mass for transfer via sub-models
+            scalarField availableMass_;
+
+            //- Cloud injection
+            injectionModelList injection_;
+
+            //- Transfer with the continuous phase
+            //transferModelList transfer_;
+
+            //- List of film forces
+            forceList forces_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("liquidFilmModel");
+
+
+    // Constructors
+
+        //- Construct from components and dict
+        liquidFilmModel
+        (
+            const word& modelType,
+            const fvPatch& patch,
+            const dictionary& dict
+        );
+
+        //- No copy construct
+        liquidFilmModel(const liquidFilmModel&) = delete;
+
+        //- No copy assignment
+        void operator=(const liquidFilmModel&) = delete;
+
+
+    //- Destructor
+    virtual ~liquidFilmModel() = default;
+
+
+    // Member Functions
+
+        // Helpers
+
+            //- Correct thermo
+            void correctThermoFields();
+
+
+        // Access
+
+            //- Access const reference mu
+            const areaScalarField& mu() const;
+
+            //- Access const reference rho
+            const areaScalarField& rho() const;
+
+            //- Access const reference sigma
+            const areaScalarField& sigma() const;
+
+            //- Access const reference Tf
+            const areaScalarField& Tf() const;
+
+            //- Access const reference Cp
+            const areaScalarField& Cp() const;
+
+            //- Access to thermo
+            const liquidMixtureProperties& thermo() const;
+
+            //- Access to reference temperature
+            scalar Tref() const;
+
+
+        // Transfer fields - to the primary region (lagragian injection)
+
+            //- Return the film mass available for transfer to cloud
+            virtual const volScalarField& cloudMassTrans() const;
+
+            //- Return the parcel diameters originating from film to cloud
+            virtual const volScalarField& cloudDiameterTrans() const;
+
+
+        // Evolution
+
+            //- Pre-evolve film
+            virtual void preEvolveRegion();
+
+            //- Post-evolve film
+            virtual void postEvolveRegion();
+
+
+        // I-O
+
+            //- Provide some feedback
+            virtual void info();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/filmSubModelBase.C b/src/regionFaModels/liquidFilm/subModels/filmSubModelBase.C
new file mode 100644
index 0000000000000000000000000000000000000000..9b072df6db0d1b13cef4c0f227f6969ea5cae8bf
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/filmSubModelBase.C
@@ -0,0 +1,110 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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 "filmSubModelBase.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+filmSubModelBase::filmSubModelBase(liquidFilmBase& film)
+:
+    subModelBase(film.outputProperties()),
+    filmModel_(film)
+{}
+
+
+filmSubModelBase::filmSubModelBase
+(
+    liquidFilmBase& film,
+    const dictionary& dict,
+    const word& baseName,
+    const word& modelType,
+    const word& dictExt
+)
+:
+    subModelBase
+    (
+        film.outputProperties(),
+        dict,
+        baseName,
+        modelType,
+        dictExt
+    ),
+    filmModel_(film)
+{}
+
+
+filmSubModelBase::filmSubModelBase
+(
+    const word& modelName,
+    liquidFilmBase& film,
+    const dictionary& dict,
+    const word& baseName,
+    const word& modelType
+)
+:
+    subModelBase
+    (
+        modelName,
+        film.outputProperties(),
+        dict,
+        baseName,
+        modelType
+    ),
+    filmModel_(film)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+filmSubModelBase::~filmSubModelBase()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+bool filmSubModelBase::writeTime() const
+{
+    return active() && filmModel_.time().writeTime();
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/filmSubModelBase.H b/src/regionFaModels/liquidFilm/subModels/filmSubModelBase.H
new file mode 100644
index 0000000000000000000000000000000000000000..12afa909d52bde3e4381989a2bb2f2709fa8bc7a
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/filmSubModelBase.H
@@ -0,0 +1,139 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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::regionModels::surfaceFilmModels::filmSubModelBase
+
+Description
+    Base class for surface film sub-models
+
+SourceFiles
+    filmSubModelBaseI.H
+    filmSubModelBase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef filmSubModelBase_H
+#define filmSubModelBase_H
+
+#include "liquidFilmBase.H"
+#include "subModelBase.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class filmSubModelBase Declaration
+\*---------------------------------------------------------------------------*/
+
+class filmSubModelBase
+:
+    public subModelBase
+{
+protected:
+
+    // Protected Data
+
+        //- Reference to the film surface film model
+        liquidFilmBase& filmModel_;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        filmSubModelBase(liquidFilmBase& film);
+
+        //- Construct from film film without name
+        filmSubModelBase
+        (
+            liquidFilmBase& film,
+            const dictionary& dict,
+            const word& baseName,
+            const word& modelType,
+            const word& dictExt = "Coeffs"
+        );
+
+        //- Construct from film film with name
+        filmSubModelBase
+        (
+            const word& modelName,
+            liquidFilmBase& film,
+            const dictionary& dict,
+            const word& baseName,
+            const word& modelType
+        );
+
+
+    //- Destructor
+    virtual ~filmSubModelBase();
+
+
+    // Member Functions
+
+        // Access
+
+            //- Flag to indicate when to write a property
+            virtual bool writeTime() const;
+
+            //- Return const access to the film surface film model
+            inline const liquidFilmBase& film() const;
+
+            //- Return the reference to the film surface film model
+            inline liquidFilmBase& film();
+
+            template<class FilmType>
+            inline const FilmType& filmType() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "filmSubModelBaseI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "filmSubModelBaseTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/filmSubModelBaseI.H b/src/regionFaModels/liquidFilm/subModels/filmSubModelBaseI.H
new file mode 100644
index 0000000000000000000000000000000000000000..70f07eb03f70be52eb16786b99629feb9cbdf0bb
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/filmSubModelBaseI.H
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+inline const liquidFilmBase& filmSubModelBase::film() const
+{
+    return filmModel_;
+}
+
+
+inline liquidFilmBase& filmSubModelBase::film()
+{
+    return filmModel_;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/filmSubModelBaseTemplates.C b/src/regionFaModels/liquidFilm/subModels/filmSubModelBaseTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..355f1a8851fabfae4c8cf708319e4a4f1f86b1da
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/filmSubModelBaseTemplates.C
@@ -0,0 +1,58 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class FilmType>
+const FilmType& filmSubModelBase::filmType() const
+{
+    if (!isA<FilmType>(filmModel_))
+    {
+        FatalErrorInFunction
+            << "Model " << this->modelType() << " requested film type "
+            << FilmType::typeName << " but film is type " << filmModel_.type()
+            << abort(FatalError);
+    }
+
+    return refCast<const FilmType>(filmModel_);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C
new file mode 100644
index 0000000000000000000000000000000000000000..cec1b7acb9a4301e045f25185efe9cf63f1348be
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C
@@ -0,0 +1,170 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "filmTurbulenceModel.H"
+#include "gravityMeshObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(filmTurbulenceModel, 0);
+defineRunTimeSelectionTable(filmTurbulenceModel, dictionary);
+
+const Enum
+<
+    filmTurbulenceModel::frictionMethodType
+>
+filmTurbulenceModel::frictionMethodTypeNames_
+{
+    { frictionMethodType::mquadraticProfile, "quadraticProfile" },
+    { frictionMethodType::mlinearProfile, "linearProfile" },
+    { frictionMethodType::mDarcyWeisbach, "DarcyWeisbach" },
+    { frictionMethodType::mManningStrickler, "ManningStrickler" }
+};
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+filmTurbulenceModel::filmTurbulenceModel
+(
+    const word& modelType,
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    film_(film),
+    dict_(dict.subDict(modelType + "Coeffs")),
+    method_(frictionMethodTypeNames_.get("friction", dict_))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+filmTurbulenceModel::~filmTurbulenceModel()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const liquidFilmBase& filmTurbulenceModel::film() const
+{
+    return film_;
+}
+
+
+tmp<areaScalarField> filmTurbulenceModel::Cw() const
+{
+    auto tCw =
+        tmp<areaScalarField>::New
+        (
+            IOobject
+            (
+                "tCw",
+                film_.primaryMesh().time().timeName(),
+                film_.primaryMesh()
+            ),
+            film_.regionMesh(),
+            dimensionedScalar(dimVelocity)
+        );
+    auto& Cw = tCw.ref();
+
+    switch (method_)
+    {
+        case mquadraticProfile:
+        {
+            const scalarField& mu = film_.mu().primitiveField();
+            const scalarField& h = film_.h().primitiveField();
+            const scalar h0 = film_.h0().value();
+            Cw.primitiveFieldRef() = 3*mu/(h + h0);
+            Cw.min(5000.0);
+            break;
+        }
+        case mlinearProfile:
+        {
+            const scalarField& mu = film_.mu().primitiveField();
+            const scalarField& h = film_.h().primitiveField();
+            const scalar h0 = film_.h0().value();
+            Cw.primitiveFieldRef() = 2*mu/(h + h0);
+            break;
+        }
+        case mDarcyWeisbach:
+        {
+            const uniformDimensionedVectorField& g =
+                meshObjects::gravity::New(film_.primaryMesh().time());
+
+            const vectorField& Uf = film_.Uf().primitiveField();
+
+            scalar Cf = dict_.get<scalar>("Cf");
+            Cw.primitiveFieldRef() = Cf*mag(g.value())*mag(Uf);
+            break;
+        }
+        case mManningStrickler:
+        {
+            const uniformDimensionedVectorField& g =
+                meshObjects::gravity::New(film_.primaryMesh().time());
+
+            const scalar n = dict_.get<scalar>("n");
+
+            const vectorField& Uf = film_.Uf().primitiveField();
+            const scalarField& h = film_.h().primitiveField();
+            const scalar h0 = film_.h0().value();
+
+            Cw.primitiveFieldRef() =
+                sqr(n)*mag(g.value())*mag(Uf)/cbrt(h+h0);
+            break;
+        }
+        default:
+        {
+            FatalErrorInFunction
+                << "Unimplemented method "
+                << frictionMethodTypeNames_[method_] << nl
+                << "Please set 'frictionMethod' to one of "
+                << flatOutput(frictionMethodTypeNames_.sortedToc()) << nl
+                << exit(FatalError);
+
+            break;
+        }
+    }
+
+    return tCw;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H
new file mode 100644
index 0000000000000000000000000000000000000000..5277983eecc508f2507272905a8c714c7cd8020e
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H
@@ -0,0 +1,183 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::areaSurfaceFilmModels::filmTurbulenceModel
+
+Description
+    Base class for film turbulence models
+
+SourceFiles
+    filmTurbulenceModel.C
+    filmTurbulenceModelNew.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef regionFaModels_filmTurbulenceModel_H
+#define regionFaModels_filmTurbulenceModel_H
+
+#include "areaFieldsFwd.H"
+#include "runTimeSelectionTables.H"
+#include "faMatrices.H"
+#include "liquidFilmBase.H"
+#include "fvMesh.H"
+#include "Enum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class filmTurbulenceModel Declaration
+\*---------------------------------------------------------------------------*/
+
+class filmTurbulenceModel
+{
+    // Private Member Functions
+
+        //- No copy construct
+        filmTurbulenceModel(const filmTurbulenceModel&) = delete;
+
+        //- No copy assignment
+        void operator=(const filmTurbulenceModel&) = delete;
+
+
+public:
+
+    // Public Enumerations
+
+        //- Options for the friction models
+        enum frictionMethodType
+        {
+            mquadraticProfile,
+            mlinearProfile,
+            mDarcyWeisbach,
+            mManningStrickler
+        };
+
+
+protected:
+
+    // Protected Data
+
+        //- Reference to liquidFilmBase
+        const liquidFilmBase& film_;
+
+        //- Names for friction models
+        static const Enum<frictionMethodType> frictionMethodTypeNames_;
+
+        //- Model dictionary
+        const dictionary dict_;
+
+        //- Method used
+        const frictionMethodType method_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("filmTurbulenceModel");
+
+
+    // Declare runtime constructor selection table
+
+         declareRunTimeSelectionTable
+         (
+             autoPtr,
+             filmTurbulenceModel,
+             dictionary,
+             (
+                liquidFilmBase& film,
+                const dictionary& dict
+             ),
+             (film, dict)
+         );
+
+
+    // Constructors
+
+        //- Construct from type name, dictionary and surface film model
+        filmTurbulenceModel
+        (
+            const word& modelType,
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    // Selectors
+
+        //- Return a reference to the selected injection model
+        static autoPtr<filmTurbulenceModel> New
+        (
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~filmTurbulenceModel();
+
+
+    // Member Functions
+
+        // Access
+
+            //- Return film
+            const liquidFilmBase& film() const;
+
+
+        // Evolution
+
+            //- Return the wall film surface friction
+            virtual tmp<areaScalarField> Cw() const;
+
+            //- Return the film turbulence viscosity
+            virtual tmp<areaScalarField> mut() const = 0;
+
+            //- Correct/update the model
+            virtual void correct() = 0;
+
+            //- Return the source for the film momentum equation
+            virtual tmp<faVectorMatrix> Su(areaVectorField& U) const = 0;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C
new file mode 100644
index 0000000000000000000000000000000000000000..446e59250abddfd41a49ab8b2d35f4d867ab9f7b
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C
@@ -0,0 +1,74 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "filmTurbulenceModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+autoPtr<filmTurbulenceModel> filmTurbulenceModel::New
+(
+    liquidFilmBase& model,
+    const dictionary& dict
+)
+{
+    const word modelType(dict.get<word>("turbulence"));
+
+    Info<< "    Selecting filmTurbulenceModel " << modelType << endl;
+
+    auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
+
+    if (!cstrIter.found())
+    {
+        FatalIOErrorInLookup
+        (
+            dict,
+            "filmTurbulenceModel",
+            modelType,
+            *dictionaryConstructorTablePtr_
+        ) << exit(FatalIOError);
+    }
+
+    return autoPtr<filmTurbulenceModel>(cstrIter()(model, dict));
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C
new file mode 100644
index 0000000000000000000000000000000000000000..7630e254661109ce28688d7d664dd581ad1a3489
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.C
@@ -0,0 +1,117 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "laminar.H"
+#include "addToRunTimeSelectionTable.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(laminar, 0);
+addToRunTimeSelectionTable(filmTurbulenceModel, laminar, dictionary);
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+laminar::laminar
+(
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    filmTurbulenceModel(type(), film, dict),
+    Cf_(dict_.get<scalar>("Cf"))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+laminar::~laminar()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+tmp<areaScalarField> laminar::mut() const
+{
+    auto tmut =
+        tmp<areaScalarField>::New
+        (
+            IOobject
+            (
+                "mut",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE
+            ),
+            film().regionMesh(),
+            dimensionedScalar(dimMass/dimLength/dimTime)
+        );
+
+    return tmut;
+}
+
+
+void laminar::correct()
+{}
+
+
+tmp<faVectorMatrix> laminar::Su(areaVectorField& U) const
+{
+    // local references to film fields
+    tmp<areaVectorField> Uw = film_.Uw();
+    tmp<areaVectorField> Up = film_.Up();
+
+    // employ simple coeff-based model
+    const dimensionedScalar Cf("Cf", dimVelocity, Cf_);
+
+    tmp<areaScalarField> wf = Cw();
+
+    return
+    (
+       - fam::Sp(Cf, U) + Cf*Up()     // surface contribution
+       - fam::Sp(wf(), U) + wf()*Uw() // wall contribution
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.H b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.H
new file mode 100644
index 0000000000000000000000000000000000000000..b0e6b7054136866f3adf18ce0953ac63d5f09663
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/filmTurbulenceModel/laminar/laminar.H
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::areaSurfaceFilmModels::laminar
+
+Description
+    Film laminar turbulence model.
+
+SourceFiles
+    laminar.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef regionFaModels_surfaceFilmModels_laminar_H
+#define regionFaModels_surfaceFilmModels_laminar_H
+
+#include "liquidFilm/subModels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H"
+#include "faCFD.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class laminar Declaration
+\*---------------------------------------------------------------------------*/
+
+class laminar
+:
+    public filmTurbulenceModel
+{
+    // Private Data
+
+        //- Surface roughness coefficient
+        scalar Cf_;
+
+
+    // Private Member Functions
+
+        //- No copy construct
+        laminar(const laminar&) = delete;
+
+        //- No copy assignment
+        void operator=(const laminar&) = delete;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("laminar");
+
+
+    // Constructors
+
+        //- Construct from surface film model
+        laminar(liquidFilmBase& film, const dictionary& dict);
+
+
+    //- Destructor
+    virtual ~laminar();
+
+
+    // Member Functions
+
+        // Evolution
+
+            //- Return the film turbulence viscosity
+            virtual tmp<areaScalarField> mut() const;
+
+            //- Correct/update the model
+            virtual void correct();
+
+            //- Return the source for the film momentum equation
+            virtual tmp<faVectorMatrix> Su(areaVectorField& U) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.C b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.C
new file mode 100644
index 0000000000000000000000000000000000000000..a78556eae94e92c0edc1bae1e09cf6e68b7d6d02
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.C
@@ -0,0 +1,195 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "contactAngleForce.H"
+#include "addToRunTimeSelectionTable.H"
+#include "faCFD.H"
+#include "unitConversion.H"
+#include "meshWavePatchDistMethod.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(contactAngleForce, 0);
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+void contactAngleForce::initialise()
+{
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+contactAngleForce::contactAngleForce
+(
+    const word& typeName,
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    force(typeName, film, dict),
+    Ccf_(coeffDict_.get<scalar>("Ccf")),
+    mask_
+    (
+        IOobject
+        (
+            typeName + ":fContactForceMask",
+            film.primaryMesh().time().timeName(),
+            film.primaryMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        film.regionMesh(),
+        dimensionedScalar("mask", dimless, 1.0)
+    )
+{
+    initialise();
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+contactAngleForce::~contactAngleForce()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+tmp<faVectorMatrix> contactAngleForce::correct(areaVectorField& U)
+{
+    tmp<areaVectorField> tForce
+    (
+        new areaVectorField
+        (
+            IOobject
+            (
+                typeName + ":contactForce",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE
+            ),
+            film().regionMesh(),
+            dimensionedVector(dimForce/dimDensity/dimArea, Zero)
+        )
+    );
+
+    vectorField& force = tForce.ref().primitiveFieldRef();
+
+    const labelUList& own = film().regionMesh().owner();
+    const labelUList& nbr = film().regionMesh().neighbour();
+
+    const DimensionedField<scalar, areaMesh>& magSf = film().regionMesh().S();
+
+    tmp<areaScalarField> talpha = film().alpha();
+    const areaScalarField& sigma = film().sigma();
+
+    const areaScalarField& rhof = film().rho();
+
+    tmp<areaScalarField> ttheta = theta();
+    const areaScalarField& theta = ttheta();
+
+    const areaVectorField gradAlpha(fac::grad(talpha()));
+
+    forAll(nbr, edgei)
+    {
+        const label faceO = own[edgei];
+        const label faceN = nbr[edgei];
+
+        label facei = -1;
+        if ((talpha()[faceO] > 0.5) && (talpha()[faceN] < 0.5))
+        {
+            facei = faceO;
+        }
+        else if ((talpha()[faceO] < 0.5) && (talpha()[faceN] > 0.5))
+        {
+            facei = faceN;
+        }
+
+        if (facei != -1 && mask_[facei] > 0.5)
+        {
+            const scalar invDx = film().regionMesh().deltaCoeffs()[edgei];
+            const vector n
+            (
+                gradAlpha[facei]/(mag(gradAlpha[facei]) + ROOTVSMALL)
+            );
+            const scalar cosTheta = cos(degToRad(theta[facei]));
+
+            force[facei] +=
+                Ccf_*n*sigma[facei]*(1 - cosTheta)/invDx/rhof[facei];
+        }
+    }
+
+    forAll(sigma.boundaryField(), patchi)
+    {
+        const faPatchField<scalar>& alphaPf = sigma.boundaryField()[patchi];
+        const faPatchField<scalar>& sigmaPf = sigma.boundaryField()[patchi];
+        const labelUList& faces = alphaPf.patch().edgeFaces();
+
+        forAll(sigmaPf, edgei)
+        {
+            label face0 = faces[edgei];
+            force[face0] = vector::zero;
+        }
+    }
+
+
+    force /= magSf.field();
+
+    if (film().regionMesh().time().writeTime())
+    {
+        tForce().write();
+        gradAlpha.write();
+    }
+
+    tmp<faVectorMatrix> tfvm
+    (
+        new faVectorMatrix(U, dimForce/dimDensity)
+    );
+
+    tfvm.ref() += tForce;
+
+    return tfvm;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.H b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.H
new file mode 100644
index 0000000000000000000000000000000000000000..f99aab9ff2ac30e1b3133a1cd09dbab38cbdef56
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/contactAngleForce/contactAngleForce.H
@@ -0,0 +1,127 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::areaSurfaceFilmModels::contactAngleForce
+
+Description
+    Base-class for film contact angle force models.
+
+    The effect of the contact angle force can be ignored over a specified
+    distance from patches.
+
+SourceFiles
+    contactAngleForce.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef contactAngleForce_H
+#define contactAngleForce_H
+
+#include "force.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class contactAngleForce Declaration
+\*---------------------------------------------------------------------------*/
+
+class contactAngleForce
+:
+    public force
+{
+    // Private Data
+
+        //- Coefficient applied to the contact angle force
+        scalar Ccf_;
+
+        //- Mask over which force is applied
+        areaScalarField mask_;
+
+
+    // Private Member Functions
+
+        //- Initialise
+        void initialise();
+
+        //- No copy construct
+        contactAngleForce(const contactAngleForce&) = delete;
+
+        //- No copy assignment
+        void operator=(const contactAngleForce&) = delete;
+
+
+protected:
+
+        //- Return the contact angle field
+        virtual tmp<areaScalarField> theta() const = 0;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("contactAngle");
+
+
+    // Constructors
+
+        //- Construct from surface film model
+        contactAngleForce
+        (
+            const word& typeName,
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~contactAngleForce();
+
+
+    // Member Functions
+
+        //- Correct
+        virtual tmp<faVectorMatrix> correct(areaVectorField& U);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.C b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.C
new file mode 100644
index 0000000000000000000000000000000000000000..10858e865f42c1d2f53cc6255ecf9995db2dcda6
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.C
@@ -0,0 +1,124 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "perturbedTemperatureDependentContactAngleForce.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(perturbedTemperatureDependentContactAngleForce, 0);
+addToRunTimeSelectionTable
+(
+    force,
+    perturbedTemperatureDependentContactAngleForce,
+    dictionary
+);
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+perturbedTemperatureDependentContactAngleForce::
+perturbedTemperatureDependentContactAngleForce
+(
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    contactAngleForce(typeName, film, dict),
+    thetaPtr_(Function1<scalar>::New("theta", coeffDict_)),
+    rndGen_(label(0)),
+    distribution_
+    (
+        distributionModel::New
+        (
+            coeffDict_.subDict("distribution"),
+            rndGen_
+        )
+    )
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+perturbedTemperatureDependentContactAngleForce::
+~perturbedTemperatureDependentContactAngleForce()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+tmp<areaScalarField> perturbedTemperatureDependentContactAngleForce::
+theta() const
+{
+    tmp<areaScalarField> ttheta
+    (
+        new areaScalarField
+        (
+            IOobject
+            (
+                typeName + ":theta",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh()
+            ),
+            film().regionMesh(),
+            dimensionedScalar(dimless, Zero)
+        )
+    );
+
+    areaScalarField& theta = ttheta.ref();
+    scalarField& thetai = theta.ref();
+
+    const areaScalarField& T = film().Tf();
+
+    // Initialize with the function of temperature
+    thetai = thetaPtr_->value(T());
+
+    // Add the stochastic perturbation
+    forAll(thetai, facei)
+    {
+        thetai[facei] += distribution_->sample();
+    }
+
+    return ttheta;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace surfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.H b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.H
new file mode 100644
index 0000000000000000000000000000000000000000..ae165b90292e02837d751c9f64a5f49729250a61
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/contactAngleForces/perturbedTemperatureDependent/perturbedTemperatureDependentContactAngleForce.H
@@ -0,0 +1,139 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::areaSurfaceFilmModels::
+        perturbedTemperatureDependentContactAngleForce
+
+Description
+    Temperature dependent contact angle force with a stochastic perturbation.
+
+    The contact angle in degrees is specified as a \c Foam::Function1 type,
+    to enable the use of, e.g. \c constant, \c polynomial, \c table values
+    and the stochastic perturbation obtained from a
+    \c Foam::distributionModels::distributionModel.
+
+See also
+  - Foam::regionModels::areaSurfaceFilmModels::contactAngleForce
+  - areaSurfaceFilmModels::temperatureDependentContactAngleForce
+  - Foam::regionModels::areaSurfaceFilmModels::distributionContactAngleForce
+  - Foam::Function1Types
+  - Foam::distributionModel
+
+SourceFiles
+    perturbedTemperatureDependentContactAngleForce.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef perturbedTemperatureDependentContactAngleForce_H
+#define perturbedTemperatureDependentContactAngleForce_H
+
+#include "contactAngleForce.H"
+#include "Function1.H"
+#include "distributionModel.H"
+#include "Random.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+       Class perturbedTemperatureDependentContactAngleForce Declaration
+\*---------------------------------------------------------------------------*/
+
+class perturbedTemperatureDependentContactAngleForce
+:
+    public contactAngleForce
+{
+    // Private Data
+
+        //- Contact angle function
+        autoPtr<Function1<scalar>> thetaPtr_;
+
+        //- Random number generator
+        Random rndGen_;
+
+        //- Parcel size PDF model
+        const autoPtr<distributionModel> distribution_;
+
+
+    // Private Member Functions
+
+        //- No copy construct
+        perturbedTemperatureDependentContactAngleForce
+        (
+            const perturbedTemperatureDependentContactAngleForce&
+        ) = delete;
+
+        //- No copy assignment
+        void operator=
+        (
+            const perturbedTemperatureDependentContactAngleForce&
+        ) = delete;
+
+
+protected:
+
+        //- Return the contact angle field
+        virtual tmp<areaScalarField> theta() const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("perturbedTemperatureDependentContactAngle");
+
+
+    // Constructors
+
+        //- Construct from surface film model
+        perturbedTemperatureDependentContactAngleForce
+        (
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~perturbedTemperatureDependentContactAngleForce();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/force.C b/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/force.C
new file mode 100644
index 0000000000000000000000000000000000000000..b70ba843efd79fe50d51c73211c17c9c0a5bf032
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/force.C
@@ -0,0 +1,75 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "force.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(force, 0);
+defineRunTimeSelectionTable(force, dictionary);
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+force::force(liquidFilmBase& film)
+:
+    filmSubModelBase(film)
+{}
+
+
+force::force
+(
+    const word& modelType,
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    filmSubModelBase(film, dict, typeName, modelType)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+force::~force()
+{}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/force.H b/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/force.H
new file mode 100644
index 0000000000000000000000000000000000000000..ef05dc43a5c175a2290167a7e3ba522f866eacdd
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/force.H
@@ -0,0 +1,138 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::areaSurfaceFilmModels::force
+
+Description
+    Base class for film (stress-based) force models
+
+SourceFiles
+    force.C
+    forceNew.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef force_H
+#define force_H
+
+#include "filmSubModelBase.H"
+#include "runTimeSelectionTables.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                          Class force Declaration
+\*---------------------------------------------------------------------------*/
+
+class force
+:
+    public filmSubModelBase
+{
+    // Private Member Functions
+
+        //- No copy construct
+        force(const force&) = delete;
+
+        //- No copy assignment
+        void operator=(const force&) = delete;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("force");
+
+
+    // Declare runtime constructor selection table
+
+         declareRunTimeSelectionTable
+         (
+             autoPtr,
+             force,
+             dictionary,
+             (
+                liquidFilmBase& film,
+                const dictionary& dict
+             ),
+             (film, dict)
+         );
+
+    // Constructors
+
+        //- Construct null
+        force(liquidFilmBase& film);
+
+        //- Construct from type name, dictionary and surface film model
+        force
+        (
+            const word& modelType,
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    // Selectors
+
+        //- Return a reference to the selected force model
+        static autoPtr<force> New
+        (
+            liquidFilmBase& film,
+            const dictionary& dict,
+            const word& modelType
+        );
+
+
+    //- Destructor
+    virtual ~force();
+
+
+    // Member Functions
+
+        // Evolution
+
+            //- Correct
+            virtual tmp<faVectorMatrix> correct(areaVectorField& U) = 0;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/forceNew.C b/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/forceNew.C
new file mode 100644
index 0000000000000000000000000000000000000000..8a90e47ee83950f927e542bf7eb3c562865cc0e4
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/force/forceNew.C
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "force.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+autoPtr<force> force::New
+(
+    liquidFilmBase& model,
+    const dictionary& dict,
+    const word& modelType
+)
+{
+    Info<< "        " << modelType << endl;
+
+    auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
+
+    if (!cstrIter.found())
+    {
+        FatalIOErrorInLookup
+        (
+            dict,
+            "force",
+            modelType,
+            *dictionaryConstructorTablePtr_
+        ) << exit(FatalIOError);
+    }
+
+    return autoPtr<force>(cstrIter()(model, dict));
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/forceList/forceList.C b/src/regionFaModels/liquidFilm/subModels/kinematic/force/forceList/forceList.C
new file mode 100644
index 0000000000000000000000000000000000000000..ea0c634fce266e9de8ec1f0b9195b2ca89cdfd93
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/forceList/forceList.C
@@ -0,0 +1,104 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "forceList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+forceList::forceList(liquidFilmBase& film)
+:
+    PtrList<force>()
+{}
+
+
+forceList::forceList
+(
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    PtrList<force>()
+{
+    const wordList models(dict.lookup("forces"));
+
+    Info<< "    Selecting film force models" << endl;
+    if (models.size() > 0)
+    {
+        this->setSize(models.size());
+
+        forAll(models, i)
+        {
+            set(i, force::New(film, dict, models[i]));
+        }
+    }
+    else
+    {
+        Info<< "        none" << endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+forceList::~forceList()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+tmp<faVectorMatrix> forceList::correct(areaVectorField& U)
+{
+    tmp<faVectorMatrix> tResult
+    (
+        new faVectorMatrix(U, dimForce/dimDensity)
+    );
+    faVectorMatrix& result = tResult.ref();
+
+    forAll(*this, i)
+    {
+        result += this->operator[](i).correct(U);
+    }
+
+    return tResult;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/force/forceList/forceList.H b/src/regionFaModels/liquidFilm/subModels/kinematic/force/forceList/forceList.H
new file mode 100644
index 0000000000000000000000000000000000000000..a778c7626555739c609eeb8ffe39b34c12709657
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/force/forceList/forceList.H
@@ -0,0 +1,98 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::surfaceFilmModels::forceList
+
+Description
+    List container for film sources
+
+SourceFiles
+    forceList.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef forceList_H
+#define forceList_H
+
+#include "PtrList.H"
+#include "force.H"
+#include "faCFD.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class forceList Declaration
+\*---------------------------------------------------------------------------*/
+
+class forceList
+:
+    public PtrList<force>
+{
+public:
+
+    // Constructors
+
+        //- Construct null
+        forceList(liquidFilmBase& film);
+
+        //- Construct from type name, dictionary and surface film model
+        forceList
+        (
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~forceList();
+
+
+    // Member Functions
+
+        //- Return (net) force system
+        tmp<faVectorMatrix> correct(areaVectorField& U);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C
new file mode 100644
index 0000000000000000000000000000000000000000..ee40e484243c15a8ae45ac352d702b4a1b3ea7ad
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.C
@@ -0,0 +1,324 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2011-2017 OpenFOAM Foundation
+    Copyright (C) 2020 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 "curvatureSeparation.H"
+#include "addToRunTimeSelectionTable.H"
+#include "Time.H"
+#include "stringListOps.H"
+#include "cyclicPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(curvatureSeparation, 0);
+addToRunTimeSelectionTable
+(
+    injectionModel,
+    curvatureSeparation,
+    dictionary
+);
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+tmp<areaScalarField> curvatureSeparation::calcInvR1
+(
+    const areaVectorField& U,
+    const scalarField& calcCosAngle
+) const
+{
+    const dimensionedScalar smallU(dimVelocity, ROOTVSMALL);
+    const areaVectorField UHat(U/(mag(U) + smallU));
+    tmp<areaScalarField> tinvR1
+    (
+        new areaScalarField("invR1", UHat & (UHat & -gradNHat_))
+    );
+
+    scalarField& invR1 = tinvR1.ref().primitiveFieldRef();
+
+    // apply defined patch radii
+    const scalar rMin = 1e-6;
+    const scalar definedInvR1 = 1.0/max(rMin, definedPatchRadii_);
+
+    if (definedPatchRadii_ > 0)
+    {
+        invR1 = definedInvR1;
+    }
+
+    // filter out large radii
+    const scalar rMax = 1e6;
+    forAll(invR1, i)
+    {
+        if ((mag(invR1[i]) < 1/rMax))
+        {
+            invR1[i] = -1.0;
+        }
+    }
+
+    return tinvR1;
+}
+
+
+tmp<scalarField> curvatureSeparation::calcCosAngle
+(
+    const edgeScalarField& phi
+) const
+{
+    const areaVectorField& U = film().Uf();
+    const dimensionedScalar smallU(dimVelocity, ROOTVSMALL);
+    const areaVectorField UHat(U/(mag(U) + smallU));
+
+    const faMesh& mesh = film().regionMesh();
+    const labelUList& own = mesh.edgeOwner();
+    const labelUList& nbr = mesh.edgeNeighbour();
+
+    scalarField phiMax(mesh.nFaces(), -GREAT);
+    scalarField cosAngle(UHat.size(), Zero);
+
+    const scalarField invR1(calcInvR1(U, cosAngle));
+
+    forAll(nbr, edgei)
+    {
+        const label cellO = own[edgei];
+        const label cellN = nbr[edgei];
+
+        if (phi[edgei] > phiMax[cellO])
+        {
+            phiMax[cellO] = phi[edgei];
+            cosAngle[cellO] = -gHat_ & UHat[cellN];
+        }
+        if (-phi[edgei] > phiMax[cellN])
+        {
+            phiMax[cellN] = -phi[edgei];
+            cosAngle[cellN] = -gHat_ & UHat[cellO];
+        }
+    }
+
+    cosAngle *= pos(invR1);
+
+    // checks
+    if (debug && mesh.time().writeTime())
+    {
+        areaScalarField volCosAngle
+        (
+            IOobject
+            (
+                "cosAngle",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ
+            ),
+            film().regionMesh(),
+            dimensionedScalar(dimless, Zero)
+        );
+        volCosAngle.primitiveFieldRef() = cosAngle;
+        volCosAngle.correctBoundaryConditions();
+        volCosAngle.write();
+    }
+
+    return max(min(cosAngle, scalar(1)), scalar(-1));
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+curvatureSeparation::curvatureSeparation
+(
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    injectionModel(type(), film, dict),
+    gradNHat_(fac::grad(film.regionMesh().faceAreaNormals())),
+    deltaByR1Min_(coeffDict_.getOrDefault<scalar>("deltaByR1Min", 0)),
+    definedPatchRadii_
+    (
+        coeffDict_.getOrDefault<scalar>("definedPatchRadii", 0)
+    ),
+    magG_(mag(film.g().value())),
+    gHat_(Zero),
+    fThreshold_
+    (
+        coeffDict_.getOrDefault<scalar>("fThreshold", 1e-8)
+    ),
+    minInvR1_
+    (
+        coeffDict_.getOrDefault<scalar>("minInvR1", 5)
+    )
+{
+    if (magG_ < ROOTVSMALL)
+    {
+        FatalErrorInFunction
+            << "Acceleration due to gravity must be non-zero"
+            << exit(FatalError);
+    }
+
+    gHat_ = film.g().value()/magG_;
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void curvatureSeparation::correct
+(
+    scalarField& availableMass,
+    scalarField& massToInject,
+    scalarField& diameterToInject
+)
+{
+    const faMesh& mesh = film().regionMesh();
+
+    const areaScalarField& delta = film().h();
+    const areaVectorField& U = film().Uf();
+    const edgeScalarField& phi = film().phi2s();
+    const areaScalarField& rho = film().rho();
+    const scalarField magSqrU(magSqr(film().Uf()));
+    const areaScalarField& sigma = film().sigma();
+
+    const scalarField cosAngle(calcCosAngle(phi));
+    const scalarField invR1(calcInvR1(U, cosAngle));
+
+
+    // calculate force balance
+    scalarField Fnet(mesh.nFaces(), Zero);
+    scalarField separated(mesh.nFaces(), Zero);
+
+    forAll(invR1, i)
+    {
+        if ((invR1[i] > minInvR1_) && (delta[i]*invR1[i] > deltaByR1Min_))
+        {
+            const scalar R1 = 1.0/(invR1[i] + ROOTVSMALL);
+            const scalar R2 = R1 + delta[i];
+
+            // inertial force
+            const scalar Fi = -delta[i]*rho[i]*magSqrU[i]*72.0/60.0*invR1[i];
+
+            // body force
+            const scalar Fb =
+               - 0.5*rho[i]*magG_*invR1[i]*(sqr(R1) - sqr(R2))*cosAngle[i];
+
+            // surface force
+            const scalar Fs = sigma[i]/R2;
+
+            Fnet[i] = Fi + Fb + Fs;
+
+            if (Fnet[i] + fThreshold_ < 0)
+            {
+                separated[i] = 1.0;
+            }
+        }
+    }
+
+    // inject all available mass
+    massToInject = separated*availableMass;
+    diameterToInject = separated*delta;
+    availableMass -= separated*availableMass;
+
+    addToInjectedMass(sum(massToInject));
+
+    if (debug && mesh.time().writeTime())
+    {
+        areaScalarField volFnet
+        (
+            IOobject
+            (
+                "Fnet",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ
+            ),
+            mesh,
+            dimensionedScalar(dimForce, Zero)
+        );
+        volFnet.primitiveFieldRef() = Fnet;
+        volFnet.write();
+
+        areaScalarField areaSeparated
+        (
+            IOobject
+            (
+                "separated",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ
+            ),
+            mesh,
+            dimensionedScalar(dimMass, Zero)
+        );
+        areaSeparated.primitiveFieldRef() = separated;
+        areaSeparated.write();
+
+        areaScalarField areaMassToInject
+        (
+            IOobject
+            (
+                "massToInject",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ
+            ),
+            mesh,
+            dimensionedScalar(dimMass, Zero)
+        );
+        areaMassToInject.primitiveFieldRef() = massToInject;
+        areaMassToInject.write();
+
+        areaScalarField areaInvR1
+        (
+            IOobject
+            (
+                "InvR1",
+                film().primaryMesh().time().timeName(),
+                film().primaryMesh(),
+                IOobject::NO_READ
+            ),
+            mesh,
+            dimensionedScalar(inv(dimLength), Zero)
+        );
+        areaInvR1.primitiveFieldRef() = invR1;
+        areaInvR1.write();
+    }
+
+    injectionModel::correct();
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.H b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.H
new file mode 100644
index 0000000000000000000000000000000000000000..0ec037e43263ff7f26f370b7184008359ad7482e
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/curvatureSeparation/curvatureSeparation.H
@@ -0,0 +1,167 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2011-2017 OpenFOAM Foundation
+    Copyright (C) 2021 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::regionModels::areaSurfaceFilmModels::curvatureSeparation
+
+Description
+    Curvature film separation model
+
+    Assesses film curvature via the mesh geometry and calculates a force
+    balance of the form:
+
+        F_sum = F_inertial + F_body + F_surface
+
+    If F_sum < 0, the film separates. Similarly, if F_sum > 0 the film will
+    remain attached.
+
+    Based on description given by
+        Owen and D. J. Ryley. The flow of thin liquid films around corners.
+        International Journal of Multiphase Flow, 11(1):51-62, 1985.
+
+SourceFiles
+    curvatureSeparation.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef curvatureSeparation_H
+#define curvatureSeparation_H
+
+#include "injectionModel.H"
+#include "faCFD.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class curvatureSeparation Declaration
+\*---------------------------------------------------------------------------*/
+
+class curvatureSeparation
+:
+    public injectionModel
+{
+    // Private Member Functions
+
+        //- No copy construct
+        curvatureSeparation(const curvatureSeparation&) = delete;
+
+        //- No copy assignment
+        void operator=(const curvatureSeparation&) = delete;
+
+
+protected:
+
+    // Protected Data
+
+        //- Gradient of surface normals
+        areaTensorField gradNHat_;
+
+        //- Minimum gravity driven film thickness (non-dimensionalised delta/R1)
+        scalar deltaByR1Min_;
+
+        //- List of radii for patches - if patch not defined, radius
+        //- calculated based on mesh geometry
+        scalar definedPatchRadii_;
+
+        //- Magnitude of gravity vector
+        scalar magG_;
+
+        //- Direction of gravity vector
+        vector gHat_;
+
+        //- Threshold force for separation
+        scalar fThreshold_;
+
+        //- Minimum inv R1 for separation
+        scalar minInvR1_;
+
+
+    // Protected Member Functions
+
+        //- Calculate local (inverse) radius of curvature
+        tmp<areaScalarField> calcInvR1
+        (
+            const areaVectorField& U,
+            const scalarField& calcCosAngle
+        ) const;
+
+        //- Calculate the cosine of the angle between gravity vector and
+        //- cell out flow direction
+        tmp<scalarField> calcCosAngle(const edgeScalarField& phi) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("curvatureSeparation");
+
+
+    // Constructors
+
+        //- Construct from surface film model
+        curvatureSeparation
+        (
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~curvatureSeparation() = default;
+
+
+    // Member Functions
+
+        // Evolution
+
+            //- Correct
+            virtual void correct
+            (
+                scalarField& availableMass,
+                scalarField& massToInject,
+                scalarField& diameterToInject
+            );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.C b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.C
new file mode 100644
index 0000000000000000000000000000000000000000..b1e5475a85886d7214a128e78e801c47cfb6830e
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.C
@@ -0,0 +1,106 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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 "injectionModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(injectionModel, 0);
+defineRunTimeSelectionTable(injectionModel, dictionary);
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void injectionModel::addToInjectedMass(const scalar dMass)
+{
+    injectedMass_ += dMass;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+injectionModel::injectionModel(liquidFilmBase& film)
+:
+    filmSubModelBase(film),
+    injectedMass_(0.0)
+{}
+
+
+injectionModel::injectionModel
+(
+    const word& modelType,
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    filmSubModelBase(film, dict, typeName, modelType),
+    injectedMass_(0.0)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+injectionModel::~injectionModel()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void injectionModel::correct()
+{
+    if (writeTime())
+    {
+        scalar injectedMass0 = getModelProperty<scalar>("injectedMass");
+        injectedMass0 += returnReduce(injectedMass_, sumOp<scalar>());
+        setModelProperty<scalar>("injectedMass", injectedMass0);
+        injectedMass_ = 0.0;
+    }
+}
+
+
+scalar injectionModel::injectedMassTotal() const
+{
+    const scalar injectedMass0 = getModelProperty<scalar>("injectedMass");
+    return injectedMass0 + returnReduce(injectedMass_, sumOp<scalar>());
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.H b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.H
new file mode 100644
index 0000000000000000000000000000000000000000..5bf117f7a9779ec9f6c6b5168a14d95959d18e20
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModel.H
@@ -0,0 +1,169 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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::regionModels::areaSurfaceFilmModels::injectionModel
+
+Description
+    Base class for film injection models, handling mass transfer from the
+    film.
+
+SourceFiles
+    injectionModel.C
+    injectionModelNew.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef injectionModel_H
+#define injectionModel_H
+
+#include "filmSubModelBase.H"
+#include "runTimeSelectionTables.H"
+#include "scalarField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class injectionModel Declaration
+\*---------------------------------------------------------------------------*/
+
+class injectionModel
+:
+    public filmSubModelBase
+{
+    // Private Data
+
+        //- Injected mass
+        scalar injectedMass_;
+
+
+    // Private Member Functions
+
+        //- No copy construct
+        injectionModel(const injectionModel&) = delete;
+
+        //- No copy assignment
+        void operator=(const injectionModel&) = delete;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Add to injected mass
+        void addToInjectedMass(const scalar dMass);
+
+        //- Correct
+        void correct();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("injectionModel");
+
+
+    // Declare runtime constructor selection table
+
+         declareRunTimeSelectionTable
+         (
+             autoPtr,
+             injectionModel,
+             dictionary,
+             (
+                liquidFilmBase& film,
+                const dictionary& dict
+             ),
+             (film, dict)
+         );
+
+
+    // Constructors
+
+        //- Construct null
+        injectionModel(liquidFilmBase& film);
+
+        //- Construct from type name, dictionary and surface film model
+        injectionModel
+        (
+            const word& modelType,
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    // Selectors
+
+        //- Return a reference to the selected injection model
+        static autoPtr<injectionModel> New
+        (
+            liquidFilmBase& film,
+            const dictionary& dict,
+            const word& mdoelType
+        );
+
+
+    //- Destructor
+    virtual ~injectionModel();
+
+
+    // Member Functions
+
+        //- Correct
+        virtual void correct
+        (
+            scalarField& availableMass,
+            scalarField& massToInject,
+            scalarField& diameterToInject
+        ) = 0;
+
+        //- Return the total mass injected
+        virtual scalar injectedMassTotal() const;
+
+        //- Accumulate the total mass injected for the patches into the
+        //- scalarField provided
+        virtual void patchInjectedMassTotals(scalar& patchMasses) const
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModelNew.C b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModelNew.C
new file mode 100644
index 0000000000000000000000000000000000000000..e44974469374cd85c82173ff7ffa753a5b2ad162
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModel/injectionModelNew.C
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 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 "injectionModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+autoPtr<injectionModel> injectionModel::New
+(
+    liquidFilmBase& model,
+    const dictionary& dict,
+    const word& modelType
+)
+{
+    Info<< "        " << modelType << endl;
+
+    auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
+
+    if (!cstrIter.found())
+    {
+        FatalIOErrorInLookup
+        (
+            dict,
+            "injectionModel",
+            modelType,
+            *dictionaryConstructorTablePtr_
+        ) << exit(FatalIOError);
+    }
+
+    return autoPtr<injectionModel>(cstrIter()(model, dict));
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.C b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.C
new file mode 100644
index 0000000000000000000000000000000000000000..01900da387ce2676c307dc283c83cf5060c3576c
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.C
@@ -0,0 +1,169 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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 "injectionModelList.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+injectionModelList::injectionModelList(liquidFilmBase& film)
+:
+    PtrList<injectionModel>(),
+    filmSubModelBase(film)
+{}
+
+
+injectionModelList::injectionModelList
+(
+    liquidFilmBase& film,
+    const dictionary& dict
+)
+:
+    PtrList<injectionModel>(),
+    filmSubModelBase
+    (
+        "injectionModelList",
+        film,
+        dict,
+        "injectionModelList",
+        "injectionModelList"
+    ),
+    massInjected_(Zero)
+{
+    const wordList activeModels(dict.lookup("injectionModels"));
+
+    wordHashSet models(activeModels);
+
+    Info<< "    Selecting film injection models" << endl;
+    if (models.size())
+    {
+        this->setSize(models.size());
+
+        label i = 0;
+        for (const word& model : models)
+        {
+            set(i, injectionModel::New(film, dict, model));
+            i++;
+        }
+    }
+    else
+    {
+        Info<< "        none" << endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+injectionModelList::~injectionModelList()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void injectionModelList::correct
+(
+    scalarField& availableMass,
+    volScalarField& massToInject,
+    volScalarField& diameterToInject
+)
+{
+    const label patchi = film().patchID();
+
+    // Correct models that accumulate mass and diameter transfers
+    forAll(*this, i)
+    {
+        injectionModel& im = operator[](i);
+        im.correct
+        (
+            availableMass,
+            massToInject.boundaryFieldRef()[patchi],
+            diameterToInject.boundaryFieldRef()[patchi]
+        );
+    }
+
+    massInjected_ += gSum(massToInject.boundaryField()[patchi]);
+}
+
+
+void injectionModelList::info(Ostream& os)
+{
+    const polyBoundaryMesh& pbm = film().primaryMesh().boundaryMesh();
+
+    scalar injectedMass = 0;
+    scalar patchInjectedMasses = 0;
+
+    forAll(*this, i)
+    {
+        const injectionModel& im = operator[](i);
+        injectedMass += im.injectedMassTotal();
+        im.patchInjectedMassTotals(patchInjectedMasses);
+    }
+
+    os  << indent << "injected mass      = " << injectedMass << nl;
+
+    const label patchi = film().patchID();
+
+    if (mag(patchInjectedMasses) > VSMALL)
+    {
+        os  << indent << indent << "from patch " << pbm[patchi].name()
+            << " = " << patchInjectedMasses << nl;
+    }
+
+    scalar mass0(Zero);
+    this->getBaseProperty("massInjected", mass0);
+
+    scalar mass(massInjected_);
+    mass += mass0;
+
+    Info<< indent << "  - patch: " << pbm[patchi].name() << "  "
+        << mass << endl;
+
+    if (film().primaryMesh().time().writeTime())
+    {
+        setBaseProperty("massInjected", mass);
+        massInjected_ = 0.0;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.H b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.H
new file mode 100644
index 0000000000000000000000000000000000000000..b159f9486a6f7242dfa3dbc3706468be0bb103ee
--- /dev/null
+++ b/src/regionFaModels/liquidFilm/subModels/kinematic/injectionModel/injectionModelList/injectionModelList.H
@@ -0,0 +1,127 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 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::regionModels::surfaceFilmModels::injectionModelList
+
+Description
+    List container for film injection models
+
+SourceFiles
+    injectionModelList.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef injectionModelList_H
+#define injectionModelList_H
+
+#include "PtrList.H"
+#include "injectionModel.H"
+#include "filmSubModelBase.H"
+#include "scalarField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace areaSurfaceFilmModels
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class injectionModelList Declaration
+\*---------------------------------------------------------------------------*/
+
+class injectionModelList
+:
+    public PtrList<injectionModel>,
+    public filmSubModelBase
+{
+    // Private Data
+
+        //- List of mass injected per patch
+        scalar massInjected_;
+
+
+    // Private Member Functions
+
+        //- No copy construct
+        injectionModelList(const injectionModelList&) = delete;
+
+        //- No copy assignment
+        void operator=(const injectionModelList&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        injectionModelList(liquidFilmBase& film);
+
+        //- Construct from type name, dictionary and surface film model
+        injectionModelList
+        (
+            liquidFilmBase& film,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~injectionModelList();
+
+
+    // Member Functions
+
+        // Evolution
+
+            //- Correct
+            virtual void correct
+            (
+                scalarField& availableMass,
+                volScalarField& massToInject,
+                volScalarField& diameterToInject
+            );
+
+
+        // I-O
+
+            //- Provide some info
+            virtual void info(Ostream& os);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace areaSurfaceFilmModels
+} // End namespace regionModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/regionFaModels/regionFaModel/regionFaModel.C b/src/regionFaModels/regionFaModel/regionFaModel.C
index 9a7078e036c3b1d77a37dc4dd2671a208e50b275..27bd759b637f9066634d987d987bff4fb5bedfda 100644
--- a/src/regionFaModels/regionFaModel/regionFaModel.C
+++ b/src/regionFaModels/regionFaModel/regionFaModel.C
@@ -41,6 +41,9 @@ namespace regionModels
 }
 }
 
+const Foam::word
+Foam::regionModels::regionFaModel::regionFaModelName("regionFaModel");
+
 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
 
 void Foam::regionModels::regionFaModel::constructMeshObjects()
@@ -60,12 +63,31 @@ void Foam::regionModels::regionFaModel::initialise()
     }
 
     vsmPtr_.reset(new volSurfaceMapping(regionMeshPtr_()));
-}
 
+    if (!outputPropertiesPtr_)
+    {
+        const fileName uniformPath(word("uniform")/regionFaModelName);
+
+        outputPropertiesPtr_.reset
+        (
+            new IOdictionary
+            (
+                IOobject
+                (
+                    regionName_ + "OutputProperties",
+                    time_.timeName(),
+                    uniformPath/regionName_,
+                    primaryMesh_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                )
+            )
+        );
+    }
+}
 
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
-bool Foam::regionModels::regionFaModel::read(const dictionary& dict)
+bool Foam::regionModels::regionFaModel::init(const dictionary& dict)
 {
     if (active_)
     {
@@ -102,6 +124,17 @@ Foam::regionModels::regionFaModel::regionFaModel
     bool readFields
 )
 :
+    IOdictionary
+    (
+        IOobject
+        (
+            IOobject::groupName(regionFaModelName, patch.name()),
+            patch.boundaryMesh().mesh().time().constant(),
+            patch.boundaryMesh().mesh().time(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        )
+    ),
     primaryMesh_(patch.boundaryMesh().mesh()),
     patch_(patch),
     time_(patch.boundaryMesh().mesh().time()),
@@ -110,19 +143,17 @@ Foam::regionModels::regionFaModel::regionFaModel
     modelName_(modelName),
     regionMeshPtr_(nullptr),
     coeffs_(dict.subOrEmptyDict(modelName + "Coeffs")),
+    outputPropertiesPtr_(nullptr),
     vsmPtr_(nullptr),
     patchID_(patch.index()),
     regionName_(dict.lookup("region"))
 {
-    if (active_)
-    {
-        constructMeshObjects();
-        initialise();
+    constructMeshObjects();
+    initialise();
 
-        if (readFields)
-        {
-            read(dict);
-        }
+    if (readFields)
+    {
+        init(dict);
     }
 }
 
@@ -165,8 +196,9 @@ void Foam::regionModels::regionFaModel::postEvolveRegion()
 {}
 
 
-void Foam::regionModels::regionFaModel::info()
-{}
-
+Foam::scalar Foam::regionModels::regionFaModel::CourantNumber() const
+{
+    return 0;
+}
 
 // ************************************************************************* //
diff --git a/src/regionFaModels/regionFaModel/regionFaModel.H b/src/regionFaModels/regionFaModel/regionFaModel.H
index 48cb985339bdc83b1b11e06e5e9387c99217e68a..bc2246c111ed4205942d28d07f9a5f877e368556 100644
--- a/src/regionFaModels/regionFaModel/regionFaModel.H
+++ b/src/regionFaModels/regionFaModel/regionFaModel.H
@@ -88,6 +88,8 @@ namespace regionModels
 \*---------------------------------------------------------------------------*/
 
 class regionFaModel
+:
+    public IOdictionary
 {
     // Private Member Functions
 
@@ -97,6 +99,9 @@ class regionFaModel
         //- Initialise the region
         void initialise();
 
+        //- Read control parameters from dictionary
+        bool init(const dictionary& dict);
+
 
 protected:
 
@@ -126,6 +131,9 @@ protected:
         //- Model coefficients dictionary
         dictionary coeffs_;
 
+        //- Dictionary of output properties
+        autoPtr<IOdictionary> outputPropertiesPtr_;
+
         //-Volume-to surface mapping
         autoPtr<volSurfaceMapping> vsmPtr_;
 
@@ -140,18 +148,15 @@ protected:
         word regionName_;
 
 
-    // Protected Member Functions
-
-        //- Read control parameters from dictionary
-        virtual bool read(const dictionary& dict);
-
-
 public:
 
     //- Runtime type information
     TypeName("regionFaModel");
 
 
+    //- Default name regionFaModel
+    static const word regionFaModelName;
+
     // Constructors
 
         //- Construct from mesh and name and dict
@@ -203,18 +208,23 @@ public:
             //- Return the model coefficients dictionary
             inline const dictionary& coeffs() const;
 
+            //- Return const access to the output properties dictionary
+            inline const IOdictionary& outputProperties() const;
+
+            //- Return output properties dictionary
+            inline IOdictionary& outputProperties();
+
             //- Return the solution dictionary
             inline const dictionary& solution() const;
 
-            //- Return volSurfaceMapping
-            const volSurfaceMapping& vsm() const;
+            //- Return patch ID
+            inline label patchID() const;
 
 
-        // Addressing
+        // Help Functions
 
-            //- Return the list of patch IDs on the primary region coupled
-            //- to this region
-            inline label patchID();
+            //- Return mapping between surface and volume fields
+            const volSurfaceMapping& vsm() const;
 
 
         // Evolution
@@ -231,11 +241,14 @@ public:
             //- Post-evolve region
             virtual void postEvolveRegion();
 
+            //- Courant number of the region
+            virtual scalar CourantNumber() const;
+
 
         // IO
 
             //- Provide some feedback
-            virtual void info();
+            virtual void info() = 0;
 };
 
 
diff --git a/src/regionFaModels/regionFaModel/regionFaModelI.H b/src/regionFaModels/regionFaModel/regionFaModelI.H
index 35fe64d499775cc8b839899c8db846b0c1c4aad6..7f45fa6ec4722771d475c28e951ab33449cc3889 100644
--- a/src/regionFaModels/regionFaModel/regionFaModelI.H
+++ b/src/regionFaModels/regionFaModel/regionFaModelI.H
@@ -101,6 +101,32 @@ inline const Foam::dictionary& Foam::regionModels::regionFaModel::coeffs() const
     return coeffs_;
 }
 
+inline const Foam::IOdictionary&
+Foam::regionModels::regionFaModel::outputProperties() const
+{
+    if (!outputPropertiesPtr_)
+    {
+        FatalErrorInFunction
+            << "outputProperties dictionary not available"
+            << abort(FatalError);
+    }
+    return *outputPropertiesPtr_;
+}
+
+
+inline Foam::IOdictionary&
+Foam::regionModels::regionFaModel::outputProperties()
+{
+    if (!outputPropertiesPtr_)
+    {
+        FatalErrorInFunction
+            << "outputProperties dictionary not available"
+            << abort(FatalError);
+    }
+
+    return *outputPropertiesPtr_;
+}
+
 
 inline const Foam::dictionary&
 Foam::regionModels::regionFaModel::solution() const
@@ -109,7 +135,7 @@ Foam::regionModels::regionFaModel::solution() const
 }
 
 
-inline Foam::label Foam::regionModels::regionFaModel::patchID()
+inline Foam::label Foam::regionModels::regionFaModel::patchID() const
 {
     return patchID_;
 }
diff --git a/src/regionFaModels/thermalShell/thermalShell.C b/src/regionFaModels/thermalShell/thermalShell.C
index 797de7e2d5e90fc32f705d7e77f4887541a86be2..491b432be1fcb88821d230d91807e49f2a7919fe 100644
--- a/src/regionFaModels/thermalShell/thermalShell.C
+++ b/src/regionFaModels/thermalShell/thermalShell.C
@@ -43,16 +43,55 @@ defineTypeNameAndDebug(thermalShell, 0);
 
 addToRunTimeSelectionTable(thermalShellModel, thermalShell, dictionary);
 
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-bool thermalShell::read(const dictionary& dict)
+bool thermalShell::init(const dictionary& dict)
 {
+    if (thickness_ > 0)
+    {
+        h_ = dimensionedScalar("thickness", dimLength, thickness_);
+    }
+
     this->solution().readEntry("nNonOrthCorr", nNonOrthCorr_);
 
     return true;
 }
 
 
+tmp<areaScalarField> thermalShell::qr()
+{
+    IOobject io
+    (
+        "tqr",
+        primaryMesh().time().timeName(),
+        primaryMesh()
+    );
+
+    auto taqr =
+        tmp<areaScalarField>::New
+        (
+            io,
+            regionMesh(),
+            dimensionedScalar(dimPower/dimArea, Zero)
+        );
+
+    if (qrName_ != "none")
+    {
+        auto& aqr = taqr.ref();
+
+        const auto qr = primaryMesh().lookupObject<volScalarField>(qrName_);
+
+        const volScalarField::Boundary& vqr = qr.boundaryField();
+
+        aqr.primitiveFieldRef() = vsm().mapToSurface<scalar>(vqr);
+    }
+
+    return taqr;
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
 void thermalShell::solveEnergy()
 {
     if (debug)
@@ -68,7 +107,7 @@ void thermalShell::solveEnergy()
       - fam::laplacian(kappa()*h_, T_)
      ==
         qs_
-      //+ q(T_) handled by faOption contactHeatFlux
+      + qr()
       + faOptions()(h_, rhoCph, T_)
     );
 
@@ -118,18 +157,16 @@ thermalShell::thermalShell
             IOobject::AUTO_WRITE
         ),
         regionMesh()
-    )
+    ),
+    qrName_(dict.getOrDefault<word>("qr", "none")),
+    thickness_(dict.getOrDefault<scalar>("thickness", 0))
 {
-    init();
+    init(dict);
 }
 
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
-void thermalShell::init()
-{}
-
-
 void thermalShell::preEvolveRegion()
 {}
 
diff --git a/src/regionFaModels/thermalShell/thermalShell.H b/src/regionFaModels/thermalShell/thermalShell.H
index 6160855c130e6b63aec44327d9f8f5ce421c0e5f..d675d68f3cf5c34be6847f1fdbbb6b0ac6bc0dae 100644
--- a/src/regionFaModels/thermalShell/thermalShell.H
+++ b/src/regionFaModels/thermalShell/thermalShell.H
@@ -98,7 +98,10 @@ class thermalShell
     // Private Member Functions
 
         //- Initialize thermalShell
-        void init();
+        bool init(const dictionary& dict);
+
+        //- Return radiative heat flux
+        tmp<areaScalarField> qr();
 
 
 protected:
@@ -125,12 +128,14 @@ protected:
             //- Thickness
             areaScalarField h_;
 
+            //- Name of the primary region radiative flux
+            const word qrName_;
 
-    // Protected Member Functions
+            //- Uniform thickness
+            scalar thickness_;
 
-        //- Read control parameters from dictionary
-        virtual bool read(const dictionary& dict);
 
+    // Protected Member Functions
 
         // Equations
 
diff --git a/src/regionFaModels/thermalShellModel/thermalShellModel.C b/src/regionFaModels/thermalShellModel/thermalShellModel.C
index 4ee3c206e35e6ebf57b0e305dc5aa6f12f6c23ad..41d242f2330786abfec302fc6fb54a993e7b4fc4 100644
--- a/src/regionFaModels/thermalShellModel/thermalShellModel.C
+++ b/src/regionFaModels/thermalShellModel/thermalShellModel.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -43,19 +43,6 @@ defineTypeNameAndDebug(thermalShellModel, 0);
 
 defineRunTimeSelectionTable(thermalShellModel, dictionary);
 
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-bool thermalShellModel::read(const dictionary& dict)
-{
-    if (regionFaModel::read(dict))
-    {
-        return true;
-    }
-
-    return false;
-}
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 thermalShellModel::thermalShellModel
@@ -95,24 +82,6 @@ void thermalShellModel::preEvolveRegion()
 {}
 
 
-const Foam::volScalarField& thermalShellModel::Tp() const
-{
-    return Tp_;
-}
-
-
-const Foam::areaScalarField& thermalShellModel::T() const
-{
-    return T_;
-}
-
-
-Foam::fa::options& thermalShellModel::faOptions()
-{
-     return faOptions_;
-}
-
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace regionModels
diff --git a/src/regionFaModels/thermalShellModel/thermalShellModel.H b/src/regionFaModels/thermalShellModel/thermalShellModel.H
index 2b2e9ec282980584ea472a5eff0af75185c7de38..5a6294e9f8f1eb64d427d68cebc3bf1807ff5e36 100644
--- a/src/regionFaModels/thermalShellModel/thermalShellModel.H
+++ b/src/regionFaModels/thermalShellModel/thermalShellModel.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,23 +34,23 @@ Usage
     \verbatim
     <patchName>
     {
-        // Mandatory/Optional (inherited) entries
+        // Mandatory/Optional entries
         ...
 
-        // Mandatory entries (unmodifiable)
+        // Mandatory entries
         T                     <Tname>;
 
-        // Optional entries (unmodifiable)
+        // Optional entries
         thermalShellModel     <thermalShellModelName>;
 
-        // Mandatory/Optional (derived) entries
+        // Derived entries
         ...
     }
     \endverbatim
 
     where the entries mean:
     \table
-      Property   | Description                       | Type  | Reqd | Dflt
+      Property   | Description                       | Type  | Reqd | Deflt
       T          | Name of operand temperature field | word  | yes  | -
       thermalShellModel | Name of thermal-shell model <!--
                         -->                      | word | no | thermalShell
@@ -90,12 +90,6 @@ class thermalShellModel
 :
     public regionFaModel
 {
-    // Private Member Functions
-
-        //- Initialize thermal Baffle
-        void init();
-
-
 protected:
 
     // Protected Data
@@ -113,12 +107,6 @@ protected:
         Foam::fa::options& faOptions_;
 
 
-    // Protected Member Functions
-
-        //- Read control parameters from dictionary
-        virtual bool read(const dictionary&);
-
-
 public:
 
     //- Runtime type information
@@ -177,13 +165,22 @@ public:
         // Access
 
             //- Return primary region temperature
-            const volScalarField& Tp() const;
+            const volScalarField& Tp() const noexcept
+            {
+                return Tp_;
+            }
 
             //- Return shell temperature
-            const areaScalarField& T() const;
+            const areaScalarField& T() const noexcept
+            {
+                return T_;
+            }
 
             //- Return faOptions
-            Foam::fa::options& faOptions();
+            Foam::fa::options& faOptions() noexcept
+            {
+                return faOptions_;
+            }
 
 
         // Evolution
diff --git a/src/regionFaModels/vibrationShellModel/vibrationShellModel.C b/src/regionFaModels/vibrationShellModel/vibrationShellModel.C
index ea309868a0de69e6d401c67ac5f17812733040fe..0be141cb911e558bdadf4f5178328ab13a40505a 100644
--- a/src/regionFaModels/vibrationShellModel/vibrationShellModel.C
+++ b/src/regionFaModels/vibrationShellModel/vibrationShellModel.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -43,20 +43,6 @@ defineTypeNameAndDebug(vibrationShellModel, 0);
 
 defineRunTimeSelectionTable(vibrationShellModel, dictionary);
 
-
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-bool vibrationShellModel::read(const dictionary& dict)
-{
-    if (regionFaModel::read(dict))
-    {
-        return true;
-    }
-
-    return false;
-}
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 vibrationShellModel::vibrationShellModel
@@ -110,36 +96,6 @@ void vibrationShellModel::preEvolveRegion()
 {}
 
 
-const Foam::volScalarField& vibrationShellModel::pa() const
-{
-    return pa_;
-}
-
-
-const Foam::areaScalarField& vibrationShellModel::w() const
-{
-    return w_;
-}
-
-
-const Foam::areaScalarField& vibrationShellModel::a() const
-{
-    return a_;
-}
-
-
-Foam::fa::options& vibrationShellModel::faOptions()
-{
-     return faOptions_;
-}
-
-
-const Foam::solidProperties& vibrationShellModel::solid() const
-{
-     return solid_;
-}
-
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace regionModels
diff --git a/src/regionFaModels/vibrationShellModel/vibrationShellModel.H b/src/regionFaModels/vibrationShellModel/vibrationShellModel.H
index 566d4fd2bd0382aa0396281b857f288876600fdd..a3eb697e3b6a2d04f1851d79e0bcfc23681e5d8d 100644
--- a/src/regionFaModels/vibrationShellModel/vibrationShellModel.H
+++ b/src/regionFaModels/vibrationShellModel/vibrationShellModel.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,10 +34,10 @@ Usage
     \verbatim
     <patchName>
     {
-        // Mandatory/Optional (inherited) entries
+        // Mandatory/Optional entries
         ...
 
-        // Mandatory entries (unmodifiable)
+        // Mandatory entries
         vibrationShellModel     <thermalShellModelName>;
         p                       <pName>;
 
@@ -53,7 +53,7 @@ Usage
 
     where the entries mean:
     \table
-      Property   | Description                            | Type  | Reqd | Dflt
+      Property   | Description                            | Type  | Reqd | Deflt
       vibrationShellModel | Name of vibration-shell model | word | yes | -
       p          | Name of the coupled field in the primary <!--
                  --> region                               | word | yes | -
@@ -94,15 +94,6 @@ class vibrationShellModel
 :
     public regionFaModel
 {
-    // Private Member Functions
-
-        //- No copy construct
-        vibrationShellModel(const vibrationShellModel&) = delete;
-
-        //- No copy assignment
-        void operator=(const vibrationShellModel&) = delete;
-
-
 protected:
 
     // Protected Data
@@ -126,12 +117,6 @@ protected:
         solidProperties solid_;
 
 
-    // Protected Member Functions
-
-        //- Read control parameters from dictionary
-        virtual bool read(const dictionary&);
-
-
 public:
 
     //- Runtime type information
@@ -164,6 +149,12 @@ public:
             const dictionary& dict
         );
 
+        //- No copy construct
+        vibrationShellModel(const vibrationShellModel&) = delete;
+
+        //- No copy assignment
+        void operator=(const vibrationShellModel&) = delete;
+
 
     // Selectors
 
@@ -184,19 +175,34 @@ public:
         // Access
 
             //- Return primary region pa
-            const volScalarField& pa() const;
+            const volScalarField& pa() const noexcept
+            {
+                return pa_;
+            }
 
             //- Return shell displacement
-            const areaScalarField& w() const;
+            const areaScalarField& w() const noexcept
+            {
+                return w_;
+            }
 
             //- Return shell acceleration
-            const areaScalarField& a() const;
+            const areaScalarField& a() const noexcept
+            {
+                return a_;
+            }
 
             //- Return faOptions
-            Foam::fa::options& faOptions();
+            Foam::fa::options& faOptions() noexcept
+            {
+                return faOptions_;
+            }
 
             //- Return solid properties
-            const solidProperties& solid() const;
+            const solidProperties& solid() const noexcept
+            {
+                return solid_;
+            }
 
 
         // Evolution
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/IDefault b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/IDefault
new file mode 100644
index 0000000000000000000000000000000000000000..865818c25b5e271c6a68778b0a15c6443242df4f
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/IDefault
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      IDefault;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [ 1 0 -3 0 0 0 0 ];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    ".*"
+    {
+        type            greyDiffusiveRadiation;
+        value           uniform 0;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/T b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/T
new file mode 100644
index 0000000000000000000000000000000000000000..4d90fcb6422e2952cafc32a07ef8147229d8a373
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/T
@@ -0,0 +1,61 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      T;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 0 0 1 0 0 0];
+
+internalField   uniform 300;
+
+boundaryField
+{
+    floor
+    {
+        type            fixedValue;
+        value           uniform 700;
+    }
+
+    ceiling
+    {
+        type                compressible::thermalShell;
+        active              true;
+        T                   T;
+
+        thermo
+        {
+            W               50;
+            rho             1000;
+            kappa           200;
+            Cp              600;
+            Hf              0;
+            emissivity      0;
+        }
+
+        region              ceilingShell;
+        thermalShellModel   thermalShell;
+
+        qr                  qr;
+        thickness           1e-3;
+
+        value               uniform 300;
+    }
+
+    "fixedWall.*"
+    {
+        type            zeroGradient;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/Ts_ceilingShell b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/Ts_ceilingShell
new file mode 100644
index 0000000000000000000000000000000000000000..1121de2b158cf27f8f670e96f1d323c20c015c35
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/Ts_ceilingShell
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaScalarField;
+    object      Ts_ceilingShell;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 0 0 1 0 0 0];
+
+internalField   uniform 300;
+
+boundaryField
+{
+    "side.*"
+    {
+        type            fixedValue;
+        value           uniform 300;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/U b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/U
new file mode 100644
index 0000000000000000000000000000000000000000..aee734968e4aba60736092cdcee284ee60e190b9
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/U
@@ -0,0 +1,30 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volVectorField;
+    object      U;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (0 0 0);
+
+boundaryField
+{
+    ".*"
+    {
+        type            noSlip;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/alphat b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/alphat
new file mode 100644
index 0000000000000000000000000000000000000000..2ce98a68bbb95f5874dc577fcf4f6828ca3007cc
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/alphat
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      alphat;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [1 -1 -1 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    ".*"
+    {
+        type            compressible::alphatWallFunction;
+        value           uniform 0;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/epsilon b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/epsilon
new file mode 100644
index 0000000000000000000000000000000000000000..11af4326d9ed96cb31dc512008880bd01a24a63c
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/epsilon
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      epsilon;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -3 0 0 0 0];
+
+internalField   uniform 0.01;
+
+boundaryField
+{
+    ".*"
+    {
+        type            epsilonWallFunction;
+        value           uniform 0.01;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/h_ceilingShell b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/h_ceilingShell
new file mode 100644
index 0000000000000000000000000000000000000000..ceb03c08ccb02af06bcab8fa531d22c6b9b317b9
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/h_ceilingShell
@@ -0,0 +1,30 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaScalarField;
+    object      h_ceilingShell;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 0 0 0 0 0];
+
+internalField   uniform 1e-3;
+
+boundaryField
+{
+    "side.*"
+    {
+        type            zeroGradient;
+    }
+}
+
+
+// ************************************************************************* //
\ No newline at end of file
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/k b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/k
new file mode 100644
index 0000000000000000000000000000000000000000..8ec430c9ef7615fa17359d5b5005fb39ff982c64
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/k
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      k;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -2 0 0 0 0];
+
+internalField   uniform 0.1;
+
+boundaryField
+{
+    ".*"
+    {
+        type            kqRWallFunction;
+        value           uniform 0.1;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/nut b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/nut
new file mode 100644
index 0000000000000000000000000000000000000000..a4697c5581e7aebe42fd6c0e7a976513f1173072
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/nut
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      nut;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -1 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    ".*"
+    {
+        type            nutkWallFunction;
+        value           uniform 0;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/p b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/p
new file mode 100644
index 0000000000000000000000000000000000000000..04fb47ad268e7ae84164670bf906ad65cd37fe61
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/p
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [1 -1 -2 0 0 0 0];
+
+internalField   uniform 1e5;
+
+boundaryField
+{
+    floor
+    {
+        type            calculated;
+        value           $internalField;
+    }
+
+    ceiling
+    {
+        type            calculated;
+        value           $internalField;
+    }
+
+    "fixedWall.*"
+    {
+        type            calculated;
+        value           $internalField;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/p_rgh b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/p_rgh
new file mode 100644
index 0000000000000000000000000000000000000000..2da53c3a75de2675fd058636a934875000891526
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/0/p_rgh
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p_rgh;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [1 -1 -2 0 0 0 0];
+
+internalField   uniform 1e5;
+
+boundaryField
+{
+    floor
+    {
+        type            fixedFluxPressure;
+        value           uniform 1e5;
+    }
+
+    ceiling
+    {
+        type            fixedFluxPressure;
+        value           uniform 1e5;
+    }
+
+    "fixedWall.*"
+    {
+        type            fixedFluxPressure;
+        value           uniform 1e5;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allclean b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allclean
new file mode 100755
index 0000000000000000000000000000000000000000..c77ab8663b8a33681ae1088f51e1db46859ff36c
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allclean
@@ -0,0 +1,10 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions      # Tutorial clean functions
+#------------------------------------------------------------------------------
+
+cleanCase
+
+cleanFaMesh
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allrun b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allrun
new file mode 100755
index 0000000000000000000000000000000000000000..85eceb74ad65c551e3cb1b0df9a2ffb6e52fe8c2
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allrun
@@ -0,0 +1,12 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runApplication makeFaMesh
+
+runApplication $(getApplication)
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allrun-parallel b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allrun-parallel
new file mode 100755
index 0000000000000000000000000000000000000000..b5e535e97ef46c543537b6a35923c031b853216f
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/Allrun-parallel
@@ -0,0 +1,16 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runParallel -s decompose redistributePar -decompose
+
+runParallel makeFaMesh
+
+runParallel $(getApplication)
+
+runParallel -s reconstruct redistributePar -reconstruct
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/boundaryRadiationProperties b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/boundaryRadiationProperties
new file mode 100644
index 0000000000000000000000000000000000000000..4c14f8798a9e27f6dba3ffcc5b2077badccc5a28
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/boundaryRadiationProperties
@@ -0,0 +1,26 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      boundaryRadiationProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+".*"
+{
+    type            lookup;
+    emissivity      0.7;
+    absorptivity    0.7;
+    transmissivity  0.0;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/g b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/g
new file mode 100644
index 0000000000000000000000000000000000000000..8972a1dd4ec0b8cc331ac471cc3b6a89ecd906c2
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/g
@@ -0,0 +1,21 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       uniformDimensionedVectorField;
+    object      g;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -2 0 0 0 0];
+value           (0 -9.81 0);
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/radiationProperties b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/radiationProperties
new file mode 100644
index 0000000000000000000000000000000000000000..13687ed929800c32a9b88973ed455bd887bb02c2
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/radiationProperties
@@ -0,0 +1,46 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      radiationProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+radiation       on;
+
+radiationModel  fvDOM;
+
+fvDOMCoeffs
+{
+    nPhi        3;
+    nTheta      5;
+    maxIter     10;
+    tolerance   1e-3;
+}
+
+// Number of flow iterations per radiation iteration
+solverFreq 10;
+
+absorptionEmissionModel constantAbsorptionEmission;
+
+constantAbsorptionEmissionCoeffs
+{
+   absorptivity    absorptivity    [ m^-1 ]         0.01;
+   emissivity      emissivity      [ m^-1 ]         0.01;
+   E               E               [ kg m^-1 s^-3 ] 0;
+}
+
+scatterModel    none;
+
+sootModel       none;
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/thermophysicalProperties b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/thermophysicalProperties
new file mode 100644
index 0000000000000000000000000000000000000000..63e9d72b13b2d27c20b1b82ad9683415366ff6c0
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/thermophysicalProperties
@@ -0,0 +1,49 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      thermophysicalProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+thermoType
+{
+    type            heRhoThermo;
+    mixture         pureMixture;
+    transport       const;
+    thermo          hConst;
+    equationOfState perfectGas;
+    specie          specie;
+    energy          sensibleEnthalpy;
+}
+
+pRef                100000;
+
+mixture
+{
+    specie
+    {
+        molWeight       28.9;
+    }
+    thermodynamics
+    {
+        Cp              1000;
+        Hf              0;
+    }
+    transport
+    {
+        mu              1.8e-05;
+        Pr              0.7;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/turbulenceProperties b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/turbulenceProperties
new file mode 100644
index 0000000000000000000000000000000000000000..0b743e50740fd8f4bbf69547adc6557efef30005
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/constant/turbulenceProperties
@@ -0,0 +1,25 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      turbulenceProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+simulationType      RAS;
+
+RAS
+{
+    RASModel        kEpsilon;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/blockMeshDict b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..5af843cae4ae096e0c51623ac3d830fe02df9c82
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/blockMeshDict
@@ -0,0 +1,98 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+scale   1;
+
+vertices
+(
+    (0 0 0)
+    (10 0 0)
+    (10 5 0)
+    (0 5 0)
+    (0 0 10)
+    (10 0 10)
+    (10 5 10)
+    (0 5 10)
+);
+
+blocks
+(
+    hex (0 1 2 3 4 5 6 7) (20 10 20) simpleGrading (1 1 1)
+);
+
+edges
+(
+);
+
+boundary
+(
+    floor
+    {
+        type wall;
+        faces
+        (
+            (1 5 4 0)
+        );
+    }
+    ceiling
+    {
+        type wall;
+        faces
+        (
+            (3 7 6 2)
+        );
+    }
+    fixedWall1
+    {
+        type wall;
+        faces
+        (
+            (0 4 7 3)
+        );
+    }
+    fixedWall2
+    {
+        type wall;
+        faces
+        (
+
+            (2 6 5 1)
+        );
+    }
+    fixedWall3
+    {
+        type wall;
+        faces
+        (
+            (0 3 2 1)
+        );
+    }
+    fixedWall4
+    {
+        type wall;
+        faces
+        (
+            (4 5 6 7)
+        );
+    }
+);
+
+mergePatchPairs
+(
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/controlDict b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/controlDict
new file mode 100644
index 0000000000000000000000000000000000000000..1c981ea3737e66c3023557c4ddc99fb3f9ad5ccb
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/controlDict
@@ -0,0 +1,52 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application     buoyantPimpleFoam;
+
+startFrom       startTime;
+
+startTime       0;
+
+stopAt          endTime;
+
+endTime         400;
+
+deltaT          1;
+
+writeControl    timeStep;
+
+writeInterval   20;
+
+purgeWrite      0;
+
+writeFormat     ascii;
+
+writePrecision  6;
+
+writeCompression off;
+
+timeFormat      general;
+
+timePrecision   6;
+
+runTimeModifiable true;
+
+adjustTimeStep  no;
+
+maxCo           0.5;
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/decomposeParDict b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/decomposeParDict
new file mode 100644
index 0000000000000000000000000000000000000000..d9a07c6d91aa14cfe7581fe0e855d04c2b7b91ad
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/decomposeParDict
@@ -0,0 +1,27 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      decomposeParDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+numberOfSubdomains 2;
+
+method          hierarchical;
+
+coeffs
+{
+    n           (2 1 1);
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faMeshDefinition b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faMeshDefinition
new file mode 100644
index 0000000000000000000000000000000000000000..46166519553c139cbd4dff1f87d4ee5b5f76d366
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faMeshDefinition
@@ -0,0 +1,51 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faMeshDefinition;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+polyMeshPatches             (ceiling);
+
+boundary
+{
+    side1
+    {
+        type                patch;
+        ownerPolyPatch      ceiling;
+        neighbourPolyPatch  fixedWall1;
+    }
+
+    side2
+    {
+        type                patch;
+        ownerPolyPatch      ceiling;
+        neighbourPolyPatch  fixedWall2;
+    }
+
+    side3
+    {
+        type                patch;
+        ownerPolyPatch      ceiling;
+        neighbourPolyPatch  fixedWall3;
+    }
+
+    side4
+    {
+        type                patch;
+        ownerPolyPatch      ceiling;
+        neighbourPolyPatch  fixedWall4;
+    }
+}
+
+
+// ************************************************************************** //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faOptions b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faOptions
new file mode 100644
index 0000000000000000000000000000000000000000..ac775459978f2f82967f0243554cfe7b7d91fbaa
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faOptions
@@ -0,0 +1,50 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faOptions;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+topSide
+{
+    type                                externalHeatFluxSource;
+    active                              true;
+    region                              ceilingShell;
+    T                                   Ts_ceilingShell;
+    selectionMode                       all;
+    mode                                coefficient;
+    Ta                                  constant 290;
+    h                                   10;
+
+}
+
+// contactHeatFluxSource is the coupling of the shell-2D and the 3D mesh
+contactHeatFlux
+{
+    type                                contactHeatFluxSource;
+    active                              true;
+    T                                   Ts_ceilingShell;
+    region                              ceilingShell;
+
+    Tprimary                            T;
+
+    kappaMethod                         fluidThermo;
+    kappa                               none;
+
+    thicknessLayers                     (0.001);
+    kappaLayers                         (0.02);
+
+    selectionMode                       all;
+}
+
+
+//************************************************************************** //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faSchemes b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..ce8870ba9e6087c49b8879593f2c25c419ade101
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faSchemes
@@ -0,0 +1,51 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         none;
+    grad(jouleHeatingSource:V_ceilingShell) Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+}
+
+laplacianSchemes
+{
+    default         none;
+    laplacian((h_ceilingShell*jouleHeatingSource:sigma_ceilingShell),jouleHeatingSource:V_ceilingShell) Gauss linear corrected;
+    laplacian((kappas*h_ceilingShell),Ts_ceilingShell) Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+}
+
+snGradSchemes
+{
+    default         none;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faSolution b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faSolution
new file mode 100644
index 0000000000000000000000000000000000000000..c833a473a56512095631f5ccdb72fd02af34e781
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/faSolution
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    Ts_ceilingShell
+    {
+        solver          PBiCGStab;
+        preconditioner  DIC;
+        tolerance       1e-07;
+        relTol          0.01;
+    }
+
+    jouleHeatingSource:V_ceilingShell
+    {
+        solver          PBiCGStab;
+        preconditioner  DIC;
+        tolerance       1e-07;
+        relTol          0.01;
+    }
+}
+
+nNonOrthCorr    1;
+
+relaxationFactors
+{
+    T           1;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/fvSchemes b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/fvSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..4afb4df7f65667ad6b22a12c105bba9a13304ee7
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/fvSchemes
@@ -0,0 +1,59 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+    div(phi,U)      Gauss upwind;
+    div(phi,h)      Gauss upwind;
+    div(phi,e)      Gauss upwind;
+    div(phi,k)      Gauss upwind;
+    div(phi,epsilon) Gauss upwind;
+    div(phi,R)      Gauss upwind;
+    div(phi,K)      Gauss linear;
+    div(phi,Ekp)    Gauss linear;
+    div(R)          Gauss linear;
+    div(Ji,Ii_h)    Gauss upwind;
+    div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
+}
+
+laplacianSchemes
+{
+    default         Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/fvSolution b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/fvSolution
new file mode 100644
index 0000000000000000000000000000000000000000..1f5ec428cf4b162334eb4c8ac2fbe9f81bfdc6cd
--- /dev/null
+++ b/tutorials/heatTransfer/buoyantPimpleFoam/hotRoomWithThermalShell/system/fvSolution
@@ -0,0 +1,82 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    "rho.*"
+    {
+        solver          PCG;
+        preconditioner  DIC;
+        tolerance       0;
+        relTol          0;
+    }
+
+    p_rgh
+    {
+        solver          PCG;
+        preconditioner  DIC;
+        tolerance       1e-8;
+        relTol          0.01;
+    }
+
+    p_rghFinal
+    {
+        $p_rgh;
+        relTol          0;
+    }
+
+    "(U|h|e|k|epsilon|R)"
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-6;
+        relTol          0.1;
+    }
+
+    "(U|h|e|k|epsilon|R)Final"
+    {
+        $U;
+        relTol          0;
+    }
+
+    Ii
+    {
+        solver              GAMG;
+        tolerance           1e-4;
+        relTol              0;
+        smoother            symGaussSeidel;
+        cacheAgglomeration  true;
+        nCellsInCoarsestLevel   10;
+        agglomerator        faceAreaPair;
+        mergeLevels         1;
+        maxIter             5;
+        nPreSweeps          0;
+        nPostSweeps         1;
+    }
+}
+
+PIMPLE
+{
+    momentumPredictor yes;
+    nOuterCorrectors 1;
+    nCorrectors     2;
+    nNonOrthogonalCorrectors 0;
+    pRefCell        0;
+    pRefValue       1e5;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/U b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/U
new file mode 100644
index 0000000000000000000000000000000000000000..a40b782ffe7c02258a403134f9f56346c91cafff
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/U
@@ -0,0 +1,95 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volVectorField;
+    object      U;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+Uinlet          (1 0 0);
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (0 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform $Uinlet;
+    }
+
+    "(outlet|side|top)"
+    {
+        type            zeroGradient;
+        value           uniform (0 0 0);
+    }
+
+    film
+    {
+        type            velocityFilmShell;
+        active          true;
+        U               U;
+        pRef            1e5;
+        T0              300;
+
+        thermo
+        {
+            H2O;
+        }
+
+        turbulence          laminar;
+
+        laminarCoeffs
+        {
+            friction        ManningStrickler;
+            n               0.1; // Manning number
+            Cf              0.9; // Gas friction
+        }
+
+        injectionModels ();
+
+        forces (perturbedTemperatureDependentContactAngle);
+
+        perturbedTemperatureDependentContactAngleCoeffs
+        {
+            Ccf     0.085;
+            theta   constant 45;
+            distribution
+            {
+                type            normal;
+                normalDistribution
+                {
+                    minValue        50;
+                    maxValue        100;
+                    expectation     75;
+                    variance        100;
+                }
+            }
+        }
+
+        region              film;
+        liquidFilmModel     kinematicThinFilm;
+        value               uniform (0 0 0);
+    }
+
+    cylinder
+    {
+        type            fixedValue;
+        value           uniform (0 0 0);
+    }
+
+    #includeEtc "caseDicts/setConstraintTypes"
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/Uf_film b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/Uf_film
new file mode 100644
index 0000000000000000000000000000000000000000..f8dfa4a37e9ea42ac466a6f737e8f1ebddc5ed15
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/Uf_film
@@ -0,0 +1,53 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaVectorField;
+    object      Uf_film;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (0 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            zeroGradient;
+    }
+
+    outlet
+    {
+        type            zeroGradient;
+    }
+
+    side
+    {
+        type            fixedValue;
+        value           $internalField;
+    }
+
+    symmetry
+    {
+        type            fixedValue;
+        value           $internalField;
+    }
+
+    cylinder
+    {
+        type            fixedValue;
+        value           $internalField;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/hf_film b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/hf_film
new file mode 100644
index 0000000000000000000000000000000000000000..becb44a6d9a7a63c30c2ad2c2824f1ff3956ef05
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/hf_film
@@ -0,0 +1,54 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaScalarField;
+    object      hf_film;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 0 0 0 0 0];
+
+internalField   uniform 1e-5;
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform 0.000141;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      $internalField;
+        value           $internalField;
+        phi             phi2s_film;
+    }
+
+    side
+    {
+        type            zeroGradient;
+    }
+
+    symmetry
+    {
+        type            zeroGradient;
+    }
+
+    cylinder
+    {
+        type            zeroGradient;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/p b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/p
new file mode 100644
index 0000000000000000000000000000000000000000..92c2d6259d3af0c566c35c95fe2b50a3262083b8
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/0/p
@@ -0,0 +1,48 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -2 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            zeroGradient;
+    }
+
+    "(outlet|side|top)"
+    {
+        type            fixedValue;
+        value           uniform 0;
+    }
+
+    film
+    {
+        type            zeroGradient;
+    }
+
+    cylinder
+    {
+        type            zeroGradient;
+    }
+
+    #includeEtc "caseDicts/setConstraintTypes"
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allclean b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allclean
new file mode 100755
index 0000000000000000000000000000000000000000..c77ab8663b8a33681ae1088f51e1db46859ff36c
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allclean
@@ -0,0 +1,10 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions      # Tutorial clean functions
+#------------------------------------------------------------------------------
+
+cleanCase
+
+cleanFaMesh
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allrun b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allrun
new file mode 100755
index 0000000000000000000000000000000000000000..85eceb74ad65c551e3cb1b0df9a2ffb6e52fe8c2
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allrun
@@ -0,0 +1,12 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runApplication makeFaMesh
+
+runApplication $(getApplication)
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allrun-parallel b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allrun-parallel
new file mode 100755
index 0000000000000000000000000000000000000000..3c324be8baeb802e5213a2deadc1b619567f6660
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/Allrun-parallel
@@ -0,0 +1,16 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runApplication decomposePar
+
+runParallel makeFaMesh
+
+runParallel $(getApplication)
+
+runApplication reconstructPar
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/g b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/g
new file mode 100644
index 0000000000000000000000000000000000000000..6987bdc182754dc09792ef734c70f748bea7f1b1
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/g
@@ -0,0 +1,21 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       uniformDimensionedVectorField;
+    object      g;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -2 0 0 0 0];
+value           (4.905 0 -8.4957);
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/transportProperties b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/transportProperties
new file mode 100644
index 0000000000000000000000000000000000000000..cfc1f72c626be3507511ffc239b444064571821a
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/transportProperties
@@ -0,0 +1,22 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      transportProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+transportModel  Newtonian;
+
+nu              1e-5;
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/turbulenceProperties b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/turbulenceProperties
new file mode 100644
index 0000000000000000000000000000000000000000..60227a572544dd792a1504554feeea20a88a5ffa
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/constant/turbulenceProperties
@@ -0,0 +1,20 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      turbulenceProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+simulationType laminar;
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/blockMeshDict b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..232fdc2f600208fb42f0165563265d34fd60621c
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/blockMeshDict
@@ -0,0 +1,162 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+scale   0.016;
+
+vertices
+(
+    (0.5 0 0)
+    (1 0 0)
+    (2 0 0)
+    (2 0.707107 0)
+    (0.707107 0.707107 0)
+    (0.353553 0.353553 0)
+    (2 2 0)
+    (0.707107 2 0)
+    (0 2 0)
+    (0 1 0)
+    (0 0.5 0)
+    (-0.5 0 0)
+    (-1 0 0)
+    (-2 0 0)
+    (-2 0.707107 0)
+    (-0.707107 0.707107 0)
+    (-0.353553 0.353553 0)
+    (-2 2 0)
+    (-0.707107 2 0)
+
+    (0.5 0 0.5)
+    (1 0 0.5)
+    (2 0 0.5)
+    (2 0.707107 0.5)
+    (0.707107 0.707107 0.5)
+    (0.353553 0.353553 0.5)
+    (2 2 0.5)
+    (0.707107 2 0.5)
+    (0 2 0.5)
+    (0 1 0.5)
+    (0 0.5 0.5)
+    (-0.5 0 0.5)
+    (-1 0 0.5)
+    (-2 0 0.5)
+    (-2 0.707107 0.5)
+    (-0.707107 0.707107 0.5)
+    (-0.353553 0.353553 0.5)
+    (-2 2 0.5)
+    (-0.707107 2 0.5)
+);
+
+blocks
+(
+    hex (5 4 9 10 24 23 28 29) (10 10 1) simpleGrading (1 1 1)
+    hex (0 1 4 5 19 20 23 24) (10 10 1) simpleGrading (1 1 1)
+    hex (1 2 3 4 20 21 22 23) (20 10 1) simpleGrading (1 1 1)
+    hex (4 3 6 7 23 22 25 26) (20 20 1) simpleGrading (1 1 1)
+    hex (9 4 7 8 28 23 26 27) (10 20 1) simpleGrading (1 1 1)
+    hex (15 16 10 9 34 35 29 28) (10 10 1) simpleGrading (1 1 1)
+    hex (12 11 16 15 31 30 35 34) (10 10 1) simpleGrading (1 1 1)
+    hex (13 12 15 14 32 31 34 33) (20 10 1) simpleGrading (1 1 1)
+    hex (14 15 18 17 33 34 37 36) (20 20 1) simpleGrading (1 1 1)
+    hex (15 9 8 18 34 28 27 37) (10 20 1) simpleGrading (1 1 1)
+);
+
+edges
+(
+    arc 0 5 (0.469846 0.17101 0)
+    arc 5 10 (0.17101 0.469846 0)
+    arc 1 4 (0.939693 0.34202 0)
+    arc 4 9 (0.34202 0.939693 0)
+    arc 19 24 (0.469846 0.17101 0.5)
+    arc 24 29 (0.17101 0.469846 0.5)
+    arc 20 23 (0.939693 0.34202 0.5)
+    arc 23 28 (0.34202 0.939693 0.5)
+    arc 11 16 (-0.469846 0.17101 0)
+    arc 16 10 (-0.17101 0.469846 0)
+    arc 12 15 (-0.939693 0.34202 0)
+    arc 15 9 (-0.34202 0.939693 0)
+    arc 30 35 (-0.469846 0.17101 0.5)
+    arc 35 29 (-0.17101 0.469846 0.5)
+    arc 31 34 (-0.939693 0.34202 0.5)
+    arc 34 28 (-0.34202 0.939693 0.5)
+);
+
+patches
+(
+    symmetry bottom
+    (
+        (0 1 20 19)
+        (1 2 21 20)
+        (12 11 30 31)
+        (13 12 31 32)
+    )
+    patch outlet
+    (
+        (2 3 22 21)
+        (3 6 25 22)
+    )
+    patch side
+    (
+        (7 8 27 26)
+        (6 7 26 25)
+        (8 18 37 27)
+        (18 17 36 37)
+    )
+    patch inlet
+    (
+        (14 13 32 33)
+        (17 14 33 36)
+    )
+    wall cylinder
+    (
+        (10 5 24 29)
+        (5 0 19 24)
+        (16 10 29 35)
+        (11 16 35 30)
+    )
+    patch film
+    (
+        (5 4 1 0)
+        (4 3 2 1)
+        (7 6 3 4)
+        (8 7 4 9)
+        (9 4 5 10)
+        (18 8 9 15)
+        (15 9 10 16)
+        (17 18 15 14)
+        (14 15 12 13)
+        (15 16 11 12)
+    )
+    patch top
+    (
+        (19 20 23 24)
+        (20 21 22 23)
+        (23 22 25 26)
+        (29 24 23 28)
+        (28 23 26 27)
+        (35 29 28 34)
+        (34 28 27 37)
+        (32 31 34 33)
+        (33 34 37 36)
+        (31 30 35 34)
+    )
+);
+
+mergePatchPairs
+(
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/controlDict b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/controlDict
new file mode 100644
index 0000000000000000000000000000000000000000..43b16a99b8ca9c09cdd909e603c1fc4371879766
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/controlDict
@@ -0,0 +1,54 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application     pimpleFoam;
+
+startFrom       startTime;
+
+startTime       0;
+
+stopAt          endTime;
+
+endTime         2.5;
+
+deltaT          0.0002;
+
+writeControl    timeStep;
+
+writeInterval   300;
+
+purgeWrite      0;
+
+writeFormat     ascii;
+
+writePrecision  6;
+
+writeCompression off;
+
+timeFormat      general;
+
+timePrecision   6;
+
+runTimeModifiable yes;
+
+adjustTimeStep      no;
+
+maxCo               1;
+
+maxDeltaT           0.1;
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/decomposeParDict b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/decomposeParDict
new file mode 100644
index 0000000000000000000000000000000000000000..0e5089d2b5bc9cf2ef68284584fdc3ac183e4d63
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/decomposeParDict
@@ -0,0 +1,27 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      decomposeParDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+numberOfSubdomains 4;
+
+method      simple;
+
+coeffs
+{
+    n       ( 2 2 1 );
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faMeshDefinition b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faMeshDefinition
new file mode 100644
index 0000000000000000000000000000000000000000..2138897bd01ef78e4347b20c9115495283da2ded
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faMeshDefinition
@@ -0,0 +1,58 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faMeshDefinition;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+polyMeshPatches  ( film );
+
+boundary
+{
+    inlet
+    {
+        type                patch;
+        ownerPolyPatch      film;
+        neighbourPolyPatch  inlet;
+    }
+
+    outlet
+    {
+        type                patch;
+        ownerPolyPatch      film;
+        neighbourPolyPatch  outlet;
+    }
+
+    side
+    {
+        type                patch;
+        ownerPolyPatch      film;
+        neighbourPolyPatch  side;
+    }
+
+    symmetry
+    {
+        type                patch;
+        ownerPolyPatch      film;
+        neighbourPolyPatch  bottom;
+    }
+
+    cylinder
+    {
+        type                patch;
+        ownerPolyPatch      film;
+        neighbourPolyPatch  cylinder;
+    }
+}
+
+
+// ************************************************************************** //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faSchemes b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..5a134f206215d755916dbb948ee09b4617cbd952
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faSchemes
@@ -0,0 +1,56 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+    div(phif_film,hf_film)         Gauss Gamma 0.5;
+    div(phi2s_film,Uf_film)        Gauss linearUpwind;
+}
+
+laplacianSchemes
+{
+    default         none;
+    laplacian(hf_film) Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+fluxRequired
+{
+    hf_film         true;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faSolution b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faSolution
new file mode 100644
index 0000000000000000000000000000000000000000..d08d1911b01f673ca1d79591e52315511470a5ed
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/faSolution
@@ -0,0 +1,52 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    Uf_film
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-08;
+        relTol          0.0;
+    }
+
+    hf_film
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-08;
+        relTol          0.0;
+    }
+}
+
+PIMPLE
+{
+    momentumPredictor true;
+    nOuterCorr        4;
+    nCorr             1;
+    nNonOrthCorr      0;
+    nFilmCorr         1;
+}
+
+relaxationFactors
+{
+    hf_Film    0.9;
+    Uf_Film    0.9;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/fvSchemes b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/fvSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..f2a58e1724c9b3c003590bcbdc3d7708d46400d9
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/fvSchemes
@@ -0,0 +1,53 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+    grad(p)         Gauss linear;
+    grad(U)         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+    div(phi,U)      Gauss linearUpwind grad(U);
+    div((nuEff*dev2(T(grad(U))))) Gauss linear;
+}
+
+laplacianSchemes
+{
+    default         Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+    interpolate(HbyA) linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/fvSolution b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/fvSolution
new file mode 100644
index 0000000000000000000000000000000000000000..bbc9377e10dcb6ab0be138ad4cbb862cb59da587
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/inclinedPlaneFilm/system/fvSolution
@@ -0,0 +1,86 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    "pcorr.*"
+    {
+        solver          GAMG;
+        smoother        GaussSeidel;
+        cacheAgglomeration no;
+        tolerance        0.02;
+        relTol           0;
+    }
+
+    p
+    {
+        $pcorr;
+        tolerance       1e-06;
+        relTol          0.01;
+    }
+
+    pFinal
+    {
+        $p;
+        tolerance       1e-06;
+        relTol          0;
+    }
+
+    U
+    {
+        solver          smoothSolver;
+        smoother        GaussSeidel;
+        tolerance       1e-05;
+        relTol          0.01;
+    }
+
+    UFinal
+    {
+        $U;
+        tolerance       1e-06;
+        relTol          0;
+    }
+
+    cellMotionUx
+    {
+        solver          PCG;
+        preconditioner  DIC;
+        tolerance       1e-08;
+        relTol          0;
+    }
+}
+
+PIMPLE
+{
+    correctPhi          no;
+    nOuterCorrectors    1;
+    nCorrectors         1;
+    nNonOrthogonalCorrectors 0;
+
+    pRefCell            0;
+    pRefValue           0;
+}
+
+relaxationFactors
+{
+    equations
+    {
+        "U.*"           1;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/T b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/T
new file mode 100644
index 0000000000000000000000000000000000000000..a924730ba66c301b963d8abca8608cba916d6471
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/T
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v1912                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      T;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 0 0 1 0 0 0];
+
+internalField   uniform 300;
+
+boundaryField
+{
+    ".*"
+    {
+        type            fixedValue;
+        value           uniform 300;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/U b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/U
new file mode 100644
index 0000000000000000000000000000000000000000..fc2264f16cbde48e2f1564f3cb7910cc2798bbba
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/U
@@ -0,0 +1,86 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volVectorField;
+    object      U;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (3 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform (3 0 0);
+        inletValue      uniform (0 0 0);
+    }
+
+    outlet
+    {
+        type            pressureInletOutletVelocity;
+        inletValue      uniform (0 0 0);
+        value           uniform (0 0 0);
+    }
+
+    "(top|sides)"
+    {
+        type            noSlip;
+    }
+
+    base
+    {
+        type            velocityFilmShell;
+        active          true;
+        infoOutput      true;
+        U               U;
+        pRef            1e5; // Reference pressure for thermo
+        T0              300; // Reference temperature for thermo
+
+        thermo
+        {
+            H2O;
+        }
+
+        turbulence          laminar;
+
+        laminarCoeffs
+        {
+            friction        ManningStrickler; // Wall friction model
+            n               0.005;  // Manning number
+            Cf              0;      // Gas friction
+        }
+
+        injectionModels
+        (
+            curvatureSeparation
+        );
+
+        forces ();
+
+        curvatureSeparationCoeffs
+        {
+            definedPatchRadii  0;
+            minInvR1           0;
+            deltaByR1Min       0; // h*invRi = 0.004*10
+        }
+
+        region              film;
+        liquidFilmModel     kinematicThinFilm;
+        value               uniform (0 0 0);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/Uf_film b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/Uf_film
new file mode 100644
index 0000000000000000000000000000000000000000..dbd1b2b06cc574a9ec1781099a6ae7353febecd4
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/Uf_film
@@ -0,0 +1,41 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaVectorField;
+    object      Uf_film;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (0 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform (5 0 0);
+    }
+
+    outlet
+    {
+        type            zeroGradient;
+    }
+
+    sides
+    {
+        type            slip;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/epsilon b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/epsilon
new file mode 100644
index 0000000000000000000000000000000000000000..36db91fd7764607acc258ef64e7f1e47828ad311
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/epsilon
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      epsilon;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -3 0 0 0 0];
+
+internalField   uniform 200;
+
+boundaryField
+{
+    inlet
+    {
+        type            turbulentIntensityKineticEnergyInlet;
+        intensity       0.05;
+        value           uniform 1;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      uniform 200;
+        value           uniform 200;
+    }
+
+    ".*"
+    {
+        type            epsilonWallFunction;
+        value           uniform 200;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/hf_film b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/hf_film
new file mode 100644
index 0000000000000000000000000000000000000000..589bd0127b492c0c5575b7f4cb8e9ea15d8997c9
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/hf_film
@@ -0,0 +1,41 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaScalarField;
+    object      hf_film;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions          [0 1 0 0 0 0 0];
+
+internalField       uniform 0.0001;
+
+boundaryField
+{
+    inlet
+    {
+        type        fixedValue;
+        value       uniform 0.001;
+    }
+
+    outlet
+    {
+        type        zeroGradient;
+    }
+
+    sides
+    {
+        type        zeroGradient;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/k b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/k
new file mode 100644
index 0000000000000000000000000000000000000000..366fa088423d078e94f0eefa385484de726fa155
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/k
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      k;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -2 0 0 0 0];
+
+internalField   uniform 1;
+
+boundaryField
+{
+    inlet
+    {
+        type            turbulentIntensityKineticEnergyInlet;
+        intensity       0.05;
+        value           uniform 1;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      uniform 1;
+        value           uniform 1;
+    }
+
+    ".*"
+    {
+        type            kqRWallFunction;
+        value           uniform 1;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/nut b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/nut
new file mode 100644
index 0000000000000000000000000000000000000000..d5b8a2c36edf7ae011ee58f16ece17a37ad1293c
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/nut
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      nut;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -1 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            calculated;
+        value           uniform 0;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      uniform 0;
+        value           uniform 0;
+    }
+
+    ".*"
+    {
+        type            nutkWallFunction;
+        value           uniform 0;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/p b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/p
new file mode 100644
index 0000000000000000000000000000000000000000..8be5a6afc95c2eb1f81228f6e1b1674ea7d13980
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/0/p
@@ -0,0 +1,46 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -2 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            zeroGradient;
+    }
+
+    outlet
+    {
+        type            totalPressure;
+        p0              uniform 0;
+    }
+
+    "(top|sides)"
+    {
+        type            zeroGradient;
+    }
+
+    base
+    {
+        type            zeroGradient;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/Allclean b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/Allclean
new file mode 100755
index 0000000000000000000000000000000000000000..c77ab8663b8a33681ae1088f51e1db46859ff36c
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/Allclean
@@ -0,0 +1,10 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions      # Tutorial clean functions
+#------------------------------------------------------------------------------
+
+cleanCase
+
+cleanFaMesh
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/Allrun b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/Allrun
new file mode 100755
index 0000000000000000000000000000000000000000..e02b384f9fee43c814fff16f287dce66bf30fc35
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/Allrun
@@ -0,0 +1,16 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runApplication makeFaMesh
+
+runApplication decomposePar
+
+runParallel $(getApplication)
+
+runApplication reconstructPar
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/g b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/g
new file mode 100644
index 0000000000000000000000000000000000000000..e340b6cb927656dd88b37458aa6442f850a63e33
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/g
@@ -0,0 +1,21 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       uniformDimensionedVectorField;
+    object      g;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -2 0 0 0 0];
+value           (0 0 -9.8);
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/kinematicCloudProperties b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/kinematicCloudProperties
new file mode 100644
index 0000000000000000000000000000000000000000..2970079fe42c56765ae707dee416669957306939
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/kinematicCloudProperties
@@ -0,0 +1,126 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v1912                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      kinematicCloudProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solution
+{
+    active          true;
+    coupled         yes;
+    transient       yes;
+    cellValueSourceCorrection no;
+    maxCo           0.3;
+
+    sourceTerms
+    {
+        schemes
+        {
+            U               semiImplicit 1;
+        }
+    }
+
+    interpolationSchemes
+    {
+        rho             cell;
+        U               cellPoint;
+        muc             cell;
+        p               cell;
+    }
+
+    integrationSchemes
+    {
+        U               Euler;
+    }
+}
+
+constantProperties
+{
+    rho0            1000;
+}
+
+subModels
+{
+    particleForces
+    {
+        sphereDrag;
+        gravity;
+    }
+
+    injectionModels
+    {
+        model1
+        {
+            type            coneInjection;
+            SOI             10.00;
+            duration        13.000;
+            positionAxis
+            (
+                ((-0.5 0.1 0.7) (1 0 -1))
+                ((-0.5 0.2 0.7) (1 0 -1))
+                ((-0.5 0.3 0.7) (1 0 -1))
+                ((-0.5 0.4 0.7) (1 0 -1))
+                ((-0.5 0.5 0.7) (1 0 -1))
+                ((-0.5 0.6 0.7) (1 0 -1))
+                ((-0.5 0.7 0.7) (1 0 -1))
+                ((-0.5 0.8 0.7) (1 0 -1))
+                ((-0.5 0.9 0.7) (1 0 -1))
+            );
+
+            massTotal       5;
+            parcelsPerInjector 20000;
+            parcelBasisType mass;
+            flowRateProfile constant 1;
+            Umag            constant 1.0;
+            thetaInner      constant 0;
+            thetaOuter      constant 45;
+
+            sizeDistribution
+            {
+                type         RosinRammler;
+                RosinRammlerDistribution
+                {
+                    minValue        5e-04;
+                    maxValue        0.0012;
+                    d               7.5e-05;
+                    n               0.5;
+                }
+            }
+        }
+    }
+
+    dispersionModel none;
+
+    patchInteractionModel standardWallInteraction;
+
+    stochasticCollisionModel none;
+
+    surfaceFilmModel kinematicSurfaceFilm;
+
+    standardWallInteractionCoeffs
+    {
+        type            rebound;
+    }
+
+    kinematicSurfaceFilmCoeffs
+    {
+        interactionType absorb;
+    }
+}
+
+
+cloudFunctions
+{}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/transportProperties b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/transportProperties
new file mode 100644
index 0000000000000000000000000000000000000000..2f4edd39aa5ce295e6259bebbd4efce25660c55d
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/transportProperties
@@ -0,0 +1,24 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      transportProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+transportModel  Newtonian;
+
+nu              1e-05;
+
+rhoInf          1.2;
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/turbulenceProperties b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/turbulenceProperties
new file mode 100644
index 0000000000000000000000000000000000000000..0b743e50740fd8f4bbf69547adc6557efef30005
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/constant/turbulenceProperties
@@ -0,0 +1,25 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      turbulenceProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+simulationType      RAS;
+
+RAS
+{
+    RASModel        kEpsilon;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/blockMeshDict b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..2fcb06b7ecb1c234e55aba1c931136c56a6c546b
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/blockMeshDict
@@ -0,0 +1,104 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+scale   1;
+
+vertices
+(
+    (0 0 0) //0
+    (5 0 0) //1
+    (5 1 0) //2
+    (0 1 0) //3
+    (-1 0 0.5) //4
+    (-1 1 0.5) //5
+    (-1 1 1) //6
+    (-1 0 1) //7
+    (5 1 1) //8
+    (0 1 0.5) //9
+    (5 0 0.5) //10
+    (5 1 0.5) //11
+    (0 0 1) //12
+    (0 1 1) //13
+    (0 0 0.5) //14
+    (5 0 1) //15
+);
+
+blocks
+(
+    hex (14 10 11 9 12 15 8 13 ) (100 20 10) simpleGrading (1 1 1)
+    hex (0 1 2 3 14 10 11 9) (100 20 10) simpleGrading (1 1 1)
+    hex (4 14 9 5 7 12 13 6) (20 20 10) simpleGrading (1 1 1)
+);
+
+edges
+(
+);
+
+boundary
+(
+    base
+    {
+        type wall;
+        faces
+        (
+            (0 1 2 3)
+            (0 3 9 14)
+            (4 14 9 5)
+        );
+    }
+    outlet
+    {
+        type patch;
+        faces
+        (
+            (1 2 11 10)
+            (15 10 11 8)
+        );
+    }
+    inlet
+    {
+        type patch;
+        faces
+        (
+            (4 5 6 7)
+        );
+    }
+    sides
+    {
+        type wall;
+        faces
+        (
+            (0 1 10 14)
+            (14 10 15 12)
+            (4 14 12 7)
+            (3 2 11 9)
+            (9 11 8 13)
+            (5 9 13 6)
+        );
+    }
+    top
+    {
+        type wall;
+        faces
+        (
+            (12 15 8 13)
+            (7 12 13 6)
+        );
+    }
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/controlDict b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/controlDict
new file mode 100644
index 0000000000000000000000000000000000000000..0eeeaacb9be98aa892f2cd36d5b83996aa1e61c5
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/controlDict
@@ -0,0 +1,56 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application     kinematicParcelFoam;
+
+startFrom       latestTime;
+
+startTime       0;
+
+stopAt          endTime;
+
+endTime         13;
+
+deltaT          0.005;
+
+writeControl    adjustable;
+
+writeInterval   0.25;
+
+purgeWrite      0;
+
+writeFormat     binary;
+
+writePrecision  6;
+
+writeCompression off;
+
+timeFormat      general;
+
+timePrecision   6;
+
+runTimeModifiable yes;
+
+adjustTimeStep  yes;
+
+maxCo           0.9;
+
+regionFaMaxCo   1;
+
+maxDeltaT       0.1;
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/decomposeParDict b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/decomposeParDict
new file mode 100644
index 0000000000000000000000000000000000000000..586c037a8a6b5512ebc71e085f2a78b74f5573a9
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/decomposeParDict
@@ -0,0 +1,27 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      decomposeParDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+numberOfSubdomains 4;
+
+method          hierarchical;
+
+coeffs
+{
+    n           ( 2 2 1 );
+}
+
+
+// ************************************************************************* //
\ No newline at end of file
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faMeshDefinition b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faMeshDefinition
new file mode 100644
index 0000000000000000000000000000000000000000..539af32b2968b0de2ade391cd26f485495af5d32
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faMeshDefinition
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faMeshDefinition;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+polyMeshPatches   ( base );
+
+boundary
+{
+    inlet
+    {
+        type                patch;
+        ownerPolyPatch      base;
+        neighbourPolyPatch  inlet;
+    }
+
+    outlet
+    {
+        type                patch;
+        ownerPolyPatch      base;
+        neighbourPolyPatch  outlet;
+    }
+
+    sides
+    {
+        type                patch;
+        ownerPolyPatch      base;
+        neighbourPolyPatch  sides;
+    }
+}
+
+
+// ************************************************************************** //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faSchemes b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..252f96477e8a49c44dc160f81e3facdfff8f063e
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faSchemes
@@ -0,0 +1,57 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default                 Euler;
+}
+
+gradSchemes
+{
+    default                 Gauss linear;
+}
+
+divSchemes
+{
+    default                  none;
+    div(phif_film,hf_film)   Gauss upwind;
+    div(phi2s_film,Uf_film)  Gauss upwind;
+    div(faceAreaNormals)     Gauss linear;
+}
+
+laplacianSchemes
+{
+    default                 none;
+    laplacian(hf_film)      Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default                 linear;
+}
+
+snGradSchemes
+{
+    default                 corrected;
+}
+
+fluxRequired
+{
+    hf_film                 true;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faSolution b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faSolution
new file mode 100644
index 0000000000000000000000000000000000000000..6d8f17e9e32d6a160db2981f55e23a4786b7e3be
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/faSolution
@@ -0,0 +1,51 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    Uf_film
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-08;
+        relTol          0.0;
+    }
+
+    hf_film
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-08;
+        relTol          0.0;
+    }
+}
+
+PIMPLE
+{
+    momentumPredictor true;
+    nOuterCorr        2;
+    nCorr             2;
+    nFilmCorr         1;
+}
+
+relaxationFactors
+{
+    hf_Film    1;
+    Uf_Film    1;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/fvSchemes b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/fvSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..f7109b859d5d331f98c8aa2d0ec2c6d52678bef4
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/fvSchemes
@@ -0,0 +1,60 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+    grad(p)         Gauss linear;
+    grad(U)         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+
+    div(phi,U)      Gauss upwind;
+    div(U)          Gauss linear;
+
+    div(phi,k)      Gauss upwind;
+    div(phi,epsilon) Gauss upwind;
+    div(phi,K)      Gauss upwind;
+
+    div((nuEff*dev2(T(grad(U))))) Gauss linear;
+}
+
+laplacianSchemes
+{
+    default         Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+    interpolate(HbyA) linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/fvSolution b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/fvSolution
new file mode 100644
index 0000000000000000000000000000000000000000..e308ba14ce168090ff23728f3d77d3af8376aa46
--- /dev/null
+++ b/tutorials/lagrangian/kinematicParcelFoam/pitzDailyWithSprinkles/system/fvSolution
@@ -0,0 +1,85 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    p
+    {
+        solver          PBiCGStab;
+        tolerance       0;
+        relTol          0.1;
+        smoother        GaussSeidel;
+        preconditioner  DIC;
+    }
+
+    pFinal
+    {
+        $p;
+        tolerance       1e-06;
+        relTol          0;
+    }
+
+    "(k|epsilon)"
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-6;
+        relTol          0.1;
+    }
+
+    "(k|epsilon)Final"
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-6;
+        relTol          0;
+    }
+
+    U
+    {
+        solver          smoothSolver;
+        smoother        GaussSeidel;
+        tolerance       1e-05;
+        relTol          0.01;
+    }
+
+    UFinal
+    {
+        $U;
+        tolerance       1e-06;
+        relTol          0;
+    }
+}
+
+PIMPLE
+{
+    momentumPredictor   yes;
+    correctPhi          no;
+    nOuterCorrectors    1;
+    nCorrectors         3;
+    nNonOrthogonalCorrectors 0;
+}
+
+relaxationFactors
+{
+    equations
+    {
+         ".*"       1;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/T b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/T
new file mode 100644
index 0000000000000000000000000000000000000000..8f0f5eb983339c79ed978b0a7d9a57689d8796ed
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/T
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      T;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 0 0 1 0 0 0];
+
+internalField   uniform 300;
+
+boundaryField
+{
+    ".*"
+    {
+        type            fixedValue;
+        value           uniform 300;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/U b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/U
new file mode 100644
index 0000000000000000000000000000000000000000..e646f5924a26a5636f9d57fe7696dc6dca5a2ca4
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/U
@@ -0,0 +1,87 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volVectorField;
+    object      U;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (3 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform (3 0 0);
+        inletValue      uniform (0 0 0);
+    }
+
+    outlet
+    {
+        type            pressureInletOutletVelocity;
+        inletValue      uniform (0 0 0);
+        value           uniform (0 0 0);
+    }
+
+    "(top|sides)"
+    {
+        type            noSlip;
+    }
+
+    base
+    {
+        type            velocityFilmShell;
+        active          true;
+        infoOutput      false;
+        deltaWet        1e-6;
+        U               U;
+        pRef            1e5; // Reference pressure for thermo
+        T0              300; // Isothermal film temperature
+
+        zeroWallVelocity    true;
+
+        thermo
+        {
+            H2O;
+        }
+
+        turbulence          laminar;
+
+        laminarCoeffs
+        {
+            friction        ManningStrickler; // Wall friction model
+            n               0.005;  // Manning number
+            Cf              0;      // Gas friction
+        }
+
+        injectionModels
+        (
+            curvatureSeparation
+        );
+
+        forces ();
+
+        curvatureSeparationCoeffs
+        {
+            definedPatchRadii  0;
+        }
+
+        region              film;
+        liquidFilmModel     kinematicThinFilm;
+        value               uniform (0 0 0);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/Uf_film b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/Uf_film
new file mode 100644
index 0000000000000000000000000000000000000000..dbd1b2b06cc574a9ec1781099a6ae7353febecd4
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/Uf_film
@@ -0,0 +1,41 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaVectorField;
+    object      Uf_film;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (0 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform (5 0 0);
+    }
+
+    outlet
+    {
+        type            zeroGradient;
+    }
+
+    sides
+    {
+        type            slip;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/Ydefault b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/Ydefault
new file mode 100644
index 0000000000000000000000000000000000000000..82d34bdd1c5e4a8faa00164e109cbe4750d05bc4
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/Ydefault
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      Ydefault;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 0 0 0 0 0 0];
+
+internalField   uniform 1;
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform 1;
+        inletValue      uniform 1;
+    }
+
+    ".*"
+    {
+        type            zeroGradient;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        value           uniform 1;
+        inletValue      uniform 1;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/alphat b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/alphat
new file mode 100644
index 0000000000000000000000000000000000000000..35e61fe774556ede5cbb9e8435b246aad20df62d
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/alphat
@@ -0,0 +1,43 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      alphat;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [1 -1 -1 0 0 0 0];
+
+internalField   uniform 1e-3;
+
+boundaryField
+{
+    inlet
+    {
+        type            calculated;
+        value           uniform 1e-3;
+    }
+
+    outlet
+    {
+        type            calculated;
+        value           uniform 1e-3;
+    }
+
+    ".*"
+    {
+        type            compressible::alphatWallFunction;;
+        value           uniform 1e-3;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/epsilon b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/epsilon
new file mode 100644
index 0000000000000000000000000000000000000000..36db91fd7764607acc258ef64e7f1e47828ad311
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/epsilon
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      epsilon;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -3 0 0 0 0];
+
+internalField   uniform 200;
+
+boundaryField
+{
+    inlet
+    {
+        type            turbulentIntensityKineticEnergyInlet;
+        intensity       0.05;
+        value           uniform 1;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      uniform 200;
+        value           uniform 200;
+    }
+
+    ".*"
+    {
+        type            epsilonWallFunction;
+        value           uniform 200;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/hf_film b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/hf_film
new file mode 100644
index 0000000000000000000000000000000000000000..1118d28bf864344d14cdc0bfb4b4f141e4845b16
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/hf_film
@@ -0,0 +1,41 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       areaScalarField;
+    object      hf_film;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 0 0 0 0 0];
+
+internalField   uniform 1e-5;
+
+boundaryField
+{
+    inlet
+    {
+        type            fixedValue;
+        value           uniform 1e-4;
+    }
+
+    outlet
+    {
+        type            zeroGradient;
+    }
+
+    sides
+    {
+        type            zeroGradient;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/k b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/k
new file mode 100644
index 0000000000000000000000000000000000000000..366fa088423d078e94f0eefa385484de726fa155
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/k
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      k;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -2 0 0 0 0];
+
+internalField   uniform 1;
+
+boundaryField
+{
+    inlet
+    {
+        type            turbulentIntensityKineticEnergyInlet;
+        intensity       0.05;
+        value           uniform 1;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      uniform 1;
+        value           uniform 1;
+    }
+
+    ".*"
+    {
+        type            kqRWallFunction;
+        value           uniform 1;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/nut b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/nut
new file mode 100644
index 0000000000000000000000000000000000000000..d5b8a2c36edf7ae011ee58f16ece17a37ad1293c
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/nut
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      nut;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -1 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            calculated;
+        value           uniform 0;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      uniform 0;
+        value           uniform 0;
+    }
+
+    ".*"
+    {
+        type            nutkWallFunction;
+        value           uniform 0;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/p b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/p
new file mode 100644
index 0000000000000000000000000000000000000000..39ec1e0fa5e137eb2d51f18ac4ed1b55b749c51f
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/p
@@ -0,0 +1,31 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [1 -1 -2 0 0 0 0];
+
+internalField   uniform 1e5;
+
+boundaryField
+{
+    ".*"
+    {
+        type            calculated;
+        value           $internalField;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/p_rgh b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/p_rgh
new file mode 100644
index 0000000000000000000000000000000000000000..2600309f00681b773fe72823802d13caf2d23840
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/0/p_rgh
@@ -0,0 +1,46 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p_rgh;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [1 -1 -2 0 0 0 0];
+
+internalField   uniform 100000;
+
+boundaryField
+{
+    inlet
+    {
+       type            fixedFluxPressure;
+    }
+
+    base
+    {
+        type            fixedFluxPressure;
+    }
+
+    outlet
+    {
+        type            totalPressure;
+        p0              uniform 100000;
+    }
+
+    "(sides|top)"
+    {
+        type            fixedFluxPressure;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allclean b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allclean
new file mode 100755
index 0000000000000000000000000000000000000000..c77ab8663b8a33681ae1088f51e1db46859ff36c
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allclean
@@ -0,0 +1,10 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions      # Tutorial clean functions
+#------------------------------------------------------------------------------
+
+cleanCase
+
+cleanFaMesh
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allrun b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allrun
new file mode 100755
index 0000000000000000000000000000000000000000..85eceb74ad65c551e3cb1b0df9a2ffb6e52fe8c2
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allrun
@@ -0,0 +1,12 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runApplication makeFaMesh
+
+runApplication $(getApplication)
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allrun-parallel b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allrun-parallel
new file mode 100755
index 0000000000000000000000000000000000000000..b5e535e97ef46c543537b6a35923c031b853216f
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/Allrun-parallel
@@ -0,0 +1,16 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+runApplication blockMesh
+
+runParallel -s decompose redistributePar -decompose
+
+runParallel makeFaMesh
+
+runParallel $(getApplication)
+
+runParallel -s reconstruct redistributePar -reconstruct
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/foam.dat b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/foam.dat
new file mode 100644
index 0000000000000000000000000000000000000000..482bba7c53477b8beb533b9056fc6616fbbca0d8
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/foam.dat
@@ -0,0 +1,36 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "constant";
+    object      foam.dat;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+air
+{
+    specie
+    {
+        molWeight   28.9;
+    }
+    thermodynamics
+    {
+        Cp          1005;
+        Hf          0;
+    }
+    transport
+    {
+        mu          1.82e-05;
+        Pr          0.71;
+    }
+}
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/foam.inp b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/foam.inp
new file mode 100644
index 0000000000000000000000000000000000000000..76841b250c2a4d7c591e4a9aba9d395efb0b10a3
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/foam.inp
@@ -0,0 +1,7 @@
+species
+(
+    air
+);
+
+reactions
+{}
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/g b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/g
new file mode 100644
index 0000000000000000000000000000000000000000..e340b6cb927656dd88b37458aa6442f850a63e33
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/g
@@ -0,0 +1,21 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       uniformDimensionedVectorField;
+    object      g;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -2 0 0 0 0];
+value           (0 0 -9.8);
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/reactingCloud1Properties
new file mode 100644
index 0000000000000000000000000000000000000000..00cb119a3d59fa9659485a3ddce7d587d6b3b5ad
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/reactingCloud1Properties
@@ -0,0 +1,172 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      reactingCloud1Properties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solution
+{
+    active          true;
+    coupled         no;
+    transient       yes;
+    cellValueSourceCorrection no;
+    maxCo           0.3;
+
+    sourceTerms
+    {
+        schemes
+        {
+            rho             explicit 1;
+            U               explicit 1;
+            Yi              explicit 1;
+            h               explicit 1;
+            radiation       explicit 1;
+        }
+    }
+
+    interpolationSchemes
+    {
+        rho             cell;
+        U               cellPoint;
+        thermo:mu       cell;
+        T               cell;
+        Cp              cell;
+        kappa           cell;
+        p               cell;
+    }
+
+    integrationSchemes
+    {
+        U               Euler;
+        T               analytical;
+    }
+}
+
+constantProperties
+{
+    rho0            1000;
+    T0              300;
+    Cp0             4187;
+
+    constantVolume  true;
+}
+
+subModels
+{
+    particleForces
+    {
+        sphereDrag;
+        gravity;
+    }
+
+    injectionModels
+    {
+        model1
+        {
+            type            coneInjection;
+            SOI             5.00;
+            duration        10.00;
+            positionAxis
+            (
+                ((-0.5 0.1 0.7) (1 0 -1))
+                ((-0.5 0.2 0.7) (1 0 -1))
+                ((-0.5 0.3 0.7) (1 0 -1))
+                ((-0.5 0.4 0.7) (1 0 -1))
+                ((-0.5 0.5 0.7) (1 0 -1))
+                ((-0.5 0.6 0.7) (1 0 -1))
+                ((-0.5 0.7 0.7) (1 0 -1))
+                ((-0.5 0.8 0.7) (1 0 -1))
+                ((-0.5 0.9 0.7) (1 0 -1))
+            );
+
+            massTotal       10;
+            parcelsPerInjector 20000;
+            parcelBasisType mass;
+            flowRateProfile constant 1;
+            Umag            constant 0.2;
+            thetaInner      constant 0;
+            thetaOuter      constant 55;
+
+            sizeDistribution
+            {
+                type         RosinRammler;
+                RosinRammlerDistribution
+                {
+                    minValue        5e-04;
+                    maxValue        0.0012;
+                    d               7.5e-05;
+                    n               0.5;
+                }
+            }
+        }
+    }
+
+    dispersionModel none;
+
+    patchInteractionModel standardWallInteraction;
+
+    heatTransferModel none;
+
+    compositionModel singleMixtureFraction;
+
+    phaseChangeModel none;
+
+    devolatilisationModel none;
+
+    surfaceReactionModel none;
+
+    stochasticCollisionModel none;
+
+    surfaceFilmModel thermoSurfaceFilm;
+
+    radiation       off;
+
+    standardWallInteractionCoeffs
+    {
+        type            rebound;
+    }
+
+    singleMixtureFractionCoeffs
+    {
+        phases
+        (
+            gas
+            {
+            }
+            liquid
+            {
+                H2O         1;
+            }
+            solid
+            {
+            }
+        );
+        YGasTot0        0;
+        YLiquidTot0     1;
+        YSolidTot0      0;
+    }
+
+    thermoSurfaceFilmCoeffs
+    {
+        interactionType absorb;
+        injectionOffset 5; // Times film thickness
+        minDiameter     1e-4;
+    }
+}
+
+
+cloudFunctions
+{}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/thermophysicalProperties b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/thermophysicalProperties
new file mode 100644
index 0000000000000000000000000000000000000000..3d70875bcbf7014ecf62fe3a455a1f67bde8cc82
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/thermophysicalProperties
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      thermophysicalProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+thermoType
+{
+    type            heRhoThermo;
+    mixture         reactingMixture;
+    transport       const;
+    thermo          hConst;
+    energy          sensibleEnthalpy;
+    equationOfState perfectGas;
+    specie          specie;
+}
+
+chemistryReader foamChemistryReader;
+
+foamChemistryFile "<constant>/foam.inp";
+
+foamChemistryThermoFile "<constant>/foam.dat";
+
+inertSpecie     air;
+
+liquids
+{
+    H2O;
+}
+
+solids
+{}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/turbulenceProperties b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/turbulenceProperties
new file mode 100644
index 0000000000000000000000000000000000000000..0b743e50740fd8f4bbf69547adc6557efef30005
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/constant/turbulenceProperties
@@ -0,0 +1,25 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      turbulenceProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+simulationType      RAS;
+
+RAS
+{
+    RASModel        kEpsilon;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/blockMeshDict b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..2fcb06b7ecb1c234e55aba1c931136c56a6c546b
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/blockMeshDict
@@ -0,0 +1,104 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+scale   1;
+
+vertices
+(
+    (0 0 0) //0
+    (5 0 0) //1
+    (5 1 0) //2
+    (0 1 0) //3
+    (-1 0 0.5) //4
+    (-1 1 0.5) //5
+    (-1 1 1) //6
+    (-1 0 1) //7
+    (5 1 1) //8
+    (0 1 0.5) //9
+    (5 0 0.5) //10
+    (5 1 0.5) //11
+    (0 0 1) //12
+    (0 1 1) //13
+    (0 0 0.5) //14
+    (5 0 1) //15
+);
+
+blocks
+(
+    hex (14 10 11 9 12 15 8 13 ) (100 20 10) simpleGrading (1 1 1)
+    hex (0 1 2 3 14 10 11 9) (100 20 10) simpleGrading (1 1 1)
+    hex (4 14 9 5 7 12 13 6) (20 20 10) simpleGrading (1 1 1)
+);
+
+edges
+(
+);
+
+boundary
+(
+    base
+    {
+        type wall;
+        faces
+        (
+            (0 1 2 3)
+            (0 3 9 14)
+            (4 14 9 5)
+        );
+    }
+    outlet
+    {
+        type patch;
+        faces
+        (
+            (1 2 11 10)
+            (15 10 11 8)
+        );
+    }
+    inlet
+    {
+        type patch;
+        faces
+        (
+            (4 5 6 7)
+        );
+    }
+    sides
+    {
+        type wall;
+        faces
+        (
+            (0 1 10 14)
+            (14 10 15 12)
+            (4 14 12 7)
+            (3 2 11 9)
+            (9 11 8 13)
+            (5 9 13 6)
+        );
+    }
+    top
+    {
+        type wall;
+        faces
+        (
+            (12 15 8 13)
+            (7 12 13 6)
+        );
+    }
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/controlDict b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/controlDict
new file mode 100644
index 0000000000000000000000000000000000000000..fa5759a96bdb036151e0ee877c4207b7567b4bfa
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/controlDict
@@ -0,0 +1,64 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application     reactingParcelFoam;
+
+startFrom       startTime;
+
+startTime       0;
+
+stopAt          endTime;
+
+endTime         1; // please increase it to 10 or more, if need be.
+
+deltaT          0.005;
+
+writeControl    adjustable;
+
+writeInterval   0.05;
+
+purgeWrite      0;
+
+writeFormat     ascii;
+
+writePrecision  6;
+
+writeCompression off;
+
+timeFormat      general;
+
+timePrecision   6;
+
+runTimeModifiable yes;
+
+adjustTimeStep  yes;
+
+maxCo           0.9;
+
+regionFaMaxCo   4; // max finiteArea Courant number
+
+maxDeltaT       0.1;
+
+functions
+{
+   faRegionCo
+   {
+        type        setTimeStepFaRegion;
+   }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/decomposeParDict b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/decomposeParDict
new file mode 100644
index 0000000000000000000000000000000000000000..68dbf1e8ad7b0d34281d3720d3f1cc7bd2879331
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/decomposeParDict
@@ -0,0 +1,27 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      decomposeParDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+numberOfSubdomains 4;
+
+method          hierarchical;
+
+coeffs
+{
+    n           ( 2 2 1 );
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faMeshDefinition b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faMeshDefinition
new file mode 100644
index 0000000000000000000000000000000000000000..7133740322916cd7a5f4abb90f2aec87b9012118
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faMeshDefinition
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "constant/faMesh";
+    object      faMeshDefinition;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+polyMeshPatches  1( base );
+
+boundary
+{
+    inlet
+    {
+        type                patch;
+        ownerPolyPatch      base;
+        neighbourPolyPatch  inlet;
+    }
+
+    outlet
+    {
+        type                patch;
+        ownerPolyPatch      base;
+        neighbourPolyPatch  outlet;
+    }
+
+    sides
+    {
+        type                patch;
+        ownerPolyPatch      base;
+        neighbourPolyPatch  sides;
+    }
+}
+
+
+// ************************************************************************** //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faSchemes b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..e97836da2c87c909aca2dab92e2e7fa78ef6f89f
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faSchemes
@@ -0,0 +1,57 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+    div(phif_film,hf_film)   Gauss upwind;
+    div(phi2s_film,Uf_film)  Gauss upwind;
+    div(faceAreaNormals)     Gauss linear;
+}
+
+laplacianSchemes
+{
+    default         none;
+    laplacian(hf_film) Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+fluxRequired
+{
+    hf_film         true;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faSolution b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faSolution
new file mode 100644
index 0000000000000000000000000000000000000000..b44bbd9d878d67111e5ba8469cbf9128c635d02d
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/faSolution
@@ -0,0 +1,52 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      faSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    Uf_film
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-08;
+        relTol          0.0;
+    }
+
+    hf_film
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-08;
+        relTol          0.0;
+    }
+}
+
+PIMPLE
+{
+    momentumPredictor true;
+    nOuterCorr        4;
+    nCorr             1;
+    nNonOrthCorr      0;
+    nFilmCorr         1;
+}
+
+relaxationFactors
+{
+    hf_Film    1;
+    Uf_Film    1;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/fvSchemes b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/fvSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..aa871a54a1c47577cee5ca87ed3cf9786c2fa107
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/fvSchemes
@@ -0,0 +1,59 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         Euler;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+    grad(p)         Gauss linear;
+    grad(U)         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+    div(phi,U)      Gauss upwind;
+    div(phi,K)      Gauss upwind;
+    div(phi,h)      Gauss upwind;
+    div(phi,k)      Gauss upwind;
+    div(phi,epsilon) Gauss upwind;
+    div(U)          Gauss linear;
+    div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
+    div(phi,Yi_h)  Gauss upwind;
+}
+
+laplacianSchemes
+{
+    default         Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+    interpolate(HbyA) linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/fvSolution b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/fvSolution
new file mode 100644
index 0000000000000000000000000000000000000000..071788055a43fd64cef193395517ff46faa15069
--- /dev/null
+++ b/tutorials/lagrangian/reactingParcelFoam/liquidFilmStepWithSprinkles/system/fvSolution
@@ -0,0 +1,102 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v2106                                 |
+|   \\  /    A nd           | Website:  www.openfoam.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      fvSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    "(rho|G)"
+    {
+        solver          PCG;
+        preconditioner  DIC;
+        tolerance       0;
+        relTol          0.1;
+    }
+
+    "(rho|G)Final"
+    {
+        $rho;
+        tolerance       1e-05;
+        relTol          0;
+    }
+
+    p_rgh
+    {
+        solver          PBiCGStab;
+        tolerance       0;
+        relTol          0.1;
+        smoother        GaussSeidel;
+        preconditioner  DIC;
+        maxIter         100;
+    }
+
+    p_rghFinal
+    {
+        $p_rgh;
+        tolerance       1e-06;
+        relTol          0;
+        maxIter         1000;
+    }
+
+    "(h|Yi|O2|N2|H2O|k|epsilon)"
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-6;
+        relTol          0.1;
+    }
+
+    "(h|Yi|O2|N2|H2O|k|epsilon)Final"
+    {
+        solver          PBiCGStab;
+        preconditioner  DILU;
+        tolerance       1e-6;
+        relTol          0;
+    }
+
+    U
+    {
+        solver          smoothSolver;
+        smoother        GaussSeidel;
+        tolerance       1e-05;
+        relTol          0.01;
+    }
+
+    UFinal
+    {
+        $U;
+        tolerance       1e-06;
+        relTol          0;
+    }
+}
+
+PIMPLE
+{
+    momentumPredictor   yes;
+    correctPhi          no;
+    nOuterCorrectors    1;
+    nCorrectors         3;
+    nNonOrthogonalCorrectors 0;
+}
+
+relaxationFactors
+{
+    equations
+    {
+         ".*"       1;
+    }
+}
+
+
+// ************************************************************************* //