DUNE PDELab (git)

dilu.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_DILU_HH
6#define DUNE_ISTL_DILU_HH
7
8#include <cmath>
9#include <complex>
10#include <map>
11#include <vector>
12#include <sstream>
13
17
18#include "istlexception.hh"
19
24namespace Dune
25{
26
31 namespace DILU
32 {
33
51 template <class M>
52 void blockDILUDecomposition(M &A, std::vector<typename M::block_type> &Dinv_)
53 {
54 auto endi = A.end();
55 for (auto row = A.begin(); row != endi; ++row)
56 {
57 const auto row_i = row.index();
58 const auto col = row->find(row_i);
59 // initialise Dinv[i] = A[i, i]
60 Dinv_[row_i] = *col;
61 }
62
63 for (auto row = A.begin(); row != endi; ++row)
64 {
65 const auto row_i = row.index();
66 for (auto a_ij = row->begin(); a_ij.index() < row_i; ++a_ij)
67 {
68 const auto col_j = a_ij.index();
69 const auto a_ji = A[col_j].find(row_i);
70 // if A[i, j] != 0 and A[j, i] != 0
71 if (a_ji != A[col_j].end())
72 {
73 // Dinv[i] -= A[i, j] * d[j] * A[j, i]
74 Dinv_[row_i] -= (*a_ij) * Dinv_[col_j] * (*a_ji);
75 }
76 }
77
78 // store the inverse
79 try
80 {
81 Impl::asMatrix(Dinv_[row_i]).invert(); // compute inverse of diagonal block
82 }
83 catch (Dune::FMatrixError &e)
84 {
85 std::ostringstream sstream;
86 sstream << THROWSPEC(MatrixBlockError)
87 << "DILU failed to invert matrix block D[" << row_i << "]" << e.what();
89 ex.message(sstream.str());
90 ex.r = row_i;
91 throw ex;
92 }
93 }
94 }
95
111 template <class M, class X, class Y>
112 void blockDILUBacksolve(const M &A, const std::vector<typename M::block_type> Dinv_, X &v, const Y &d)
113 {
114 using dblock = typename Y::block_type;
115 using vblock = typename X::block_type;
116
117 // lower triangular solve: (D + L_A) y = d
118 auto endi = A.end();
119 for (auto row = A.begin(); row != endi; ++row)
120 {
121 const auto row_i = row.index();
122 dblock rhsValue(d[row_i]);
123 auto &&rhs = Impl::asVector(rhsValue);
124 for (auto a_ij = (*row).begin(); a_ij.index() < row_i; ++a_ij)
125 {
126 // if A[i][j] != 0
127 // rhs -= A[i][j]* y[j], where v_j stores y_j
128 const auto col_j = a_ij.index();
129 Impl::asMatrix(*a_ij).mmv(v[col_j], rhs);
130 }
131 // y_i = Dinv_i * rhs
132 // storing y_i in v_i
133 auto &&vi = Impl::asVector(v[row_i]);
134 Impl::asMatrix(Dinv_[row_i]).mv(rhs, vi); // (D + L_A)_ii = D_i
135 }
136
137 // upper triangular solve: (D + U_A) v = Dy
138 auto rendi = A.beforeBegin();
139 for (auto row = A.beforeEnd(); row != rendi; --row)
140 {
141 const auto row_i = row.index();
142 // rhs = 0
143 vblock rhs(0.0);
144 for (auto a_ij = (*row).beforeEnd(); a_ij.index() > row_i; --a_ij)
145 {
146 // if A[i][j] != 0
147 // rhs += A[i][j]*v[j]
148 const auto col_j = a_ij.index();
149 Impl::asMatrix(*a_ij).umv(v[col_j], rhs);
150 }
151 // calculate update v = M^-1*d
152 // v_i = y_i - Dinv_i*rhs
153 // before update v_i is y_i
154 auto &&vi = Impl::asVector(v[row_i]);
155 Impl::asMatrix(Dinv_[row_i]).mmv(rhs, vi);
156 }
157 }
158 } // end namespace DILU
159
162} // end namespace
163
164#endif
Error thrown if operations of a FieldMatrix fail.
Definition: densematrix.hh:126
Error when performing an operation on a matrix block.
Definition: istlexception.hh:52
void blockDILUDecomposition(M &A, std::vector< typename M::block_type > &Dinv_)
Definition: dilu.hh:52
void blockDILUBacksolve(const M &A, const std::vector< typename M::block_type > Dinv_, X &v, const Y &d)
Definition: dilu.hh:112
Implements a matrix constructed from a given type representing a field and compile-time given number ...
void message(const std::string &msg)
store string in internal message buffer
Definition: exceptions.cc:32
Dune namespace.
Definition: alignedallocator.hh:13
Implements a scalar matrix view wrapper around an existing scalar.
Implements a scalar vector view wrapper around an existing scalar.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)