26#ifndef DUMUX_MULTIDOMAIN_FACECENTERED_LOCAL_ASSEMBLER_HH
27#define DUMUX_MULTIDOMAIN_FACECENTERED_LOCAL_ASSEMBLER_HH
29#include <dune/common/indices.hh>
30#include <dune/common/hybridutilities.hh>
31#include <dune/grid/common/gridenums.hh>
53template<std::
size_t id,
class TypeTag,
class Assembler,
class Implementation, DiffMethod dm,
bool implicit>
59 using SolutionVector =
typename Assembler::SolutionVector;
63 using GridVolumeVariables =
typename GridVariables::GridVolumeVariables;
64 using ElementVolumeVariables =
typename GridVolumeVariables::LocalView;
65 using ElementFluxVariablesCache =
typename GridVariables::GridFluxVariablesCache::LocalView;
66 using Scalar =
typename GridVariables::Scalar;
68 using GridGeometry =
typename GridVariables::GridGeometry;
69 using FVElementGeometry =
typename GridGeometry::LocalView;
70 using SubControlVolume =
typename GridGeometry::SubControlVolume;
71 using GridView =
typename GridGeometry::GridView;
72 using Element =
typename GridView::template Codim<0>::Entity;
74 using CouplingManager =
typename Assembler::CouplingManager;
80 static constexpr auto domainId =
typename Dune::index_constant<id>();
82 using ParentType::ParentType;
88 const Element& element,
89 const SolutionVector&
curSol,
91 : ParentType(assembler,
99 (element.partitionType() ==
Dune::GhostEntity))
107 template<
class JacobianMatrixRow,
class Gr
idVariablesTuple>
110 auto assembleCouplingBlocks = [&](
const auto& residual)
113 using namespace Dune::Hybrid;
114 forEach(integralRange(Dune::Hybrid::size(jacRow)), [&](
auto&& i)
123 ParentType::assembleJacobianAndResidual(jacRow[
domainId], res, *std::get<domainId>(gridVariables), noReassembler, assembleCouplingBlocks);
130 template<std::size_t otherId,
class JacRow,
class GridVariables,
131 typename std::enable_if_t<(otherId == id),
int> = 0>
139 template<std::size_t otherId,
class JacRow,
class GridVariables,
140 typename std::enable_if_t<(otherId != id),
int> = 0>
144 this->asImp_().assembleJacobianCoupling(domainJ, jacRow[domainJ], res, *std::get<domainId>(gridVariables));
157 for (
auto&& scv : scvs(this->fvGeometry()))
159 const auto& curVolVars = elemVolVars[scv];
160 auto source = this->localResidual().computeSource(
problem(), element, this->fvGeometry(), elemVolVars, scv);
161 source *= -scv.volume()*curVolVars.extrusionFactor();
162 residual[scv.localDofIndex()] = std::move(source);
172 {
return this->
evalLocalSourceResidual(neighbor, implicit ? this->curElemVolVars() : this->prevElemVolVars()); }
180 const auto& element = this->element();
182 auto&& fvGeometry = this->fvGeometry();
183 auto&& curElemVolVars = this->curElemVolVars();
184 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
187 couplingManager_.bindCouplingContext(
domainId, element, this->assembler());
188 fvGeometry.bind(element);
192 curElemVolVars.bind(element, fvGeometry,
curSol);
193 elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars);
194 if (!this->assembler().isStationaryProblem())
195 this->prevElemVolVars().bindElement(element, fvGeometry, this->assembler().prevSol()[
domainId]);
199 auto& prevElemVolVars = this->prevElemVolVars();
200 const auto& prevSol = this->assembler().prevSol()[
domainId];
202 curElemVolVars.bindElement(element, fvGeometry,
curSol);
203 prevElemVolVars.bind(element, fvGeometry, prevSol);
204 elemFluxVarsCache.bind(element, fvGeometry, prevElemVolVars);
207 this->elemBcTypes().update(
problem(), this->element(), this->fvGeometry());
211 template<std::
size_t i = domainId>
213 {
return this->assembler().problem(
domainId); }
216 template<std::
size_t i = domainId>
218 {
return ParentType::curSol()[dId]; }
222 {
return couplingManager_; }
239template<std::
size_t id,
class TypeTag,
class Assembler, DiffMethod DM = DiffMethod::numeric,
bool implicit = true>
248template<std::
size_t id,
class TypeTag,
class Assembler>
259 using FVElementGeometry =
typename GridGeometry::LocalView;
260 using GridView =
typename GridGeometry::GridView;
261 using Element =
typename GridView::template Codim<0>::Entity;
262 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
265 enum { dim = GridView::dimension };
269 static constexpr auto domainI = Dune::index_constant<id>();
272 using ParentType::ParentType;
279 template<
class ElemSol>
282 this->
couplingManager().updateCouplingContext(domainI, *
this, domainI, scv.dofIndex(), elemSol[scv.localDofIndex()], pvIdx);
288 template<
class JacobianMatrixDiagBlock,
class Gr
idVariables>
291 this->
couplingManager().evalAdditionalDomainDerivatives(domainI, *
this, origResiduals, A, gridVariables);
298 template<std::
size_t otherId,
class JacobianBlock,
class Gr
idVariables>
307 const auto& element = this->element();
308 const auto& fvGeometry = this->fvGeometry();
309 auto&& curElemVolVars = this->curElemVolVars();
310 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
313 const auto& curSolJ = this->
curSol(domainJ);
316 auto updateCoupledVariables = [&] ()
320 if constexpr (enableGridFluxVarsCache)
322 if constexpr (enableGridVolVarsCache)
323 this->
couplingManager().updateCoupledVariables(domainI, *
this, gridVariables.curGridVolVars(), gridVariables.gridFluxVarsCache());
325 this->
couplingManager().updateCoupledVariables(domainI, *
this, curElemVolVars, gridVariables.gridFluxVarsCache());
329 if constexpr (enableGridVolVarsCache)
330 this->
couplingManager().updateCoupledVariables(domainI, *
this, gridVariables.curGridVolVars(), elemFluxVarsCache);
332 this->
couplingManager().updateCoupledVariables(domainI, *
this, curElemVolVars, elemFluxVarsCache);
336 for (
const auto& scv : scvs(fvGeometry))
338 const auto& stencil = this->
couplingManager().couplingStencil(domainI, element, scv, domainJ);
340 for (
const auto globalJ : stencil)
342 const auto origResidual = this->
couplingManager().evalCouplingResidual(domainI, *
this, scv, domainJ, globalJ);
344 const auto origPriVarsJ = curSolJ[globalJ];
345 auto priVarsJ = origPriVarsJ;
347 for (
int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
349 auto evalCouplingResidual = [&](Scalar priVar)
351 priVarsJ[pvIdx] = priVar;
352 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
353 updateCoupledVariables();
354 return this->
couplingManager().evalCouplingResidual(domainI, *
this, scv, domainJ, globalJ);
360 const auto& paramGroup = this->assembler().problem(domainJ).paramGroup();
362 static const auto epsCoupl = this->
couplingManager().numericEpsilon(domainJ, paramGroup);
365 epsCoupl(origPriVarsJ[pvIdx], pvIdx), numDiffMethod);
368 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
374 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
379 if (scv.boundary() && this->elemBcTypes().hasDirichlet())
381 const auto bcTypes = this->elemBcTypes()[fvGeometry.frontalScvfOnBoundary(scv).localIndex()];
382 if (bcTypes.hasDirichlet())
387 for (
int eqIdx = 0; eqIdx < numEq; ++eqIdx)
389 for (
int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
391 if (bcTypes.isCouplingDirichlet(eqIdx))
392 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = partialDerivs[scv.localDofIndex()][pvIdx];
393 else if (bcTypes.isDirichlet(eqIdx))
394 A[scv.dofIndex()][globalJ][eqIdx][pvIdx] = 0.0;
401 priVarsJ[pvIdx] = origPriVarsJ[pvIdx];
404 this->
couplingManager().updateCouplingContext(domainI, *
this, domainJ, globalJ, priVarsJ, pvIdx);
411 updateCoupledVariables();
A class for numeric differentiation.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
An adapter class for local assemblers using numeric differentiation.
An assembler for Jacobian and residual contribution per element (face-centered staggered methods).
An enum class to define various differentiation methods available in order to compute the derivatives...
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:38
@ 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: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
Definition common/pdesolver.hh:36
An assembler for Jacobian and residual contribution per element (Face-centered methods).
Definition fclocalassembler.hh:295
Definition partialreassembler.hh:44
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
ElementResidualVector evalLocalSourceResidual(const Element &neighbor) const
Evaluates the local source term depending on time discretization scheme.
Definition subdomainfclocalassembler.hh:171
CouplingManager & couplingManager()
Definition subdomainfclocalassembler.hh:221
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 subdomainfclocalassembler.hh:108
void bindLocalViews()
Prepares all local views necessary for local assembly.
Definition subdomainfclocalassembler.hh:177
const auto & curSol(Dune::index_constant< i > dId=domainId) const
Definition subdomainfclocalassembler.hh:217
const Problem & problem(Dune::index_constant< i > dId=domainId) const
return reference to the underlying problem
Definition subdomainfclocalassembler.hh:212
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:150
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:132
SubDomainFaceCenteredLocalAssemblerBase(const Assembler &assembler, const Element &element, const SolutionVector &curSol, CouplingManager &couplingManager)
Definition subdomainfclocalassembler.hh:87
static constexpr auto domainId
Definition subdomainfclocalassembler.hh:80
typename ParentType::LocalResidual::ElementResidualVector ElementResidualVector
export element residual vector type
Definition subdomainfclocalassembler.hh:84
The face-centered staggered scheme multidomain local assembler.
Definition subdomainfclocalassembler.hh:240
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:299
typename ParentType::LocalResidual::ElementResidualVector ElementResidualVector
export element residual vector type
Definition subdomainfclocalassembler.hh:274
void maybeUpdateCouplingContext(const SubControlVolume &scv, ElemSol &elemSol, const int pvIdx)
Update the coupling context for coupled models.
Definition subdomainfclocalassembler.hh:280
void maybeEvalAdditionalDomainDerivatives(const ElementResidualVector &origResiduals, const JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
Update the additional domain derivatives for coupled models.
Definition subdomainfclocalassembler.hh:289
Declares all properties used in Dumux.