2 % performing a test of the gradient_approx routine
4 % It generates a simple
'2x2' grid on which the gradients over each edge can be
5 % pre-calculated manually (c.f. 'grad_correct' vector), and compares it to the
6 % output of gradient_approx()
9 % OK: '1', if test is OK, '0' otherwise
11 % Martin Drohmann 21.05.2008
15 gradient_approx_matrix_common_settings
19 grad_correct = [-2 0;2 0;-2 0;2 0];
20 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],1)))
21 disp('x gradient over edge 1 incorrect!');
24 grad_correct = [-1 0;1 0;-1 0;1 0];
25 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],2)))
26 disp('x gradient over edge 2 incorrect!');
29 grad_correct = [0 0;-2 0;0 0;-2 0];
30 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],3)))
31 disp('x gradient over edge 3 incorrect!');
34 grad_correct = [-1 0;1 0;-1 0;1 0];
35 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],4)))
36 disp('x gradient over edge 4 incorrect!');
39 % grad = gradient_approx2(U, model_data, params, i)
43 grad_correct = [0 -1; 0 0; 0 -1; 2 0];
44 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],1)))
45 disp('y gradient over edge 1 incorrect!');
48 grad_correct = [-1 -2;1 -2;-2 0;2 0];
49 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],2)))
50 disp('y gradient over edge 2 incorrect!');
53 grad_correct = [0 0;0 -1;-2 0;0 -1];
54 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],3)))
55 disp('y gradient over edge 3 incorrect!');
58 grad_correct = [0 0;0 0;-1 -2;1 -2];
59 if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],4)))
60 disp('y gradient over edge 4 incorrect!');
64 f = @(x) sin(x(:,1)) .* cos(x(:,2));
65 fx = @(x) cos(x(:,1)) .* cos(x(:,2));
66 fy = @(x) (-1)*sin(x(:,1)) .* sin(x(:,2));
69 OK = check_convergence(params,f,fx,fy,edge) & OK;
73 function [ret] = grad_test(params, model_data,U,NU_ind,edge)
75 ret = gradient_approx(params, model_data, U, NU_ind, edge);
79 function [OK] = check_equal(correct, testval,edge)
80 % checks whether the computed gradients over a specified edge are equal to
83 if ~all(all(correct == testval))
84 disp(['gradient over edge ', num2str(edge), ' incorrect!']);
85 disp(['expected: ', mat2str(correct), ...
86 ' got: ', mat2str(testval)]);
92 function [OK] = check_convergence(params,f,fx,fy,edge)
93 % EOC convergence check of discrete gradient computations
95 params.xnumintervals = 4;
96 params.ynumintervals = 4;
97 params.bnd_rect_index = [-2, -2];
102 model_data = nonlin_evol_gen_model_data(params);
104 grid = model_data.grid;
110 ie = grid.ECX(:,edge) > dx & grid.ECX(:,edge) < 1-dx...
111 & grid.ECY(:,edge) > dy & grid.ECY(:,edge) < 1-dy; % inner edges
112 U = f([grid.CX,grid.CY])';
113 g1 = [fx([grid.ECX(ie,edge),grid.ECY(ie,edge)]),...
114 fy([grid.ECX(ie,edge),grid.ECY(ie,edge)])];
116 recons = grad_test(params,model_data,U,[],edge);
117 recons = recons(ie,:);
119 maxerr(refstep) = max(max(g1 - recons));
121 params.xnumintervals = params.xnumintervals*2;
122 params.ynumintervals = params.ynumintervals*2;
125 eocrefstep = log(maxerr(1:end-1)./maxerr(2:end))/log(2);
126 if min(eocrefstep) < 1.5
127 disp(['gradient over edge ', num2str(edge), ' incorrect!']);
128 disp(['EOC sequence has too small entries(<1.5): ', mat2str(eocrefstep)]);