Mercurial > repos > public > sbplib
comparison +scheme/Hypsyst2d.m @ 905:459eeb99130f feature/utux2D
Include type as (optional) input parameter in the interface method of all schemes.
author | Martin Almquist <malmquist@stanford.edu> |
---|---|
date | Thu, 22 Nov 2018 22:03:44 -0800 |
parents | 9d1fc984f40d |
children | b9c98661ff5d |
comparison
equal
deleted
inserted
replaced
904:14b093a344eb | 905:459eeb99130f |
---|---|
4 n %size of system | 4 n %size of system |
5 h % Grid spacing | 5 h % Grid spacing |
6 x,y % Grid | 6 x,y % Grid |
7 X,Y % Values of x and y for each grid point | 7 X,Y % Values of x and y for each grid point |
8 order % Order accuracy for the approximation | 8 order % Order accuracy for the approximation |
9 | 9 |
10 D % non-stabalized scheme operator | 10 D % non-stabalized scheme operator |
11 A, B, E %Coefficient matrices | 11 A, B, E %Coefficient matrices |
12 | 12 |
13 H % Discrete norm | 13 H % Discrete norm |
14 % Norms in the x and y directions | 14 % Norms in the x and y directions |
15 Hxi,Hyi % Kroneckerd norms. 1'*Hx*v corresponds to integration in the x dir. | 15 Hxi,Hyi % Kroneckerd norms. 1'*Hx*v corresponds to integration in the x dir. |
16 I_x,I_y, I_N | 16 I_x,I_y, I_N |
17 e_w, e_e, e_s, e_n | 17 e_w, e_e, e_s, e_n |
18 params %parameters for the coeficient matrice | 18 params %parameters for the coeficient matrice |
19 end | 19 end |
20 | 20 |
21 methods | 21 methods |
22 %Solving Hyperbolic systems on the form u_t=-Au_x-Bu_y-Eu | 22 %Solving Hyperbolic systems on the form u_t=-Au_x-Bu_y-Eu |
23 function obj = Hypsyst2d(m, lim, order, A, B, E, params) | 23 function obj = Hypsyst2d(m, lim, order, A, B, E, params) |
24 default_arg('E', []) | 24 default_arg('E', []) |
25 xlim = lim{1}; | 25 xlim = lim{1}; |
26 ylim = lim{2}; | 26 ylim = lim{2}; |
27 | 27 |
28 if length(m) == 1 | 28 if length(m) == 1 |
29 m = [m m]; | 29 m = [m m]; |
30 end | 30 end |
31 | 31 |
32 obj.A=A; | 32 obj.A=A; |
33 obj.B=B; | 33 obj.B=B; |
34 obj.E=E; | 34 obj.E=E; |
35 | 35 |
36 m_x = m(1); | 36 m_x = m(1); |
37 m_y = m(2); | 37 m_y = m(2); |
38 obj.params = params; | 38 obj.params = params; |
39 | 39 |
40 ops_x = sbp.D2Standard(m_x,xlim,order); | 40 ops_x = sbp.D2Standard(m_x,xlim,order); |
41 ops_y = sbp.D2Standard(m_y,ylim,order); | 41 ops_y = sbp.D2Standard(m_y,ylim,order); |
42 | 42 |
43 obj.x = ops_x.x; | 43 obj.x = ops_x.x; |
44 obj.y = ops_y.x; | 44 obj.y = ops_y.x; |
45 | 45 |
46 obj.X = kr(obj.x,ones(m_y,1)); | 46 obj.X = kr(obj.x,ones(m_y,1)); |
47 obj.Y = kr(ones(m_x,1),obj.y); | 47 obj.Y = kr(ones(m_x,1),obj.y); |
48 | 48 |
49 Aevaluated = obj.evaluateCoefficientMatrix(A, obj.X, obj.Y); | 49 Aevaluated = obj.evaluateCoefficientMatrix(A, obj.X, obj.Y); |
50 Bevaluated = obj.evaluateCoefficientMatrix(B, obj.X, obj.Y); | 50 Bevaluated = obj.evaluateCoefficientMatrix(B, obj.X, obj.Y); |
51 Eevaluated = obj.evaluateCoefficientMatrix(E, obj.X, obj.Y); | 51 Eevaluated = obj.evaluateCoefficientMatrix(E, obj.X, obj.Y); |
52 | 52 |
53 obj.n = length(A(obj.params,0,0)); | 53 obj.n = length(A(obj.params,0,0)); |
54 | 54 |
55 I_n = eye(obj.n);I_x = speye(m_x); | 55 I_n = eye(obj.n);I_x = speye(m_x); |
56 obj.I_x = I_x; | 56 obj.I_x = I_x; |
57 I_y = speye(m_y); | 57 I_y = speye(m_y); |
58 obj.I_y = I_y; | 58 obj.I_y = I_y; |
59 | 59 |
60 | 60 |
61 D1_x = kr(I_n, ops_x.D1, I_y); | 61 D1_x = kr(I_n, ops_x.D1, I_y); |
62 obj.Hxi = kr(I_n, ops_x.HI, I_y); | 62 obj.Hxi = kr(I_n, ops_x.HI, I_y); |
63 D1_y = kr(I_n, I_x, ops_y.D1); | 63 D1_y = kr(I_n, I_x, ops_y.D1); |
64 obj.Hyi = kr(I_n, I_x, ops_y.HI); | 64 obj.Hyi = kr(I_n, I_x, ops_y.HI); |
65 | 65 |
66 obj.e_w = kr(I_n, ops_x.e_l, I_y); | 66 obj.e_w = kr(I_n, ops_x.e_l, I_y); |
67 obj.e_e = kr(I_n, ops_x.e_r, I_y); | 67 obj.e_e = kr(I_n, ops_x.e_r, I_y); |
68 obj.e_s = kr(I_n, I_x, ops_y.e_l); | 68 obj.e_s = kr(I_n, I_x, ops_y.e_l); |
69 obj.e_n = kr(I_n, I_x, ops_y.e_r); | 69 obj.e_n = kr(I_n, I_x, ops_y.e_r); |
70 | 70 |
71 obj.m = m; | 71 obj.m = m; |
72 obj.h = [ops_x.h ops_y.h]; | 72 obj.h = [ops_x.h ops_y.h]; |
73 obj.order = order; | 73 obj.order = order; |
74 | 74 |
75 obj.D = -Aevaluated*D1_x-Bevaluated*D1_y-Eevaluated; | 75 obj.D = -Aevaluated*D1_x-Bevaluated*D1_y-Eevaluated; |
76 | 76 |
77 end | 77 end |
78 | 78 |
79 % Closure functions return the opertors applied to the own doamin to close the boundary | 79 % Closure functions return the opertors applied to the own doamin to close the boundary |
80 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. | 80 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. |
81 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. | 81 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. |
82 % type is a string specifying the type of boundary condition if there are several. | 82 % type is a string specifying the type of boundary condition if there are several. |
83 % data is a function returning the data that should be applied at the boundary. | 83 % data is a function returning the data that should be applied at the boundary. |
90 [closure,penalty] = boundary_condition_general(obj,boundary,L); | 90 [closure,penalty] = boundary_condition_general(obj,boundary,L); |
91 otherwise | 91 otherwise |
92 error('No such boundary condition') | 92 error('No such boundary condition') |
93 end | 93 end |
94 end | 94 end |
95 | 95 |
96 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) | 96 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary,type) |
97 error('An interface function does not exist yet'); | 97 error('An interface function does not exist yet'); |
98 end | 98 end |
99 | 99 |
100 function N = size(obj) | 100 function N = size(obj) |
101 N = obj.m; | 101 N = obj.m; |
102 end | 102 end |
103 | 103 |
104 function [ret] = evaluateCoefficientMatrix(obj, mat, X, Y) | 104 function [ret] = evaluateCoefficientMatrix(obj, mat, X, Y) |
105 params = obj.params; | 105 params = obj.params; |
106 | 106 |
107 if isa(mat,'function_handle') | 107 if isa(mat,'function_handle') |
108 [rows,cols] = size(mat(params,0,0)); | 108 [rows,cols] = size(mat(params,0,0)); |
109 matVec = mat(params,X',Y'); | 109 matVec = mat(params,X',Y'); |
110 matVec = sparse(matVec); | 110 matVec = sparse(matVec); |
111 side = max(length(X),length(Y)); | 111 side = max(length(X),length(Y)); |
114 [rows,cols] = size(matVec); | 114 [rows,cols] = size(matVec); |
115 side = max(length(X),length(Y)); | 115 side = max(length(X),length(Y)); |
116 cols = cols/side; | 116 cols = cols/side; |
117 end | 117 end |
118 ret = cell(rows,cols); | 118 ret = cell(rows,cols); |
119 | 119 |
120 for ii = 1:rows | 120 for ii = 1:rows |
121 for jj=1:cols | 121 for jj=1:cols |
122 ret{ii,jj} = diag(matVec(ii,(jj-1)*side+1:jj*side)); | 122 ret{ii,jj} = diag(matVec(ii,(jj-1)*side+1:jj*side)); |
123 end | 123 end |
124 end | 124 end |
125 ret = cell2mat(ret); | 125 ret = cell2mat(ret); |
126 end | 126 end |
127 | 127 |
128 %Characteristic boundary conditions | 128 %Characteristic boundary conditions |
129 function [closure, penalty] = boundary_condition_char(obj,boundary) | 129 function [closure, penalty] = boundary_condition_char(obj,boundary) |
130 params = obj.params; | 130 params = obj.params; |
131 x = obj.x; | 131 x = obj.x; |
132 y = obj.y; | 132 y = obj.y; |
133 | 133 |
134 switch boundary | 134 switch boundary |
135 case {'w','W','west'} | 135 case {'w','W','west'} |
136 e_ = obj.e_w; | 136 e_ = obj.e_w; |
137 mat = obj.A; | 137 mat = obj.A; |
138 boundPos = 'l'; | 138 boundPos = 'l'; |
162 side = max(length(x)); | 162 side = max(length(x)); |
163 end | 163 end |
164 pos = signVec(1); | 164 pos = signVec(1); |
165 zeroval = signVec(2); | 165 zeroval = signVec(2); |
166 neg = signVec(3); | 166 neg = signVec(3); |
167 | 167 |
168 switch boundPos | 168 switch boundPos |
169 case {'l'} | 169 case {'l'} |
170 tau = sparse(obj.n*side,pos); | 170 tau = sparse(obj.n*side,pos); |
171 Vi_plus = Vi(1:pos,:); | 171 Vi_plus = Vi(1:pos,:); |
172 tau(1:pos,:) = -abs(D(1:pos,1:pos)); | 172 tau(1:pos,:) = -abs(D(1:pos,1:pos)); |
178 Vi_minus = Vi((pos+zeroval)+1:obj.n*side,:); | 178 Vi_minus = Vi((pos+zeroval)+1:obj.n*side,:); |
179 closure = Hi*e_*V*tau*Vi_minus*e_'; | 179 closure = Hi*e_*V*tau*Vi_minus*e_'; |
180 penalty = -Hi*e_*V*tau*Vi_minus; | 180 penalty = -Hi*e_*V*tau*Vi_minus; |
181 end | 181 end |
182 end | 182 end |
183 | 183 |
184 % General boundary condition in the form Lu=g(x) | 184 % General boundary condition in the form Lu=g(x) |
185 function [closure,penalty] = boundary_condition_general(obj,boundary,L) | 185 function [closure,penalty] = boundary_condition_general(obj,boundary,L) |
186 params = obj.params; | 186 params = obj.params; |
187 x = obj.x; | 187 x = obj.x; |
188 y = obj.y; | 188 y = obj.y; |
189 | 189 |
190 switch boundary | 190 switch boundary |
191 case {'w','W','west'} | 191 case {'w','W','west'} |
192 e_ = obj.e_w; | 192 e_ = obj.e_w; |
193 mat = obj.A; | 193 mat = obj.A; |
194 boundPos = 'l'; | 194 boundPos = 'l'; |
216 e_ = obj.e_n; | 216 e_ = obj.e_n; |
217 mat = obj.B; | 217 mat = obj.B; |
218 boundPos = 'r'; | 218 boundPos = 'r'; |
219 Hi = obj.Hyi; | 219 Hi = obj.Hyi; |
220 [V,Vi,D,signVec] = obj.matrixDiag(mat,x,y(end)); | 220 [V,Vi,D,signVec] = obj.matrixDiag(mat,x,y(end)); |
221 L = obj.evaluateCoefficientMatrix(L,x,y(end)); | 221 L = obj.evaluateCoefficientMatrix(L,x,y(end)); |
222 side = max(length(x)); | 222 side = max(length(x)); |
223 end | 223 end |
224 | 224 |
225 pos = signVec(1); | 225 pos = signVec(1); |
226 zeroval = signVec(2); | 226 zeroval = signVec(2); |
227 neg = signVec(3); | 227 neg = signVec(3); |
228 | 228 |
229 switch boundPos | 229 switch boundPos |
230 case {'l'} | 230 case {'l'} |
231 tau = sparse(obj.n*side,pos); | 231 tau = sparse(obj.n*side,pos); |
232 Vi_plus = Vi(1:pos,:); | 232 Vi_plus = Vi(1:pos,:); |
233 Vi_minus = Vi(pos+zeroval+1:obj.n*side,:); | 233 Vi_minus = Vi(pos+zeroval+1:obj.n*side,:); |
234 V_plus = V(:,1:pos); | 234 V_plus = V(:,1:pos); |
235 V_minus = V(:,(pos+zeroval)+1:obj.n*side); | 235 V_minus = V(:,(pos+zeroval)+1:obj.n*side); |
236 | 236 |
237 tau(1:pos,:) = -abs(D(1:pos,1:pos)); | 237 tau(1:pos,:) = -abs(D(1:pos,1:pos)); |
238 R = -inv(L*V_plus)*(L*V_minus); | 238 R = -inv(L*V_plus)*(L*V_minus); |
239 closure = Hi*e_*V*tau*(Vi_plus-R*Vi_minus)*e_'; | 239 closure = Hi*e_*V*tau*(Vi_plus-R*Vi_minus)*e_'; |
240 penalty = -Hi*e_*V*tau*inv(L*V_plus)*L; | 240 penalty = -Hi*e_*V*tau*inv(L*V_plus)*L; |
241 case {'r'} | 241 case {'r'} |
242 tau = sparse(obj.n*side,neg); | 242 tau = sparse(obj.n*side,neg); |
243 tau((pos+zeroval)+1:obj.n*side,:) = -abs(D((pos+zeroval)+1:obj.n*side,(pos+zeroval)+1:obj.n*side)); | 243 tau((pos+zeroval)+1:obj.n*side,:) = -abs(D((pos+zeroval)+1:obj.n*side,(pos+zeroval)+1:obj.n*side)); |
244 Vi_plus = Vi(1:pos,:); | 244 Vi_plus = Vi(1:pos,:); |
245 Vi_minus = Vi((pos+zeroval)+1:obj.n*side,:); | 245 Vi_minus = Vi((pos+zeroval)+1:obj.n*side,:); |
246 | 246 |
247 V_plus = V(:,1:pos); | 247 V_plus = V(:,1:pos); |
248 V_minus = V(:,(pos+zeroval)+1:obj.n*side); | 248 V_minus = V(:,(pos+zeroval)+1:obj.n*side); |
249 R = -inv(L*V_minus)*(L*V_plus); | 249 R = -inv(L*V_minus)*(L*V_plus); |
250 closure = Hi*e_*V*tau*(Vi_minus-R*Vi_plus)*e_'; | 250 closure = Hi*e_*V*tau*(Vi_minus-R*Vi_plus)*e_'; |
251 penalty = -Hi*e_*V*tau*inv(L*V_minus)*L; | 251 penalty = -Hi*e_*V*tau*inv(L*V_minus)*L; |
252 end | 252 end |
253 end | 253 end |
254 | 254 |
255 % Function that diagonalizes a symbolic matrix A as A=V*D*Vi | 255 % Function that diagonalizes a symbolic matrix A as A=V*D*Vi |
256 % D is a diagonal matrix with the eigenvalues on A on the diagonal sorted by their sign | 256 % D is a diagonal matrix with the eigenvalues on A on the diagonal sorted by their sign |
257 % [d+ ] | 257 % [d+ ] |
258 % D = [ d0 ] | 258 % D = [ d0 ] |
259 % [ d-] | 259 % [ d-] |
260 % signVec is a vector specifying the number of possitive, zero and negative eigenvalues of D | 260 % signVec is a vector specifying the number of possitive, zero and negative eigenvalues of D |
261 function [V,Vi, D,signVec] = matrixDiag(obj,mat,x,y) | 261 function [V,Vi, D,signVec] = matrixDiag(obj,mat,x,y) |
262 params = obj.params; | 262 params = obj.params; |
263 syms xs ys | 263 syms xs ys |
264 [V, D]= eig(mat(params,xs,ys)); | 264 [V, D]= eig(mat(params,xs,ys)); |
265 Vi = inv(V); | 265 Vi = inv(V); |
266 xs = x; | 266 xs = x; |
267 ys = y; | 267 ys = y; |
268 | 268 |
269 side = max(length(x),length(y)); | 269 side = max(length(x),length(y)); |
270 Dret = zeros(obj.n,side*obj.n); | 270 Dret = zeros(obj.n,side*obj.n); |
271 Vret = zeros(obj.n,side*obj.n); | 271 Vret = zeros(obj.n,side*obj.n); |
272 Viret = zeros(obj.n,side*obj.n); | 272 Viret = zeros(obj.n,side*obj.n); |
273 | 273 |
274 for ii = 1:obj.n | 274 for ii = 1:obj.n |
275 for jj = 1:obj.n | 275 for jj = 1:obj.n |
276 Dret(jj,(ii-1)*side+1:side*ii) = eval(D(jj,ii)); | 276 Dret(jj,(ii-1)*side+1:side*ii) = eval(D(jj,ii)); |
277 Vret(jj,(ii-1)*side+1:side*ii) = eval(V(jj,ii)); | 277 Vret(jj,(ii-1)*side+1:side*ii) = eval(V(jj,ii)); |
278 Viret(jj,(ii-1)*side+1:side*ii) = eval(Vi(jj,ii)); | 278 Viret(jj,(ii-1)*side+1:side*ii) = eval(Vi(jj,ii)); |
279 end | 279 end |
280 end | 280 end |
281 | 281 |
282 D = sparse(Dret); | 282 D = sparse(Dret); |
283 V = sparse(Vret); | 283 V = sparse(Vret); |
284 Vi = sparse(Viret); | 284 Vi = sparse(Viret); |
285 V = obj.evaluateCoefficientMatrix(V,x,y); | 285 V = obj.evaluateCoefficientMatrix(V,x,y); |
286 Vi = obj.evaluateCoefficientMatrix(Vi,x,y); | 286 Vi = obj.evaluateCoefficientMatrix(Vi,x,y); |
287 D = obj.evaluateCoefficientMatrix(D,x,y); | 287 D = obj.evaluateCoefficientMatrix(D,x,y); |
288 DD = diag(D); | 288 DD = diag(D); |
289 | 289 |
290 poseig = (DD>0); | 290 poseig = (DD>0); |
291 zeroeig = (DD==0); | 291 zeroeig = (DD==0); |
292 negeig = (DD<0); | 292 negeig = (DD<0); |
293 | 293 |
294 D = diag([DD(poseig); DD(zeroeig); DD(negeig)]); | 294 D = diag([DD(poseig); DD(zeroeig); DD(negeig)]); |
295 V = [V(:,poseig) V(:,zeroeig) V(:,negeig)]; | 295 V = [V(:,poseig) V(:,zeroeig) V(:,negeig)]; |
296 Vi = [Vi(poseig,:); Vi(zeroeig,:); Vi(negeig,:)]; | 296 Vi = [Vi(poseig,:); Vi(zeroeig,:); Vi(negeig,:)]; |
297 signVec = [sum(poseig),sum(zeroeig),sum(negeig)]; | 297 signVec = [sum(poseig),sum(zeroeig),sum(negeig)]; |
298 end | 298 end |
299 | 299 |
300 end | 300 end |
301 end | 301 end |