comparison +scheme/Laplace1D.m @ 898:bd79326ebcd0

Mordernize Laplace1d
author Jonatan Werpers <jonatan@werpers.com>
date Thu, 22 Nov 2018 10:44:11 +0100
parents 09c5fbc783d3
children 21394c78c72e
comparison
equal deleted inserted replaced
897:ba7e442ea639 898:bd79326ebcd0
1 classdef Laplace1D < scheme.Scheme 1 classdef Laplace1D < scheme.Scheme
2 properties 2 properties
3 g 3 grid
4 order % Order accuracy for the approximation 4 order % Order accuracy for the approximation
5 5
6 D % non-stabalized scheme operator 6 D % non-stabalized scheme operator
7 H % Discrete norm 7 H % Discrete norm
8 M % Derivative norm 8 M % Derivative norm
16 d_r 16 d_r
17 gamm 17 gamm
18 end 18 end
19 19
20 methods 20 methods
21 function obj = Laplace1D(g, order, a) 21 function obj = Laplace1D(grid, order, a)
22 default_arg('a', 1); 22 default_arg('a', 1);
23 23
24 assertType(g, 'grid.Cartesian'); 24 assertType(grid, 'grid.Cartesian');
25 25
26 ops = sbp.Ordinary(g.size(), g.h, order); 26 ops = sbp.D2Standard(grid.size(), grid.lim{1}, order);
27 27
28 obj.D2 = sparse(ops.derivatives.D2); 28 obj.D2 = sparse(ops.D2);
29 obj.H = sparse(ops.norms.H); 29 obj.H = sparse(ops.H);
30 obj.Hi = sparse(ops.norms.HI); 30 obj.Hi = sparse(ops.HI);
31 obj.M = sparse(ops.norms.M); 31 obj.M = sparse(ops.M);
32 obj.e_l = sparse(ops.boundary.e_1); 32 obj.e_l = sparse(ops.e_l);
33 obj.e_r = sparse(ops.boundary.e_m); 33 obj.e_r = sparse(ops.e_r);
34 obj.d_l = sparse(ops.boundary.S_1); 34 obj.d_l = -sparse(ops.d1_l);
35 obj.d_r = sparse(ops.boundary.S_m); 35 obj.d_r = sparse(ops.d1_r);
36 36
37 37
38 obj.g = g; 38 obj.grid = grid;
39 obj.order = order; 39 obj.order = order;
40 40
41 obj.a = a; 41 obj.a = a;
42 obj.D = a*obj.D2; 42 obj.D = a*obj.D2;
43 43
44 obj.gamm = h*ops.borrowing.M.S; 44 obj.gamm = grid.h*ops.borrowing.M.S;
45 end 45 end
46 46
47 47
48 % Closure functions return the opertors applied to the own doamin to close the boundary 48 % Closure functions return the opertors applied to the own doamin to close the boundary
49 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. 49 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin.
59 [e,d,s] = obj.get_boundary_ops(boundary); 59 [e,d,s] = obj.get_boundary_ops(boundary);
60 60
61 switch type 61 switch type
62 % Dirichlet boundary condition 62 % Dirichlet boundary condition
63 case {'D','dirichlet'} 63 case {'D','dirichlet'}
64 alpha = obj.alpha; 64 tuning = 1.1;
65 tau1 = -tuning/obj.gamm;
66 tau2 = 1;
65 67
66 % tau1 < -alpha^2/gamma 68 tau = tau1*e + tau2*d;
67 tuning = 1.1;
68 tau1 = -tuning*alpha/obj.gamm;
69 tau2 = s*alpha;
70 69
71 p = tau1*e + tau2*d; 70 closure = obj.a*obj.Hi*tau*e';
72 71 penalty = obj.a*obj.Hi*tau;
73 closure = obj.Hi*p*e';
74
75 pp = obj.Hi*p;
76 switch class(data)
77 case 'double'
78 penalty = pp*data;
79 case 'function_handle'
80 penalty = @(t)pp*data(t);
81 otherwise
82 error('Wierd data argument!')
83 end
84
85 72
86 % Neumann boundary condition 73 % Neumann boundary condition
87 case {'N','neumann'} 74 case {'N','neumann'}
88 alpha = obj.alpha; 75 tau = -e;
89 tau1 = -s*alpha;
90 tau2 = 0;
91 tau = tau1*e + tau2*d;
92 76
93 closure = obj.Hi*tau*d'; 77 closure = obj.a*obj.Hi*tau*d';
94 78 penalty = -obj.a*obj.Hi*tau;
95 pp = obj.Hi*tau;
96 switch class(data)
97 case 'double'
98 penalty = pp*data;
99 case 'function_handle'
100 penalty = @(t)pp*data(t);
101 otherwise
102 error('Wierd data argument!')
103 end
104 79
105 % Unknown, boundary condition 80 % Unknown, boundary condition
106 otherwise 81 otherwise
107 error('No such boundary condition: type = %s',type); 82 error('No such boundary condition: type = %s',type);
108 end 83 end
109 end 84 end
110 85
111 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) 86 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
112 % u denotes the solution in the own domain 87 % u denotes the solution in the own domain
113 % v denotes the solution in the neighbour domain 88 % v denotes the solution in the neighbour domain
89
114 [e_u,d_u,s_u] = obj.get_boundary_ops(boundary); 90 [e_u,d_u,s_u] = obj.get_boundary_ops(boundary);
115 [e_v,d_v,s_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary); 91 [e_v,d_v,s_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary);
116 92
117 tuning = 1.1;
118 93
119 alpha_u = obj.alpha; 94 a_u = obj.a;
120 alpha_v = neighbour_scheme.alpha; 95 a_v = neighbour_scheme.a;
121 96
122 gamm_u = obj.gamm; 97 gamm_u = obj.gamm;
123 gamm_v = neighbour_scheme.gamm; 98 gamm_v = neighbour_scheme.gamm;
124 99
125 % tau1 < -(alpha_u/gamm_u + alpha_v/gamm_v) 100 tuning = 1.1;
126 101
127 tau1 = -(alpha_u/gamm_u + alpha_v/gamm_v) * tuning; 102 tau1 = -(a_u/gamm_u + a_v/gamm_v) * tuning;
128 tau2 = s_u*1/2*alpha_u; 103 tau2 = 1/2*a_u;
129 sig1 = s_u*(-1/2); 104 sig1 = -1/2;
130 sig2 = 0; 105 sig2 = 0;
131 106
132 tau = tau1*e_u + tau2*d_u; 107 tau = tau1*e_u + tau2*d_u;
133 sig = sig1*e_u + sig2*d_u; 108 sig = sig1*e_u + sig2*d_u;
134 109
135 closure = obj.Hi*( tau*e_u' + sig*alpha_u*d_u'); 110 closure = obj.Hi*( tau*e_u' + sig*a_u*d_u');
136 penalty = obj.Hi*(-tau*e_v' - sig*alpha_v*d_v'); 111 penalty = obj.Hi*(-tau*e_v' + sig*a_v*d_v');
137 end 112 end
138 113
139 % Ruturns the boundary ops and sign for the boundary specified by the string boundary. 114 % Ruturns the boundary ops and sign for the boundary specified by the string boundary.
140 % The right boundary is considered the positive boundary 115 % The right boundary is considered the positive boundary
141 function [e,d,s] = get_boundary_ops(obj,boundary) 116 function [e,d,s] = get_boundary_ops(obj,boundary)
152 error('No such boundary: boundary = %s',boundary); 127 error('No such boundary: boundary = %s',boundary);
153 end 128 end
154 end 129 end
155 130
156 function N = size(obj) 131 function N = size(obj)
157 N = obj.m; 132 N = obj.grid.size();
158 end 133 end
159 134
160 end 135 end
161 136
162 methods(Static) 137 methods(Static)