comparison diracDiscr.m @ 1250:8ec777fb473e

Merged in feature/dirac_discr (pull request #17) Add multi-d dirac discretization with tests Approved-by: Vidar Stiernström <vidar.stiernstrom@it.uu.se> Approved-by: Martin Almquist <malmquist@stanford.edu> Approved-by: Jonatan Werpers <jonatan.werpers@it.uu.se>
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Wed, 20 Nov 2019 22:24:06 +0000
parents 25efceb0c392
children 60c875c18de3
comparison
equal deleted inserted replaced
1220:4dc295afe473 1250:8ec777fb473e
1 % n-dimensional delta function
2 % g: cartesian grid
3 % x_s: source point coordinate vector, e.g. [x; y] or [x; y; z].
4 % m_order: Number of moment conditions
5 % s_order: Number of smoothness conditions
6 % H: cell array of 1D norm matrices
7 function d = diracDiscr(g, x_s, m_order, s_order, H)
8 assertType(g, 'grid.Cartesian');
9
10 dim = g.d;
11 d_1D = cell(dim,1);
12
13 % Allow for non-cell input in 1D
14 if dim == 1
15 H = {H};
16 end
17 % Create 1D dirac discr for each coordinate dir.
18 for i = 1:dim
19 d_1D{i} = diracDiscr1D(x_s(i), g.x{i}, m_order, s_order, H{i});
20 end
21
22 d = d_1D{dim};
23 for i = dim-1: -1: 1
24 % Perform outer product, transpose, and then turn into column vector
25 d = (d_1D{i}*d')';
26 d = d(:);
27 end
28 end
29
30
31 % Helper function for 1D delta functions
32 function ret = diracDiscr1D(x_s, x, m_order, s_order, H)
33
34 % Return zeros if x0 is outside grid
35 if x_s < x(1) || x_s > x(end)
36 ret = zeros(size(x));
37 return
38 end
39
40 tot_order = m_order+s_order; %This is equiv. to the number of equations solved for
41 S = [];
42 M = [];
43
44 % Get interior grid spacing
45 middle = floor(length(x)/2);
46 h = x(middle+1) - x(middle); % Use middle point to allow for staggered grids.
47
48 index = sourceIndices(x_s, x, tot_order, h);
49
50 polynomial = (x(index)-x(index(1)))/(x(index(end))-x(index(1)));
51 x_0 = (x_s-x(index(1)))/(x(index(end))-x(index(1)));
52
53 quadrature = diag(H);
54 quadrature_weights = quadrature(index)/h;
55
56 h_polynomial = polynomial(2)-polynomial(1);
57 b = zeros(tot_order,1);
58
59 for i = 1:m_order
60 b(i,1) = x_0^(i-1);
61 end
62
63 for i = 1:tot_order
64 for j = 1:m_order
65 M(j,i) = polynomial(i)^(j-1)*h_polynomial*quadrature_weights(i);
66 end
67 end
68
69 for i = 1:tot_order
70 for j = 1:s_order
71 S(j,i) = (-1)^(i-1)*polynomial(i)^(j-1);
72 end
73 end
74
75 A = [M;S];
76
77 d = A\b;
78 ret = x*0;
79 ret(index) = d/h*h_polynomial;
80 end
81
82
83 function I = sourceIndices(x_s, x, tot_order, h)
84 % Find the indices that are within range of of the point source location
85 I = find(tot_order*h/2 >= abs(x-x_s));
86
87 if length(I) > tot_order
88 if length(I) == tot_order + 2
89 I = I(2:end-1);
90 elseif length(I) == tot_order + 1
91 I = I(1:end-1);
92 end
93 elseif length(I) < tot_order
94 if x_s < x(1) + ceil(tot_order/2)*h
95 I = 1:tot_order;
96 elseif x_s > x(end) - ceil(tot_order/2)*h
97 I = length(x)-tot_order+1:length(x);
98 else
99 if I(end) < length(x)
100 I = [I; I(end)+1];
101 else
102 I = [I(1)-1; I];
103 end
104 end
105 end
106 end