-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathdiff_matrices1d.m
90 lines (76 loc) · 2.39 KB
/
diff_matrices1d.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
function [Ix,D1xx,D1xc,D1xb,D1xf] = diff_matrices1d(N, dx, BC)
%DIFF_MATRICES1D Build 1D difference operators (default periodic BCs)
% [Ix,D1xx,D1xc,D1xb,D1xf] = diff_matrices1d(N, dx)
% N is length and dx is the grid spacing, with periodic BCs.
%
% [Ix,D1xx,D1xc,D1xb,D1xf] = diff_matrices1d(N, dx, 'n')
% Homogeneous Neumann BCs, using mirrored ghost values.
%
% [Ix,D1xx,D1xc,D1xb,D1xf] = diff_matrices1d(N, dx, 'd')
% Homoegeneous Dirichlet BCs, using mirrored ghost values.
%
% TODO: there are many ways of imposing BC: these may not be choices
% you want... The Neumann conditions for forward/backward
% differences is the one that's consistent with half-point
% evaluations.
if nargin < 3
BC = 'p';
end
switch BC
case 'p' % periodic BCs
Ix = speye(N,N);
e = ones(N,1);
D1xx = spdiags([e -2*e e], [-1 0 1], N, N);
D1xx(1,N) = 1;
D1xx(N,1) = 1;
D1xx = D1xx/dx^2;
D1xc = spdiags([-e e], [-1 1], N, N);
D1xc(1,N) = -1;
D1xc(N,1) = 1;
D1xc = D1xc/(2*dx);
D1xb = spdiags([-e e], [-1 0], N, N);
D1xb(1,N) = -1;
D1xb = D1xb/dx;
D1xf = spdiags([-e e], [0 1], N, N);
D1xf(N,1) = 1;
D1xf = D1xf/dx;
case 'n' % neumann BCs
Ix = speye(N,N);
e = ones(N,1);
D1xx = spdiags([e -2*e e], [-1 0 1], N, N);
D1xx(1,2) = 2;
D1xx(N,N-1) = 2;
D1xx = D1xx/dx^2;
D1xc = spdiags([-e e], [-1 1], N, N);
D1xc(1,2) = 0;
D1xc(N,N-1) = 0;
D1xc = D1xc/(2*dx);
D1xb = spdiags([-e e], [-1 0], N, N);
D1xb(1,2) = -1;
%D1xb(1,1) = 0; D1xb(N,N) = 0; D1xb(N,N-1) = 0;
D1xb = D1xb/dx;
D1xf = spdiags([-e e], [0 1], N, N);
D1xf(N,N-1) = 1;
%D1xf(N,N) = 0; D1xf(1,1) = 0; D1xf(1,2) = 0;
D1xf = D1xf/dx;
case 'd' % dirichlet BCs
Ix = speye(N,N);
e = ones(N,1);
% or maybe user would want one-sided 2nd-difference...
D1xx = spdiags([e -2*e e], [-1 0 1], N, N);
%D1xx(1,1) = 0;
D1xx(1,2) = 0;
%D1xx(N,N) = 0;
D1xx(N,N-1) = 0;
D1xx = D1xx/dx^2;
D1xc = spdiags([-e e], [-1 1], N, N);
D1xc(1,2) = 2;
D1xc(N,N-1) = -2;
D1xc = D1xc/(2*dx);
D1xb = spdiags([-e e], [-1 0], N, N);
D1xb(1,2) = 1;
D1xb = D1xb/dx;
D1xf = spdiags([-e e], [0 1], N, N);
D1xf(N,N-1) = -1;
D1xf = D1xf/dx;
end