14#ifndef DUMUX_MULTIDOMAIN_FACECENTERED_LOCAL_ASSEMBLER_HH
15#define DUMUX_MULTIDOMAIN_FACECENTERED_LOCAL_ASSEMBLER_HH
17#include <dune/common/indices.hh>
18#include <dune/common/hybridutilities.hh>
19#include <dune/grid/common/gridenums.hh>
41template<std::
size_t id,
class TypeTag,
class Assembler,
class Implementation, DiffMethod dm,
bool implicit>
47 using SolutionVector =
typename Assembler::SolutionVector;
50 using GridVolumeVariables =
typename GridVariables::GridVolumeVariables;
51 using ElementVolumeVariables =
typename GridVolumeVariables::LocalView;
52 using ElementFluxVariablesCache =
typename GridVariables::GridFluxVariablesCache::LocalView;
53 using Scalar =
typename GridVariables::Scalar;
55 using GridGeometry =
typename GridVariables::GridGeometry;
56 using FVElementGeometry =
typename GridGeometry::LocalView;
57 using SubControlVolume =
typename GridGeometry::SubControlVolume;
58 using GridView =
typename GridGeometry::GridView;
59 using Element =
typename GridView::template Codim<0>::Entity;
61 using CouplingManager =
typename Assembler::CouplingManager;
67 static constexpr auto domainId =
typename Dune::index_constant<id>();
69 using ParentType::ParentType;
75 const Element& element,
76 const SolutionVector&
curSol,
78 : ParentType(assembler,
86 (element.partitionType() ==
Dune::GhostEntity))
94 template<
class JacobianMatrixRow,
class SubRes
idualVector,
class Gr
idVariablesTuple>
97 auto assembleCouplingBlocks = [&](
const auto& residual)
100 using namespace Dune::Hybrid;
101 forEach(integralRange(Dune::Hybrid::size(jacRow)), [&](
auto&& i)
110 ParentType::assembleJacobianAndResidual(jacRow[
domainId], res, *std::get<domainId>(gridVariables), noReassembler, assembleCouplingBlocks);
117 template<std::size_t otherId,
class JacRow,
class GridVariables,
118 typename std::enable_if_t<(otherId == id),
int> = 0>
126 template<std::size_t otherId,
class JacRow,
class GridVariables,
127 typename std::enable_if_t<(otherId != id),
int> = 0>
131 this->asImp_().assembleJacobianCoupling(domainJ, jacRow[domainJ], res, *std::get<domainId>(gridVariables));
144 for (
auto&& scv :
scvs(this->fvGeometry()))
146 const auto& curVolVars = elemVolVars[scv];
147 auto source = this->localResidual().computeSource(
problem(), element, this->fvGeometry(), elemVolVars, scv);
148 source *= -scv.volume()*curVolVars.extrusionFactor();
149 residual[scv.localDofIndex()] = std::move(source);
159 {
return this->
evalLocalSourceResidual(neighbor, implicit ? this->curElemVolVars() : this->prevElemVolVars()); }
167 const auto& element = this->element();
169 auto&& fvGeometry = this->fvGeometry();
170 auto&& curElemVolVars = this->curElemVolVars();
171 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
174 couplingManager_.bindCouplingContext(
domainId, element, this->assembler());
175 fvGeometry.bind(element);
179 curElemVolVars.bind(element, fvGeometry,
curSol);
180 elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars);
181 if (!this->assembler().isStationaryProblem())
182 this->prevElemVolVars().bindElement(element, fvGeometry, this->assembler().prevSol()[
domainId]);
186 auto& prevElemVolVars = this->prevElemVolVars();
187 const auto& prevSol = this->assembler().prevSol()[
domainId];
189 curElemVolVars.bindElement(element, fvGeometry,
curSol);
190 prevElemVolVars.bind(element, fvGeometry, prevSol);
191 elemFluxVarsCache.bind(element, fvGeometry, prevElemVolVars);
194 this->elemBcTypes().update(
problem(), this->element(), this->fvGeometry());
198 template<std::
size_t i = domainId>
200 {
return this->assembler().problem(
domainId); }
203 template<std::
size_t i = domainId>
205 {
return ParentType::curSol()[dId]; }
209 {
return couplingManager_; }
226template<std::
size_t id,
class TypeTag,
class Assembler, DiffMethod DM = DiffMethod::numeric,
bool implicit = true>
235template<std::
size_t id,
class TypeTag,
class Assembler>
238 id, TypeTag, Assembler,
249 using FVElementGeometry =
typename GridGeometry::LocalView;
250 using GridView =
typename GridGeometry::GridView;
251 using Element =
typename GridView::template Codim<0>::Entity;
252 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
255 enum { dim = GridView::dimension };
259 static constexpr auto domainI = Dune::index_constant<id>();
262 using ParentType::ParentType;
269 template<
class ElemSol>
272 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[scv.localDofIndex()], pvIdx);
278 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
281 this->
couplingManager().evalAdditionalDomainDerivatives(domainI, *
this, origResiduals, A, gridVariables);
288 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
297 const auto& element = this->element();
298 const auto& fvGeometry = this->fvGeometry();
299 auto&& curElemVolVars = this->curElemVolVars();
300 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
303 const auto& curSolJ = this->
curSol(domainJ);
306 auto updateCoupledVariables = [&] ()
310 if constexpr (enableGridFluxVarsCache)
312 if constexpr (enableGridVolVarsCache)
313 this->
couplingManager().updateCoupledVariables(domainI, *
this, gridVariables.curGridVolVars(), gridVariables.gridFluxVarsCache());
315 this->
couplingManager().updateCoupledVariables(domainI, *
this, curElemVolVars, gridVariables.gridFluxVarsCache());
319 if constexpr (enableGridVolVarsCache)
320 this->
couplingManager().updateCoupledVariables(domainI, *
this, gridVariables.curGridVolVars(), elemFluxVarsCache);
322 this->
couplingManager().updateCoupledVariables(domainI, *
this, curElemVolVars, elemFluxVarsCache);
326 const bool interiorElement = element.partitionType() == Dune::InteriorEntity;
327 for (
const auto& scv :
scvs(fvGeometry))
330 if (!interiorElement && element.template subEntity<1>(scv.indexInElement()).partitionType() != Dune::BorderEntity)
334 if constexpr (Problem::enableInternalDirichletConstraints())
336 if (this->internalDirichletValue(scv))
340 const auto& stencil = this->
couplingManager().couplingStencil(domainI, element, scv, domainJ);
342 for (
const auto globalJ : stencil)
344 const auto origResidual = this->
couplingManager().evalCouplingResidual(domainI, *
this, scv, domainJ, globalJ);
346 const auto origPriVarsJ = curSolJ[globalJ];
347 auto priVarsJ = origPriVarsJ;
349 for (
int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
351 auto evalCouplingResidual = [&](
auto priVar)
353 priVarsJ[pvIdx] = priVar;
354 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
355 updateCoupledVariables();
356 return this->
couplingManager().evalCouplingResidual(domainI, *
this, scv, domainJ, globalJ);
362 const auto& paramGroup = this->assembler().problem(domainJ).paramGroup();
364 static const auto epsCoupl = this->
couplingManager().numericEpsilon(domainJ, paramGroup);
367 epsCoupl(origPriVarsJ[pvIdx], pvIdx), numDiffMethod);
370 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
376 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
380 if (scv.boundary() && this->elemBcTypes().hasDirichlet())
382 const auto bcTypes = this->elemBcTypes()[fvGeometry.frontalScvfOnBoundary(scv).localIndex()];
383 if (bcTypes.hasDirichlet())
388 for (
int eqIdx = 0; eqIdx < numEq; ++eqIdx)
390 for (
int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
392 if (bcTypes.isCouplingDirichlet(eqIdx))
393 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = partialDerivs[scv.localDofIndex()][pvIdx];
394 else if (bcTypes.isDirichlet(eqIdx))
395 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
402 priVarsJ[pvIdx] = origPriVarsJ[pvIdx];
405 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
412 updateCoupledVariables();
424template<std::
size_t id,
class TypeTag,
class Assembler>
427 id, TypeTag, Assembler,
428 SubDomainFaceCenteredLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric, false>,
429 DiffMethod::numeric, false
435 using FVElementGeometry =
typename GridGeometry::LocalView;
436 using GridView =
typename GridGeometry::GridView;
437 using Element =
typename GridView::template Codim<0>::Entity;
438 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
439 static constexpr auto domainI = Dune::index_constant<id>();
441 using ParentType::ParentType;
448 template<
class ElemSol>
451 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[scv.localDofIndex()], pvIdx);
457 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
465 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:37
Definition partialreassembler.hh:32
An assembler for Jacobian and residual contribution per element (Face-centered methods).
Definition fclocalassembler.hh:328
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const int numericDifferenceMethod=1)
Computes the derivative of a function with respect to a function parameter.
Definition numericdifferentiation.hh:56
void assembleJacobianCoupling(Dune::index_constant< otherId > domainJ, JacobianBlock &A, const ElementResidualVector &res, GridVariables &gridVariables)
Computes the derivatives of residuals in subcontrolvolumes in the given element with respect to prima...
Definition subdomainfclocalassembler.hh:289
typename ParentType::LocalResidual::ElementResidualVector ElementResidualVector
export element residual vector type
Definition subdomainfclocalassembler.hh:264
void maybeUpdateCouplingContext(const SubControlVolume &scv, ElemSol &elemSol, const int pvIdx)
Update the coupling context for coupled models.
Definition subdomainfclocalassembler.hh:270
void maybeEvalAdditionalDomainDerivatives(const ElementResidualVector &origResiduals, const JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
Update the additional domain derivatives for coupled models.
Definition subdomainfclocalassembler.hh:279
typename ParentType::LocalResidual::ElementResidualVector ElementResidualVector
export element residual vector type
Definition subdomainfclocalassembler.hh:443
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 subdomainfclocalassembler.hh:466
void maybeUpdateCouplingContext(const SubControlVolume &scv, ElemSol &elemSol, const int pvIdx)
Update the coupling context for coupled models.
Definition subdomainfclocalassembler.hh:449
void maybeEvalAdditionalDomainDerivatives(const ElementResidualVector &origResiduals, const JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
Update the additional domain derivatives for coupled models.
Definition subdomainfclocalassembler.hh:458
ElementResidualVector evalLocalSourceResidual(const Element &neighbor) const
Evaluates the local source term depending on time discretization scheme.
Definition subdomainfclocalassembler.hh:158
CouplingManager & couplingManager()
Definition subdomainfclocalassembler.hh:208
void bindLocalViews()
Prepares all local views necessary for local assembly.
Definition subdomainfclocalassembler.hh:164
const auto & curSol(Dune::index_constant< i > dId=domainId) const
Definition subdomainfclocalassembler.hh:204
const Problem & problem(Dune::index_constant< i > dId=domainId) const
return reference to the underlying problem
Definition subdomainfclocalassembler.hh:199
void assembleJacobianAndResidual(JacobianMatrixRow &jacRow, SubResidualVector &res, GridVariablesTuple &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix....
Definition subdomainfclocalassembler.hh:95
ElementResidualVector evalLocalSourceResidual(const Element &element, const ElementVolumeVariables &elemVolVars) const
Evaluates the local source term for an element and given element volume variables.
Definition subdomainfclocalassembler.hh:137
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 subdomainfclocalassembler.hh:119
SubDomainFaceCenteredLocalAssemblerBase(const Assembler &assembler, const Element &element, const SolutionVector &curSol, CouplingManager &couplingManager)
Definition subdomainfclocalassembler.hh:74
static constexpr auto domainId
Definition subdomainfclocalassembler.hh:67
typename ParentType::LocalResidual::ElementResidualVector ElementResidualVector
export element residual vector type
Definition subdomainfclocalassembler.hh:71
The face-centered staggered scheme multidomain local assembler.
Definition subdomainfclocalassembler.hh:227
Defines all properties used in Dumux.
An enum class to define various differentiation methods available in order to compute the derivatives...
An assembler for Jacobian and residual contribution per element (face-centered staggered methods).
DiffMethod
Differentiation methods in order to compute the derivatives of the residual i.e. the entries in the j...
Definition diffmethod.hh:25
@ numeric
Definition diffmethod.hh:26
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:165
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
std::ranges::range auto scvs(const FVElementGeometry &fvGeometry, const LocalDof &localDof)
Definition localdof.hh:82
Definition common/pdesolver.hh:24
A class for numeric differentiation.
An adapter class for local assemblers using numeric differentiation.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.