25#ifndef DUMUX_PRIMARY_VARIABLE_SWITCH_HH
26#define DUMUX_PRIMARY_VARIABLE_SWITCH_HH
30#include <dune/common/exceptions.hh>
31#include <dune/common/fvector.hh>
44 template<
typename... Args>
47 template<
typename... Args>
void reset(Args&&...) {}
48 template<
typename... Args>
bool wasSwitched(Args&&...)
const {
return false; }
49 template<
typename... Args>
bool update(Args&&...) {
return false; }
59template<
class Implementation>
74 void reset(
const std::size_t numDofs)
87 template<
class SolutionVector,
class Gr
idVariables,
class Problem>
89 GridVariables& gridVariables,
90 const Problem& problem,
91 const typename GridVariables::GridGeometry& gridGeometry)
93 bool switched =
false;
95 std::size_t countSwitched = 0;
97 auto fvGeometry =
localView(gridGeometry);
98 auto elemVolVars =
localView(gridVariables.curGridVolVars());
100 for (
const auto& element : elements(gridGeometry.gridView()))
103 fvGeometry.bindElement(element);
104 elemVolVars.bindElement(element, fvGeometry, curSol);
106 const auto curElemSol =
elementSolution(element, curSol, gridGeometry);
107 for (
auto&& scv : scvs(fvGeometry))
111 const auto dofIdxGlobal = scv.dofIndex();
117 auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv);
118 volVars.update(curElemSol, problem, element, scv);
120 if (
asImp_().
update_(curSol[dofIdxGlobal], volVars, dofIdxGlobal, scv.dofPosition()))
129 if (verbosity_ > 0 && countSwitched > 0)
130 std::cout <<
"Switched primary variables at " << countSwitched <<
" dof locations on processor "
131 << gridGeometry.gridView().comm().rank() <<
"." << std::endl;
135 if (gridGeometry.gridView().comm().size() > 1)
136 switched = gridGeometry.gridView().comm().max(switched);
147 template<
class Problem,
class Gr
idVariables,
class SolutionVector>
149 const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
150 const typename GridVariables::GridGeometry& gridGeometry,
151 GridVariables& gridVariables,
152 const SolutionVector& sol)
154 if constexpr (GridVariables::GridVolumeVariables::cachingEnabled)
157 const auto fvGeometry =
localView(gridGeometry).bindElement(element);
160 for (
auto&& scv : scvs(fvGeometry))
162 const auto dofIdxGlobal = scv.dofIndex();
166 auto& volVars = gridVariables.curGridVolVars().volVars(scv);
167 volVars.update(elemSol, problem, element, scv);
179 template<
class Problem,
class Gr
idVariables,
class SolutionVector>
181 const typename GridVariables::GridGeometry::GridView::template Codim<0>::Entity& element,
182 const typename GridVariables::GridGeometry& gridGeometry,
183 GridVariables& gridVariables,
184 const SolutionVector& sol)
186 if constexpr (GridVariables::GridFluxVariablesCache::cachingEnabled
190 const auto dofIdxGlobal = gridGeometry.dofMapper().index(element);
192 if (
asImp_().wasSwitched(dofIdxGlobal))
195 const auto fvGeometry =
localView(gridGeometry).bind(element);
196 const auto curElemVolVars =
localView(gridVariables.curGridVolVars()).bind(element, fvGeometry, sol);
197 gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
207 template<
class Problem,
class Gr
idVariables,
class SolutionVector>
209 const typename GridVariables::GridGeometry& gridGeometry,
210 GridVariables& gridVariables,
213 if constexpr (GridVariables::GridGeometry::discMethod ==
DiscretizationMethods::box || Problem::enableInternalDirichletConstraints())
215 std::vector<bool> stateChanged(sol.size(),
false);
216 std::size_t countChanged = 0;
218 for (
const auto& element : elements(gridGeometry.gridView()))
220 const auto fvGeometry =
localView(gridGeometry).bindElement(element);
223 if (!Problem::enableInternalDirichletConstraints() && !fvGeometry.hasBoundaryScvf())
226 const auto elemVolVars =
localView(gridVariables.curGridVolVars()).bindElement(element, fvGeometry, sol);
228 for (
const auto& scv : scvs(fvGeometry))
230 const auto dofIdx = scv.dofIndex();
232 if (stateChanged[dofIdx])
237 if (gridGeometry.dofOnBoundary(dofIdx))
241 stateChanged[dofIdx] =
true;
248 if constexpr (Problem::enableInternalDirichletConstraints())
252 stateChanged[dofIdx] =
true;
259 if constexpr (GridVariables::GridVolumeVariables::cachingEnabled)
261 if (countChanged > 0)
264 for (
const auto& scv : scvs(fvGeometry))
266 if (stateChanged[scv.dofIndex()])
268 auto& volVars = getVolVarAccess_(gridVariables.curGridVolVars(), elemVolVars, scv);
269 volVars.update(curElemSol, problem, element, scv);
276 if (verbosity_ > 0 && countChanged > 0)
277 std::cout <<
"Changed primary variable states and solution values to Dirichlet states and values at " << countChanged <<
" dof locations on processor "
278 << gridGeometry.gridView().comm().rank() <<
"." << std::endl;
284 {
return verbosity_; }
290 {
return *
static_cast<Implementation*
>(
this); }
294 {
return *
static_cast<const Implementation*
>(
this); }
297 template<
class VolumeVariables,
class GlobalPosition>
298 bool update_(
typename VolumeVariables::PrimaryVariables& priVars,
299 const VolumeVariables& volVars,
300 std::size_t dofIdxGlobal,
301 const GlobalPosition& globalPos)
305 DUNE_THROW(Dune::NotImplemented,
"This model seems to use a primary variable switch but none is implemented!");
309 template<
class Geometry,
class Problem>
310 bool skipDof_(
const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element,
311 const Geometry& fvGeometry,
312 const typename Geometry::SubControlVolume& scv,
313 const Problem& problem)
324 template<
class Geometry,
class Problem>
325 bool isConstrainedDof_(
const typename Geometry::GridGeometry::GridView::template Codim<0>::Entity& element,
326 const Geometry& fvGeometry,
327 const typename Geometry::SubControlVolume& scv,
328 const Problem& problem)
331 if constexpr (Geometry::GridGeometry::discMethod !=
DiscretizationMethods::box && !Problem::enableInternalDirichletConstraints())
335 const auto isInternallyConstrainedDof = [&]()
337 if constexpr (!Problem::enableInternalDirichletConstraints())
341 const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv);
342 return internalDirichletConstraints.any();
346 if (isInternallyConstrainedDof())
352 if (!fvGeometry.hasBoundaryScvf())
355 const auto dofIdx = scv.dofIndex();
356 if (!fvGeometry.gridGeometry().dofOnBoundary(dofIdx))
359 const auto bcTypes = problem.boundaryTypes(element, scv);
360 if (bcTypes.hasDirichlet())
367 template<
class Problem,
class Element,
class SubControlVolume,
class SolutionVector>
369 const Element& element,
370 const SubControlVolume& scv,
373 bool changed =
false;
374 const auto bcTypes = problem.boundaryTypes(element, scv);
375 if (bcTypes.hasDirichlet())
377 const auto dirichletValues = problem.dirichlet(element, scv);
378 const auto dofIdx = scv.dofIndex();
380 if (sol[dofIdx].state() != dirichletValues.state())
383 std::cout <<
"Changing primary variable state at boundary (" << sol[dofIdx].state()
384 <<
") to the one given by the Dirichlet condition (" << dirichletValues.state() <<
") at dof " << dofIdx
385 <<
", coordinates: " << scv.dofPosition()
389 sol[dofIdx].setState(dirichletValues.state());
393 for (
int eqIdx = 0; eqIdx < SolutionVector::block_type::dimension; ++eqIdx)
395 if (bcTypes.isDirichlet(eqIdx))
397 const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
398 sol[dofIdx][pvIdx] = dirichletValues[pvIdx];
407 template<
class Problem,
class Element,
class SubControlVolume,
class SolutionVector>
409 const Element& element,
410 const SubControlVolume& scv,
413 bool changed =
false;
415 const auto internalDirichletConstraints = problem.hasInternalDirichletConstraint(element, scv);
416 if (internalDirichletConstraints.none())
419 const auto dirichletValues = problem.internalDirichlet(element, scv);
420 const auto dofIdx = scv.dofIndex();
422 if (sol[dofIdx].state() != dirichletValues.state())
425 std::cout <<
"Changing primary variable state at internal DOF (" << sol[dofIdx].state()
426 <<
") to the one given by the internal Dirichlet constraint (" << dirichletValues.state() <<
") at dof " << dofIdx
427 <<
", coordinates: " << scv.dofPosition()
431 sol[dofIdx].setState(dirichletValues.state());
435 for (
int pvIdx = 0; pvIdx < SolutionVector::block_type::dimension; ++pvIdx)
437 if (internalDirichletConstraints[pvIdx])
438 sol[dofIdx][pvIdx] = dirichletValues[pvIdx];
449 template<
class Gr
idVolumeVariables,
class ElementVolumeVariables,
class SubControlVolume>
450 typename GridVolumeVariables::VolumeVariables&
451 getVolVarAccess_(GridVolumeVariables& gridVolVars, ElementVolumeVariables& elemVolVars,
const SubControlVolume& scv)
const
453 if constexpr (GridVolumeVariables::cachingEnabled)
454 return gridVolVars.volVars(scv);
456 return elemVolVars[scv];
Element solution classes and factory functions.
The available discretization methods in Dumux.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::box, BoxElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for box schemes.
Definition: box/elementsolution.hh:118
constexpr Box box
Definition: method.hh:139
Empty class for models without pri var switch.
Definition: compositional/primaryvariableswitch.hh:42
void reset(Args &&...)
Definition: compositional/primaryvariableswitch.hh:47
void updateSwitchedVolVars(Args &&...)
Definition: compositional/primaryvariableswitch.hh:50
NoPrimaryVariableSwitch(Args &&...)
Definition: compositional/primaryvariableswitch.hh:45
bool wasSwitched(Args &&...) const
Definition: compositional/primaryvariableswitch.hh:48
bool update(Args &&...)
Definition: compositional/primaryvariableswitch.hh:49
void updateDirichletConstraints(Args &&...)
Definition: compositional/primaryvariableswitch.hh:52
void updateSwitchedFluxVarsCache(Args &&...)
Definition: compositional/primaryvariableswitch.hh:51
The primary variable switch controlling the phase presence state variable.
Definition: compositional/primaryvariableswitch.hh:61
bool wasSwitched(std::size_t dofIdxGlobal) const
If the primary variables were recently switched.
Definition: compositional/primaryvariableswitch.hh:68
std::vector< bool > wasSwitched_
Definition: compositional/primaryvariableswitch.hh:445
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:148
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:325
bool handleDirichletBoundaryCondition_(const Problem &problem, const Element &element, const SubControlVolume &scv, SolutionVector &sol)
Definition: compositional/primaryvariableswitch.hh:368
PrimaryVariableSwitch(int verbosity=1)
Definition: compositional/primaryvariableswitch.hh:63
bool handleInternalDirichletConstraint_(const Problem &problem, const Element &element, const SubControlVolume &scv, SolutionVector &sol)
Definition: compositional/primaryvariableswitch.hh:408
Implementation & asImp_()
Return actual implementation (static polymorphism)
Definition: compositional/primaryvariableswitch.hh:289
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:208
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:310
const Implementation & asImp_() const
Return actual implementation (static polymorphism)
Definition: compositional/primaryvariableswitch.hh:293
bool update(SolutionVector &curSol, GridVariables &gridVariables, const Problem &problem, const typename GridVariables::GridGeometry &gridGeometry)
Updates the variable switch / phase presence.
Definition: compositional/primaryvariableswitch.hh:88
int verbosity() const
The verbosity level.
Definition: compositional/primaryvariableswitch.hh:283
void reset(const std::size_t numDofs)
Reset all flags.
Definition: compositional/primaryvariableswitch.hh:74
bool update_(typename VolumeVariables::PrimaryVariables &priVars, const VolumeVariables &volVars, std::size_t dofIdxGlobal, const GlobalPosition &globalPos)
Definition: compositional/primaryvariableswitch.hh:298
std::vector< bool > visited_
Definition: compositional/primaryvariableswitch.hh:446
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:180