version 3.11-dev
Loading...
Searching...
No Matches
experimental/assembly/subdomaincclocalassembler.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//
15#ifndef DUMUX_EXPERIMENTAL_SUBDOMAIN_CC_LOCAL_ASSEMBLER_HH
16#define DUMUX_EXPERIMENTAL_SUBDOMAIN_CC_LOCAL_ASSEMBLER_HH
17
18#include <dune/common/indices.hh>
19#include <dune/common/reservedvector.hh>
20#include <dune/common/hybridutilities.hh>
21#include <dune/grid/common/gridenums.hh> // for GhostEntity
22#include <dune/istl/matrixindexset.hh>
23
33
35
36namespace Dumux::Experimental {
37
49template<std::size_t id, class TypeTag, class Assembler, class Implementation, DiffMethod dm>
50class SubDomainCCLocalAssemblerBase : public Experimental::CCLocalAssembler<TypeTag, Assembler, dm, Implementation>
51{
53
57 using SolutionVector = typename Assembler::SolutionVector;
59
61 using GridVolumeVariables = typename GridVariables::GridVolumeVariables;
62 using ElementVolumeVariables = typename GridVolumeVariables::LocalView;
63 using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
64 using Scalar = typename GridVariables::Scalar;
65
66 using GridGeometry = typename GridVariables::GridGeometry;
67 using FVElementGeometry = typename GridGeometry::LocalView;
68 using SubControlVolume = typename GridGeometry::SubControlVolume;
69 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
70 using Extrusion = Extrusion_t<GridGeometry>;
71 using GridView = typename GridGeometry::GridView;
72 using Element = typename GridView::template Codim<0>::Entity;
73
74 using CouplingManager = typename Assembler::CouplingManager;
75 using ElementResidualVector = typename ParentType::LocalResidual::ElementResidualVector;
76
77public:
79 static constexpr auto domainId = typename Dune::index_constant<id>();
83 using ParentType::ParentType;
84
86 explicit SubDomainCCLocalAssemblerBase(const Assembler& assembler,
87 const Element& element,
88 const SolutionVector& curSol,
89 CouplingManager& couplingManager)
90 : ParentType(assembler,
91 element,
92 curSol,
93 localView(assembler.gridGeometry(domainId)),
94 localView(assembler.gridVariables(domainId).curGridVolVars()),
95 localView(assembler.gridVariables(domainId).gridFluxVarsCache()),
96 assembler.localResidual(domainId),
97 (element.partitionType() == Dune::GhostEntity),
98 assembler.isImplicit())
99 , couplingManager_(couplingManager)
100 {}
101
106 template<class JacobianMatrixRow, class SubResidualVector, class GridVariablesTuple, class StageParams>
107 void assembleJacobianAndResidual(JacobianMatrixRow& jacRow, SubResidualVector& res, GridVariablesTuple& gridVariables,
108 const StageParams& stageParams, SubResidualVector& temporal, SubResidualVector& spatial,
109 SubResidualVector& constrainedDofs)
110 {
111 auto assembleCouplingBlocks = [&](const auto& residual)
112 {
113 // for the coupling blocks
114 using namespace Dune::Hybrid;
115 forEach(integralRange(Dune::Hybrid::size(jacRow)), [&](auto&& i)
116 {
117 if (std::decay_t<decltype(i)>{} != id)
118 this->assembleJacobianCoupling(i, jacRow, residual, gridVariables);
119 });
120 };
121
122 // the coupled model does not support partial reassembly yet
123 const DefaultPartialReassembler* noReassembler = nullptr;
124 ParentType::assembleJacobianAndResidual(
125 jacRow[domainId], res,
126 *std::get<domainId>(gridVariables),
127 stageParams, temporal, spatial,
128 constrainedDofs,
129 noReassembler,
130 assembleCouplingBlocks
131 );
132 }
133
138 template<std::size_t otherId, class JacRow, class GridVariables>
139 void assembleJacobianCoupling(Dune::index_constant<otherId> domainJ, JacRow& jacRow,
140 const LocalResidualValues& res, GridVariables& gridVariables)
141 {
142 if constexpr (id != otherId)
143 this->asImp_().assembleJacobianCoupling(domainJ, jacRow[domainJ], res, *std::get<domainId>(gridVariables));
144 }
145
150 {
151 // get some references for convenience
152 const auto& element = this->element();
153 const auto& curSol = this->curSol(domainId);
154 auto&& fvGeometry = this->fvGeometry();
155 auto&& curElemVolVars = this->curElemVolVars();
156 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
157
158 // bind the caches
159 couplingManager_.bindCouplingContext(domainId, element, this->assembler());
160 fvGeometry.bind(element);
161 curElemVolVars.bind(element, fvGeometry, curSol);
162 elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars);
163 }
164
166 template<std::size_t i = domainId>
167 const Problem& problem(Dune::index_constant<i> dId = domainId) const
168 { return this->assembler().problem(domainId); }
169
171 template<std::size_t i = domainId>
172 const auto& curSol(Dune::index_constant<i> dId = domainId) const
173 { return ParentType::curSol()[dId]; }
174
176 CouplingManager& couplingManager()
177 { return couplingManager_; }
178
179private:
180 CouplingManager& couplingManager_;
181};
182
194template<std::size_t id, class TypeTag, class Assembler, DiffMethod DM = DiffMethod::numeric>
196
204template<std::size_t id, class TypeTag, class Assembler>
206: public SubDomainCCLocalAssemblerBase<id, TypeTag, Assembler,
207 SubDomainCCLocalAssembler<id, TypeTag, Assembler, DiffMethod::numeric>, DiffMethod::numeric>
208{
212
214
216 using FVElementGeometry = typename GridGeometry::LocalView;
217 using SubControlVolume = typename GridGeometry::SubControlVolume;
218 using GridView = typename GridGeometry::GridView;
219 using Element = typename GridView::template Codim<0>::Entity;
220
222 enum { dim = GridView::dimension };
223
226 static constexpr int maxElementStencilSize = GridGeometry::maxElementStencilSize;
227 static constexpr auto domainI = Dune::index_constant<id>();
228
229public:
230 using ParentType::ParentType;
231 using ElementResidualVector = typename ParentType::LocalResidual::ElementResidualVector;
232
236 template<class ElemSol>
237 void maybeUpdateCouplingContext(const SubControlVolume& scv, ElemSol& elemSol, const int pvIdx)
238 {
239 if (this->assembler().isImplicit())
240 this->couplingManager().updateCouplingContext(domainI, *this, domainI, scv.dofIndex(), elemSol[0], pvIdx);
241 }
242
246 template<class JacobianMatrixDiagBlock, class GridVariables>
247 void maybeEvalAdditionalDomainDerivatives(const ElementResidualVector& origResiduals, JacobianMatrixDiagBlock& A, GridVariables& gridVariables)
248 {
249 if (this->assembler().isImplicit())
250 this->couplingManager().evalAdditionalDomainDerivatives(domainI, *this, origResiduals, A, gridVariables);
251 }
252
257 template<std::size_t otherId, class JacobianBlock, class GridVariables>
258 void assembleJacobianCoupling(Dune::index_constant<otherId> domainJ, JacobianBlock& A,
259 const LocalResidualValues& res, GridVariables& gridVariables)
260 {
261 if (!this->assembler().isImplicit())
262 return;
263
265 // Calculate derivatives of all dofs in the element with respect to all dofs in the coupling stencil. //
267
268 // get some aliases for convenience
269 const auto& element = this->element();
270 const auto& fvGeometry = this->fvGeometry();
271 const auto& gridGeometry = fvGeometry.gridGeometry();
272 auto&& curElemVolVars = this->curElemVolVars();
273 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
274
275 // get stencil information
276 const auto globalI = gridGeometry.elementMapper().index(element);
277 const auto& stencil = this->couplingManager().couplingStencil(domainI, element, domainJ);
278 const auto& curSolJ = this->curSol(domainJ);
279
280 // make sure the flux variables cache does not contain any artifacts from prior differentiation
281 elemFluxVarsCache.update(element, fvGeometry, curElemVolVars);
282
283 // convenience lambda for call to update self
284 auto updateCoupledVariables = [&] ()
285 {
286 // Update ourself after the context has been modified. Depending on the
287 // type of caching, other objects might have to be updated. All ifs can be optimized away.
288 if (enableGridFluxVarsCache)
289 {
290 if (enableGridVolVarsCache)
291 {
292 this->couplingManager().updateCoupledVariables(domainI, *this, gridVariables.curGridVolVars(), gridVariables.gridFluxVarsCache());
293 this->couplingManager().updateCoupledVariables(domainI, *this, gridVariables.curGridVolVars(), elemFluxVarsCache);
294 }
295 else
296 {
297 this->couplingManager().updateCoupledVariables(domainI, *this, curElemVolVars, gridVariables.gridFluxVarsCache());
298 this->couplingManager().updateCoupledVariables(domainI, *this, curElemVolVars, elemFluxVarsCache);
299 }
300 }
301 else
302 {
303 if (enableGridVolVarsCache)
304 this->couplingManager().updateCoupledVariables(domainI, *this, gridVariables.curGridVolVars(), elemFluxVarsCache);
305 else
306 this->couplingManager().updateCoupledVariables(domainI, *this, curElemVolVars, elemFluxVarsCache);
307 }
308 };
309
310 for (const auto& globalJ : stencil)
311 {
312 // undeflected privars and privars to be deflected
313 const auto origPriVarsJ = curSolJ[globalJ];
314 auto priVarsJ = origPriVarsJ;
315
316 const auto origResidual = this->couplingManager().evalCouplingResidual(domainI, *this, domainJ, globalJ)[0];
317
318 for (int pvIdx = 0; pvIdx < JacobianBlock::block_type::cols; ++pvIdx)
319 {
320 auto evalCouplingResidual = [&](auto priVar)
321 {
322 // update the volume variables and the flux var cache
323 priVarsJ[pvIdx] = priVar;
324 this->couplingManager().updateCouplingContext(domainI, *this, domainJ, globalJ, priVarsJ, pvIdx);
325 updateCoupledVariables();
326 return this->couplingManager().evalCouplingResidual(domainI, *this, domainJ, globalJ)[0];
327 };
328
329 // derive the residuals numerically
330 LocalResidualValues partialDeriv(0.0);
331 const auto& paramGroup = this->assembler().problem(domainJ).paramGroup();
332 static const int numDiffMethod = getParamFromGroup<int>(paramGroup, "Assembly.NumericDifferenceMethod");
333 static const auto epsCoupl = this->couplingManager().numericEpsilon(domainJ, paramGroup);
334 NumericDifferentiation::partialDerivative(evalCouplingResidual, priVarsJ[pvIdx], partialDeriv, origResidual,
335 epsCoupl(priVarsJ[pvIdx], pvIdx), numDiffMethod);
336
337 // add the current partial derivatives to the global jacobian matrix
338 if constexpr (Problem::enableInternalDirichletConstraints())
339 {
340 const auto& scv = fvGeometry.scv(globalI);
341 const auto internalDirichletConstraints = this->problem().hasInternalDirichletConstraint(this->element(), scv);
342 if (internalDirichletConstraints.none())
343 {
344 for (int eqIdx = 0; eqIdx < numEq; eqIdx++)
345 A[globalI][globalJ][eqIdx][pvIdx] += partialDeriv[eqIdx];
346 }
347 else
348 {
349 for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
350 {
351 if (internalDirichletConstraints[eqIdx])
352 A[globalI][globalJ][eqIdx][pvIdx] = 0.0;
353 else
354 A[globalI][globalJ][eqIdx][pvIdx] += partialDeriv[eqIdx];
355 }
356 }
357 }
358 else
359 {
360 for (int eqIdx = 0; eqIdx < numEq; eqIdx++)
361 A[globalI][globalJ][eqIdx][pvIdx] += partialDeriv[eqIdx];
362 }
363
364 // restore the current element solution
365 priVarsJ[pvIdx] = origPriVarsJ[pvIdx];
366
367 // restore the undeflected state of the coupling context
368 this->couplingManager().updateCouplingContext(domainI, *this, domainJ, globalJ, priVarsJ, pvIdx);
369 }
370
371 // restore original state of the flux vars cache and/or vol vars in case of global caching.
372 // This has to be done in order to guarantee that the undeflected residual computation done
373 // above is correct when jumping to the next coupled dof of domainJ.
374 updateCoupledVariables();
375 }
376 }
377};
378
379} // end namespace Dumux
380
381#endif
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:37
Definition partialreassembler.hh:32
A linear system assembler (residual and Jacobian) for general discretization schemes.
Definition assembly/assembler.hh:83
GetPropType< TypeTag, Properties::SolutionVector > SolutionVector
Definition assembly/assembler.hh:96
An assembler for Jacobian and residual contribution per element (cell-centered methods).
Definition experimental/assembly/cclocalassembler.hh:186
typename PrimaryVariables::value_type Scalar
export scalar
Definition discretization/gridvariables.hh:42
void assembleJacobianCoupling(Dune::index_constant< otherId > domainJ, JacobianBlock &A, const LocalResidualValues &res, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition experimental/assembly/subdomaincclocalassembler.hh:258
void maybeUpdateCouplingContext(const SubControlVolume &scv, ElemSol &elemSol, const int pvIdx)
Update the coupling context for coupled models.
Definition experimental/assembly/subdomaincclocalassembler.hh:237
void maybeEvalAdditionalDomainDerivatives(const ElementResidualVector &origResiduals, JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
Update the additional domain derivatives for coupled models.
Definition experimental/assembly/subdomaincclocalassembler.hh:247
typename ParentType::LocalResidual::ElementResidualVector ElementResidualVector
Definition experimental/assembly/subdomaincclocalassembler.hh:231
const auto & curSol(Dune::index_constant< i > dId=domainId) const
Definition experimental/assembly/subdomaincclocalassembler.hh:172
CouplingManager & couplingManager()
Definition experimental/assembly/subdomaincclocalassembler.hh:176
const Problem & problem(Dune::index_constant< i > dId=domainId) const
return reference to the subdomain problem
Definition experimental/assembly/subdomaincclocalassembler.hh:167
SubDomainCCLocalAssemblerBase(const Assembler &assembler, const Element &element, const SolutionVector &curSol, CouplingManager &couplingManager)
the constructor
Definition experimental/assembly/subdomaincclocalassembler.hh:86
void assembleJacobianAndResidual(JacobianMatrixRow &jacRow, SubResidualVector &res, GridVariablesTuple &gridVariables, const StageParams &stageParams, SubResidualVector &temporal, SubResidualVector &spatial, SubResidualVector &constrainedDofs)
Computes the derivatives with respect to the given element and adds them to the global matrix....
Definition experimental/assembly/subdomaincclocalassembler.hh:107
void assembleJacobianCoupling(Dune::index_constant< otherId > domainJ, JacRow &jacRow, const LocalResidualValues &res, GridVariables &gridVariables)
Assemble the entries in a coupling block of the jacobian. There is no coupling block between a domain...
Definition experimental/assembly/subdomaincclocalassembler.hh:139
void bindLocalViews()
Prepares all local views necessary for local assembly.
Definition experimental/assembly/subdomaincclocalassembler.hh:149
GetPropType< TypeTag, Properties::LocalResidual > LocalResidual
the local residual type of this domain
Definition experimental/assembly/subdomaincclocalassembler.hh:81
static constexpr auto domainId
Definition experimental/assembly/subdomaincclocalassembler.hh:79
The cell-centered scheme multidomain local assembler.
Definition experimental/assembly/subdomaincclocalassembler.hh:195
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
Defines all properties used in Dumux.
An enum class to define various differentiation methods available in order to compute the derivatives...
Element solution classes and factory functions.
An assembler for Jacobian and residual contribution per element (cell-centered methods).
Helper classes to compute the integration elements.
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
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition numeqvector.hh:34
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
Definition assembly/assembler.hh:44
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:257
Definition common/pdesolver.hh:24
A helper to deduce a vector with the same size as numbers of equations.
A class for numeric differentiation.
An adapter class for local assemblers using numeric differentiation.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
A arithmetic block vector type based on DUNE's reserved vector.