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