1 function Dmat=mat_div3(X,h)
3 % Compute divergence matrix for a staggered mesh
4 % Note: this will work only for meshes on a standard Cartesian
7 % X staggered mesh (midpoints of sides)
10 % Dmat divergence matrix (sparse) on mesh
13 % Input parameter checking
15 error('mat_div3 only works in 3 dimensions')
17 if ~(isequal(size(X{1}),size(X{2}),size(X{3})))
18 error('Size of mesh must be the same in for u,w,z for mat_div3')
25 x = X{1}; y = X{2}; z = X{3};
26 [nx1, ny1, nz1] = size(x);
27 nx = nx1 - 1; ny = ny1 - 1; nz = nz1 - 1;
28 n = nx * ny * nz1 + nx * ny1 * nz + nx1 * ny * nz;
30 % Compute number of nonzeros
31 % Each boundary cell accounts for 1 nonzero, each non-boundary cell adds
32 % 2 (in each dimension)
33 nnz = (nx1 - 2) * ny * nz + ny * nz + ...
34 (ny1 - 2) * nx * nz + nx * nz + ...
35 (nz1 - 2) * nx * ny + nx * ny;
41 D = zeros(nnz,1); % Value of Dmat at index (I,J)
44 D_entry = 1; % Current entry of Dmat
48 surf_area = h(2) * h(3);
50 surf_area = h(3) * h(1);
52 surf_area = h(1) * h(2);
55 % Size of the grid for the current direction
56 grid_size = [nx,ny,nz];
57 grid_size(ux) = grid_size(ux) + 1;
58 X_len = grid_size(1); Y_len = grid_size(2); Z_len = grid_size(3);
60 % Main loop, iterates through all columns of Dmat
65 % Edge cases and relevant indices
67 low_row_ind = ix - 1 + (jx - 1) * nx + (kx - 1) * ny * nx;
68 row_ind = ix + (jx - 1) * nx + (kx - 1) * ny * nx;
69 is_lower_edge = ix == 1;
70 is_upper_edge = ix == X_len;
72 low_row_ind = ix + (jx - 2) * nx + (kx - 1) * ny * nx;
73 row_ind = ix + (jx - 1) * nx + (kx - 1) * ny * nx;
74 is_lower_edge = jx == 1;
75 is_upper_edge = jx == Y_len;
77 low_row_ind = ix + (jx - 1) * nx + (kx - 2) * ny * nx;
78 row_ind = ix + (jx - 1) * nx + (kx - 1) * ny * nx;
79 is_lower_edge = kx == 1;
80 is_upper_edge = kx == Z_len;
84 % Special case for top boundary
85 D(D_entry) = -1 * surf_area;
88 D_entry = D_entry + 1;
90 % Special case for lower boundary
91 D(D_entry) = 1 * surf_area;
92 I(D_entry) = low_row_ind;
94 D_entry = D_entry + 1;
97 D(D_entry) = 1 * surf_area;
98 I(D_entry) = low_row_ind;
100 D_entry = D_entry + 1;
101 D(D_entry) = -1 / h(ux);
102 I(D_entry) = row_ind;
104 D_entry = D_entry + 1;
111 Dmat = sparse(I, J, D, nx * nz *ny, n);