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>
56template<std::
size_t id,
class TypeTag,
class Assembler,
class Implementation,
bool implicit>
65 using SolutionVector =
typename Assembler::SolutionVector;
70 using GridVolumeVariables =
typename GridVariables::GridVolumeVariables;
71 using ElementVolumeVariables =
typename GridVolumeVariables::LocalView;
72 using ElementFluxVariablesCache =
typename GridVariables::GridFluxVariablesCache::LocalView;
73 using Scalar =
typename GridVariables::Scalar;
75 using GridGeometry =
typename GridVariables::GridGeometry;
76 using FVElementGeometry =
typename GridGeometry::LocalView;
77 using SubControlVolume =
typename GridGeometry::SubControlVolume;
78 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
79 using GridView =
typename GridGeometry::GridView;
80 using Element =
typename GridView::template Codim<0>::Entity;
82 using CouplingManager =
typename Assembler::CouplingManager;
88 static constexpr auto domainId =
typename Dune::index_constant<id>();
90 using ParentType::ParentType;
95 const SolutionVector&
curSol,
113 template<
class JacobianMatrixRow,
class Gr
idVariablesTuple>
116 this->
asImp_().bindLocalViews();
121 const auto residual = this->
asImp_().assembleJacobianAndResidualImpl(jacRow[
domainId], *std::get<domainId>(gridVariables));
124 for (
const auto& scv : scvs(this->
fvGeometry()))
125 res[scv.dofIndex()] += residual[scv.localDofIndex()];
128 using namespace Dune::Hybrid;
129 forEach(integralRange(Dune::Hybrid::size(jacRow)), [&](
auto&& i)
136 auto applyDirichlet = [&] (
const auto& scvI,
137 const auto& dirichletValues,
141 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
147 for (
const auto& scvJ : scvs(this->
fvGeometry()))
148 jacRow[
domainId][scvI.dofIndex()][scvJ.dofIndex()][eqIdx] = 0.0;
151 jacRow[
domainId][scvI.dofIndex()][scvI.dofIndex()][eqIdx][pvIdx] = 1.0;
155 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
162 template<std::size_t otherId,
class JacRow,
class GridVariables,
163 typename std::enable_if_t<(otherId == id),
int> = 0>
165 const ElementResidualVector& res, GridVariables& gridVariables)
171 template<std::size_t otherId,
class JacRow,
class GridVariables,
172 typename std::enable_if_t<(otherId != id),
int> = 0>
174 const ElementResidualVector& res, GridVariables& gridVariables)
176 this->
asImp_().assembleJacobianCoupling(domainJ, jacRow[domainJ], res, *std::get<domainId>(gridVariables));
184 this->
asImp_().bindLocalViews();
188 for (
const auto& scv : scvs(this->
fvGeometry()))
189 res[scv.dofIndex()] += residual[scv.localDofIndex()];
191 auto applyDirichlet = [&] (
const auto& scvI,
192 const auto& dirichletValues,
196 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
199 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
208 ElementResidualVector residual(this->
fvGeometry().numScv());
214 const auto& curVolVars = elemVolVars[scv];
216 source *= -scv.volume()*curVolVars.extrusionFactor();
217 residual[scv.localDofIndex()] = std::move(source);
230 template<
typename ApplyFunction>
234 this->
asImp_().evalDirichletBoundaries(applyDirichlet);
236 this->
asImp_().enforceInternalDirichletConstraints(applyDirichlet);
243 template<
typename ApplyDirichletFunctionType >
250 for (
const auto& scvI : scvs(this->
fvGeometry()))
252 const auto bcTypes = this->
elemBcTypes()[scvI.localDofIndex()];
253 if (bcTypes.hasDirichlet())
255 const auto dirichletValues = this->
problem().dirichlet(this->
element(), scvI);
258 for (
int eqIdx = 0; eqIdx < numEq; ++eqIdx)
260 if (bcTypes.isDirichlet(eqIdx))
262 const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
263 assert(0 <= pvIdx && pvIdx < numEq);
264 applyDirichlet(scvI, dirichletValues, eqIdx, pvIdx);
292 if (!this->
assembler().isStationaryProblem())
312 {
return couplingManager_; }
329template<std::
size_t id,
class TypeTag,
class Assembler, DiffMethod DM = DiffMethod::numeric,
bool implicit = true>
338template<std::
size_t id,
class TypeTag,
class Assembler>
347 using ElementResidualVector =
typename ParentType::LocalResidual::ElementResidualVector;
351 using FVElementGeometry =
typename GridGeometry::LocalView;
352 using GridView =
typename GridGeometry::GridView;
353 using Element =
typename GridView::template Codim<0>::Entity;
356 enum { dim = GridView::dimension };
360 static constexpr auto domainI = Dune::index_constant<id>();
363 using ParentType::ParentType;
371 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
394 auto partialDerivs = origResiduals;
400 const auto dofIdx = scv.dofIndex();
402 const VolumeVariables origVolVars(curVolVars);
405 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
409 auto evalResiduals = [&](Scalar priVar)
412 const auto localDofIndex = scv.localDofIndex();
413 elemSol[localDofIndex][pvIdx] = priVar;
415 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[localDofIndex], pvIdx);
423 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
428 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
434 A[scvJ.dofIndex()][dofIdx][eqIdx][pvIdx] += partialDerivs[scvJ.localDofIndex()][eqIdx];
439 curVolVars = origVolVars;
442 elemSol[scv.localDofIndex()][pvIdx] =
curSol[scv.dofIndex()][pvIdx];
443 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[scv.localDofIndex()], pvIdx);
448 this->
couplingManager().evalAdditionalDomainDerivatives(domainI, *
this, origResiduals, A, gridVariables);
450 return origResiduals;
459 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
461 const ElementResidualVector& res, GridVariables& gridVariables)
477 auto updateCoupledVariables = [&] ()
481 if (enableGridFluxVarsCache)
483 if (enableGridVolVarsCache)
484 this->
couplingManager().updateCoupledVariables(domainI, *
this, gridVariables.curGridVolVars(), gridVariables.gridFluxVarsCache());
490 if (enableGridVolVarsCache)
497 const auto& curSolJ = this->
curSol()[domainJ];
498 for (
const auto globalJ : stencil)
501 const auto origPriVarsJ = curSolJ[globalJ];
502 auto priVarsJ = origPriVarsJ;
505 const auto origResidual = this->
couplingManager().evalCouplingResidual(domainI, *
this, domainJ, globalJ);
507 for (
int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
509 auto evalCouplingResidual = [&](Scalar priVar)
511 priVarsJ[pvIdx] = priVar;
512 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
513 updateCoupledVariables();
514 return this->
couplingManager().evalCouplingResidual(domainI, *
this, domainJ, globalJ);
518 ElementResidualVector partialDerivs(
element.subEntities(dim));
520 const auto& paramGroup = this->
assembler().problem(domainJ).paramGroup();
522 static const auto epsCoupl = this->
couplingManager().numericEpsilon(domainJ, paramGroup);
525 epsCoupl(origPriVarsJ[pvIdx], pvIdx), numDiffMethod);
530 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
540 const auto bcTypes = this->
elemBcTypes()[scv.localDofIndex()];
541 if (bcTypes.isCouplingDirichlet(eqIdx))
542 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = partialDerivs[scv.localDofIndex()][eqIdx];
543 else if (bcTypes.isDirichlet(eqIdx))
544 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
546 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
551 priVarsJ[pvIdx] = origPriVarsJ[pvIdx];
554 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
561 updateCoupledVariables();
572template<std::
size_t id,
class TypeTag,
class Assembler>
575 SubDomainBoxLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, false>, false >
581 using ElementResidualVector =
typename ParentType::LocalResidual::ElementResidualVector;
584 using FVElementGeometry =
typename GridGeometry::LocalView;
585 using GridView =
typename GridGeometry::GridView;
586 using Element =
typename GridView::template Codim<0>::Entity;
589 enum { dim = GridView::dimension };
593 static constexpr auto domainI = Dune::index_constant<id>();
596 using ParentType::ParentType;
604 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
607 if (this->
assembler().isStationaryProblem())
608 DUNE_THROW(Dune::InvalidStateException,
"Using explicit jacobian assembler with stationary local residual");
630 ElementResidualVector partialDerivs(
element.subEntities(dim));
636 const auto dofIdx = scv.dofIndex();
638 const VolumeVariables origVolVars(curVolVars);
641 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
645 auto evalStorage = [&](Scalar priVar)
648 elemSol[scv.localDofIndex()][pvIdx] = priVar;
657 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
660 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
666 A[dofIdx][dofIdx][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
670 curVolVars = origVolVars;
673 elemSol[scv.localDofIndex()][pvIdx] =
curSol[scv.dofIndex()][pvIdx];
679 return origResiduals;
688 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
690 const ElementResidualVector& res, GridVariables& gridVariables)
An enum class to define various differentiation methods available in order to compute the derivatives...
An adapter class for local assemblers using numeric differentiation.
A base class for all local assemblers.
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.
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==DiscretizationMethod::box, BoxElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for box schemes.
Definition box/elementsolution.hh:115
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
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:375
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:153
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition propertysystem.hh:149
Definition common/pdesolver.hh:35
ElementVolumeVariables & curElemVolVars()
Definition fvlocalassemblerbase.hh:263
typename LocalResidual::ElementResidualVector ElementResidualVector
Definition fvlocalassemblerbase.hh:68
ElementBoundaryTypes & elemBcTypes()
Definition fvlocalassemblerbase.hh:279
Implementation & asImp_()
Definition fvlocalassemblerbase.hh:307
ElementVolumeVariables & prevElemVolVars()
Definition fvlocalassemblerbase.hh:267
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:259
const Assembler & assembler() const
Definition fvlocalassemblerbase.hh:243
ElementFluxVariablesCache & elemFluxVarsCache()
Definition fvlocalassemblerbase.hh:271
LocalResidual & localResidual()
Definition fvlocalassemblerbase.hh:275
const Element & element() const
Definition fvlocalassemblerbase.hh:247
VolumeVariables & getVolVarAccess(GridVolumeVariables &gridVolVars, ElementVolumeVariables &elemVolVars, const SubControlVolume &scv)
Definition fvlocalassemblerbase.hh:314
ElementResidualVector evalLocalStorageResidual() const
Definition fvlocalassemblerbase.hh:176
const SolutionVector & curSol() const
Definition fvlocalassemblerbase.hh:255
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
Definition multidomain/couplingmanager.hh:46
void enforceDirichletConstraints(const ApplyFunction &applyDirichlet)
Enforce Dirichlet constraints.
Definition subdomainboxlocalassembler.hh:231
void bindLocalViews()
Prepares all local views necessary for local assembly.
Definition subdomainboxlocalassembler.hh:275
static constexpr auto domainId
Definition subdomainboxlocalassembler.hh:88
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:205
CouplingManager & couplingManager()
Definition subdomainboxlocalassembler.hh:311
ElementResidualVector evalLocalSourceResidual(const Element &neighbor) const
Evaluates the local source term depending on time discretization scheme.
Definition subdomainboxlocalassembler.hh:226
void evalDirichletBoundaries(ApplyDirichletFunctionType applyDirichlet)
Incorporate Dirichlet boundary conditions.
Definition subdomainboxlocalassembler.hh:244
void assembleResidual(SubSolutionVector &res)
Assemble the residual vector entries only.
Definition subdomainboxlocalassembler.hh:182
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:164
const Problem & problem() const
return reference to the underlying problem
Definition subdomainboxlocalassembler.hh:307
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:114
SubDomainBoxLocalAssemblerBase(const Assembler &assembler, const Element &element, const SolutionVector &curSol, CouplingManager &couplingManager)
Definition subdomainboxlocalassembler.hh:93
The box scheme multidomain local assembler.
Definition subdomainboxlocalassembler.hh:330
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:372
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:460
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:605
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:689
Declares all properties used in Dumux.