rbmatlab 0.10.01
|
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