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);
180 if (
asImp_().wasSwitched(dofIdxGlobal))
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];
Empty class for models without pri var switch.
Definition: compositional/primaryvariableswitch.hh:30
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
The primary variable switch controlling the phase presence state variable.
Definition: compositional/primaryvariableswitch.hh:49
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
The verbosity level.
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