5#ifndef DUNE_ISTL_ILU_HH
6#define DUNE_ISTL_ILU_HH
38 typedef typename M::RowIterator rowiterator;
39 typedef typename M::ColIterator coliterator;
40 typedef typename M::block_type block;
43 rowiterator endi=A.end();
44 for (rowiterator i=A.begin(); i!=endi; ++i)
47 coliterator endij=(*i).end();
51 for (ij=(*i).begin(); ij.index()<i.index(); ++ij)
54 coliterator jj = A[ij.index()].find(ij.index());
57 Impl::asMatrix(*ij).rightmultiply(Impl::asMatrix(*jj));
60 coliterator endjk=A[ij.index()].end();
61 coliterator jk=jj; ++jk;
62 coliterator ik=ij; ++ik;
63 while (ik!=endij && jk!=endjk)
64 if (ik.index()==jk.index())
67 Impl::asMatrix(B).leftmultiply(Impl::asMatrix(*ij));
73 if (ik.index()<jk.index())
81 if (ij.index()!=i.index())
84 Impl::asMatrix(*ij).invert();
90 <<
"ILU failed to invert matrix block A["
91 << i.index() <<
"][" << ij.index() <<
"]" << e.
what();
102 template<
class M,
class X,
class Y>
106 using rowiterator =
typename M::ConstRowIterator;
107 using coliterator =
typename M::ConstColIterator;
108 typedef typename Y::block_type dblock;
109 typedef typename X::block_type vblock;
112 rowiterator endi=A.end();
113 for (rowiterator i=A.begin(); i!=endi; ++i)
121 dblock rhsValue(d[i.index()]);
122 auto&& rhs = Impl::asVector(rhsValue);
123 for (coliterator j=(*i).begin(); j.index()<i.index(); ++j)
124 Impl::asMatrix(*j).mmv(Impl::asVector(v[j.index()]),rhs);
125 Impl::asVector(v[i.index()]) = rhs;
130 auto rindex = [](
auto it) {
return std::prev(it.base()).index(); };
132 rrowiterator rbegini{A.begin()};
133 for (rrowiterator i = rrowiterator{A.end()}; i!=rbegini; ++i)
141 auto row = rindex(i);
142 vblock rhsValue(v[row]);
143 auto&& rhs = Impl::asVector(rhsValue);
145 for (j = rcoliterator{(*i).end()}; rindex(j)>row; ++j)
146 Impl::asMatrix(*j).mmv(Impl::asVector(v[rindex(j)]),rhs);
147 auto&& vi = Impl::asVector(v[row]);
148 Impl::asMatrix(*j).mv(rhs,vi);
167 template<
class K,
int n,
int m>
183 typedef typename M::ColIterator coliterator;
184 typedef typename M::ConstRowIterator crowiterator;
185 typedef typename M::ConstColIterator ccoliterator;
186 typedef typename M::CreateIterator createiterator;
187 typedef typename M::field_type K;
189 typedef typename map::iterator mapiterator;
192 crowiterator endi=A.end();
193 createiterator ci=ILU.createbegin();
194 for (crowiterator i=A.begin(); i!=endi; ++i)
199 for (ccoliterator j=(*i).begin(); j!=(*i).end(); ++j)
200 rowpattern[j.index()] = 0;
203 for (mapiterator ik=rowpattern.begin(); (*ik).first<i.index(); ++ik)
207 coliterator endk = ILU[(*ik).first].end();
208 coliterator kj = ILU[(*ik).first].find((*ik).first);
209 for (++kj; kj!=endk; ++kj)
217 mapiterator ij = rowpattern.find(kj.index());
218 if (ij==rowpattern.end())
220 rowpattern[kj.index()] = generation+1;
228 for (mapiterator ik=rowpattern.begin(); ik!=rowpattern.end(); ++ik)
229 ci.insert((*ik).first);
233 coliterator endILUij = ILU[i.index()].end();;
234 for (coliterator ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
239 for (crowiterator i=A.begin(); i!=endi; ++i)
242 coliterator endILUij = ILU[i.index()].end();;
243 for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
245 ccoliterator Aij = (*i).begin();
246 ccoliterator endAij = (*i).end();
247 ILUij = ILU[i.index()].begin();
248 while (Aij!=endAij && ILUij!=endILUij)
250 if (Aij.index()==ILUij.index())
257 if (Aij.index()<ILUij.index())
270 template <
class B,
class Alloc = std::allocator<B>>
298 if(
values_.capacity() < needed )
319 template<
class M,
class CRS,
class InvVector>
322 typedef typename M :: size_type size_type;
329 const size_t memEstimate = (A.nonzeroes() - A.N())/2;
331 assert( A.nonzeroes() != 0 );
335 const auto endi = A.end();
337 size_type colcount = 0;
338 lower.
rows_[ 0 ] = colcount;
339 for (
auto i=A.begin(); i!=endi; ++i, ++row)
341 const size_type iIndex = i.index();
344 for (
auto j=(*i).begin(); j.index() < iIndex; ++j )
349 lower.
rows_[ iIndex+1 ] = colcount;
355 upper.
rows_[ 0 ] = colcount ;
356 auto rindex = [](
auto it) {
return std::prev(it.base()).index(); };
364 const size_type iIndex = rindex(i);
369 const size_type jIndex = rindex(j);
370 if( rindex(j) == iIndex )
375 else if ( rindex(j) >= rindex(i) )
381 upper.
rows_[ row+1 ] = colcount;
386 template<
class CRS,
class InvVector,
class X,
class Y>
389 const InvVector& inv,
393 typedef typename Y :: block_type dblock;
394 typedef typename X :: block_type vblock;
395 typedef typename X :: size_type size_type ;
397 const size_type iEnd = lower.
rows();
398 const size_type lastRow = iEnd - 1;
399 if( iEnd != upper.
rows() )
405 for( size_type i=0; i<iEnd; ++ i )
407 dblock rhsValue( d[ i ] );
408 auto&& rhs = Impl::asVector(rhsValue);
409 const size_type rowI = lower.
rows_[ i ];
410 const size_type rowINext = lower.
rows_[ i+1 ];
412 for( size_type
col = rowI;
col < rowINext; ++
col )
413 Impl::asMatrix(lower.
values_[
col ]).mmv( Impl::asVector(v[ lower.
cols_[
col ] ] ), rhs );
415 Impl::asVector(v[ i ]) = rhs;
419 for( size_type i=0; i<iEnd; ++ i )
421 auto&& vBlock = Impl::asVector(v[ lastRow - i ]);
422 vblock rhsValue ( v[ lastRow - i ] );
423 auto&& rhs = Impl::asVector(rhsValue);
424 const size_type rowI = upper.
rows_[ i ];
425 const size_type rowINext = upper.
rows_[ i+1 ];
427 for( size_type
col = rowI;
col < rowINext; ++
col )
428 Impl::asMatrix(upper.
values_[
col ]).mmv( Impl::asVector(v[ upper.
cols_[
col ] ]), rhs );
431 Impl::asMatrix(inv[ i ]).mv(rhs, vBlock);
Col col
Definition matrixmatrix.hh:351
void convertToCRS(const M &A, CRS &lower, CRS &upper, InvVector &inv)
convert ILU decomposition into CRS format for lower and upper triangular and inverse.
Definition ilu.hh:320
void blockILUBacksolve(const M &A, X &v, const Y &d)
LU backsolve with stored inverse.
Definition ilu.hh:103
M::field_type & firstMatrixElement(M &A, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr)
Definition ilu.hh:154
void blockILU0Decomposition(M &A)
compute ILU decomposition of A. A is overwritten by its decomposition
Definition ilu.hh:35
void blockILUDecomposition(const M &A, int n, M &ILU)
Definition ilu.hh:180
static constexpr size_type M()
std::ptrdiff_t index() const
void message(const std::string &msg)
#define DUNE_THROW(E,...)
const char * what() const noexcept override
decltype(auto) lane(std::size_t l, V &&v)
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
a simple compressed row storage matrix class
Definition ilu.hh:272
std::vector< size_type > cols_
Definition ilu.hh:314
size_type nonZeros() const
Definition ilu.hh:280
void resize(const size_type nRows)
Definition ilu.hh:286
size_type rows() const
Definition ilu.hh:278
CRS()
Definition ilu.hh:276
void reserveAdditional(const size_type nonZeros)
Definition ilu.hh:295
B block_type
Definition ilu.hh:273
std::vector< block_type, Alloc > values_
Definition ilu.hh:313
size_type nRows_
Definition ilu.hh:315
size_t size_type
Definition ilu.hh:274
std::vector< size_type > rows_
Definition ilu.hh:312
void push_back(const block_type &value, const size_type index)
Definition ilu.hh:306
derive error class from the base class in common
Definition istlexception.hh:19
Error when performing an operation on a matrix block.
Definition istlexception.hh:52
int c
Definition istlexception.hh:54
int r
Definition istlexception.hh:54
T make_reverse_iterator(T... args)