13#ifndef DUMUX_PRIMARY_VARIABLE_SWITCH_HH 
   14#define DUMUX_PRIMARY_VARIABLE_SWITCH_HH 
   18#include <dune/common/exceptions.hh> 
   19#include <dune/common/fvector.hh> 
   32    template<
typename... Args>
 
   35    template<
typename... Args> 
void reset(Args&&...) {}
 
   36    template<
typename... Args> 
bool wasSwitched(Args&&...)
 const { 
return false; }
 
   37    template<
typename... Args> 
bool update(Args&&...) { 
return false; }
 
 
   47template<
class Implementation>
 
   62    void reset(
const std::size_t numDofs)
 
 
   75    template<
class SolutionVector, 
class Gr
idVariables, 
class Problem>
 
   77                GridVariables& gridVariables,
 
   78                const Problem& problem,
 
   79                const typename GridVariables::GridGeometry& gridGeometry)
 
   81        bool switched = 
false;
 
   83        std::size_t countSwitched = 0;
 
   85        auto fvGeometry = 
localView(gridGeometry);
 
   86        auto elemVolVars = 
localView(gridVariables.curGridVolVars());
 
   88        for (
const auto& element : elements(gridGeometry.gridView()))
 
   91            fvGeometry.bindElement(element);
 
   92            elemVolVars.bindElement(element, fvGeometry, curSol);
 
   95            for (
auto&& scv : scvs(fvGeometry))
 
   99                    const auto dofIdxGlobal = scv.dofIndex();
 
  105                    auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv);
 
  106                    volVars.update(curElemSol, problem, element, scv);
 
  108                    if (
asImp_().
update_(curSol[dofIdxGlobal], volVars, dofIdxGlobal, scv.dofPosition()))
 
  117        if (verbosity_ > 0 && countSwitched > 0)
 
  118            std::cout << 
"Switched primary variables at " << countSwitched << 
" dof locations on processor " 
  119                      << gridGeometry.gridView().comm().rank() << 
"." << std::endl;
 
  123        if (gridGeometry.gridView().comm().size() > 1)
 
  124            switched = gridGeometry.gridView().comm().max(switched);
 
 
  135    template<
class Problem, 
class Gr
idVariables, 
class SolutionVector>
 
  137                               const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
 
  138                               const typename GridVariables::GridGeometry& gridGeometry,
 
  139                               GridVariables& gridVariables,
 
  140                               const SolutionVector& sol)
 
  142        if constexpr (GridVariables::GridVolumeVariables::cachingEnabled)
 
  145            const auto fvGeometry = 
localView(gridGeometry).bindElement(element);
 
  148            for (
auto&& scv : scvs(fvGeometry))
 
  150                const auto dofIdxGlobal = scv.dofIndex();
 
  154                    auto& volVars = gridVariables.curGridVolVars().volVars(scv);
 
  155                    volVars.update(elemSol, problem, element, scv);
 
 
  167    template<
class Problem, 
class Gr
idVariables, 
class SolutionVector>
 
  169                                     const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
 
  170                                     const typename GridVariables::GridGeometry& gridGeometry,
 
  171                                     GridVariables& gridVariables,
 
  172                                     const SolutionVector& sol)
 
  174        if constexpr (GridVariables::GridFluxVariablesCache::cachingEnabled
 
  178            const auto dofIdxGlobal = gridGeometry.dofMapper().index(element);
 
  183                const auto fvGeometry = 
localView(gridGeometry).bind(element);
 
  184                const auto curElemVolVars = 
localView(gridVariables.curGridVolVars()).bind(element, fvGeometry, sol);
 
  185                gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
 
 
  195    template<
class Problem, 
class Gr
idVariables, 
class SolutionVector>
 
  197                                    const typename GridVariables::GridGeometry& gridGeometry,
 
  198                                    GridVariables& gridVariables,
 
  201        if constexpr (GridVariables::GridGeometry::discMethod == 
DiscretizationMethods::box || Problem::enableInternalDirichletConstraints())
 
  203            std::vector<bool> stateChanged(sol.size(), 
false);
 
  204            std::size_t countChanged = 0;
 
  206            for (
const auto& element : elements(gridGeometry.gridView()))
 
  208                const auto fvGeometry = 
localView(gridGeometry).bindElement(element);
 
  211                if (!Problem::enableInternalDirichletConstraints() && !fvGeometry.hasBoundaryScvf())
 
  214                const auto elemVolVars = 
localView(gridVariables.curGridVolVars()).bindElement(element, fvGeometry, sol);
 
  216                for (
const auto& scv : scvs(fvGeometry))
 
  218                    const auto dofIdx = scv.dofIndex();
 
  220                    if (stateChanged[dofIdx])
 
  225                        if (gridGeometry.dofOnBoundary(dofIdx))
 
  229                                stateChanged[dofIdx] = 
true;
 
  236                    if constexpr (Problem::enableInternalDirichletConstraints())
 
  240                                stateChanged[dofIdx] = 
true;
 
  247                if constexpr (GridVariables::GridVolumeVariables::cachingEnabled)
 
  249                    if (countChanged > 0)
 
  252                        for (
const auto& scv : scvs(fvGeometry))
 
  254                            if (stateChanged[scv.dofIndex()])
 
  256                                auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv);
 
  257                                volVars.update(curElemSol, problem, element, scv);
 
  264            if (verbosity_ > 0 && countChanged > 0)
 
  265                std::cout << 
"Changed primary variable states and solution values to Dirichlet states and values at " << countChanged << 
" dof locations on processor " 
  266                          << gridGeometry.gridView().comm().rank() << 
"." << std::endl;
 
 
  272    { 
return verbosity_; }
 
 
  278    { 
return *
static_cast<Implementation*
>(
this); }
 
 
  282    { 
return *
static_cast<const Implementation*
>(
this); }
 
 
  285    template<
class VolumeVariables, 
class GlobalPosition>
 
  286    bool update_(
typename VolumeVariables::PrimaryVariables& priVars,
 
  287                 const VolumeVariables& volVars,
 
  288                 std::size_t dofIdxGlobal,
 
  289                 const GlobalPosition& globalPos)
 
  293        DUNE_THROW(Dune::NotImplemented, 
"This model seems to use a primary variable switch but none is implemented!");
 
 
  297    template<
class Geometry, 
class Problem>
 
  298    bool skipDof_(
const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element,
 
  299                  const Geometry& fvGeometry,
 
  300                  const typename Geometry::SubControlVolume& scv,
 
  301                  const Problem& problem)
 
 
  312    template<
class Geometry, 
class Problem>
 
  313    bool isConstrainedDof_(
const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element,
 
  314                           const Geometry& fvGeometry,
 
  315                           const typename Geometry::SubControlVolume& scv,
 
  316                           const Problem& problem)
 
  319        if constexpr (Geometry::GridGeometry::discMethod != 
DiscretizationMethods::box && !Problem::enableInternalDirichletConstraints())
 
  323        const auto isInternallyConstrainedDof = [&]()
 
  325            if constexpr (!Problem::enableInternalDirichletConstraints())
 
  329                const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv);
 
  330                return internalDirichletConstraints.any();
 
  334        if (isInternallyConstrainedDof())
 
  340            if (!fvGeometry.hasBoundaryScvf())
 
  343            const auto dofIdx = scv.dofIndex();
 
  344            if (!fvGeometry.gridGeometry().dofOnBoundary(dofIdx))
 
  347            const auto bcTypes = problem.boundaryTypes(element, scv);
 
  348            if (bcTypes.hasDirichlet())
 
 
  355    template<
class Problem, 
class Element, 
class SubControlVolume, 
class SolutionVector>
 
  357                                           const Element& element,
 
  358                                           const SubControlVolume& scv,
 
  361        bool changed = 
false;
 
  362        const auto bcTypes = problem.boundaryTypes(element, scv);
 
  363        if (bcTypes.hasDirichlet())
 
  365            const auto dirichletValues = problem.dirichlet(element, scv);
 
  366            const auto dofIdx = scv.dofIndex();
 
  368            if (sol[dofIdx].state() != dirichletValues.state())
 
  371                    std::cout << 
"Changing primary variable state at boundary (" << sol[dofIdx].state()
 
  372                                << 
") to the one given by the Dirichlet condition (" << dirichletValues.state() << 
") at dof " << dofIdx
 
  373                                << 
", coordinates: " << scv.dofPosition()
 
  377                sol[dofIdx].setState(dirichletValues.state());
 
  381                for (
int eqIdx = 0; eqIdx < SolutionVector::block_type::dimension; ++eqIdx)
 
  383                    if (bcTypes.isDirichlet(eqIdx))
 
  385                        const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
 
  386                        sol[dofIdx][pvIdx] = dirichletValues[pvIdx];
 
 
  395    template<
class Problem, 
class Element, 
class SubControlVolume, 
class SolutionVector>
 
  397                                            const Element& element,
 
  398                                            const SubControlVolume& scv,
 
  401        bool changed = 
false;
 
  403        const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv);
 
  404        if (internalDirichletConstraints.none())
 
  407        const auto dirichletValues = problem.internalDirichlet(element, scv);
 
  408        const auto dofIdx = scv.dofIndex();
 
  410        if (sol[dofIdx].state() != dirichletValues.state())
 
  413                std::cout << 
"Changing primary variable state at internal DOF (" << sol[dofIdx].state()
 
  414                            << 
") to the one given by the internal Dirichlet constraint (" << dirichletValues.state() << 
") at dof " << dofIdx
 
  415                            << 
", coordinates: " << scv.dofPosition()
 
  419            sol[dofIdx].setState(dirichletValues.state());
 
  423            for (
int pvIdx = 0; pvIdx < SolutionVector::block_type::dimension; ++pvIdx)
 
  425                if (internalDirichletConstraints[pvIdx])
 
  426                    sol[dofIdx][pvIdx] = dirichletValues[pvIdx];
 
 
  437    template<
class Gr
idVolumeVariables, 
class ElementVolumeVariables, 
class SubControlVolume>
 
  438    typename GridVolumeVariables::VolumeVariables&
 
  439    getVolVarAccess_(GridVolumeVariables& gridVolVars, ElementVolumeVariables& elemVolVars, 
const SubControlVolume& scv)
 const 
  441        if constexpr (GridVolumeVariables::cachingEnabled)
 
  442            return gridVolVars.volVars(scv);
 
  444            return elemVolVars[scv];
 
 
void reset(Args &&...)
Definition compositional/primaryvariableswitch.hh:35
void updateSwitchedVolVars(Args &&...)
Definition compositional/primaryvariableswitch.hh:38
NoPrimaryVariableSwitch(Args &&...)
Definition compositional/primaryvariableswitch.hh:33
bool wasSwitched(Args &&...) const
Definition compositional/primaryvariableswitch.hh:36
bool update(Args &&...)
Definition compositional/primaryvariableswitch.hh:37
void updateDirichletConstraints(Args &&...)
Definition compositional/primaryvariableswitch.hh:40
void updateSwitchedFluxVarsCache(Args &&...)
Definition compositional/primaryvariableswitch.hh:39
bool wasSwitched(std::size_t dofIdxGlobal) const
If the primary variables were recently switched.
Definition compositional/primaryvariableswitch.hh:56
std::vector< bool > wasSwitched_
Definition compositional/primaryvariableswitch.hh:433
void updateSwitchedVolVars(const Problem &problem, const typename GridVariables::GridGeometry::GridView::template Codim< 0 >::Entity &element, const typename GridVariables::GridGeometry &gridGeometry, GridVariables &gridVariables, const SolutionVector &sol)
Updates the volume variables whose primary variables were switched.
Definition compositional/primaryvariableswitch.hh:136
bool isConstrainedDof_(const typename Geometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const Geometry &fvGeometry, const typename Geometry::SubControlVolume &scv, const Problem &problem)
Definition compositional/primaryvariableswitch.hh:313
bool handleDirichletBoundaryCondition_(const Problem &problem, const Element &element, const SubControlVolume &scv, SolutionVector &sol)
Definition compositional/primaryvariableswitch.hh:356
PrimaryVariableSwitch(int verbosity=1)
Definition compositional/primaryvariableswitch.hh:51
bool handleInternalDirichletConstraint_(const Problem &problem, const Element &element, const SubControlVolume &scv, SolutionVector &sol)
Definition compositional/primaryvariableswitch.hh:396
Implementation & asImp_()
Return actual implementation (static polymorphism)
Definition compositional/primaryvariableswitch.hh:277
void updateDirichletConstraints(const Problem &problem, const typename GridVariables::GridGeometry &gridGeometry, GridVariables &gridVariables, SolutionVector &sol)
Updates the the primary variables state at the boundary.
Definition compositional/primaryvariableswitch.hh:196
bool skipDof_(const typename Geometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const Geometry &fvGeometry, const typename Geometry::SubControlVolume &scv, const Problem &problem)
Definition compositional/primaryvariableswitch.hh:298
const Implementation & asImp_() const
Return actual implementation (static polymorphism)
Definition compositional/primaryvariableswitch.hh:281
bool update(SolutionVector &curSol, GridVariables &gridVariables, const Problem &problem, const typename GridVariables::GridGeometry &gridGeometry)
Updates the variable switch / phase presence.
Definition compositional/primaryvariableswitch.hh:76
int verbosity() const
Definition compositional/primaryvariableswitch.hh:271
void reset(const std::size_t numDofs)
Reset all flags.
Definition compositional/primaryvariableswitch.hh:62
bool update_(typename VolumeVariables::PrimaryVariables &priVars, const VolumeVariables &volVars, std::size_t dofIdxGlobal, const GlobalPosition &globalPos)
Definition compositional/primaryvariableswitch.hh:286
std::vector< bool > visited_
Definition compositional/primaryvariableswitch.hh:434
void updateSwitchedFluxVarsCache(const Problem &problem, const typename GridVariables::GridGeometry::GridView::template Codim< 0 >::Entity &element, const typename GridVariables::GridGeometry &gridGeometry, GridVariables &gridVariables, const SolutionVector &sol)
Updates the fluxVars cache for dof whose primary variables were switched.
Definition compositional/primaryvariableswitch.hh:168
Element solution classes and factory functions.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::cctpfa||GridGeometry::discMethod==DiscretizationMethods::ccmpfa, CCElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for cell-centered schemes.
Definition cellcentered/elementsolution.hh:101
The available discretization methods in Dumux.
constexpr Box box
Definition method.hh:147