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)