Skip to content
Snippets Groups Projects

Fix: Cope with omitted diagonal blocks in outer GS loop.

Merged maxka requested to merge feature/blocksolver-missing-diagonal into master
@@ -47,22 +47,17 @@ void linearStep(const M& m, V& x, const V& b, const BitVector* ignore,
// Compute residual
auto ri = b[i];
bool hasDiagonal = false;
using Block = typename M::block_type;
const Block* diag = nullptr;
for (auto cIt = row_i.begin(); cIt != row_i.end(); ++cIt) {
size_t j = cIt.index();
cIt->mmv(x[j], ri);
if(j==i)
hasDiagonal = true;
if (j == i)
diag = &*cIt;
}
// Update iterate with correction
if (hasDiagonal)
x[i] += localSolver(row_i[i], std::move(ri), ignore_i);
else {
;
typename M::block_type zero(0.0);
x[i] += localSolver(zero, std::move(ri), ignore_i);
}
x[i] += localSolver(diag ? *diag : Block(0.0), std::move(ri), ignore_i);
};
if (direction != Direction::BACKWARD)
@@ -185,9 +180,10 @@ namespace LocalSolverFromLinearSolver {
*/
template <class LinearSolver>
auto truncateSymmetrically(LinearSolver&& linearSolver) {
return [linearSolver = std::move(linearSolver) ](
const auto& m, const auto& b, const auto& ignore) {
using Return = typename std::result_of<LinearSolver(decltype(m), decltype(b))>::type;
return [linearSolver = std::move(linearSolver)](const auto& m, const auto& b,
const auto& ignore) {
using Return =
typename std::result_of<LinearSolver(decltype(m), decltype(b))>::type;
if (ignore.all())
return Return(0);
@@ -283,7 +279,8 @@ auto cg(size_t maxIter = LinearSolvers::defaultCgMaxIter,
auto cgSolver = std::bind(
LinearSolvers::cg<std::decay_t<decltype(m)>, std::decay_t<decltype(b)>>,
_1, _2, maxIter, tol);
auto cgTruncatedSolver = LocalSolverFromLinearSolver::truncateSymmetrically(cgSolver);
auto cgTruncatedSolver =
LocalSolverFromLinearSolver::truncateSymmetrically(cgSolver);
auto cgTruncatedRegularizedSolver =
LocalSolverRegularizer::diagRegularize(r, cgTruncatedSolver);
return cgTruncatedRegularizedSolver(m, b, ignore);
Loading