This is a static copy of a profile report

Home

Diffusion_Operator (4 calls, 1.054 sec)
Generated 04-Aug-2014 13:05:20 using cpu time.
function in file /gdata/projects/atl/FV_Matlab_Framework_JingPJH/trunk/Src/MatrixOps/Diffusion_Operator.m
Copy to new window for comparing multiple runs

Parents (calling functions)

Function NameFunction TypeCalls
FluidsSolver2_DO3function4
Lines where the most time was spent

Line NumberCodeCallsTotal Time% TimeTime Plot
81
J(I <= 0) = []; I(I <= 0...
40.142 s13.5%
112
Adj = sparse(I, J, kron([1;2;3...
40.129 s12.3%
85
A = sparse(I, J, kron([2*(Cx+C...
40.129 s12.3%
132
Adj = Adj + sparse(I, J, 9*one...
40.045 s4.3%
122
Adj = Adj + sparse(I, J, 7*one...
40.045 s4.3%
All other lines  0.563 s53.4%
Totals  1.054 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
kronfunction80.013 s1.2%
Self time (built-ins, overhead, etc.)  1.041 s98.8%
Totals  1.054 s100% 
Code Analyzer results
No Code Analyzer messages.
Coverage results
Show coverage for parent directory
Total lines in function287
Non-code lines (comments, blank lines)150
Code lines (lines that can run)137
Code lines that did run137
Code lines that did not run0
Coverage (did run/can run)100.00 %
Function listing
time 
calls 
 line
   1 
function [Dfs, Dfs_bc, Dfs_bc_rhs] = Diffusion_Operator(stagr, Node, bcsD, bcsO, bcsN,...
   2 
    dx, dy, nu_x, nu_y, Rm_Singularity)
   3 
% function [Dfs, Dfs_bc, Dfs_bc_rhs] = Diffusion_Operator(stagr, Node,...
   4 
%     bcsD, bcsO, bcsN,dx, dy, nu_x, nu_y, Rm_Singularity)
   5 
% This function creates the discrete diffusion operator (matrix), its RHS vector
   6 
% and the matrix to generate this RHS vector from boundary conditions.
   7 
% 
   8 
% Warning: Note that the diffusion operator here is meant to be
   9 
%                     - nu_x d^2/dx^2 - nu_y d^2/dy^2
  10 
% This is not simply a Laplace operator! Two things to keep in mind:
  11 
% 1. There is a negative sign.
  12 
% 2. The two diffusion coeffcients are included and can be different.
  13 
% 
  14 
% To further clarify the usage, we consider the following Poisson equation about P
  15 
%                  (- nu_x d^2/dx^2 - nu_y d^2/dy^2)P = b
  16 
% where b is some arbitray forcing.
  17 
% With the boundary conditions specified as the input of this Matlab function,
  18 
% after the output is obtained, the discrete version of the Poisson equation is
  19 
%                       Dfs * P_hat = b_hat + Dfs_bc_rhs
  20 
% Solving this linear system gives the numerical solution of P:
  21 
%                    P_hat = (Dfs)^(-1) * (b_hat + Dfs_bc_rhs)
  22 
%
  23 
% INPUTS:
  24 
%       stagr:  String indicating which grid to use: 'P', 'u', or 'v'. 
  25 
%       Node:   Node numbering matrix.
  26 
%               NOTE: Node needs to include boundary conditions. In the case for
  27 
%               periodic boundaries, the periodicity needs to be included. See NodePad.m
  28 
%       bcsD:   Vector containing the values of Dirichlet BCs.
  29 
%       bcsO:   Vector containing the IDs of Dirichelet BCs that are actually open BCs.
  30 
%       bcsN:   Vector containing the values of Neumann BCs.         
  31 
%               (eg. bcsN = g means du/dn = g on the boundary)
  32 
%       dx:     Mesh spacing in x direction
  33 
%       dy:     Mesh sapcing in y direction
  34 
%       nu_x:   Diffusion coeffcients in x direction
  35 
%       nu_y:   Diffusion coeffcients in y direction
  36 
%
  37 
%       Rm_Singularity: (Optional) Logical variable indicating whether to remove
  38 
%               the singularity of the operator matrix Dfs when no Dirichlet BCs are
  39 
%               specified. The singularity is removed by changing the last equation to 
  40 
%               be one setting the last interior cell equal to 0.
  41 
%
  42 
% OUTPUTS:
  43 
%       Dfs:        The diffusion operator matrix
  44 
%       Dfs_bc:     The matrix used to create the right-hand-side vector
  45 
%       Dfs_bc_rhs: The right-hand-side vector from BC contributions
  46 
%
  47 
% See also: NodePad.m
  48 
%
  49 
% Date: Dec. 2013
  50 
% Author: Jing Lin
  51 

  52 

  53 
%% Preliminaries
  54 

  55 
% Nx: Number of cells in the x-direction (include boundaries)
  56 
% Ny: Number of cells in the y-direction (include boundaries)
      4 
  57 
[Ny, Nx] = size(Node); 
  58 

      4 
  59 
NbcsD = length(bcsD); 
      4 
  60 
NbcsO = length(bcsO); 
      4 
  61 
NbcsN = length(bcsN); 
      4 
  62 
Nbcs = NbcsD + NbcsN; % Number of all boundary conditions 
      4 
  63 
bcD_ID = 1 : NbcsD; 
      4 
  64 
bcN_ID = (NbcsD + 1) : Nbcs; 
      4 
  65 
Int_ID = (Nbcs + 1) : max(Node(:)); 
      4 
  66 
Num_Cell = length(Int_ID); % Number of interior cells 
  67 

  68 
% Define the number clusters appearing in entries of diffusion operator matrix
      4 
  69 
Cx = nu_x/dx^2; 
      4 
  70 
Cy = nu_y/dy^2; 
  71 

  72 

  73 
%% Build a preliminary matrix A of size Num_Cell * (Num_Cell + Nbcs)
  74 

  75 
%Create the indices for the entries of A
      4 
  76 
idsx = 2 : (Nx - 1); 
      4 
  77 
idsy = 2 : (Ny - 1); 
  0.03 
      4 
  78 
I = repmat(Node(idsy, idsx) - Nbcs, 1, 5); 
  0.05 
      4 
  79 
J = [Node(idsy, idsx), Node(idsy, idsx - 1), Node(idsy, idsx + 1),... 
  80 
    Node(idsy + 1, idsx), Node(idsy - 1, idsx)];
  0.14 
      4 
  81 
J(I <= 0) = []; I(I <= 0) = []; I = I(:); J = J(:); 
  82 

  83 
% Create the A matrix in sparse form
      4 
  84 
One = ones(Num_Cell, 1); 
  0.13 
      4 
  85 
A = sparse(I, J, kron([2*(Cx+Cy);-Cx;-Cx;-Cy;-Cy], One),... 
  86 
    Num_Cell, Num_Cell + Nbcs, 5 * Num_Cell);
  87 

  88 
% Break the A matrix into three parts corresponding to Dirichlet, Neumann boundary
  89 
% cells and interior cells
      4 
  90 
A_Dbc = A(:,bcD_ID); 
      4 
  91 
A_Nbc = A(:,bcN_ID); 
  0.03 
      4 
  92 
A = A(:, Int_ID); 
  93 

  94 

  95 
%% Construct an adjacency matrix Adj
  96 

  97 
% Construct an adjacency matrix of the same size as A indicating in which direction
  98 
% the adjacent cells corresponding to entries of A lie.
  99 
% The mapping follows the rule:
 100 
% 1 :    Center cell (i  ,  j)
 101 
% 2 :      West cell (i  ,j-1)
 102 
% 3 :      East cell (i  ,j+1)
 103 
% 4 :     South cell (i+1,  j)
 104 
% 5 :     North cell (i-1,  j)
 105 
% 6 :  Far west cell (i  ,j-2)
 106 
% 7 :  Far east cell (i  ,j+2)
 107 
% 8 : Far south cell (i+2,  j)
 108 
% 9 : Far north cell (i-2,  j)
 109 

      4 
 110 
idsx2 = 2 : (Nx - 2); 
      4 
 111 
idsy2 = 2 : (Ny - 2); 
  0.13 
      4 
 112 
Adj = sparse(I, J, kron([1;2;3;4;5], One), Num_Cell, Num_Cell + Nbcs, 9 * Num_Cell); 
 113 

 114 
% Mark the far west cells.
      4 
 115 
I = Node(idsy, idsx2+1) - Nbcs; J = Node(idsy, idsx2-1); 
  0.03 
      4 
 116 
J(I <= 0) = []; I(I <= 0) = []; I = I(:); J = J(:); 
  0.03 
      4 
 117 
Adj = Adj + sparse(I, J, 6*ones(length(I), 1), Num_Cell, Num_Cell + Nbcs); 
 118 

 119 
% Mark the far east cells.
< 0.01 
      4 
 120 
I = Node(idsy, idsx2) - Nbcs; J = Node(idsy, idsx2+2); 
  0.03 
      4 
 121 
J(I <= 0) = []; I(I <= 0) = []; I = I(:); J = J(:); 
  0.05 
      4 
 122 
Adj = Adj + sparse(I, J, 7*ones(length(I), 1), Num_Cell, Num_Cell + Nbcs); 
 123 

 124 
% Mark the far south cells.
  0.01 
      4 
 125 
I = Node(idsy2, idsx) - Nbcs; J = Node(idsy2+2, idsx); 
  0.02 
      4 
 126 
J(I <= 0) = []; I(I <= 0) = []; I = I(:); J = J(:); 
  0.04 
      4 
 127 
Adj = Adj + sparse(I, J, 8*ones(length(I), 1), Num_Cell, Num_Cell + Nbcs); 
 128 

 129 
% Mark the far north cells.
  0.01 
      4 
 130 
I = Node(idsy2+1, idsx) - Nbcs; J = Node(idsy2-1, idsx); 
< 0.01 
      4 
 131 
J(I <= 0) = []; I(I <= 0) = []; I = I(:); J = J(:); 
  0.05 
      4 
 132 
Adj = Adj + sparse(I, J, 9*ones(length(I), 1), Num_Cell, Num_Cell + Nbcs); 
 133 

 134 
% Break the Adj matrix into three parts corresponding to Dirichlet, Neumann boundary
 135 
% cells and interior cells
      4 
 136 
Adj_Dbc = Adj(:,bcD_ID); 
      4 
 137 
Adj_Nbc = Adj(:,bcN_ID); 
  0.02 
      4 
 138 
Adj = Adj(:, Int_ID); 
 139 

 140 

 141 
%% Set up the Dirichlet, Neumann and open boundary conditions
 142 

      4 
 143 
if ~isempty(bcsD) 
 144 
    
 145 
    % Dirichlet BC along x-direction
      3 
 146 
    if (stagr == 'P')||(stagr == 'v') 
      2 
 147 
        Posi = (Adj_Dbc == 2)|(Adj_Dbc == 3); 
< 0.01 
      2 
 148 
        Cell_ID = find(sum(Posi, 2)); 
 149 
        % Modify the boundary cell coeffcients
      2 
 150 
        A_Dbc(Posi) = A_Dbc(Posi) + (-(-1) + (-16/5))*Cx; 
 151 
        % Modify the center cell coefficients
      2 
 152 
        Temp_A = (Adj == 1); 
      2 
 153 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      2 
 154 
        A(Cell_ID,:) = A(Cell_ID,:) + (-2 + 5)*Cx*Temp_A; 
 155 
        % Modify the inward interior cell coefficients
  0.01 
      2 
 156 
        Temp_A = (Adj == 2)|(Adj == 3); 
      2 
 157 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      2 
 158 
        A(Cell_ID,:) = A(Cell_ID,:) + (-(-1) + (-2))*Cx*Temp_A; 
 159 
        % Modify the far inward interior cell coefficients
< 0.01 
      2 
 160 
        Temp_A = (Adj == 6)|(Adj == 7); 
      2 
 161 
        Temp_A = Temp_A(Cell_ID, :); 
  0.01 
      2 
 162 
        A(Cell_ID,:) = A(Cell_ID,:) + (-0 + 1/5)*Cx*Temp_A; 
      2 
 163 
    end; 
 164 
    
 165 
    % Dirichlet BC along y-direction
      3 
 166 
    if (stagr == 'P')||(stagr == 'u') 
      2 
 167 
        Posi = (Adj_Dbc == 4)|(Adj_Dbc == 5); 
      2 
 168 
        Cell_ID = find(sum(Posi, 2)); 
 169 
        % Modify the boundary cell coeffcients
      2 
 170 
        A_Dbc(Posi) = A_Dbc(Posi) + (-(-1) + (-16/5))*Cy; 
 171 
        % Modify the center cell coefficients
      2 
 172 
        Temp_A = (Adj == 1); 
      2 
 173 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      2 
 174 
        A(Cell_ID,:) = A(Cell_ID,:) + (-2 + 5)*Cy*Temp_A; 
 175 
        % Modify the inward interior cell coefficients
< 0.01 
      2 
 176 
        Temp_A = (Adj == 4)|(Adj == 5); 
      2 
 177 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      2 
 178 
        A(Cell_ID,:) = A(Cell_ID,:) + (-(-1) + (-2))*Cy*Temp_A; 
 179 
        % Modify the far inward interior cell coefficients
< 0.01 
      2 
 180 
        Temp_A = (Adj == 8)|(Adj == 9); 
      2 
 181 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      2 
 182 
        A(Cell_ID,:) = A(Cell_ID,:) + (-0 + 1/5)*Cy*Temp_A; 
      2 
 183 
    end; 
      3 
 184 
end; 
 185 

      4 
 186 
if ~isempty(bcsN) 
  0.04 
      4 
 187 
    A(Adj == 1) = A(Adj == 1) + sum(A_Nbc, 2); 
 188 
    
 189 
    % Neumann BC along x-direction
      4 
 190 
    Posi = (Adj_Nbc == 2)|(Adj_Nbc == 3); 
      4 
 191 
    if (stagr == 'P')||(stagr == 'v') 
 192 
        % Modify the boundary cell coeffcients
      3 
 193 
        A_Nbc(Posi) = A_Nbc(Posi) * dx; 
      1 
 194 
    else 
      1 
 195 
        Cell_ID = find(sum(Posi, 2)); 
 196 
        % Modify the boundary cell coeffcients
      1 
 197 
        A_Nbc(Posi) = A_Nbc(Posi) + (-(-1)*Cx + (-6/11)*Cx*dx); 
 198 
        % Modify the center cell coefficients
< 0.01 
      1 
 199 
        Temp_A = (Adj == 1); 
      1 
 200 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      1 
 201 
        A(Cell_ID,:) = A(Cell_ID,:) + (-(2-1) + 4/11)*Cx*Temp_A; 
 202 
        % Modify the inward interior cell coefficients
      1 
 203 
        Temp_A = (Adj == 2)|(Adj == 3); 
< 0.01 
      1 
 204 
        Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      1 
 205 
        A(Cell_ID,:) = A(Cell_ID,:) + (-(-1) + (-2/11))*Cx*Temp_A; 
 206 
        % Modify the far inward interior cell coefficients
      1 
 207 
        Temp_A = (Adj == 6)|(Adj == 7); 
      1 
 208 
        Temp_A = Temp_A(Cell_ID, :); 
  0.01 
      1 
 209 
        A(Cell_ID,:) = A(Cell_ID,:) + (-0 + (-2/11))*Cx*Temp_A; 
      1 
 210 
    end; 
 211 
    
 212 
    % Neumann BC along y-direction
      4 
 213 
    Posi = (Adj_Nbc == 4)|(Adj_Nbc == 5); 
      4 
 214 
    if (stagr == 'P')||(stagr == 'u') 
 215 
        % Modify the boundary cell coeffcients
< 0.01 
      3 
 216 
        A_Nbc(Posi) = A_Nbc(Posi) * dy; 
      1 
 217 
    else 
      1 
 218 
        Cell_ID = find(sum(Posi, 2)); 
 219 
        % Modify the boundary cell coeffcients
      1 
 220 
        A_Nbc(Posi) = A_Nbc(Posi) + (-(-1)*Cy + (-6/11)*Cy*dy); 
 221 
        % Modify the center cell coefficients
      1 
 222 
        Temp_A = (Adj == 1); 
      1 
 223 
        Temp_A = Temp_A(Cell_ID, :); 
      1 
 224 
        A(Cell_ID,:) = A(Cell_ID,:) + (-(2-1) + 4/11)*Cy*Temp_A; 
 225 
        % Modify the inward interior cell coefficients
< 0.01 
      1 
 226 
        Temp_A = (Adj == 4)|(Adj == 5); 
      1 
 227 
        Temp_A = Temp_A(Cell_ID, :); 
      1 
 228 
        A(Cell_ID,:) = A(Cell_ID,:) + (-(-1) + (-2/11))*Cy*Temp_A; 
 229 
        % Modify the far inward interior cell coefficients
< 0.01 
      1 
 230 
        Temp_A = (Adj == 8)|(Adj == 9); 
      1 
 231 
        Temp_A = Temp_A(Cell_ID, :); 
      1 
 232 
        A(Cell_ID,:) = A(Cell_ID,:) + (-0 + (-2/11))*Cy*Temp_A; 
      1 
 233 
    end; 
      4 
 234 
end; 
 235 

      4 
 236 
if (stagr == 'P')&&(~isempty(bcsO)) 
 237 
    
 238 
    % Modify the boundary cell coeffcients
      1 
 239 
    A_Dbc(:, bcsO) = 0; 
 240 
    
      1 
 241 
    Adj_Obc = Adj_Dbc(:, bcsO); 
 242 
    
 243 
    % Open BC along x-direction
      1 
 244 
    Posi = (Adj_Obc == 2)|(Adj_Obc == 3); 
      1 
 245 
    Cell_ID = find(sum(Posi, 2)); 
 246 
    % Modify the center cell coefficients
< 0.01 
      1 
 247 
    Temp_A = (Adj == 1); 
      1 
 248 
    Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      1 
 249 
    A(Cell_ID,:) = A(Cell_ID,:) + (-5 + (-1/3))*Cx*Temp_A; 
 250 
    % Modify the inward interior cell coefficients
      1 
 251 
    Temp_A = (Adj == 2)|(Adj == 3); 
      1 
 252 
    Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      1 
 253 
    A(Cell_ID,:) = A(Cell_ID,:) + (-(-2) + 2/3)*Cx*Temp_A; 
 254 
    % Modify the far inward interior cell coefficients
< 0.01 
      1 
 255 
    Temp_A = (Adj == 6)|(Adj == 7); 
      1 
 256 
    Temp_A = Temp_A(Cell_ID, :); 
< 0.01 
      1 
 257 
    A(Cell_ID,:) = A(Cell_ID,:) + (-1/5 + (-1/3))*Cx*Temp_A; 
 258 
    
 259 
    % Open BC along y-direction
      1 
 260 
    Posi = (Adj_Obc == 4)|(Adj_Obc == 5); 
      1 
 261 
    Cell_ID = find(sum(Posi, 2)); 
 262 
    % Modify the center cell coefficients
< 0.01 
      1 
 263 
    Temp_A = (Adj == 1); 
      1 
 264 
    Temp_A = Temp_A(Cell_ID, :); 
      1 
 265 
    A(Cell_ID,:) = A(Cell_ID,:) + (-5 + (-1/3))*Cy*Temp_A; 
 266 
    % Modify the inward interior cell coefficients
< 0.01 
      1 
 267 
    Temp_A = (Adj == 4)|(Adj == 5); 
      1 
 268 
    Temp_A = Temp_A(Cell_ID, :); 
      1 
 269 
    A(Cell_ID,:) = A(Cell_ID,:) + (-(-2) + 2/3)*Cy*Temp_A; 
 270 
    % Modify the far inward interior cell coefficients
< 0.01 
      1 
 271 
    Temp_A = (Adj == 8)|(Adj == 9); 
      1 
 272 
    Temp_A = Temp_A(Cell_ID, :); 
      1 
 273 
    A(Cell_ID,:) = A(Cell_ID,:) + (-1/5 + (-1/3))*Cy*Temp_A; 
      1 
 274 
end; 
 275 

 276 
% Remove the singularity if no Dirichlet BCs are specified.
      4 
 277 
if (nargin == 10)&&(Rm_Singularity)&&(NbcsD == NbcsO)&&(stagr == 'P') 
< 0.01 
      1 
 278 
    A(end, :) = 0; A(end, end) = 1; 
      1 
 279 
    A_Dbc(end, :) = 0; A_Nbc(end, :) = 0; 
      1 
 280 
end; 
 281 

 282 

 283 
%% Finally, distribute entries of A to outputs
 284 

      4 
 285 
Dfs = A; 
      4 
 286 
Dfs_bc = [A_Dbc, A_Nbc]; 
      4 
 287 
Dfs_bc_rhs = -Dfs_bc * [bcsD; bcsN];