rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
gradient_approx2.m
1 function grad = gradient_approx2(U, grid, params, edge)
2  nels = grid.nelements;
3 
4 
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)
12  UE = zeros(nels, 4);
13 
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
20  % the edge's center
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
23  % edge's tip.
24 
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);
29 
30  % the case23_mapper maps to the correct edge tip (correct column index)
31  % in UE.
32  if edge > 2
33  case23_mapper = [ mod(edge, 4) + 1, edge ];
34  else
35  case23_mapper = [ edge, mod(edge, 4) + 1 ];
36  end
37 
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
42  % used.
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);
57 
58  % now every ghost cell should have a positive index
59  %assert(max(max(ENBI <= 0)) == 0);
60 
61  UENBI = U(ENBI);
62  % + ytrans(grid.CX(ENBI(non_zero_ind)), grid.CY(ENBI(non_zero_ind)));
63 
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;
68 
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);
77  UE(case1_dir_ind, 2) = dirichlet_values(Xdir, Ydir, params);% + Yoff;
78 
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);
82  UE(case2_dir_ind, 3) = dirichlet_values(Xdir, Ydir, params);% + Yoff;
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);
86  UE(case3_dir_ind, 4) = dirichlet_values(Xdir, Ydir, params);% + Yoff;
87 
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':
91  factor = -1;
92  tmp = edge;
93  if(edge > 2)
94  tmp = edge - 2;
95  factor = 1;
96  end
97 
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) ) ...
102  * factor;
103 
104  AcellT = Acell';
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 ], ...
108  diag(lhs_cell), ...
109  [ 0; lhs_cell(1,2) ]),...
110  nels, 1);
111  LHS = spdiags(LHS_d, -1:1, 2*nels, 2*nels);
112 
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) );
118 % full(AT)
119  % RHS = A^T b
120  RHS = AT * reshape(UE', 4*nels, 1);
121 
122  grad = reshape(LHS \ RHS, 2, nels)';
123  %grad
124  %keyboard
125 
126 
127 % TO BE ADJUSTED TO NEW SYNTAX
128 %| \docupdate
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.
Definition: rectgrid.m:17