26#ifndef DUMUX_MULTIDOMAIN_BOX_LOCAL_ASSEMBLER_HH
27#define DUMUX_MULTIDOMAIN_BOX_LOCAL_ASSEMBLER_HH
29#include <dune/common/reservedvector.hh>
30#include <dune/common/indices.hh>
31#include <dune/common/hybridutilities.hh>
32#include <dune/grid/common/gridenums.hh>
33#include <dune/istl/matrixindexset.hh>
58template<std::
size_t id,
class TypeTag,
class Assembler,
class Implementation,
bool implicit>
67 using SolutionVector =
typename Assembler::SolutionVector;
72 using GridVolumeVariables =
typename GridVariables::GridVolumeVariables;
73 using ElementVolumeVariables =
typename GridVolumeVariables::LocalView;
74 using ElementFluxVariablesCache =
typename GridVariables::GridFluxVariablesCache::LocalView;
75 using Scalar =
typename GridVariables::Scalar;
77 using GridGeometry =
typename GridVariables::GridGeometry;
78 using FVElementGeometry =
typename GridGeometry::LocalView;
79 using SubControlVolume =
typename GridGeometry::SubControlVolume;
80 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
82 using GridView =
typename GridGeometry::GridView;
83 using Element =
typename GridView::template Codim<0>::Entity;
85 using CouplingManager =
typename Assembler::CouplingManager;
91 static constexpr auto domainId =
typename Dune::index_constant<id>();
93 using ParentType::ParentType;
98 const SolutionVector&
curSol,
116 template<
class JacobianMatrixRow,
class Gr
idVariablesTuple>
119 this->
asImp_().bindLocalViews();
126 const auto residual = this->
asImp_().assembleJacobianAndResidualImpl(jacRow[
domainId], *std::get<domainId>(gridVariables));
129 for (
const auto& scv : scvs(this->
fvGeometry()))
130 res[scv.dofIndex()] += residual[scv.localDofIndex()];
133 using namespace Dune::Hybrid;
134 forEach(integralRange(Dune::Hybrid::size(jacRow)), [&](
auto&& i)
142 using GridGeometry =
typename GridVariables::GridGeometry;
143 using GridView =
typename GridGeometry::GridView;
144 static constexpr auto dim = GridView::dimension;
146 int numVerticesLocal = this->
element().subEntities(dim);
148 for (
int i = 0; i < numVerticesLocal; ++i)
150 const auto vertex = this->
element().template subEntity<dim>(i);
152 if (vertex.partitionType() == Dune::InteriorEntity ||
153 vertex.partitionType() == Dune::BorderEntity)
160 const auto vIdx = this->
assembler().gridGeometry(
domainId).vertexMapper().index(vertex);
162 typedef typename JacobianMatrix::block_type BlockType;
163 BlockType &J = jacRow[
domainId][vIdx][vIdx];
164 for (
int j = 0; j < BlockType::rows; ++j)
173 auto applyDirichlet = [&] (
const auto& scvI,
174 const auto& dirichletValues,
178 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
184 for (
const auto& scvJ : scvs(this->
fvGeometry()))
185 jacRow[
domainId][scvI.dofIndex()][scvJ.dofIndex()][eqIdx] = 0.0;
188 jacRow[
domainId][scvI.dofIndex()][scvI.dofIndex()][eqIdx][pvIdx] = 1.0;
192 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
199 template<std::size_t otherId,
class JacRow,
class GridVariables,
200 typename std::enable_if_t<(otherId == id),
int> = 0>
202 const ElementResidualVector& res, GridVariables& gridVariables)
208 template<std::size_t otherId,
class JacRow,
class GridVariables,
209 typename std::enable_if_t<(otherId != id),
int> = 0>
211 const ElementResidualVector& res, GridVariables& gridVariables)
213 this->
asImp_().assembleJacobianCoupling(domainJ, jacRow[domainJ], res, *std::get<domainId>(gridVariables));
221 this->
asImp_().bindLocalViews();
225 for (
const auto& scv : scvs(this->
fvGeometry()))
226 res[scv.dofIndex()] += residual[scv.localDofIndex()];
228 auto applyDirichlet = [&] (
const auto& scvI,
229 const auto& dirichletValues,
233 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
236 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
245 ElementResidualVector residual(this->
fvGeometry().numScv());
251 const auto& curVolVars = elemVolVars[scv];
253 source *= -Extrusion::volume(scv)*curVolVars.extrusionFactor();
254 residual[scv.localDofIndex()] = std::move(source);
267 template<
typename ApplyFunction>
271 this->
asImp_().evalDirichletBoundaries(applyDirichlet);
273 this->
asImp_().enforceInternalDirichletConstraints(applyDirichlet);
280 template<
typename ApplyDirichletFunctionType >
287 for (
const auto& scvI : scvs(this->
fvGeometry()))
289 const auto bcTypes = this->
elemBcTypes()[scvI.localDofIndex()];
290 if (bcTypes.hasDirichlet())
292 const auto dirichletValues = this->
problem().dirichlet(this->
element(), scvI);
295 for (
int eqIdx = 0; eqIdx < numEq; ++eqIdx)
297 if (bcTypes.isDirichlet(eqIdx))
299 const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
300 assert(0 <= pvIdx && pvIdx < numEq);
301 applyDirichlet(scvI, dirichletValues, eqIdx, pvIdx);
329 if (!this->
assembler().isStationaryProblem())
349 {
return couplingManager_; }
366template<std::
size_t id,
class TypeTag,
class Assembler, DiffMethod DM = DiffMethod::numeric,
bool implicit = true>
375template<std::
size_t id,
class TypeTag,
class Assembler>
384 using ElementResidualVector =
typename ParentType::LocalResidual::ElementResidualVector;
388 using FVElementGeometry =
typename GridGeometry::LocalView;
389 using GridView =
typename GridGeometry::GridView;
390 using Element =
typename GridView::template Codim<0>::Entity;
394 enum { dim = GridView::dimension };
398 static constexpr auto domainI = Dune::index_constant<id>();
401 using ParentType::ParentType;
409 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
432 auto partialDerivs = origResiduals;
438 const auto dofIdx = scv.dofIndex();
440 const VolumeVariables origVolVars(curVolVars);
443 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
447 auto evalResiduals = [&](Scalar priVar)
450 const auto localDofIndex = scv.localDofIndex();
451 elemSol[localDofIndex][pvIdx] = priVar;
453 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[localDofIndex], pvIdx);
461 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
466 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
472 A[scvJ.dofIndex()][dofIdx][eqIdx][pvIdx] += partialDerivs[scvJ.localDofIndex()][eqIdx];
477 curVolVars = origVolVars;
480 elemSol[scv.localDofIndex()][pvIdx] =
curSol[scv.dofIndex()][pvIdx];
481 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[scv.localDofIndex()], pvIdx);
486 this->
couplingManager().evalAdditionalDomainDerivatives(domainI, *
this, origResiduals, A, gridVariables);
488 return origResiduals;
495 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
497 const ElementResidualVector& res, GridVariables& gridVariables)
513 auto updateCoupledVariables = [&] ()
517 if (enableGridFluxVarsCache)
519 if (enableGridVolVarsCache)
520 this->
couplingManager().updateCoupledVariables(domainI, *
this, gridVariables.curGridVolVars(), gridVariables.gridFluxVarsCache());
526 if (enableGridVolVarsCache)
533 const auto& curSolJ = this->
curSol()[domainJ];
534 for (
const auto globalJ : stencil)
537 const auto origPriVarsJ = curSolJ[globalJ];
538 auto priVarsJ = origPriVarsJ;
541 const auto origResidual = this->
couplingManager().evalCouplingResidual(domainI, *
this, domainJ, globalJ);
543 for (
int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
545 auto evalCouplingResidual = [&](Scalar priVar)
547 priVarsJ[pvIdx] = priVar;
548 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
549 updateCoupledVariables();
550 return this->
couplingManager().evalCouplingResidual(domainI, *
this, domainJ, globalJ);
554 ElementResidualVector partialDerivs(
element.subEntities(dim));
556 const auto& paramGroup = this->
assembler().problem(domainJ).paramGroup();
558 static const auto epsCoupl = this->
couplingManager().numericEpsilon(domainJ, paramGroup);
561 epsCoupl(origPriVarsJ[pvIdx], pvIdx), numDiffMethod);
566 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
576 const auto bcTypes = this->
elemBcTypes()[scv.localDofIndex()];
577 if (bcTypes.isCouplingDirichlet(eqIdx))
578 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = partialDerivs[scv.localDofIndex()][eqIdx];
579 else if (bcTypes.isDirichlet(eqIdx))
580 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
582 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
585 if constexpr (Problem::enableInternalDirichletConstraints())
587 const auto internalDirichletConstraints = this->
problem().hasInternalDirichletConstraint(this->
element(), scv);
588 if (internalDirichletConstraints[eqIdx])
589 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
596 priVarsJ[pvIdx] = origPriVarsJ[pvIdx];
599 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
606 updateCoupledVariables();
617template<std::
size_t id,
class TypeTag,
class Assembler>
620 SubDomainBoxLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, false>, false >
626 using ElementResidualVector =
typename ParentType::LocalResidual::ElementResidualVector;
629 using FVElementGeometry =
typename GridGeometry::LocalView;
630 using GridView =
typename GridGeometry::GridView;
631 using Element =
typename GridView::template Codim<0>::Entity;
634 enum { dim = GridView::dimension };
638 static constexpr auto domainI = Dune::index_constant<id>();
641 using ParentType::ParentType;
649 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
652 if (this->
assembler().isStationaryProblem())
653 DUNE_THROW(Dune::InvalidStateException,
"Using explicit jacobian assembler with stationary local residual");
675 ElementResidualVector partialDerivs(
element.subEntities(dim));
681 const auto dofIdx = scv.dofIndex();
683 const VolumeVariables origVolVars(curVolVars);
686 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
690 auto evalStorage = [&](Scalar priVar)
693 elemSol[scv.localDofIndex()][pvIdx] = priVar;
702 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
705 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
711 A[dofIdx][dofIdx][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
715 curVolVars = origVolVars;
718 elemSol[scv.localDofIndex()][pvIdx] =
curSol[scv.dofIndex()][pvIdx];
724 return origResiduals;
733 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
735 const ElementResidualVector& res, GridVariables& gridVariables)
A helper to deduce a vector with the same size as numbers of equations.
A class for numeric differentiation.
A arithmetic block vector type based on DUNE's reserved vector.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
A base class for all local assemblers.
An adapter class for local assemblers using numeric differentiation.
An enum class to define various differentiation methods available in order to compute the derivatives...
Helper classes to compute the integration elements.
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
DiffMethod
Differentiation methods in order to compute the derivatives of the residual i.e. the entries in the j...
Definition diffmethod.hh:37
@ numeric
Definition diffmethod.hh:38
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition numeqvector.hh:46
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:161
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:154
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:150
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:177
Definition common/pdesolver.hh:36
ElementVolumeVariables & curElemVolVars()
Definition fvlocalassemblerbase.hh:265
typename LocalResidual::ElementResidualVector ElementResidualVector
Definition fvlocalassemblerbase.hh:68
ElementBoundaryTypes & elemBcTypes()
Definition fvlocalassemblerbase.hh:281
Implementation & asImp_()
Definition fvlocalassemblerbase.hh:309
ElementVolumeVariables & prevElemVolVars()
Definition fvlocalassemblerbase.hh:269
ElementResidualVector evalLocalResidual() const
Definition fvlocalassemblerbase.hh:120
FVLocalAssemblerBase(const Assembler &assembler, const Element &element, const SolutionVector &curSol)
Definition fvlocalassemblerbase.hh:73
FVElementGeometry & fvGeometry()
Definition fvlocalassemblerbase.hh:261
const Assembler & assembler() const
Definition fvlocalassemblerbase.hh:245
ElementFluxVariablesCache & elemFluxVarsCache()
Definition fvlocalassemblerbase.hh:273
bool elementIsGhost() const
Definition fvlocalassemblerbase.hh:253
LocalResidual & localResidual()
Definition fvlocalassemblerbase.hh:277
const Element & element() const
Definition fvlocalassemblerbase.hh:249
VolumeVariables & getVolVarAccess(GridVolumeVariables &gridVolVars, ElementVolumeVariables &elemVolVars, const SubControlVolume &scv)
Definition fvlocalassemblerbase.hh:316
ElementResidualVector evalLocalStorageResidual() const
Definition fvlocalassemblerbase.hh:176
const SolutionVector & curSol() const
Definition fvlocalassemblerbase.hh:257
A helper class for local assemblers using numeric differentiation to determine the epsilon.
Definition numericepsilon.hh:41
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const int numericDifferenceMethod=1)
Computes the derivative of a function with repect to a function parameter.
Definition numericdifferentiation.hh:61
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:60
void enforceDirichletConstraints(const ApplyFunction &applyDirichlet)
Enforce Dirichlet constraints.
Definition subdomainboxlocalassembler.hh:268
void bindLocalViews()
Prepares all local views necessary for local assembly.
Definition subdomainboxlocalassembler.hh:312
static constexpr auto domainId
Definition subdomainboxlocalassembler.hh:91
ElementResidualVector evalLocalSourceResidual(const Element &element, const ElementVolumeVariables &elemVolVars) const
Evaluates the local source term for an element and given element volume variables.
Definition subdomainboxlocalassembler.hh:242
CouplingManager & couplingManager()
Definition subdomainboxlocalassembler.hh:348
ElementResidualVector evalLocalSourceResidual(const Element &neighbor) const
Evaluates the local source term depending on time discretization scheme.
Definition subdomainboxlocalassembler.hh:263
void evalDirichletBoundaries(ApplyDirichletFunctionType applyDirichlet)
Incorporate Dirichlet boundary conditions.
Definition subdomainboxlocalassembler.hh:281
void assembleResidual(SubSolutionVector &res)
Assemble the residual vector entries only.
Definition subdomainboxlocalassembler.hh:219
void assembleJacobianCoupling(Dune::index_constant< otherId > domainJ, JacRow &jacRow, const ElementResidualVector &res, GridVariables &gridVariables)
Assemble the entries in a coupling block of the jacobian. There is no coupling block between a domain...
Definition subdomainboxlocalassembler.hh:201
const Problem & problem() const
return reference to the underlying problem
Definition subdomainboxlocalassembler.hh:344
void assembleJacobianAndResidual(JacobianMatrixRow &jacRow, SubSolutionVector &res, GridVariablesTuple &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix....
Definition subdomainboxlocalassembler.hh:117
SubDomainBoxLocalAssemblerBase(const Assembler &assembler, const Element &element, const SolutionVector &curSol, CouplingManager &couplingManager)
Definition subdomainboxlocalassembler.hh:96
The box scheme multidomain local assembler.
Definition subdomainboxlocalassembler.hh:367
ElementResidualVector assembleJacobianAndResidualImpl(JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition subdomainboxlocalassembler.hh:410
void assembleJacobianCoupling(Dune::index_constant< otherId > domainJ, JacobianBlock &A, const ElementResidualVector &res, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition subdomainboxlocalassembler.hh:496
ElementResidualVector assembleJacobianAndResidualImpl(JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition subdomainboxlocalassembler.hh:650
void assembleJacobianCoupling(Dune::index_constant< otherId > domainJ, JacobianBlock &A, const ElementResidualVector &res, GridVariables &gridVariables)
Computes the coupling derivatives with respect to the given element and adds them to the global matri...
Definition subdomainboxlocalassembler.hh:734
Declares all properties used in Dumux.