rbmatlab 0.10.01
datafunc/gradient_approx2.m
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 
 All Classes Namespaces Files Functions Variables