version 3.11-dev
Loading...
Searching...
No Matches
jacobianpattern.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//
12#ifndef DUMUX_JACOBIAN_PATTERN_HH
13#define DUMUX_JACOBIAN_PATTERN_HH
14
15#include <type_traits>
16#include <dune/istl/matrixindexset.hh>
19
20namespace Dumux {
21
26template<bool isImplicit, class GridGeometry,
27 typename std::enable_if_t<( (GridGeometry::discMethod == DiscretizationMethods::cctpfa)
28 || (GridGeometry::discMethod == DiscretizationMethods::ccmpfa) ), int> = 0>
29Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry)
30{
31 const auto numDofs = gridGeometry.numDofs();
32 Dune::MatrixIndexSet pattern;
33 pattern.resize(numDofs, numDofs);
34
35 // matrix pattern for implicit Jacobians
36 if (isImplicit)
37 {
38 for (unsigned int globalI = 0; globalI < numDofs; ++globalI)
39 {
40 pattern.add(globalI, globalI);
41 for (const auto& dataJ : gridGeometry.connectivityMap()[globalI])
42 pattern.add(dataJ.globalJ, globalI);
43 }
44 }
45
46 // matrix pattern for explicit Jacobians -> diagonal matrix
47 else
48 {
49 for (unsigned int globalI = 0; globalI < numDofs; ++globalI)
50 pattern.add(globalI, globalI);
51 }
52
53 return pattern;
54}
55
60template<bool isImplicit, class GridGeometry,
61 typename std::enable_if_t<( (GridGeometry::discMethod == DiscretizationMethods::staggered) ), int> = 0>
62auto getJacobianPattern(const GridGeometry& gridGeometry)
63{
64 // resize the jacobian and the residual
65 const auto numDofs = gridGeometry.numDofs();
66 Dune::MatrixIndexSet pattern(numDofs, numDofs);
67
68 const auto& connectivityMap = gridGeometry.connectivityMap();
69
70 auto fvGeometry = localView(gridGeometry);
71 // evaluate the actual pattern
72 for (const auto& element : elements(gridGeometry.gridView()))
73 {
74 if(gridGeometry.isCellCenter())
75 {
76 // the global index of the element at hand
77 static constexpr auto cellCenterIdx = GridGeometry::cellCenterIdx();
78 const auto ccGlobalI = gridGeometry.elementMapper().index(element);
79 pattern.add(ccGlobalI, ccGlobalI);
80 for (auto&& ccGlobalJ : connectivityMap(cellCenterIdx, cellCenterIdx, ccGlobalI))
81 pattern.add(ccGlobalI, ccGlobalJ);
82 }
83 else
84 {
85 static constexpr auto faceIdx = GridGeometry::faceIdx();
86 fvGeometry.bindElement(element);
87
88 // loop over sub control faces
89 for (auto&& scvf : scvfs(fvGeometry))
90 {
91 const auto faceGlobalI = scvf.dofIndex();
92 pattern.add(faceGlobalI, faceGlobalI);
93 for (auto&& faceGlobalJ : connectivityMap(faceIdx, faceIdx, scvf.index()))
94 pattern.add(faceGlobalI, faceGlobalJ);
95 }
96 }
97 }
98
99 return pattern;
100}
101
106template<class FEBasis>
107Dune::MatrixIndexSet getFEJacobianPattern(const FEBasis& feBasis)
108{
109 const auto numDofs = feBasis.size();
110
111 Dune::MatrixIndexSet pattern;
112 pattern.resize(numDofs, numDofs);
113
114 auto localView = feBasis.localView();
115 // matrix pattern for implicit Jacobians
116 for (const auto& element : elements(feBasis.gridView()))
117 {
118 localView.bind(element);
119
120 const auto& finiteElement = localView.tree().finiteElement();
121 const auto numLocalDofs = finiteElement.localBasis().size();
122 for (std::size_t i = 0; i < numLocalDofs; i++)
123 {
124 const auto dofIdxI = localView.index(i);
125 for (std::size_t j = 0; j < numLocalDofs; j++)
126 {
127 const auto dofIdxJ = localView.index(j);
128 pattern.add(dofIdxI, dofIdxJ);
129 }
130 }
131 }
132
133 return pattern;
134}
135
142template<bool isImplicit, class GridGeometry,
143 typename std::enable_if_t<(GridGeometry::discMethod == DiscretizationMethods::fem), int> = 0>
144Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry)
145{ return getFEJacobianPattern(gridGeometry.feBasis()); }
146
151template<bool isImplicit, class GridGeometry,
152 typename std::enable_if_t<(GridGeometry::discMethod == DiscretizationMethods::fcstaggered), int> = 0>
153Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry)
154{
155 // resize the jacobian and the residual
156 const auto numDofs = gridGeometry.numDofs();
157 Dune::MatrixIndexSet pattern(numDofs, numDofs);
158
159 const auto& connectivityMap = gridGeometry.connectivityMap();
160 auto fvGeometry = localView(gridGeometry);
161
162 // set the pattern
163 for (const auto& element : elements(gridGeometry.gridView()))
164 {
165 fvGeometry.bind(element);
166 for (const auto& scv : scvs(fvGeometry))
167 {
168 const auto globalI = scv.dofIndex();
169 pattern.add(globalI, globalI);
170
171 for (const auto& scvIdxJ : connectivityMap[scv.index()])
172 {
173 const auto globalJ = fvGeometry.scv(scvIdxJ).dofIndex();
174 pattern.add(globalI, globalJ);
175
176 if (gridGeometry.isPeriodic())
177 {
178 if (gridGeometry.dofOnPeriodicBoundary(globalI) && globalI != globalJ)
179 {
180 const auto& periodicallyMappedDofs =
181 Dumux::Deprecated::rangeOfPeriodicallyMappedDofs(gridGeometry, globalI);
182
183 for (const auto globalIP : periodicallyMappedDofs)
184 {
185 pattern.add(globalIP, globalI);
186 pattern.add(globalI, globalIP);
187
188 if (globalI > globalIP)
189 pattern.add(globalIP, globalJ);
190 }
191 }
192 }
193 }
194 }
195 }
196
197 return pattern;
198}
199
204template<bool isImplicit, class GridGeometry,
205 typename std::enable_if_t<DiscretizationMethods::isCVFE<typename GridGeometry::DiscretizationMethod>, int> = 0>
206Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry)
207{
208 // resize the jacobian and the residual
209 const auto numDofs = gridGeometry.numDofs();
210 Dune::MatrixIndexSet pattern(numDofs, numDofs);
211
212 // matrix pattern for implicit Jacobians
213 if constexpr (isImplicit)
214 {
215 auto fvGeometry = localView(gridGeometry);
216 for (const auto& element : elements(gridGeometry.gridView()))
217 {
218 fvGeometry.bindElement(element);
219 for (const auto& localDof : localDofs(fvGeometry))
220 {
221 const auto globalI = localDof.dofIndex();
222 const auto globalIP = gridGeometry.isPeriodic() && gridGeometry.dofOnPeriodicBoundary(globalI)
223 ? std::ranges::min(Dumux::Deprecated::rangeOfPeriodicallyMappedDofs(gridGeometry,globalI))
224 : globalI;
225 for (const auto& localDofJ : localDofs(fvGeometry))
226 {
227 const auto globalJ = localDofJ.dofIndex();
228 pattern.add(globalI, globalJ);
229
230 if (globalI != globalJ && globalI != globalIP)
231 {
232 pattern.add(globalIP, globalI);
233 pattern.add(globalI, globalIP);
234
235 if (globalI > globalIP)
236 pattern.add(globalIP, globalJ);
237 }
238 }
239 }
240 }
241 }
242
243 // matrix pattern for explicit Jacobians -> diagonal matrix
244 else
245 {
246 for (unsigned int globalI = 0; globalI < numDofs; ++globalI)
247 pattern.add(globalI, globalI);
248 }
249
250 return pattern;
251}
252
253
254} // namespace Dumux
255
256#endif
Helpers for deprecation.
Dune::MatrixIndexSet getJacobianPattern(const GridGeometry &gridGeometry)
Helper function to generate Jacobian pattern for cell-centered methods.
Definition jacobianpattern.hh:29
Dune::MatrixIndexSet getFEJacobianPattern(const FEBasis &feBasis)
Helper function to generate Jacobian pattern for finite element scheme.
Definition jacobianpattern.hh:107
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
The available discretization methods in Dumux.
constexpr CCMpfa ccmpfa
Definition method.hh:175
constexpr CCTpfa cctpfa
Definition method.hh:174
constexpr Staggered staggered
Definition method.hh:181
constexpr FEM fem
Definition method.hh:182
constexpr FCStaggered fcstaggered
Definition method.hh:183
Definition adapt.hh:17
std::ranges::range auto scvs(const FVElementGeometry &fvGeometry, const LocalDof &localDof)
Definition localdof.hh:82
auto localDofs(const FVElementGeometry &fvGeometry)
range over local dofs
Definition localdof.hh:50