3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
croperator.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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_CROPERATOR2P_HH
25#define DUMUX_CROPERATOR2P_HH
26
27#include<iostream>
28#include<vector>
29#include<set>
30#include<map>
31#include<cassert>
32
33#include<dune/common/timer.hh>
34#include<dune/common/fvector.hh>
35#include<dune/common/fmatrix.hh>
36#include<dune/common/exceptions.hh>
37#include<dune/geometry/type.hh>
38#include<dune/grid/common/grid.hh>
39#include<dune/grid/common/mcmgmapper.hh>
40#include<dune/istl/bvector.hh>
41#include<dune/istl/operators.hh>
42#include<dune/istl/bcrsmatrix.hh>
43
47#include "localstiffness.hh"
48
49namespace Dumux {
50
65template<class TypeTag>
67{
68 template<int dim>
69 struct FaceLayout
70 {
71 bool contains (Dune::GeometryType gt)
72 {
73 return gt.dim() == dim-1;
74 }
75 };
78 enum {dim=GridView::dimension};
79 using IS = typename GridView::IndexSet;
80 using BlockType = Dune::FieldMatrix<Scalar, 1, 1>;
82 using MBlockType = typename MatrixType::block_type;
83 using rowiterator = typename MatrixType::RowIterator;
84 using coliterator = typename MatrixType::ColIterator;
85 using BCBlockType = std::array<BoundaryConditions::Flags, 1>; // componentwise boundary conditions
86 using SatType = Dune::BlockVector< Dune::FieldVector<double, 1> >;
87 using FaceMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
88
90 enum
91 {
92 pressureEqIdx = Indices::pressureEqIdx,
93 };
94
96 int nnz()
97 {
98 return (4*dim - 1)*size_;
99 }
100
101public:
103
104 CROperatorAssemblerTwoP (const GridView& gridview)
105 : gridView_(gridview)
106 , faceMapper_(gridView_, Dune::mcmgLayout(Dune::Codim<1>()))
107 , size_(faceMapper_.size())
108 , A_(size_, size_, nnz()
109 , RepresentationType::random)
110 {}
111
114 {
115 if constexpr (Deprecated::hasUpdateGridView<FaceMapper, GridView>())
116 faceMapper_.update(gridView_);
117 else
118 Deprecated::update(faceMapper_);
119
120 size_ = faceMapper_.size();
121 A_.setSize(size_, size_, nnz());
122
123 assert(nnz() != 0);
124
125 // set size of all rows to zero
126 for (unsigned int i = 0; i < size_; i++)
127 A_.setrowsize(i,0);
128
129 // build needs a flag for all entities of all codims
130 std::vector<bool> visited(size_, false);
131
132 // LOOP 1 : Compute row sizes
133 for (const auto& element : elements(gridView_))
134 {
135 int numFaces = element.subEntities(1);
136
137 for (int i = 0; i < numFaces; i++)
138 {
139 int index = faceMapper_.subIndex(element, i,1);
140
141 if (!visited[index])
142 {
143 A_.incrementrowsize(index);
144 visited[index] = true;
145 // std::cout << "increment row " << index << std::endl;
146 }
147 A_.incrementrowsize(index, numFaces - 1);
148 // std::cout << "increment row " << index
149 // << " by " << numFaces - 1 << std::endl;
150 }
151 }
152
153 // now the row sizes have been set
154 A_.endrowsizes();
155
156 // clear the flags for the next round, actually that is not necessary because addindex takes care of this
157 visited.assign(size_, false);
158
159 // LOOP 2 : insert the nonzeros
160 for (const auto& element : elements(gridView_))
161 {
162 int numFaces = element.subEntities(1);
163
164 for (int i = 0; i < numFaces; i++)
165 {
166 int indexI = faceMapper_.subIndex(element, i, 1);
167
168 if (!visited[indexI])
169 {
170 A_.addindex(indexI,indexI);
171 visited[indexI] = true;
172 }
173 for (int k = 0; k < numFaces; k++)
174 if (k != i) {
175 int indexJ = faceMapper_.subIndex(element, k, 1);
176
177 A_.addindex(indexI, indexJ);
178 //std::cout << "indexI = " << indexI << ", added indexJ = " << indexJ << std::endl;
179 }
180 }
181 }
182
183 // now the matrix is ready for use
184 A_.endindices();
185 }
186
189 {
190 return A_;
191 }
192
195 {
196 return A_;
197 }
198
199 const FaceMapper& faceMapper()
200 {
201 return faceMapper_;
202 }
203
204 const FaceMapper& faceMapper() const
205 {
206 return faceMapper_;
207 }
208
226 template <class LocalStiffness, class Vector>
227 void assemble (LocalStiffness& loc, Vector& u, Vector& f)
228 {
229
230 // check size
231 if (u.N()!=A_.M() || f.N()!=A_.N())
232 DUNE_THROW(Dune::MathError,"CROperatorAssemblerTwoP::assemble(): size mismatch");
233 // clear global stiffness matrix and right hand side
234 A_ = 0;
235 f = 0;
236
237 // allocate flag vector to hold flags for essential boundary conditions
238 std::vector<BCBlockType> essential(faceMapper_.size());
239 for (typename std::vector<BCBlockType>::size_type i=0; i<essential.size(); i++)
240 essential[i][0] = BoundaryConditions::neumann;
241
242 // local to global id mapping (do not ask vertex mapper repeatedly
243 Dune::FieldVector<int, 2*dim> local2Global(0);
244
245 // run over all leaf elements
246 for (const auto& element : elements(gridView_))
247 {
248 unsigned int numFaces = element.subEntities(1);
249
250 // get local to global id map
251 for (unsigned int k = 0; k < numFaces; k++)
252 {
253 int alpha = faceMapper_.subIndex(element, k, 1);
254 local2Global[k] = alpha;
255 }
256
257 // build local stiffness matrix for CR elements
258 // inludes rhs and boundary condition information
259 loc.assemble(element, 1); // assemble local stiffness matrix
260
261
262 // accumulate local matrix into global matrix for non-hanging nodes
263 for (unsigned int i=0; i<numFaces; i++) // loop over rows, i.e. test functions
264 {
265 // accumulate matrix
266 for (unsigned int j=0; j<numFaces; j++)
267 {
268 // the standard entry
269 A_[local2Global[i]][local2Global[j]] += loc.mat(i,j);
270 }
271
272 // essential boundary condition and rhs
273 if (loc.bc(i).isDirichlet(pressureEqIdx))
274 {
275 essential[local2Global[i]][0] = BoundaryConditions::dirichlet;
276 f[local2Global[i]][0] = loc.rhs(i)[0];
277 }
278 else
279 f[local2Global[i]][0] += loc.rhs(i)[0];
280 }
281 }
282 // run over all leaf elements
283 for (const auto& element : elements(gridView_))
284 {
285 unsigned int numFaces = element.subEntities(1);
286
287 // get local to global id map
288 for (unsigned int k = 0; k < numFaces; k++)
289 {
290 int alpha = faceMapper_.subIndex(element, k, 1);
291 local2Global[k] = alpha;
292 }
293 loc.completeRHS(element, local2Global, f);
294 }
295
296 // put in essential boundary conditions
297 rowiterator endi=A_.end();
298 for (rowiterator i=A_.begin(); i!=endi; ++i)
299 {
300 // muck up extra rows
301 if ((int) i.index() >= (int) faceMapper_.size())
302 {
303 coliterator endj=(*i).end();
304 for (coliterator j=(*i).begin(); j!=endj; ++j)
305 {
306 (*j) = 0;
307 if (j.index()==i.index())
308 (*j)[0][0] = 1;
309 }
310 f[i.index()] = 0;
311 }
312 // insert dirichlet and processor boundary conditions
313 else if (essential[i.index()][0]!=BoundaryConditions::neumann)
314 {
315 coliterator endj=(*i).end();
316 for (coliterator j=(*i).begin(); j!=endj; ++j)
317 if (j.index()==i.index())
318 {
319 (*j)[0][0] = 1;
320 }
321 else
322 {
323 (*j)[0][0] = 0;
324 }
325 u[i.index()][0] = f[i.index()][0];
326 }
327 }
328 }
329
330protected:
331 const GridView gridView_;
332 FaceMapper faceMapper_;
333 unsigned int size_;
335};
336
337} // end namespace Dumux
338
339#endif
Definition of boundary condition types, extend if necessary.
Helpers for deprecation.
Base class for assembling local stiffness matrices.
Definition: adapt.hh:29
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
@ dirichlet
Dirichlet boundary.
Definition: boundaryconditions.hh:41
@ neumann
Neumann boundary.
Definition: boundaryconditions.hh:39
Definition: matrix.hh:32
Extends CROperatorBase by a generic methods to assemble global stiffness matrix from local stiffness ...
Definition: croperator.hh:67
const GridView gridView_
Definition: croperator.hh:331
CROperatorAssemblerTwoP(const GridView &gridview)
Definition: croperator.hh:104
FaceMapper faceMapper_
Definition: croperator.hh:332
unsigned int size_
Definition: croperator.hh:333
const FaceMapper & faceMapper() const
Definition: croperator.hh:204
const RepresentationType & operator*() const
Returns const reference to operator matrix.
Definition: croperator.hh:188
const FaceMapper & faceMapper()
Definition: croperator.hh:199
void assemble(LocalStiffness &loc, Vector &u, Vector &f)
Assembles global stiffness matrix.
Definition: croperator.hh:227
void initialize()
Initialize the CR operator assembler.
Definition: croperator.hh:113
RepresentationType A_
Definition: croperator.hh:334
Base class for local assemblers.
Definition: localstiffness.hh:60
const VBlockType & rhs(int i) const
Accesses right hand side.
Definition: localstiffness.hh:210
const MBlockType & mat(int i, int j) const
Accesses the local stiffness matrix.
Definition: localstiffness.hh:197
const BoundaryTypes & bc(int i) const
Accesses boundary condition for each dof.
Definition: localstiffness.hh:223
virtual void assemble(const Entity &e, int k=1)=0
Assembles local stiffness matrix including boundary conditions for given element and order.
Base file for properties related to sequential IMPET algorithms.