diff --git a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh
index 5a90cc053a209e2b0dd5f93f714733c626088d04..b0ced7e5123746dafb0f6d0b5776cd8f5a5eafd2 100644
--- a/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh
+++ b/dumux/discretization/cellcentered/mpfa/fluxvariablescachefiller.hh
@@ -252,84 +252,8 @@ private:
         using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType);
         using AdvectionFiller = typename AdvectionType::Cache::Filler;
 
-        static constexpr auto AdvectionMethod = AdvectionType::myDiscretizationMethod;
-        using LambdaFactory = TensorLambdaFactory<TypeTag, AdvectionMethod>;
-
-        // skip the following if advection doesn't use mpfa
-        if (AdvectionMethod == DiscretizationMethods::CCMpfa)
-        {
-            // get instance of the interaction volume-local assembler
-            using IVTraits = typename InteractionVolume::Traits;
-            using IvLocalAssembler = InteractionVolumeAssembler< IVTraits, InteractionVolume::MpfaMethod >;
-            IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
-
-            // Use different assembly if gravity is enabled
-            static const bool enableGravity = getParamFromGroup<bool>(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Problem.EnableGravity");
-
-            // Assemble T only if permeability is sol-dependent or if update is forced
-            if (forceUpdateAll || soldependentAdvection)
-            {
-                // distinguish between normal/surface grids (optimized away by compiler)
-                if (dim < dimWorld)
-                {
-                    if (enableGravity)
-                        localAssembler.assembleWithGravity( handle.advectionTout(),
-                                                            handle.advectionT(),
-                                                            handle.gravityOutside(),
-                                                            handle.gravity(),
-                                                            handle.advectionCA(),
-                                                            handle.advectionA(),
-                                                            iv,
-                                                            LambdaFactory::getAdvectionLambda() );
-
-                    else
-                        localAssembler.assemble( handle.advectionTout(),
-                                                 handle.advectionT(),
-                                                 iv,
-                                                 LambdaFactory::getAdvectionLambda() );
-                }
-
-                // normal grids
-                else
-                {
-                    if (enableGravity)
-                        localAssembler.assembleWithGravity( handle.advectionT(),
-                                                            handle.gravity(),
-                                                            handle.advectionCA(),
-                                                            iv,
-                                                            LambdaFactory::getAdvectionLambda() );
-                    else
-                        localAssembler.assemble( handle.advectionT(),
-                                                 iv,
-                                                 LambdaFactory::getAdvectionLambda() );
-                }
-            }
-
-            // (maybe) only reassemble gravity vector
-            else if (enableGravity)
-            {
-                if (dim == dimWorld)
-                    localAssembler.assembleGravity( handle.gravity(),
-                                                    iv,
-                                                    handle.advectionCA(),
-                                                    LambdaFactory::getAdvectionLambda() );
-                else
-                    localAssembler.assembleGravity( handle.gravity(),
-                                                    handle.gravityOutside(),
-                                                    iv,
-                                                    handle.advectionCA(),
-                                                    handle.advectionA(),
-                                                    LambdaFactory::getAdvectionLambda() );
-            }
-
-            // assemble pressure vectors
-            for (unsigned int pIdx = 0; pIdx < GET_PROP_VALUE(TypeTag, NumPhases); ++pIdx)
-            {
-                const auto& evv = &elemVolVars();
-                auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); };
-                localAssembler.assemble(handle.pressures(pIdx), iv, getPressure);
-            }
-        }
+        // fill data in the handle
+        fillAdvectionHandle(iv, handle, forceUpdateAll);
 
         // fill advection caches
         for (unsigned int i = 0; i < iv.localFaceData().size(); ++i)
@@ -384,17 +308,9 @@ private:
         using DiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType);
         using DiffusionFiller = typename DiffusionType::Cache::Filler;
 
-        static constexpr auto DiffusionMethod = DiffusionType::myDiscretizationMethod;
-        using LambdaFactory = TensorLambdaFactory<TypeTag, DiffusionMethod>;
-
         static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases);
         static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents);
 
-        // get instance of the interaction volume-local assembler
-        using IVTraits = typename InteractionVolume::Traits;
-        using IvLocalAssembler = InteractionVolumeAssembler< IVTraits, InteractionVolume::MpfaMethod >;
-        IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
-
         for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
         {
             for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
@@ -402,33 +318,8 @@ private:
                 if (phaseIdx == compIdx)
                     continue;
 
-                // solve the local system subject to the diffusion tensor (if uses mpfa)
-                if (DiffusionMethod == DiscretizationMethods::CCMpfa)
-                {
-                    // update the context in handle
-                    handle.setPhaseIndex(phaseIdx);
-                    handle.setComponentIndex(compIdx);
-
-                    // assemble T
-                    if (forceUpdateAll || soldependentDiffusion)
-                    {
-                        if (dim < dimWorld)
-                            localAssembler.assemble( handle.diffusionTout(),
-                                                     handle.diffusionT(),
-                                                     iv,
-                                                     LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) );
-                        else
-                            localAssembler. assemble( handle.diffusionT(),
-                                                      iv,
-                                                      LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) );
-                    }
-
-                    // assemble vector of mole fractions
-                    const auto& evv = &elemVolVars();
-                    auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx)
-                                           { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); };
-                    localAssembler.assemble(handle.moleFractions(phaseIdx, compIdx), iv, getMoleFraction);
-                }
+                // fill data in the handle
+                fillDiffusionHandle(iv, handle, forceUpdateAll, phaseIdx, compIdx);
 
                 // fill diffusion caches
                 for (unsigned int i = 0; i < iv.localFaceData().size(); ++i)
@@ -487,35 +378,8 @@ private:
         using HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType);
         using HeatConductionFiller = typename HeatConductionType::Cache::Filler;
 
-        static constexpr auto HeatConductionMethod = HeatConductionType::myDiscretizationMethod;
-        using LambdaFactory = TensorLambdaFactory<TypeTag, HeatConductionMethod>;
-
-        // maybe solve the local system subject to fourier coefficient
-        if (HeatConductionMethod == DiscretizationMethods::CCMpfa)
-        {
-            // get instance of the interaction volume-local assembler
-            using IVTraits = typename InteractionVolume::Traits;
-            using IvLocalAssembler = InteractionVolumeAssembler< IVTraits, InteractionVolume::MpfaMethod >;
-            IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
-
-            if (forceUpdateAll || soldependentAdvection)
-            {
-                if (dim < dimWorld)
-                    localAssembler.assemble( handle.heatConductionTout(),
-                                             handle.heatConductionT(),
-                                             iv,
-                                             LambdaFactory::getHeatConductionLambda() );
-                else
-                    localAssembler.assemble( handle.heatConductionT(),
-                                             iv,
-                                             LambdaFactory::getHeatConductionLambda() );
-            }
-
-            // assemble vector of temperatures
-            const auto& evv = &elemVolVars();
-            auto getMoleFraction = [&evv] (auto volVarIdx) { return (evv->operator[](volVarIdx)).temperature(); };
-            localAssembler.assemble(handle.temperatures(), iv, getMoleFraction);
-        }
+        // prepare data in handle
+        fillHeatConductionHandle(iv, handle, forceUpdateAll);
 
         // fill heat conduction caches
         for (unsigned int i = 0; i < iv.localFaceData().size(); ++i)
@@ -556,6 +420,184 @@ private:
                             bool forceUpdateAll = false)
     {}
 
+    //! prepares the quantities necessary for advective fluxes in the handle
+    template< class InteractionVolume,
+              class DataHandle,
+              class AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType),
+              typename std::enable_if_t<AdvectionType::myDiscretizationMethod == DiscretizationMethods::CCMpfa, int> = 0 >
+    void fillAdvectionHandle(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll)
+    {
+        using LambdaFactory = TensorLambdaFactory<TypeTag, DiscretizationMethods::CCMpfa>;
+
+        // get instance of the interaction volume-local assembler
+        using IVTraits = typename InteractionVolume::Traits;
+        using IvLocalAssembler = InteractionVolumeAssembler< IVTraits, InteractionVolume::MpfaMethod >;
+        IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
+
+        // Use different assembly if gravity is enabled
+        static const bool enableGravity = getParamFromGroup<bool>(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Problem.EnableGravity");
+
+        // Assemble T only if permeability is sol-dependent or if update is forced
+        if (forceUpdateAll || soldependentAdvection)
+        {
+            // distinguish between normal/surface grids (optimized away by compiler)
+            if (dim < dimWorld)
+            {
+                if (enableGravity)
+                    localAssembler.assembleWithGravity( handle.advectionTout(),
+                                                        handle.advectionT(),
+                                                        handle.gravityOutside(),
+                                                        handle.gravity(),
+                                                        handle.advectionCA(),
+                                                        handle.advectionA(),
+                                                        iv,
+                                                        LambdaFactory::getAdvectionLambda() );
+
+                else
+                    localAssembler.assemble( handle.advectionTout(),
+                                             handle.advectionT(),
+                                             iv,
+                                             LambdaFactory::getAdvectionLambda() );
+            }
+
+            // normal grids
+            else
+            {
+                if (enableGravity)
+                    localAssembler.assembleWithGravity( handle.advectionT(),
+                                                        handle.gravity(),
+                                                        handle.advectionCA(),
+                                                        iv,
+                                                        LambdaFactory::getAdvectionLambda() );
+                else
+                    localAssembler.assemble( handle.advectionT(),
+                                             iv,
+                                             LambdaFactory::getAdvectionLambda() );
+            }
+        }
+
+        // (maybe) only reassemble gravity vector
+        else if (enableGravity)
+        {
+            if (dim == dimWorld)
+                localAssembler.assembleGravity( handle.gravity(),
+                                                iv,
+                                                handle.advectionCA(),
+                                                LambdaFactory::getAdvectionLambda() );
+            else
+                localAssembler.assembleGravity( handle.gravity(),
+                                                handle.gravityOutside(),
+                                                iv,
+                                                handle.advectionCA(),
+                                                handle.advectionA(),
+                                                LambdaFactory::getAdvectionLambda() );
+        }
+
+        // assemble pressure vectors
+        for (unsigned int pIdx = 0; pIdx < GET_PROP_VALUE(TypeTag, NumPhases); ++pIdx)
+        {
+            const auto& evv = &elemVolVars();
+            auto getPressure = [&evv, pIdx] (auto volVarIdx) { return (evv->operator[](volVarIdx)).pressure(pIdx); };
+            localAssembler.assemble(handle.pressures(pIdx), iv, getPressure);
+        }
+    }
+
+    //! prepares the quantities necessary for diffusive fluxes in the handle
+    template< class InteractionVolume,
+              class DataHandle,
+              class DiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType),
+              typename std::enable_if_t<DiffusionType::myDiscretizationMethod == DiscretizationMethods::CCMpfa, int> = 0 >
+    void fillDiffusionHandle(InteractionVolume& iv,
+                             DataHandle& handle,
+                             bool forceUpdateAll,
+                             int phaseIdx, int compIdx)
+    {
+        using LambdaFactory = TensorLambdaFactory<TypeTag, DiscretizationMethods::CCMpfa>;
+
+        // get instance of the interaction volume-local assembler
+        using IVTraits = typename InteractionVolume::Traits;
+        using IvLocalAssembler = InteractionVolumeAssembler< IVTraits, InteractionVolume::MpfaMethod >;
+        IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
+
+        // solve the local system subject to the tensor and update the handle
+        handle.setPhaseIndex(phaseIdx);
+        handle.setComponentIndex(compIdx);
+
+        // assemble T
+        if (forceUpdateAll || soldependentDiffusion)
+        {
+            if (dim < dimWorld)
+                localAssembler.assemble( handle.diffusionTout(),
+                                         handle.diffusionT(),
+                                         iv,
+                                         LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) );
+            else
+                localAssembler. assemble( handle.diffusionT(),
+                                          iv,
+                                          LambdaFactory::getDiffusionLambda(phaseIdx, compIdx) );
+        }
+
+        // assemble vector of mole fractions
+        const auto& evv = &elemVolVars();
+        auto getMoleFraction = [&evv, phaseIdx, compIdx] (auto volVarIdx)
+                               { return (evv->operator[](volVarIdx)).moleFraction(phaseIdx, compIdx); };
+        localAssembler.assemble(handle.moleFractions(phaseIdx, compIdx), iv, getMoleFraction);
+    }
+
+    //! prepares the quantities necessary for conductive fluxes in the handle
+    template< class InteractionVolume,
+              class DataHandle,
+              class HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType),
+              typename std::enable_if_t<HeatConductionType::myDiscretizationMethod == DiscretizationMethods::CCMpfa, int> = 0 >
+    void fillHeatConductionHandle(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll)
+    {
+        using LambdaFactory = TensorLambdaFactory<TypeTag, DiscretizationMethods::CCMpfa>;
+
+        // get instance of the interaction volume-local assembler
+        using IVTraits = typename InteractionVolume::Traits;
+        using IvLocalAssembler = InteractionVolumeAssembler< IVTraits, InteractionVolume::MpfaMethod >;
+        IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
+
+        if (forceUpdateAll || soldependentAdvection)
+        {
+            if (dim < dimWorld)
+                localAssembler.assemble( handle.heatConductionTout(),
+                                         handle.heatConductionT(),
+                                         iv,
+                                         LambdaFactory::getHeatConductionLambda() );
+            else
+                localAssembler.assemble( handle.heatConductionT(),
+                                         iv,
+                                         LambdaFactory::getHeatConductionLambda() );
+        }
+
+        // assemble vector of temperatures
+        const auto& evv = &elemVolVars();
+        auto getMoleFraction = [&evv] (auto volVarIdx) { return (evv->operator[](volVarIdx)).temperature(); };
+        localAssembler.assemble(handle.temperatures(), iv, getMoleFraction);
+    }
+
+    //! fill handle only when advection uses mpfa
+    template< class InteractionVolume,
+              class DataHandle,
+              class AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType),
+              typename std::enable_if_t<AdvectionType::myDiscretizationMethod != DiscretizationMethods::CCMpfa, int> = 0 >
+    void fillAdvectionHandle(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll) {}
+
+    //! fill handle only when diffusion uses mpfa
+    template< class InteractionVolume,
+              class DataHandle,
+              class DiffusionType = typename GET_PROP_TYPE(TypeTag, MolecularDiffusionType),
+              typename std::enable_if_t<DiffusionType::myDiscretizationMethod != DiscretizationMethods::CCMpfa, int> = 0 >
+    void fillDiffusionHandle(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll, int phaseIdx, int compIdx) {}
+
+    //! fill handle only when heat conduction uses mpfa
+    template< class InteractionVolume,
+              class DataHandle,
+              class HeatConductionType = typename GET_PROP_TYPE(TypeTag, HeatConductionType),
+              typename std::enable_if_t<HeatConductionType::myDiscretizationMethod != DiscretizationMethods::CCMpfa, int> = 0 >
+    void fillHeatConductionHandle(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll) {}
+
     const Problem* problemPtr_;
     const Element* elementPtr_;
     const FVElementGeometry* fvGeometryPtr_;