55 for (
auto row = A.begin(); row != endi; ++row)
57 const auto row_i = row.index();
58 const auto col = row->find(row_i);
63 for (
auto row = A.begin(); row != endi; ++row)
65 const auto row_i = row.index();
66 for (
auto a_ij = row->begin(); a_ij.index() < row_i; ++a_ij)
68 const auto col_j = a_ij.index();
69 const auto a_ji = A[col_j].find(row_i);
71 if (a_ji != A[col_j].end())
74 Dinv_[row_i] -= (*a_ij) * Dinv_[col_j] * (*a_ji);
81 Impl::asMatrix(Dinv_[row_i]).invert();
83 catch (Dune::FMatrixError &e)
85 std::ostringstream sstream;
87 <<
"DILU failed to invert matrix block D[" << row_i <<
"]" << e.what();
89 ex.message(sstream.str());
112 void blockDILUBacksolve(
const M &A,
const std::vector<typename M::block_type> Dinv_, X &v,
const Y &d)
114 using dblock =
typename Y::block_type;
115 using vblock =
typename X::block_type;
119 for (
auto row = A.begin(); row != endi; ++row)
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)
128 const auto col_j = a_ij.index();
129 Impl::asMatrix(*a_ij).mmv(v[col_j], rhs);
133 auto &&vi = Impl::asVector(v[row_i]);
134 Impl::asMatrix(Dinv_[row_i]).mv(rhs, vi);
138 auto rendi = A.beforeBegin();
139 for (
auto row = A.beforeEnd(); row != rendi; --row)
141 const auto row_i = row.index();
144 for (
auto a_ij = (*row).beforeEnd(); a_ij.index() > row_i; --a_ij)
148 const auto col_j = a_ij.index();
149 Impl::asMatrix(*a_ij).umv(v[col_j], rhs);
154 auto &&vi = Impl::asVector(v[row_i]);
155 Impl::asMatrix(Dinv_[row_i]).mmv(rhs, vi);