comparison +scheme/Euler1d.m @ 49:8f0c2dc747dd

Made lots of updates to Euler1d.
author Jonatan Werpers <jonatan@werpers.com>
date Thu, 05 Nov 2015 16:33:53 -0800
parents 48b6fb693025
children 75ebf5d3cfe5
comparison
equal deleted inserted replaced
48:b21c53ff61d4 49:8f0c2dc747dd
1 classdef SchmBeam2d < noname.Scheme 1 classdef Euler1d < scheme.Scheme
2 properties 2 properties
3 m % Number of points in each direction, possibly a vector 3 m % Number of points in each direction, possibly a vector
4 N % Number of points total 4 N % Number of points total
5 h % Grid spacing 5 h % Grid spacing
6 u % Grid values 6 u % Grid values
7 x % Values of x and y for each 7 x % Values of x and y for each
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 Fx
11 M % Derivative norm 12 M % Derivative norm
12 alpha 13 gamma
14
15 T
16 p
17
13 18
14 H % Discrete norm 19 H % Discrete norm
15 Hi 20 Hi
16 e_l, e_r 21 e_l, e_r, e_L, e_R;
17 22
18 end 23 end
19 24
20 methods 25 methods
21 function obj = SchmBeam2d(m,xlim,order,gamma,opsGen) 26 function obj = Euler1d(m,xlim,order,gama,opsGen,do_upwind)
22 default_arg('opsGen',@sbp.Ordinary); 27 default_arg('opsGen',@sbp.Ordinary);
23 default_arg('gamma', 1.4); 28 default_arg('gama', 1.4);
24 29 default_arg('do_upwind', false);
25 [x, h] = util.get_grid(xlim{:},m_x); 30 gamma = gama;
26 31
27 ops = opsGen(m_x,h_x,order); 32 [x, h] = util.get_grid(xlim{:},m);
28 33
29 I_x = speye(m); 34 if do_upwind
30 I_3 = speye(3); 35 ops = spb.Upwind(m,h,order);
31 36 Dp = ops.derivatives.Dp;
32 D1 = sparse(ops.derivatives.D1); 37 Dm = ops.derivatives.Dm;
38
39 printExpr('issparse(Dp)');
40 printExpr('issparse(Dm)');
41
42 D1 = (Dp + Dm)/2;
43 else
44 ops = opsGen(m,h,order);
45 D1 = sparse(ops.derivatives.D1);
46 end
47
33 H = sparse(ops.norms.H); 48 H = sparse(ops.norms.H);
34 Hi = sparse(ops.norms.HI); 49 Hi = sparse(ops.norms.HI);
35 e_l = sparse(ops.boundary.e_1); 50 e_l = sparse(ops.boundary.e_1);
36 e_r = sparse(ops.boundary.e_m); 51 e_r = sparse(ops.boundary.e_m);
37 52
53 I_x = speye(m);
54 I_3 = speye(3);
55
56
38 D1 = kr(D1, I_3); 57 D1 = kr(D1, I_3);
58 if do_upwind
59 Ddisp = kr(Ddisp,I_3);
60 end
39 61
40 % Norms 62 % Norms
41 obj.H = kr(H,I_3); 63 obj.H = kr(H,I_3);
64 obj.Hi = kr(Hi,I_3);
42 65
43 % Boundary operators 66 % Boundary operators
44 obj.e_l = kr(e_l,I_3); 67 obj.e_l = e_l;
45 obj.e_r = kr(e_r,I_3); 68 obj.e_r = e_r;
69 obj.e_L = kr(e_l,I_3);
70 obj.e_R = kr(e_r,I_3);
46 71
47 obj.m = m; 72 obj.m = m;
48 obj.h = h; 73 obj.h = h;
49 obj.order = order; 74 obj.order = order;
50 75
51
52 % Man har Q_t+F_x=0 i 1D Euler, där 76 % Man har Q_t+F_x=0 i 1D Euler, där
53 % q=[rho, rho*u, e]^T 77 % q=[rho, rho*u, e]^T
54 % F=[rho*u, rho*u^2+p, (e+p)*u] ^T 78 % F=[rho*u, rho*u^2+p, (e+p)*u] ^T
55 % p=(gamma-1)*(e-rho/2*u^2); 79 % p=(gamma-1)*(e-rho*u^2/2);
56
57 80
58 %Solving on form q_t + F_x = 0 81 %Solving on form q_t + F_x = 0
59 function o = F(q) 82 function o = F(q)
60 o = [q(2); q(2).^2/q(1) + p(q); (q(3)+p(q))*q(2)/q(1)]; 83 o = [q(2); q(2).^2/q(1) + p(q); (q(3)+p(q))*q(2)/q(1)];
61 end 84 end
62 85
63 % Equation of state 86 % Equation of state
64 function o = p(q) 87 function o = p(q)
65 o = (gamma-1)*(q(3)-q(2).^2/q(1)/2); 88 o = (gamma-1)*(q(3)-q(2).^2/q(1)/2);
66 end 89 end
67
68 90
69 % R = 91 % R =
70 % [sqrt(2*(gamma-1))*rho , rho , rho ; 92 % [sqrt(2*(gamma-1))*rho , rho , rho ;
71 % sqrt(2*(gamma-1))*rho*u , rho*(u+c) , rho*(u-c) ; 93 % sqrt(2*(gamma-1))*rho*u , rho*(u+c) , rho*(u-c) ;
72 % sqrt(2*(gamma-1))*rho*u^2/2, e+(gamma-1)*(e-rho*u^2/2)+rho*u*c, e+(gamma-1)*(e-rho*u^2/2)-rho*u*c]); 94 % sqrt(2*(gamma-1))*rho*u^2/2, e+(gamma-1)*(e-rho*u^2/2)+rho*u*c, e+(gamma-1)*(e-rho*u^2/2)-rho*u*c]);
73 function o = R(q) 95 function o = T(q)
74 rho = q(1); 96 rho = q(1);
75 u = q(2)/q(1); 97 u = q(2)/q(1);
76 e = q(3); 98 e = q(3);
99
100 c = sqrt(gamma*p(q)/rho);
77 101
78 sqrt2gamm = sqrt(2*(gamma-1)); 102 sqrt2gamm = sqrt(2*(gamma-1));
79 103
80 o = [ 104 o = [
81 sqrt2gamm*rho , rho , rho ; 105 sqrt2gamm*rho , rho , rho ;
82 sqrt2gamm*rho*u , rho*(u+c) , rho*(u-c) ; 106 sqrt2gamm*rho*u , rho*(u+c) , rho*(u-c) ;
83 sqrt2gamm*rho*u^2/2, e+(gamma-1)*(e-rho*u^2/2)+rho*u*c , e+(gamma-1)*(e-rho*u^2/2)-rho*u*c 107 sqrt2gamm*rho*u^2/2, e+(gamma-1)*(e-rho*u^2/2)+rho*u*c , e+(gamma-1)*(e-rho*u^2/2)-rho*u*c
84 ]; 108 ];
109 % Devide columns by stuff to get rid of extra comp?
85 end 110 end
86 111
87 function o = Fx(q) 112 function o = Fx(q)
88 o = zeros(size(q)); 113 o = zeros(size(q));
89 for i = 1:3:3*m 114 for i = 1:3:3*m
90 o(i:i+2) = F(q(i:i+2)); 115 o(i:i+2) = F(q(i:i+2));
91 end 116 end
92 end 117 o = D1*o;
93 118 end
94 119
95 120
96 % A=R*Lambda*inv(R), där Lambda=diag(u, u+c, u-c) (c är ljudhastigheten) 121 % A=R*Lambda*inv(R), där Lambda=diag(u, u+c, u-c) (c är ljudhastigheten)
97 % c^2=gamma*p/rho 122 % c^2=gamma*p/rho
98 % function o = A(rho,u,e) 123 % function o = A(rho,u,e)
99 % end 124 % end
100 125 if do_upwind
101 126 obj.D = @(q)-Fx(q) + Ddisp*(1)*u;
102 obj.D = @Fx; 127 else
128 obj.D = @(q)-Fx(q);
129 end
130
131 obj.Fx = @Fx;
132 obj.T = @T;
103 obj.u = x; 133 obj.u = x;
104 obj.x = kr(x,ones(3,1)); 134 obj.x = kr(x,ones(3,1));
105 end 135 obj.p = @p;
106 136 obj.gamma = gamma;
107 137 end
108 % Closure functions return the opertors applied to the own doamin to close the boundary 138
109 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. 139
110 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. 140 % Enforces the boundary conditions
111 % type is a string specifying the type of boundary condition if there are several. 141 % w+ = R*w- + g(t)
112 % data is a function returning the data that should be applied at the boundary. 142 function closure = boundary_condition(obj,boundary, type, varargin)
113 % neighbour_scheme is an instance of Scheme that should be interfaced to. 143 [e_s,e_S,s] = obj.get_boundary_ops(boundary);
114 % neighbour_boundary is a string specifying which boundary to interface to.
115 function [closure, penalty] = boundary_condition(obj,boundary, alpha,data)
116 default_arg('alpha',0);
117 default_arg('data',0);
118 144
119 % Boundary condition on form 145 % Boundary condition on form
120 % w_in = w_out + g, where g is data 146 % w_in = R*w_out + g, where g is data
121 147
122 [e,s] = obj.get_boundary_ops(boundary); 148 % How to handle when the number of BC we want to set changes
123 149 % How to handel u = 0 as an example
124 tuning = 1; % ????????????????????????? 150
125 151 % Måste sätta in s och fixa tecken som de ska vara
126 tau = R(q)*lambda(q)*tuning; % SHOULD THIS BE abs(lambda)????? 152
127 153 % Kanske ska man tala om vilka karakteristikor som är in och ut i anropet
128 function closure_fun(q,t) 154 % Man kan sen kolla om det stämmer (men hur blir det med u=0?)
129 q_b = e * q; 155 % Och antingen tillåta att man skickar in flera alternativ och väljer automatiskt
130 end 156 % eller låta koden utanför bestämma vilken penalty som ska appliceras.
131 157
132 function penalty_fun(q,t) 158 switch type
133 end 159 case 'wall'
134 160 closure = obj.boundary_condition_wall(boundary);
135
136
137
138
139 % tau1 < -alpha^2/gamma
140
141 tau1 = tuning * alpha/delt;
142 tau4 = s*alpha;
143
144 sig2 = tuning * alpha/gamm;
145 sig3 = -s*alpha;
146
147 tau = tau1*e+tau4*d3;
148 sig = sig2*d1+sig3*d2;
149
150 closure = halfnorm_inv*(tau*e' + sig*d1');
151
152 pp_e = halfnorm_inv*tau;
153 pp_d = halfnorm_inv*sig;
154 switch class(data)
155 case 'double'
156 penalty_e = pp_e*data;
157 penalty_d = pp_d*data;
158 case 'function_handle'
159 penalty_e = @(t)pp_e*data(t);
160 penalty_d = @(t)pp_d*data(t);
161 otherwise 161 otherwise
162 error('Wierd data argument!') 162 error('Unsupported bc type: %s', type);
163 end 163 end
164 164
165 % T = obj.T(e_S*v);
166
167 % c = sqrt(gamma*p/rho);
168 % l = [u, u+c, u-c];
169
170 % p_in = find(s*l <= 0);
171 % p_ot = find(s*l > 0);
172
173 % p = [p_in, p_ot] % Permutation to sort
174 % pt(p) = 1:length(p); % Inverse permutation
175
176 % L_in = diag(abs(l(p_in)));
177 % L_ot = diag(abs(l(p_ot)));
178
179 % Lambda = diag(u, u+c, u-c);
180
181 % tau = -e_S*sparse(T*[L_in; R'*L_in]); % Något med pt
182
183
184 % w_s = T'*(e_S*v);
185 % w_in = w_s(p_in);
186 % w_ot = w_s(p_ot);
187
188
189 % function closure_fun(q,t)
190 % obj.Hi * tau * (w_in - R*w_ot - g(t));
191 % end
192
193 % function closure_fun_indep(q,t)
194 % obj.Hi * tau * (w_in - R*w_ot - g;
195 % end
196
197
198 % switch class(g)
199 % case 'double'
200 % closure = @closure_fun;
201 % case 'function_handle'
202 % closure = @closure_fun_indep;
203 % otherwise
204 % error('Wierd data argument!');
205 % end
206
207 end
208
209 % Set wall boundary condition v = 0.
210 function closure = boundary_condition_wall(obj,boundary)
211 [e_s,e_S,s] = obj.get_boundary_ops(boundary);
212
213 % v = 0 corresponds to
214 % L = [0 1 0];
215 % g = 0
216 %
217 % Tp =
218 % R = -(u-c)/(u+c)
219
220 % tau = alpha * (u+c)
221 % (alpha+1)(u+c) + 1/4* alpha^2|u-c| <= 0
222 % 4*(alpha+1)(u+c) + alpha^2|u-c| <= 0
223 % 4 * (alpha+1)(u+c) + alpha^2|u| + alpha^2*c <= 0
224 % |u|*(sgn(u)*4 + sgn(u)*4*alpha + alpha^2) + c*(4 + 4alpha + alpha^2) <= 0
225 % |u|*(alpha^2 + 4*sgn(u)*alpha + 4*sgn(u)) + c*(alpha+2)^2 <= 0
226 % |u|*[(alpha + 2*sgn(u))^2 - 4*(sgn(u)-1)] + c*(alpha+2)^2 <= 0
227
228
229 % om vi låtsas att u = 0:
230 % (alpha+1)c + 1/4 * alpha^2*c <= 0
231 % alpha^2 + 4*alpha +4 <= 0
232 % (alpha + 2)^2 <= 0
233 % alpha = -2 gives tau = -2*c;
234
235
236 % Vill vi sätta penalty på karateristikan som är nära noll också eller vill
237 % vi låta den vara fri?
238
239
240 switch s
241 case -1
242 p_in = 2;
243 p_zero = 1;
244 p_ot = 3;
245 case 1
246 p_in = 3;
247 p_zero = 1;
248 p_ot = 2;
249 otherwise
250 error();
251 end
252
253 p = [p_in, p_zero, p_ot]; % Permutation to sort
254 pt(p) = 1:length(p); % Inverse permutation
255
256 function o = closure_fun(q)
257 p = obj.p(q);
258
259 q_s = e_S'*q;
260 rho = q_s(1);
261 u = q_s(2)/rho;
262 c = sqrt(obj.gamma*p/rho);
263
264 T = obj.T(q_s);
265 R = -(u-c)/(u+c);
266 % l = [u, u+c, u-c];
267
268 % p_in = find(s*l <= 0);
269 % p_ot = find(s*l > 0);
270
271
272 tau1 = -2*c;
273 tau2 = [0; 0]; % Penalty only on ingoing char.
274
275 % L_in = diag(abs(l(p_in)));
276 % L_ot = diag(abs(l(p_ot)));
277
278 tauHat = [tau1; tau2];
279 tau = -s*e_S*sparse(T*tauHat(pt));
280
281 w_s = inv(T)*q_s;
282 % w_s = T\q_s;
283 % w_s = Tinv * q_s; % Med analytisk matris
284 w_in = w_s(p_in);
285 w_ot = w_s(p_ot);
286
287 o = obj.Hi * tau * (w_in - R*w_ot);
288 end
289
290 closure = @closure_fun;
165 end 291 end
166 292
167 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) 293 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
294 error('NOT DONE')
168 % u denotes the solution in the own domain 295 % u denotes the solution in the own domain
169 % v denotes the solution in the neighbour domain 296 % v denotes the solution in the neighbour domain
170 [e_u,d1_u,d2_u,d3_u,s_u,gamm_u,delt_u, halfnorm_inv] = obj.get_boundary_ops(boundary); 297 [e_u,d1_u,d2_u,d3_u,s_u,gamm_u,delt_u, halfnorm_inv] = obj.get_boundary_ops(boundary);
171 [e_v,d1_v,d2_v,d3_v,s_v,gamm_v,delt_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary); 298 [e_v,d1_v,d2_v,d3_v,s_v,gamm_v,delt_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary);
172 299
195 penalty = -halfnorm_inv*(tau*e_v' + sig*d1_v' + phi*alpha_v*d2_v' + psi*alpha_v*d3_v'); 322 penalty = -halfnorm_inv*(tau*e_v' + sig*d1_v' + phi*alpha_v*d2_v' + psi*alpha_v*d3_v');
196 end 323 end
197 324
198 % Ruturns the boundary ops and sign for the boundary specified by the string boundary. 325 % Ruturns the boundary ops and sign for the boundary specified by the string boundary.
199 % The right boundary is considered the positive boundary 326 % The right boundary is considered the positive boundary
200 function [e,d1,d2,d3,s,gamm, delt, halfnorm_inv] = get_boundary_ops(obj,boundary) 327 function [e,E,s] = get_boundary_ops(obj,boundary)
201 switch boundary 328 switch boundary
202 case 'w' 329 case 'l'
203 e = obj.e_w; 330 e = obj.e_l;
204 d1 = obj.d1_w; 331 E = obj.e_L;
205 d2 = obj.d2_w;
206 d3 = obj.d3_w;
207 s = -1; 332 s = -1;
208 gamm = obj.gamm_x; 333 case 'r'
209 delt = obj.delt_x; 334 e = obj.e_r;
210 halfnorm_inv = obj.Hix; 335 E = obj.e_R;
211 case 'e'
212 e = obj.e_e;
213 d1 = obj.d1_e;
214 d2 = obj.d2_e;
215 d3 = obj.d3_e;
216 s = 1; 336 s = 1;
217 gamm = obj.gamm_x;
218 delt = obj.delt_x;
219 halfnorm_inv = obj.Hix;
220 case 's'
221 e = obj.e_s;
222 d1 = obj.d1_s;
223 d2 = obj.d2_s;
224 d3 = obj.d3_s;
225 s = -1;
226 gamm = obj.gamm_y;
227 delt = obj.delt_y;
228 halfnorm_inv = obj.Hiy;
229 case 'n'
230 e = obj.e_n;
231 d1 = obj.d1_n;
232 d2 = obj.d2_n;
233 d3 = obj.d3_n;
234 s = 1;
235 gamm = obj.gamm_y;
236 delt = obj.delt_y;
237 halfnorm_inv = obj.Hiy;
238 otherwise 337 otherwise
239 error('No such boundary: boundary = %s',boundary); 338 error('No such boundary: boundary = %s',boundary);
240 end 339 end
241 end 340 end
242 341