version 3.8
embedded/extendedsourcestencil.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_MULTIDOMAIN_EMBEDDED_EXTENDEDSOURCESTENCIL_HH
14#define DUMUX_MULTIDOMAIN_EMBEDDED_EXTENDEDSOURCESTENCIL_HH
15
16#include <vector>
17
18#include <dune/common/indices.hh>
19
24
26
28
34template<class CouplingManager>
36{
37 using MDTraits = typename CouplingManager::MultiDomainTraits;
38 using Scalar = typename MDTraits::Scalar;
39
40 template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
41 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
42 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
43 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
44
45 static constexpr auto bulkIdx = typename MDTraits::template SubDomain<0>::Index();
46 static constexpr auto lowDimIdx = typename MDTraits::template SubDomain<1>::Index();
47
48 template<std::size_t id>
49 static constexpr bool isBox()
50 { return GridGeometry<id>::discMethod == DiscretizationMethods::box; }
51public:
58 template<std::size_t id, class JacobianPattern>
59 void extendJacobianPattern(const CouplingManager& couplingManager, Dune::index_constant<id> domainI, JacobianPattern& pattern) const
60 {
61 // add additional dof dependencies
62 for (const auto& element : elements(couplingManager.gridView(domainI)))
63 {
64 const auto& dofs = extendedSourceStencil_(couplingManager, domainI, element);
65 if constexpr (isBox<domainI>())
66 {
67 for (int i = 0; i < element.subEntities(GridView<domainI>::dimension); ++i)
68 for (const auto globalJ : dofs)
69 pattern.add(couplingManager.problem(domainI).gridGeometry().vertexMapper().subIndex(element, i, GridView<domainI>::dimension), globalJ);
70 }
71 else
72 {
73 const auto globalI = couplingManager.problem(domainI).gridGeometry().elementMapper().index(element);
74 for (const auto globalJ : dofs)
75 pattern.add(globalI, globalJ);
76 }
77 }
78 }
79
87 template<std::size_t i, class LocalAssemblerI, class JacobianMatrixDiagBlock, class GridVariables>
89 Dune::index_constant<i> domainI,
90 const LocalAssemblerI& localAssemblerI,
91 JacobianMatrixDiagBlock& A,
92 GridVariables& gridVariables) const
93 {
94 const auto& curSolI = couplingManager.curSol(domainI);
95 constexpr auto numEq = std::decay_t<decltype(curSolI[0])>::size();
96 const auto& elementI = localAssemblerI.element();
97
98 // only do something if we have an extended stencil
99 if (extendedSourceStencil_(couplingManager, domainI, elementI).empty())
100 return;
101
102 // compute the undeflected residual (source only!)
103 const auto origResidual = localAssemblerI.evalLocalSourceResidual(elementI);
104
105 // compute derivate for all additional dofs in the circle stencil
106 for (const auto dofIndex : extendedSourceStencil_(couplingManager, domainI, elementI))
107 {
108 auto partialDerivs = origResidual;
109 const auto origPriVars = curSolI[dofIndex];
110 auto priVars = origPriVars;
111
112 // calculate derivatives w.r.t to the privars at the dof at hand
113 for (int pvIdx = 0; pvIdx < numEq; pvIdx++)
114 {
115 // reset partial derivatives
116 partialDerivs = 0.0;
117
118 const auto evalResiduals = [&](const Scalar priVar)
119 {
120 // update the coupling context (solution vector and recompute element residual)
121 priVars[pvIdx] = priVar;
122 couplingManager.updateCouplingContext(domainI, localAssemblerI, domainI, dofIndex, priVars, pvIdx);
123 return localAssemblerI.evalLocalSourceResidual(elementI);
124 };
125
126 // derive the residuals numerically
127 static const NumericEpsilon<Scalar, numEq> eps_{localAssemblerI.problem().paramGroup()};
128 static const int numDiffMethod = getParamFromGroup<int>(localAssemblerI.problem().paramGroup(), "Assembly.NumericDifferenceMethod");
130 evalResiduals, priVars[pvIdx], partialDerivs, origResidual, eps_(priVars[pvIdx], pvIdx), numDiffMethod
131 );
132
133 // update the global stiffness matrix with the current partial derivatives
134 for (const auto& scvJ : scvs(localAssemblerI.fvGeometry()))
135 {
136 for (int eqIdx = 0; eqIdx < numEq; eqIdx++)
137 {
138 // A[i][col][eqIdx][pvIdx] is the rate of change of
139 // the residual of equation 'eqIdx' at dof 'i'
140 // depending on the primary variable 'pvIdx' at dof
141 // 'col'.
142 A[scvJ.dofIndex()][dofIndex][eqIdx][pvIdx] += partialDerivs[scvJ.indexInElement()][eqIdx];
143 }
144 }
145
146 // restore the current element solution
147 priVars[pvIdx] = origPriVars[pvIdx];
148
149 // restore the original coupling context
150 couplingManager.updateCouplingContext(domainI, localAssemblerI, domainI, dofIndex, origPriVars, pvIdx);
151 }
152 }
153 }
154
156 void clear() { sourceStencils_.clear(); }
157
159 typename CouplingManager::template CouplingStencils<bulkIdx>& stencil()
160 { return sourceStencils_; }
161
163 const typename CouplingManager::template CouplingStencils<bulkIdx>& stencil() const
164 { return sourceStencils_; }
165
166private:
168 template<std::size_t id>
169 const auto& extendedSourceStencil_(const CouplingManager& couplingManager, Dune::index_constant<id> domainId, const Element<id>& element) const
170 {
171 if constexpr (domainId == bulkIdx)
172 {
173 const auto bulkElementIdx = couplingManager.problem(bulkIdx).gridGeometry().elementMapper().index(element);
174 if (auto stencil = sourceStencils_.find(bulkElementIdx); stencil != sourceStencils_.end())
175 return stencil->second;
176 }
177
178 return couplingManager.emptyStencil(domainId);
179 }
180
182 typename CouplingManager::template CouplingStencils<bulkIdx> sourceStencils_;
183};
184
185} // end namespace Dumux::EmbeddedCoupling
186
187#endif
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:48
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Return a reference to the sub problem.
Definition: multidomain/couplingmanager.hh:309
SubSolutionVector< i > & curSol(Dune::index_constant< i > domainIdx)
the solution vector of the subproblem
Definition: multidomain/couplingmanager.hh:338
A class managing an extended source stencil.
Definition: embedded/extendedsourcestencil.hh:36
void evalAdditionalDomainDerivatives(CouplingManager &couplingManager, Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, JacobianMatrixDiagBlock &A, GridVariables &gridVariables) const
evaluate additional derivatives of the element residual of a domain with respect to dofs in the same ...
Definition: embedded/extendedsourcestencil.hh:88
void extendJacobianPattern(const CouplingManager &couplingManager, Dune::index_constant< id > domainI, JacobianPattern &pattern) const
extend the jacobian pattern of the diagonal block of domain i by those entries that are not already i...
Definition: embedded/extendedsourcestencil.hh:59
const CouplingManager::template CouplingStencils< bulkIdx > & stencil() const
return a const reference to the stencil
Definition: embedded/extendedsourcestencil.hh:163
void clear()
clear the internal data
Definition: embedded/extendedsourcestencil.hh:156
CouplingManager::template CouplingStencils< bulkIdx > & stencil()
return a reference to the stencil
Definition: embedded/extendedsourcestencil.hh:159
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:49
A helper class for local assemblers using numeric differentiation to determine the epsilon.
Definition: numericepsilon.hh:29
Defines all properties used in Dumux.
void updateCouplingContext(Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, Dune::index_constant< j > domainJ, std::size_t dofIdxGlobalJ, const PrimaryVariables< j > &priVarsJ, int pvIdxJ)
updates all data and variables that are necessary to evaluate the residual of the element of domain i...
Definition: multidomain/couplingmanager.hh:183
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
The available discretization methods in Dumux.
constexpr Box box
Definition: method.hh:147
Definition: circlepoints.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.