We have implemented multigrid solvers for linear algebraic systems arising from various finite element methods. Here we briefly present the usage for a symmetric and positive definite matrix equation Ax = b.
x = A\b;
x = amg(A,b);
x = mg(A,b,elem);
Backslash \ is the build-in direct solver of MATLAB. It is suitable for small size problems. x = amg(A,b) implements algebraic multigrid solver. To acheive multigrid efficiency, a hierarchical 'grids' is generated from the graph of A. When the mesh is avaiable, x = mg(A,b,elem) implements geometric multigrid solvers. Inside mg, an coarsening algorithm is applied to the mesh given by elem.
More options is allowed in mg and amg. Try help mg and help amg for possible options including tolerance, V or W-cycles, number of smoothings steps, and print level etc.
Here we include several examples for discrete Poisson matrices. Solvers for other finite element methods and other equations can be found
% setting
mesh.shape = 'square';
mesh.type = 'uniform';
mesh.size = 2e5;
pde = 'Poisson';
fem = 'P1';
% get the matrix
[eqn,T] = getfemmatrix(mesh,pde,fem);
% compare solvers
tic; disp('Direct solver'); x1 = eqn.A\eqn.b; toc;
tic; x2 = mg(eqn.A,eqn.b,T.elem); toc;
tic; x3 = amg(eqn.A,eqn.b); toc;
format shorte
fprintf('Difference between direct and mg, amg solvers %0.2g, %0.2g \n',...
norm(x1-x2)/norm(eqn.b),norm(x1-x3)/norm(eqn.b));
For problem size of $2.6 \times 10^5$, mg ties with direct solver \. But amg is aroud 3-4 times slover.
%% Lshape adaptive grids
mesh.shape = 'Lshape';
mesh.type = 'adaptive';
mesh.size = 2e4;
pde = 'Poisson';
fem = 'P1';
% get the matrix
[eqn,T] = getfemmatrix(mesh,pde,fem);
% compare solvers
tic; disp('Direct solver'); x1 = eqn.A\eqn.b; toc;
tic; x2 = mg(eqn.A,eqn.b,T.elem); toc;
tic; x3 = amg(eqn.A,eqn.b); toc;
fprintf('Difference between direct and mg, amg solvers %0.2g, %0.2g \n',...
norm(x1-x2)/norm(eqn.b),norm(x1-x3)/norm(eqn.b));
The finest mesh is several uniform refinement of an adaptive mesh shown above. Now the multigrid outperforms the direct solver around the size of 7e5. amg is 4-5 times slower.
% Cube uniform grids
mesh.shape = 'cube';
mesh.type = 'uniform';
mesh.size = 2e4;
pde = 'Poisson';
fem = 'P1';
% get the matrix
[eqn,T] = getfemmatrix3(mesh,pde,fem);
% compare solvers
tic; disp('Direct solver'); x1 = eqn.A\eqn.b; toc;
tic; x2 = mg(eqn.A,eqn.b,T.elem); toc;
tic; x3 = amg(eqn.A,eqn.b); toc;
fprintf('Difference between direct and mg, amg solvers %0.2g, %0.2g \n',...
norm(x1-x2)/norm(eqn.b),norm(x1-x3)/norm(eqn.b));
For 3-D linear element, mg wins at an even smaller size $3.6\times 10^4$. Again amg is 3-4 times slower than mg.