rbmatlab 0.10.01
|
00001 function grad = gradient_approx2(U, grid, params, edge) 00002 nels = grid.nelements; 00003 00004 00005 % get a 6-environment of each cell (c.f. get_ENBI for details) 00006 ENBI = get_ENBI(grid, edge); 00007 % initialise the U values of the 6 environment 00008 % UENBI = zeros(size(ENBI)); 00009 % initialise UE, a 4 environment that stores interpolated values at the 00010 % edges tips and exact values at the two adjacent cell centers. From UE 00011 % the gradient is calculated by lineare interpolation (lsq) 00012 UE = zeros(nels, 4); 00013 00014 %%%% Handle dirichlet cells ("ghost" cells with index -1) %%%% 00015 % if a cell adjacent to the current edge is a _dirichlet_ "ghost" cell, 00016 % entries in the matrix UE have to be replaced by exact evaluations at 00017 % the dirichlet boundary. The following cases have to be separated: 00018 % case 1: one of the adjacent cells is a ghost 00019 % => replace the cell's entry in UE with the dirichlet value at 00020 % the edge's center 00021 % case 2/3: one cell adjacent to the tip is a ghost 00022 % => replace the tip's entry in UE with the dirichlet value at the 00023 % edge's tip. 00024 00025 % find the _row_ index (edge inedex) of the three cases 00026 case1_dir_ind = find(ENBI(:,4) == -1); 00027 case2_dir_ind = find(ENBI(:,5) == -1); 00028 case3_dir_ind = find(ENBI(:,6) == -1); 00029 00030 % the case23_mapper maps to the correct edge tip (correct column index) 00031 % in UE. 00032 if edge > 2 00033 case23_mapper = [ mod(edge, 4) + 1, edge ]; 00034 else 00035 case23_mapper = [ edge, mod(edge, 4) + 1 ]; 00036 end 00037 00038 % neuman boundaries!!! For all other ghost cells the entries of 00039 % adjacent non-ghost cells are copied. Ghost cells in the corners of 00040 % the rectgrid are assigned in the end by copying one of the already 00041 % assigned adjacent ghost-cell. It is unspecified which ghost cell is 00042 % used. 00043 nb_ind = find(ENBI(:,2) <= 0); 00044 ENBI(nb_ind, 2) = ENBI(nb_ind, 1); 00045 nb_ind = find(ENBI(:,3) <= 0); 00046 ENBI(nb_ind, 3) = ENBI(nb_ind, 1); 00047 nb_ind = find(ENBI(:,4) <= 0); 00048 ENBI(nb_ind, 4) = ENBI(nb_ind, 1); 00049 nb_ind = find(ENBI(:,5) == -2); 00050 ENBI(nb_ind, 5) = ENBI(nb_ind, 2); 00051 nb_ind = find(ENBI(:,5) <= 0); 00052 ENBI(nb_ind, 5) = ENBI(nb_ind, 4); 00053 nb_ind = find(ENBI(:,6) == -2); 00054 ENBI(nb_ind, 6) = ENBI(nb_ind, 3); 00055 nb_ind = find(ENBI(:,6) <= 0); 00056 ENBI(nb_ind, 6) = ENBI(nb_ind, 4); 00057 00058 % now every ghost cell should have a positive index 00059 %assert(max(max(ENBI <= 0)) == 0); 00060 00061 UENBI = U(ENBI); 00062 % + ytrans(grid.CX(ENBI(non_zero_ind)), grid.CY(ENBI(non_zero_ind))); 00063 00064 % construct the 4-environment UE 00065 UE(:,[1,2]) = UENBI(:,[1,4]); 00066 UE(:,3) = sum(UENBI(:,[1,2,4,5]), 2) / 4; 00067 UE(:,4) = sum(UENBI(:,[1,3,4,6]), 2) / 4; 00068 00069 % construct the 4-environment UE 00070 UE(:,[1,2]) = UENBI(:,[1,4]); 00071 UE(:,3) = sum(UENBI(:,[1,2,4,5]), 2) / 4; 00072 UE(:,4) = sum(UENBI(:,[1,3,4,6]), 2) / 4; 00073 % update the 4-environment concerning dirichlet cells 00074 Xdir = grid.ESX(case1_dir_ind, edge); 00075 Ydir = grid.ESY(case1_dir_ind, edge); 00076 % Yoff = ytrans(Xdir, Ydir); 00077 UE(case1_dir_ind, 2) = dirichlet_values(Xdir, Ydir, params);% + Yoff; 00078 00079 Xdir = grid.X(grid.VI(case2_dir_ind, case23_mapper(1) )); 00080 Ydir = grid.Y(grid.VI(case2_dir_ind, case23_mapper(1) )); 00081 % Yoff = ytrans(Xdir, Ydir); 00082 UE(case2_dir_ind, 3) = dirichlet_values(Xdir, Ydir, params);% + Yoff; 00083 Xdir = grid.X(grid.VI(case3_dir_ind, case23_mapper(2) )); 00084 Ydir = grid.Y(grid.VI(case3_dir_ind, case23_mapper(2) )); 00085 % Yoff = ytrans(Xdir, Ydir); 00086 UE(case3_dir_ind, 4) = dirichlet_values(Xdir, Ydir, params);% + Yoff; 00087 00088 % construct the LHS matrix of the LES, it is - up to the sign - 00089 % identical for edges 1 and 3, respectively 2 and 4. 00090 % Therefore we need this factor 'factor' and an dummy edge 'tmp': 00091 factor = -1; 00092 tmp = edge; 00093 if(edge > 2) 00094 tmp = edge - 2; 00095 factor = 1; 00096 end 00097 00098 nb_ind = grid.NBI(1, tmp); 00099 Acell = [ grid.CX([1; nb_ind]) , grid.CY([1; nb_ind]); ... 00100 grid.X(grid.VI(1,(0:1) + tmp))', grid.Y(grid.VI(1,(0:1) + tmp))']; 00101 Acell = ( Acell - repmat([grid.ECX(1,tmp), grid.ECY(1, tmp)], 4, 1) ) ... 00102 * factor; 00103 00104 AcellT = Acell'; 00105 lhs_cell = AcellT * Acell; 00106 % The 3 diagonals of the LHS matrix A^T*A. 00107 LHS_d = repmat(horzcat([ lhs_cell(2,1); 0 ], ... 00108 diag(lhs_cell), ... 00109 [ 0; lhs_cell(1,2) ]),... 00110 nels, 1); 00111 LHS = spdiags(LHS_d, -1:1, 2*nels, 2*nels); 00112 00113 % The sparse matrix A^T (consists of 2x4 matrix blocks) 00114 AT = sparse( repmat([1;2], 4*nels, 1) ... 00115 + reshape(repmat(0:2:2*nels-1, 8, 1), 8*nels, 1), ... 00116 reshape(repmat(1:4*nels, 2, 1), 8*nels, 1), ... 00117 repmat(reshape(AcellT, 8, 1), nels, 1) ); 00118 % full(AT) 00119 % RHS = A^T b 00120 RHS = AT * reshape(UE', 4*nels, 1); 00121 00122 grad = reshape(LHS \ RHS, 2, nels)'; 00123 %grad 00124 %keyboard 00125 00126 00127 % TO BE ADJUSTED TO NEW SYNTAX 00128 %| \docupdate