% % IDRS parameterised testproblems % % The software is distributed without any warranty. % % Martin van Gijzen % Copyright (c) August 2010 % clear all; close all; clc; disp('FDM discretisation of a 3D convection-diffusion-reaction problem on a unit cube'); disp('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); % Define system % Defaults: h = 0.025; eps = 1; beta(1) = 0/sqrt(5); beta(2) = 250/sqrt(5); beta(3) = 500/sqrt(5); r = 400; Title = 'Parameters'; prompt = {'Gridsize h:','Diffusion:','Convection x-direction:','Convection y-direction:','Convection z-direction:', 'Reaction:'}; defaults = {num2str(h),num2str(eps),num2str(beta(1)),num2str(beta(2)),num2str(beta(3)),num2str(r)}; lineNo=[1 25]; params=inputdlg(prompt,Title,lineNo,defaults); % Actual values: h = str2num(char(params(1))); eps = str2num(char(params(2))); beta(1) = str2num(char(params(3))); beta(2) = str2num(char(params(4))); beta(3) = str2num(char(params(5))); r = str2num(char(params(6))); % Generate matrix m = round(1/h)-1; if ( m < 1 ) error('h too small, should be large than 0.5'); end n = m*m*m; Sx = gallery('tridiag',m,-eps/h^2-beta(1)/(2*h),2*eps/h^2,-eps/h^2+beta(1)/(2*h)); Sy = gallery('tridiag',m,-eps/h^2-beta(2)/(2*h),2*eps/h^2,-eps/h^2+beta(2)/(2*h)); Sz = gallery('tridiag',m,-eps/h^2-beta(3)/(2*h),2*eps/h^2,-eps/h^2+beta(3)/(2*h)); Is = speye(m,m); I = speye(n,n); A = kron(kron(Is,Is),Sx) + kron(kron(Is,Sy),Is)+ kron(kron(Sz,Is),Is) -r*I; x = linspace(h,1-h,m); sol = kron(kron(x.*(1-x),x.*(1-x)),x.*(1-x))'; b = A*sol; disp(' '); disp('The parameters of the problem are :'); disp(['Gridsize h = ',num2str(h),';']); disp(['Number of equations = ', num2str(n),';']); disp(['Diffusion parameter = ', num2str(eps),';']); disp(['Convection parameters = (',num2str(beta(1)),',',num2str(beta(2)),',',num2str(beta(3)),');']); disp(['Reaction parameter = ',num2str(r),' (Note: positive reaction parameter gives negative shift to matrix);']); disp(' '); % Defaults for the iterative solvers: tol = 1e-8; maxit = 1000; choice = 1; scrsz = get(0,'ScreenSize'); fig = figure('Position',[scrsz(1) + scrsz(3)/2 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2]); hold on; xlabel('Number of MATVECS') ylabel('|r|/|b|') title(['Convergence convection-diffusion-reaction problem']); grid on; t = cputime; disp('GMRES iteration...'); [x, flag, relres, iter, resvec] = gmres(A, b, [], tol, 400 ); time = cputime - t; resvec = log10(resvec/resvec(1)); it = [0:1:length(resvec)-1]; plot(it,resvec,'k-+'); drawnow; disp(['Final accuracy: ', num2str(norm(b-A*x)/norm(b))]) disp(['Iterations: ',num2str(iter(2))]); disp(['CPU time: ',num2str(time),'s.']); disp(' '); t = cputime; disp('Bi-CGSTAB iteration...'); [x, flag, relres, iter, resvec] = bicgstab(A, b, tol, maxit ); time = cputime - t; resvec = log10(resvec/resvec(1)); it = [0:1:length(resvec)-1]; plot(it,resvec,'b-+'); drawnow; disp(['Final accuracy: ', num2str(norm(b-A*x)/norm(b))]) disp(['Iterations: ',num2str(iter)]); disp(['CPU time: ',num2str(time),'s.']); disp(' '); s = 1; t = cputime; disp('IDR(1) iteration...'); [x, flag, relres, iter, resvec] = idrs( A, b, s, tol, maxit ); time = cputime - t; resvec = log10(resvec/resvec(1)); it = [0:1:length(resvec)-1]; plot(it,resvec,'r-+'); drawnow; disp(['Final accuracy: ', num2str(norm(b-A*x)/norm(b))]); disp(['Iterations: ',num2str(iter)]); disp(['CPU time: ',num2str(time),'s.']); disp(' '); s = 2; t = cputime; disp('IDR(2) iteration...'); [x, flag, relres, iter, resvec] = idrs( A, b, s, tol, maxit ); time = cputime - t; resvec = log10(resvec/resvec(1)); it = [0:1:length(resvec)-1]; plot(it,resvec,'r-x'); drawnow; disp(['Final accuracy: ', num2str(norm(b-A*x)/norm(b))]); disp(['Iterations: ',num2str(iter)]); disp(['CPU time: ',num2str(time),'s.']); disp(' '); s = 4; t = cputime; disp('IDR(4) iteration...'); [x, flag, relres, iter, resvec] = idrs( A, b, s, tol, maxit ); time = cputime - t; resvec = log10(resvec/resvec(1)); it = [0:1:length(resvec)-1]; plot(it,resvec,'r-*'); drawnow; disp(['Final accuracy: ', num2str(norm(b-A*x)/norm(b))]); disp(['Iterations: ',num2str(iter)]); disp(['CPU time: ',num2str(time),'s.']); disp(' '); s = 8; t = cputime; disp('IDR(8) iteration...'); [x, flag, relres, iter, resvec] = idrs( A, b, s, tol, maxit ); drawnow; time = cputime - t; resvec = log10(resvec/resvec(1)); it = [0:1:length(resvec)-1]; plot(it,resvec,'r-s'); drawnow; disp(['Final accuracy: ', num2str(norm(b-A*x)/norm(b))]); disp(['Iterations: ',num2str(iter)]); disp(['CPU time: ',num2str(time),'s.']); disp(' '); legend('GMRES', 'Bi-CGSTAB', 'IDR(1)', 'IDR(2)', 'IDR(4)', 'IDR(8)' ); hold off;