1
// Copyright (C) 2008 Anders Logg.
2
// Licensed under the GNU LGPL Version 2.1.
4
// Simple test program for solving a singular system
5
// with GMRES + AMG (PETSc + Hypre BoomerAMG)
7
// This system has a zero eigenvalue with corresponding
8
// eigenvector v = (1, 1, 1, ...). This gives a compatibility
9
// condition (corresponding to the integral of the right-hand
10
// side being zero for the Neumann problem).
12
// To solve the linear system, we must therefore either make the
13
// system nonsingular by adding a constraint, like zero average for x,
14
// or modify the right-hand side to satisfy the compatibility
20
using namespace dolfin;
22
int main(int argc, char* argv[])
24
// Initialize PETSc with command-line arguments
25
SubSystemsManager::initPETSc(argc, argv);
27
// Monitor convergence
28
dolfin_set("Krylov monitor convergence", true);
31
class Source : public Function
35
Source(Mesh& mesh) : Function(mesh) {}
37
real eval(const real* x) const
41
return 500.0*exp(-(dx*dx + dy*dy)/0.02);
47
UnitSquare mesh(2, 2);
53
PoissonBilinearForm a;
54
PoissonLinearForm L(f);
56
// Assemble linear system
62
// Solve linear system using ordinary linear solver
63
LinearSolver s0(gmres, amg);
65
cout << "Residual: " << residual(A, x, b) << endl;
67
// Solve linear system using special singular solver
68
SingularSolver s1(gmres, amg);
70
cout << "Residual: " << residual(A, x, b) << endl;
72
// Solve modified linear system using ordinary linear solver
73
LinearSolver s2(gmres, amg);
74
normalize(b, average);
76
cout << "Residual: " << residual(A, x, b) << endl;