1 function grad = gradient_approx2(U, grid, params, edge)
5 % get a 6-environment of each cell (c.f. get_ENBI for details)
6 ENBI = get_ENBI(grid, edge);
7 % initialise the U values of the 6 environment
8 % UENBI = zeros(size(ENBI));
9 % initialise UE, a 4 environment that stores interpolated values at the
10 % edges tips and exact values at the two adjacent cell centers. From UE
11 % the gradient is calculated by lineare interpolation (lsq)
14 %%%% Handle dirichlet cells ("ghost" cells with index -1) %%%%
15 % if a cell adjacent to the current edge is a _dirichlet_ "ghost" cell,
16 % entries in the matrix UE have to be replaced by exact evaluations at
17 % the dirichlet boundary. The following cases have to be separated:
18 % case 1: one of the adjacent cells is a ghost
19 % => replace the cell's entry in UE with the dirichlet value at
21 % case 2/3: one cell adjacent to the tip is a ghost
22 % => replace the tip's entry in UE with the dirichlet value at the
25 % find the _row_ index (edge inedex) of the three cases
26 case1_dir_ind = find(ENBI(:,4) == -1);
27 case2_dir_ind = find(ENBI(:,5) == -1);
28 case3_dir_ind = find(ENBI(:,6) == -1);
30 % the case23_mapper maps to the correct edge tip (correct column index)
33 case23_mapper = [ mod(edge, 4) + 1, edge ];
35 case23_mapper = [ edge, mod(edge, 4) + 1 ];
38 % neuman boundaries!!! For all other ghost cells the entries of
39 % adjacent non-ghost cells are copied. Ghost cells in the corners of
40 % the
rectgrid are assigned in the end by copying one of the already
41 % assigned adjacent ghost-cell. It is unspecified which ghost cell is
43 nb_ind = find(ENBI(:,2) <= 0);
44 ENBI(nb_ind, 2) = ENBI(nb_ind, 1);
45 nb_ind = find(ENBI(:,3) <= 0);
46 ENBI(nb_ind, 3) = ENBI(nb_ind, 1);
47 nb_ind = find(ENBI(:,4) <= 0);
48 ENBI(nb_ind, 4) = ENBI(nb_ind, 1);
49 nb_ind = find(ENBI(:,5) == -2);
50 ENBI(nb_ind, 5) = ENBI(nb_ind, 2);
51 nb_ind = find(ENBI(:,5) <= 0);
52 ENBI(nb_ind, 5) = ENBI(nb_ind, 4);
53 nb_ind = find(ENBI(:,6) == -2);
54 ENBI(nb_ind, 6) = ENBI(nb_ind, 3);
55 nb_ind = find(ENBI(:,6) <= 0);
56 ENBI(nb_ind, 6) = ENBI(nb_ind, 4);
58 % now every ghost cell should have a positive index
59 %assert(max(max(ENBI <= 0)) == 0);
62 % + ytrans(grid.CX(ENBI(non_zero_ind)), grid.CY(ENBI(non_zero_ind)));
64 % construct the 4-environment UE
65 UE(:,[1,2]) = UENBI(:,[1,4]);
66 UE(:,3) = sum(UENBI(:,[1,2,4,5]), 2) / 4;
67 UE(:,4) = sum(UENBI(:,[1,3,4,6]), 2) / 4;
69 % construct the 4-environment UE
70 UE(:,[1,2]) = UENBI(:,[1,4]);
71 UE(:,3) = sum(UENBI(:,[1,2,4,5]), 2) / 4;
72 UE(:,4) = sum(UENBI(:,[1,3,4,6]), 2) / 4;
73 % update the 4-environment concerning dirichlet cells
74 Xdir = grid.ESX(case1_dir_ind, edge);
75 Ydir = grid.ESY(case1_dir_ind, edge);
76 % Yoff = ytrans(Xdir, Ydir);
79 Xdir = grid.X(grid.VI(case2_dir_ind, case23_mapper(1) ));
80 Ydir = grid.Y(grid.VI(case2_dir_ind, case23_mapper(1) ));
81 % Yoff = ytrans(Xdir, Ydir);
83 Xdir = grid.X(grid.VI(case3_dir_ind, case23_mapper(2) ));
84 Ydir = grid.Y(grid.VI(case3_dir_ind, case23_mapper(2) ));
85 % Yoff = ytrans(Xdir, Ydir);
88 % construct the LHS matrix of the LES, it is - up to the sign -
89 % identical for edges 1 and 3, respectively 2 and 4.
90 % Therefore we need this factor 'factor' and an dummy edge 'tmp':
98 nb_ind = grid.NBI(1, tmp);
99 Acell = [ grid.CX([1; nb_ind]) , grid.CY([1; nb_ind]); ...
100 grid.X(grid.VI(1,(0:1) + tmp))', grid.Y(grid.VI(1,(0:1) + tmp))'];
101 Acell = ( Acell - repmat([grid.ECX(1,tmp), grid.ECY(1, tmp)], 4, 1) ) ...
105 lhs_cell = AcellT * Acell;
106 % The 3 diagonals of the LHS matrix A^T*A.
107 LHS_d = repmat(horzcat([ lhs_cell(2,1); 0 ], ...
109 [ 0; lhs_cell(1,2) ]),...
111 LHS = spdiags(LHS_d, -1:1, 2*nels, 2*nels);
113 % The sparse matrix A^T (consists of 2x4 matrix blocks)
114 AT = sparse( repmat([1;2], 4*nels, 1) ...
115 + reshape(repmat(0:2:2*nels-1, 8, 1), 8*nels, 1), ...
116 reshape(repmat(1:4*nels, 2, 1), 8*nels, 1), ...
117 repmat(reshape(AcellT, 8, 1), nels, 1) );
120 RHS = AT * reshape(UE', 4*nels, 1);
122 grad = reshape(LHS \ RHS, 2, nels)';
127 % TO BE ADJUSTED TO NEW SYNTAX
function Udirichlet = dirichlet_values(model, X, Y)
UDIRICHLET = DIRICHLET_VALUES([X],[Y], MODEL) Examples dirichlet_values([0,1,2],[1,1,1],struct(name_dirichlet_values, homogeneous, ... c_dir, 1)) dirichlet_values([0:0.1:1],[0],struct(name_dirichlet_values, xstripes, ... c_dir, [0 1 2], ... dir_borders, [0.3 0.6])) dirichlet_values([0:0.1:1],[0],struct(name_dirichlet_values, box, ... c_dir, 1, ... dir_box_xrange, [0.3 0.6], ... dir_box_yrange, [-0.1 0.1]))
A cartesian rectangular grid in two dimensions with axis parallel elements.