diff --git a/dumux/nonlinear/privarswitchnewtonsolver.hh b/dumux/nonlinear/privarswitchnewtonsolver.hh
index ea4f9b4164b6d3579a3da05a0234ee83eb341201..b1e727bbe1f2758e102e442b82df9823677384d5 100644
--- a/dumux/nonlinear/privarswitchnewtonsolver.hh
+++ b/dumux/nonlinear/privarswitchnewtonsolver.hh
@@ -44,9 +44,6 @@ class PriVarSwitchNewtonSolver : public NewtonSolver<Assembler, LinearSolver>
     using ParentType = NewtonSolver<Assembler, LinearSolver>;
     using SolutionVector = typename Assembler::ResidualType;
 
-    static constexpr auto discMethod = Assembler::FVGridGeometry::discMethod;
-    static constexpr bool isBox = discMethod == DiscretizationMethod::box;
-
 public:
     using ParentType::ParentType;
 
@@ -98,20 +95,15 @@ public:
         switchedInLastIteration_ = priVarSwitch_->update(uCurrentIter, gridVariables,
                                                          problem, fvGridGeometry);
 
-        constexpr bool volVarCachingEnabled = std::decay_t<decltype(gridVariables.curGridVolVars())>::cachingEnabled;
-        constexpr bool fluxVarCachingEnabled = std::decay_t<decltype(gridVariables.gridFluxVarsCache())>::cachingEnabled;
         if(switchedInLastIteration_)
         {
             for (const auto& element : elements(fvGridGeometry.gridView()))
             {
                 // if the volume variables are cached globally, we need to update those where the primary variables have been switched
-                updateSwitchedVolVars_(std::integral_constant<bool, volVarCachingEnabled>(),
-                                       element, assembler, uCurrentIter, uLastIter);
+                priVarSwitch_->updateSwitchedVolVars(problem, element, fvGridGeometry, gridVariables, uCurrentIter);
 
                 // if the flux variables are cached globally, we need to update those where the primary variables have been switched
-                // (not needed for box discretization)
-                updateSwitchedFluxVarsCache_(std::integral_constant<bool, (fluxVarCachingEnabled && !isBox)>(),
-                                             element, assembler, uCurrentIter, uLastIter);
+                priVarSwitch_->updateSwitchedFluxVarsCache(problem, element, fvGridGeometry, gridVariables, uCurrentIter);
             }
         }
     }
@@ -131,75 +123,6 @@ public:
     }
 
 private:
-
-    /*!
-     * \brief Update the volume variables whose primary variables were
-              switched. Required when volume variables are cached globally.
-     */
-    template<class Element>
-    void updateSwitchedVolVars_(std::true_type,
-                                const Element& element,
-                                Assembler& assembler,
-                                const SolutionVector &uCurrentIter,
-                                const SolutionVector &uLastIter)
-    {
-        const auto& fvGridGeometry = assembler.fvGridGeometry();
-        const auto& problem = assembler.problem();
-        auto& gridVariables = assembler.gridVariables();
-
-        // make sure FVElementGeometry is bound to the element
-        auto fvGeometry = localView(fvGridGeometry);
-        fvGeometry.bindElement(element);
-
-        // update the secondary variables if global caching is enabled
-        for (auto&& scv : scvs(fvGeometry))
-        {
-            const auto dofIdxGlobal = scv.dofIndex();
-            if (priVarSwitch_->wasSwitched(dofIdxGlobal))
-            {
-                const auto elemSol = elementSolution(element, uCurrentIter, fvGridGeometry);
-                auto& volVars = gridVariables.curGridVolVars().volVars(scv);
-                volVars.update(elemSol, problem, element, scv);
-            }
-        }
-    }
-
-    /*!
-     * \brief Update the fluxVars cache for dof whose primary variables were
-              switched. Required when flux variables are cached globally.
-     */
-     template<class Element>
-     void updateSwitchedFluxVarsCache_(std::true_type,
-                                       const Element& element,
-                                       Assembler& assembler,
-                                       const SolutionVector &uCurrentIter,
-                                       const SolutionVector &uLastIter)
-    {
-        const auto& fvGridGeometry = assembler.fvGridGeometry();
-        auto& gridVariables = assembler.gridVariables();
-
-        // update the flux variables if global caching is enabled
-        const auto dofIdxGlobal = fvGridGeometry.dofMapper().index(element);
-
-        if (priVarSwitch_->wasSwitched(dofIdxGlobal))
-        {
-            // make sure FVElementGeometry and the volume variables are bound
-            auto fvGeometry = localView(fvGridGeometry);
-            fvGeometry.bind(element);
-            auto curElemVolVars = localView(gridVariables.curGridVolVars());
-            curElemVolVars.bind(element, fvGeometry, uCurrentIter);
-            gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
-        }
-    }
-
-     //! brief Do nothing when volume variables are not cached globally.
-    template <typename... Args>
-    void updateSwitchedVolVars_(std::false_type, Args&&... args) const {}
-
-    //! brief Do nothing when flux variables are not cached globally.
-    template <typename... Args>
-    void updateSwitchedFluxVarsCache_(std::false_type, Args&&... args) const {}
-
     //! the class handling the primary variable switch
     std::unique_ptr<PrimaryVariableSwitch> priVarSwitch_;
     //! if we switched primary variables in the last iteration
diff --git a/dumux/porousmediumflow/compositional/primaryvariableswitch.hh b/dumux/porousmediumflow/compositional/primaryvariableswitch.hh
index 39ef5fda73b4bc5f64b6acfac89807b0d3c506c8..86de1f1cc91220f9c852d6707f093b0d88a0c11e 100644
--- a/dumux/porousmediumflow/compositional/primaryvariableswitch.hh
+++ b/dumux/porousmediumflow/compositional/primaryvariableswitch.hh
@@ -38,9 +38,12 @@ namespace Dumux {
 class NoPrimaryVariableSwitch
 {
 public:
+    NoPrimaryVariableSwitch(...) {}
     void init(...) {}
     bool wasSwitched(...) const { return false; }
     bool update(...) { return false; }
+    void updateSwitchedVolVars(...) {}
+    void updateSwitchedFluxVarsCache(...) {}
     bool update_(...) {return false; }
 };
 
@@ -104,7 +107,6 @@ public:
 
                     if (asImp_().update_(curSol[dofIdxGlobal], volVars, dofIdxGlobal, scv.dofPosition()))
                         switched = true;
-
                 }
             }
         }
@@ -117,6 +119,81 @@ public:
         return switched;
     }
 
+    /*!
+     * \brief Update the volume variables whose primary variables were
+              switched. Required when volume variables are cached globally.
+     */
+    template<class Problem, class GridVariables, class SolutionVector,
+             std::enable_if_t<GridVariables::GridVolumeVariables::cachingEnabled, int> = 0>
+    void updateSwitchedVolVars(const Problem& problem,
+                               const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
+                               const typename GridVariables::GridGeometry& fvGridGeometry,
+                               GridVariables& gridVariables,
+                               const SolutionVector& sol)
+    {
+        // make sure FVElementGeometry is bound to the element
+        auto fvGeometry = localView(fvGridGeometry);
+        fvGeometry.bindElement(element);
+
+        // update the secondary variables if global caching is enabled
+        for (auto&& scv : scvs(fvGeometry))
+        {
+            const auto dofIdxGlobal = scv.dofIndex();
+            if (asImp_().wasSwitched(dofIdxGlobal))
+            {
+                const auto elemSol = elementSolution(element, sol, fvGridGeometry);
+                auto& volVars = gridVariables.curGridVolVars().volVars(scv);
+                volVars.update(elemSol, problem, element, scv);
+            }
+        }
+    }
+
+    /*!
+     * \brief Update the fluxVars cache for dof whose primary variables were
+              switched. Required when flux variables are cached globally (not for box method).
+     */
+     template<class Problem, class GridVariables, class SolutionVector,
+              std::enable_if_t<(GridVariables::GridFluxVariablesCache::cachingEnabled &&
+                                GridVariables::GridGeometry::discMethod != DiscretizationMethod::box), int> = 0>
+     void updateSwitchedFluxVarsCache(const Problem& problem,
+                                const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
+                                const typename GridVariables::GridGeometry& fvGridGeometry,
+                                GridVariables& gridVariables,
+                                const SolutionVector& sol)
+    {
+        // update the flux variables if global caching is enabled
+        const auto dofIdxGlobal = fvGridGeometry.dofMapper().index(element);
+
+        if (asImp_().wasSwitched(dofIdxGlobal))
+        {
+            // make sure FVElementGeometry and the volume variables are bound
+            auto fvGeometry = localView(fvGridGeometry);
+            fvGeometry.bind(element);
+            auto curElemVolVars = localView(gridVariables.curGridVolVars());
+            curElemVolVars.bind(element, fvGeometry, sol);
+            gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
+        }
+    }
+
+     //! brief Do nothing when volume variables are not cached globally.
+     template<class Problem, class GridVariables, class SolutionVector,
+              std::enable_if_t<!GridVariables::GridVolumeVariables::cachingEnabled, int> = 0>
+    void updateSwitchedVolVars(const Problem& problem,
+                               const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
+                               const typename GridVariables::GridGeometry& fvGridGeometry,
+                               GridVariables& gridVariables,
+                               const SolutionVector &uCurrentIter) const {}
+
+    //! brief Do nothing when flux variables are not cached globally or the box method is used.
+    template<class Problem, class GridVariables, class SolutionVector,
+             std::enable_if_t<(!GridVariables::GridFluxVariablesCache::cachingEnabled ||
+                               GridVariables::GridGeometry::discMethod == DiscretizationMethod::box), int> = 0>
+    void updateSwitchedFluxVarsCache(const Problem& problem,
+                               const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
+                               const typename GridVariables::GridGeometry& fvGridGeometry,
+                               GridVariables& gridVariables,
+                               const SolutionVector& sol) const {}
+
 protected:
 
     //! return actual implementation (static polymorphism)