rbmatlab 0.10.01
datafunc/gradient_approx.m
00001 function grad = gradient_approx(model,model_data,U, NU_ind, edge)
00002 %function grad = gradient_approx(model,model_data,U, [NU_ind], edge)
00003 %
00004 % function that computes an approximation of the gradient over the edge
00005 % given by 'edge'.
00006 %
00007 % Martin Drohmann 13.05.2008
00008 
00009   grid = model_data.grid;
00010   nels = grid.nelements;
00011 
00012   if(isempty(NU_ind))
00013     NU_ind = 1:nels;
00014   end
00015   % get a 6-environment of each cell (see get_enbi for details)
00016   ENBI    = get_enbi(grid, edge, model.tstep);
00017   % initialise UE, a 4 environment that stores interpolated values at the
00018   % edges tips and exact values at the two adjacent cell centers. From UE
00019   % the gradient is calculated by lineare interpolation (lsq)
00020   UE          = zeros(nels, 4);
00021 
00022   %%%% Handle dirichlet cells ("ghost" cells with index -1) %%%%
00023   % if a cell adjacent to the current edge is a _dirichlet_ "ghost" cell,
00024   % entries in the matrix UE have to be replaced by exact evaluations at
00025   % the dirichlet boundary. The following cases have to be separated:
00026   % case 1: one of the adjacent cells is a ghost
00027   %      => replace the cell's entry in UE with the dirichlet value at
00028   %         the edge's center
00029   % case 2/3: one cell adjacent to the tip is a ghost
00030   %      => replace the tip's entry in UE with the dirichlet value at the
00031   %         edge's tip.
00032 
00033   % find the _row_ index (edge inedex) of the three cases
00034   case1_dir_ind = find(ENBI(:,4) == -1);
00035   case2_dir_ind = find(ENBI(:,5) == -1);
00036   case3_dir_ind = find(ENBI(:,6) == -1);
00037 
00038   % the case23_mapper maps to the correct edge tip (correct column index)
00039   % in UE.
00040   if edge > 2
00041     case23_mapper = [ mod(edge, 4) + 1, edge ];
00042   else
00043     case23_mapper = [ edge, mod(edge, 4) + 1 ];
00044   end
00045 
00046   % neuman boundaries!!! For all other ghost cells the entries of
00047   % adjacent non-ghost cells are copied. Ghost cells in the corners of
00048   % the rectgrid are assigned in the end by copying one of the already
00049   % assigned adjacent ghost-cell. It is unspecified which ghost cell is
00050   % used.
00051   if(any(any(ENBI(NU_ind, :) == -10)))
00052     keyboard;
00053     disp('Attention in gradient_approx! This line should never be executed');
00054     disp('Maybe the wrong stencil_mode was set in dmodel???');
00055   end
00056   nb_ind          = find(ENBI(:,2) <= 0);
00057   ENBI(nb_ind, 2) = ENBI(nb_ind, 1);
00058   nb_ind          = find(ENBI(:,3) <= 0);
00059   ENBI(nb_ind, 3) = ENBI(nb_ind, 1);
00060   nb_ind          = find(ENBI(:,4) <= 0);
00061   ENBI(nb_ind, 4) = ENBI(nb_ind, 1);
00062   nb_ind          = find(ENBI(:,5) == -2);
00063   ENBI(nb_ind, 5) = ENBI(nb_ind, 2);
00064   nb_ind          = find(ENBI(:,5) <= 0);
00065   ENBI(nb_ind, 5) = ENBI(nb_ind, 4);
00066   nb_ind          = find(ENBI(:,6) == -2);
00067   ENBI(nb_ind, 6) = ENBI(nb_ind, 3);
00068   nb_ind          = find(ENBI(:,6) <= 0);
00069   ENBI(nb_ind, 6) = ENBI(nb_ind, 4);
00070 
00071   % now every ghost cell should have a positive index
00072 %  assert(max(max(ENBI <= 0)) == 0);
00073 
00074   UENBI = U(ENBI);
00075   % + ytrans(grid.CX(ENBI(non_zero_ind)), grid.CY(ENBI(non_zero_ind))); 
00076 
00077   % construct the 4-environment UE            
00078   UE(NU_ind,[1,2]) = UENBI(NU_ind,[1,4]);
00079   UE(NU_ind,3)     = sum(UENBI(NU_ind,[1,2,4,5]), 2) / 4;
00080   UE(NU_ind,4)     = sum(UENBI(NU_ind,[1,3,4,6]), 2) / 4;
00081   % update the 4-environment concerning dirichlet cells
00082   Xdir = grid.ESX(case1_dir_ind, edge);
00083   Ydir = grid.ESY(case1_dir_ind, edge);
00084   UE(case1_dir_ind, 2) = model.dirichlet_values_ptr([Xdir,Ydir], model);
00085   Xdir = grid.X(grid.VI(case2_dir_ind, case23_mapper(1) ));
00086   Ydir = grid.Y(grid.VI(case2_dir_ind, case23_mapper(1) ));
00087   UE(case2_dir_ind, 3) = model.dirichlet_values_ptr([Xdir,Ydir], model);
00088   Xdir = grid.X(grid.VI(case3_dir_ind, case23_mapper(2) ));
00089   Ydir = grid.Y(grid.VI(case3_dir_ind, case23_mapper(2) ));
00090   UE(case3_dir_ind, 4) = model.dirichlet_values_ptr([Xdir,Ydir], model);
00091 
00092   horiz_length = grid.EL(1,1);
00093   vert_length  = grid.EL(1,2);
00094 
00095   if edge == 1
00096     grad = [(UE(NU_ind,2)-UE(NU_ind,1))./horiz_length, (UE(NU_ind,4)-UE(NU_ind,3))./vert_length];
00097   elseif edge == 2
00098     grad = [(UE(NU_ind,3)-UE(NU_ind,4))./horiz_length,  (UE(NU_ind,2)-UE(NU_ind,1))./vert_length];
00099   elseif edge == 3
00100     grad = [(UE(NU_ind,1)-UE(NU_ind,2))./horiz_length, (UE(NU_ind,4)-UE(NU_ind,3))./vert_length];
00101   elseif edge == 4
00102     grad = [(UE(NU_ind,3)-UE(NU_ind,4))./horiz_length,  (UE(NU_ind,1)-UE(NU_ind,2))./vert_length];
00103   end
00104 
00105 %| \docupdate 
 All Classes Namespaces Files Functions Variables