version 3.11-dev
Loading...
Searching...
No Matches
dualnetwork/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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13
14#ifndef DUMUX_DUAL_NETWORK_EXTENDEDSOURCESTENCIL_HH
15#define DUMUX_DUAL_NETWORK_EXTENDEDSOURCESTENCIL_HH
16
17#include <vector>
18
19#include <dune/common/indices.hh>
20
25
26namespace Dumux::PoreNetwork {
27
34template<class CouplingManager>
36{
37 using MDTraits = typename CouplingManager::MultiDomainTraits;
38
39 template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
40 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
41 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
42 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
43
44 static constexpr auto solidDomainIdx = CouplingManager::solidDomainIdx;
45 static constexpr auto voidDomainIdx = CouplingManager::voidDomainIdx;
46
47 template<std::size_t id>
48 static constexpr bool isBox()
49 { return GridGeometry<id>::discMethod == DiscretizationMethods::box; }
50public:
57 template<std::size_t id, class JacobianPattern>
58 void extendJacobianPattern(const CouplingManager& couplingManager, Dune::index_constant<id> domainI, JacobianPattern& pattern) const
59 {
60 // add additional dof dependencies
61 for (const auto& element : elements(couplingManager.gridView(domainI)))
62 {
63 const auto& dofs = extendedSourceStencil_(couplingManager, domainI, element);
64 if constexpr (isBox<domainI>())
65 {
66 for (int i = 0; i < element.subEntities(GridView<domainI>::dimension); ++i)
67 for (const auto globalJ : dofs)
68 pattern.add(couplingManager.problem(domainI).gridGeometry().vertexMapper().subIndex(element, i, GridView<domainI>::dimension), globalJ);
69 }
70 else
71 {
72 const auto globalI = couplingManager.problem(domainI).gridGeometry().elementMapper().index(element);
73 for (const auto globalJ : dofs)
74 pattern.add(globalI, globalJ);
75 }
76 }
77 }
78
86 template<std::size_t i, class LocalAssemblerI, class SolutionVector, class JacobianMatrixDiagBlock, class GridVariables> //TODO edit function s.t. curSol from couplingmanager is used like in dumux/dumux/multidomain/embedded/extendedsourcestencil.hh (commit 3257876)
88 Dune::index_constant<i> domainI,
89 const LocalAssemblerI& localAssemblerI,
90 const SolutionVector& curSol,
91 JacobianMatrixDiagBlock& A,
92 GridVariables& gridVariables) const
93 {
94 // const auto& curSolI = couplingManager.curSol(domainI); //TODO:curSol declared protected in .../dumux/dumux/multidomain/couplingmanager.hh
95 const auto& curSolI = curSol;
96 constexpr auto numEq = std::decay_t<decltype(curSolI[0])>::size();
97 const auto& elementI = localAssemblerI.element();
98
99 // only do something if we have an extended stencil
100 if (extendedSourceStencil_(couplingManager, domainI, elementI).empty())
101 return;
102
103 // compute the undeflected residual (source only!)
104 const auto origResidual = localAssemblerI.evalLocalSourceResidual(elementI);
105
106 // compute derivate for all additional dofs in the circle stencil
107 for (const auto dofIndex : extendedSourceStencil_(couplingManager, domainI, elementI))
108 {
109 // std::cout << "deflecting " << dofIndex << std::endl;
110 auto partialDerivs = origResidual;
111 const auto origPriVars = curSolI[dofIndex];
112
113 // calculate derivatives w.r.t to the privars at the dof at hand
114 for (int pvIdx = 0; pvIdx < numEq; pvIdx++)
115 {
116 // reset partial derivatives
117 partialDerivs = 0.0;
118
119 auto evalResiduals = [&](auto priVar)
120 {
121 // update the coupling context (solution vector and recompute element residual)
122 auto priVars = origPriVars;
123 priVars[pvIdx] = priVar;
124 couplingManager.updateCouplingContext(domainI, localAssemblerI, domainI, dofIndex, priVars, pvIdx);
125 return localAssemblerI.evalLocalSourceResidual(elementI);
126 };
127
128 // derive the residuals numerically
129 static const int numDiffMethod = getParam<int>("Assembly.NumericDifferenceMethod");
130 NumericDifferentiation::partialDerivative(evalResiduals, curSolI[dofIndex][pvIdx],
131 partialDerivs, origResidual, numDiffMethod); //TODO: maybe change like in dumux/dumux/md/embedded/extendedsourcestencil.hh line 142
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 // std::cout << "Adding " << partialDerivs[scvJ.indexInElement()][eqIdx] << ", pvIdx " << pvIdx << std::endl;
143 A[scvJ.dofIndex()][dofIndex][eqIdx][pvIdx] += partialDerivs[scvJ.indexInElement()][eqIdx];
144 }
145 }
146
147 // restore the original coupling context
148 couplingManager.updateCouplingContext(domainI, localAssemblerI, domainI, dofIndex, origPriVars, pvIdx);
149 }
150 }
151 }
152
154 void clear() { sourceStencils_.clear(); }
155
157 auto& stencil()
158 { return sourceStencils_; }
159
160private:
162 template<std::size_t id>
163 const auto& extendedSourceStencil_(const CouplingManager& couplingManager, Dune::index_constant<id> domainId, const Element<id>& element) const
164 {
165 if constexpr (domainId == voidDomainIdx)
166 {
167 const auto voidElementIdx = couplingManager.problem(voidDomainIdx).gridGeometry().elementMapper().index(element);
168 if (sourceStencils_.count(voidElementIdx))
169 return sourceStencils_.at(voidElementIdx);
170 }
171
172 return couplingManager.emptyStencil(domainId);
173 }
174
176 std::unordered_map<std::size_t, std::vector<std::size_t>> sourceStencils_;
177};
178
179} // end namespace Dumux::PoreNetwork
180
181#endif
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:37
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Return a reference to the sub problem.
Definition multidomain/couplingmanager.hh:318
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
A class managing an extended source stencil.
Definition dualnetwork/extendedsourcestencil.hh:36
void evalAdditionalDomainDerivatives(CouplingManager &couplingManager, Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, const SolutionVector &curSol, JacobianMatrixDiagBlock &A, GridVariables &gridVariables) const
evaluate additional derivatives of the element residual of a domain with respect to dofs in the same ...
Definition dualnetwork/extendedsourcestencil.hh:87
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 dualnetwork/extendedsourcestencil.hh:58
auto & stencil()
return a reference to the stencil
Definition dualnetwork/extendedsourcestencil.hh:157
void clear()
clear the internal data
Definition dualnetwork/extendedsourcestencil.hh:154
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:171
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:155
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:176
Definition discretization/porenetwork/fvelementgeometry.hh:24
std::ranges::range auto scvs(const FVElementGeometry &fvGeometry, const LocalDof &localDof)
Definition localdof.hh:82
A class for numeric differentiation.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.