comparison +scheme/Euler1d.m @ 60:e707cd9e6d0a

Euler1d: Created a general bc routine.
author Jonatan Werpers <jonatan@werpers.com>
date Sat, 14 Nov 2015 15:43:01 -0800
parents e431c1260f52
children 183d9349b4c1
comparison
equal deleted inserted replaced
59:e431c1260f52 60:e707cd9e6d0a
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
12 M % Derivative norm 11 M % Derivative norm
13 gamma 12 gamma
14 13
15 T 14 T
16 p 15 p
17 c 16 c
17 Lambda
18 18
19 19
20 H % Discrete norm 20 H % Discrete norm
21 Hi 21 Hi
22 e_l, e_r, e_L, e_R; 22 e_l, e_r, e_L, e_R;
85 % Equation of state 85 % Equation of state
86 function o = p(Q) 86 function o = p(Q)
87 % Pressure p = (gamma-1)*(q3-q2.^2/q1/2) 87 % Pressure p = (gamma-1)*(q3-q2.^2/q1/2)
88 o = (gamma-1)*( Q(3,:)-1/2*Q(2,:).^2./Q(1,:) ); 88 o = (gamma-1)*( Q(3,:)-1/2*Q(2,:).^2./Q(1,:) );
89 end 89 end
90 obj.p = @p;
90 91
91 function o = c(Q) 92 function o = c(Q)
92 % Speed of light c = sqrt(obj.gamma*p/rho); 93 % Speed of light c = sqrt(obj.gamma*p/rho);
93 o = sqrt(gamma*p(Q)./Q(1,:)); 94 o = sqrt(gamma*p(Q)./Q(1,:));
94 end 95 end
96 obj.c = @c;
97
98 function o = Lambda(q)
99 u = q(2)/q(1);
100 c = obj.c(q);
101 L = [u, u+c, u-c];
102 o = diag(L);
103 end
104 obj.Lambda = @Lambda;
95 105
96 function o = T(q) 106 function o = T(q)
97 % T is the transformation such that A = T*Lambda*inv(T) 107 % T is the transformation such that A = T*Lambda*inv(T)
98 % where Lambda=diag(u, u+c, u-c) 108 % where Lambda=diag(u, u+c, u-c)
99 rho = q(1); 109 rho = q(1);
109 sqrt2gamm*rho*u , rho*(u+c) , rho*(u-c) ; 119 sqrt2gamm*rho*u , rho*(u+c) , rho*(u-c) ;
110 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 ; 120 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 ;
111 ]; 121 ];
112 % Devide columns by stuff to get rid of extra comp? 122 % Devide columns by stuff to get rid of extra comp?
113 end 123 end
124 obj.T = @T;
114 125
115 function o = Fx(q) 126 function o = Fx(q)
116 Q = reshape(q,3,m); 127 Q = reshape(q,3,m);
117 o = reshape(F(Q),3*m,1); 128 o = reshape(F(Q),3*m,1);
118 o = D1*o; 129 o = D1*o;
139 obj.D = @Fx_disp; 150 obj.D = @Fx_disp;
140 else 151 else
141 obj.D = @(q)-Fx(q); 152 obj.D = @(q)-Fx(q);
142 end 153 end
143 154
144 obj.Fx = @Fx;
145 obj.T = @T;
146 obj.u = x; 155 obj.u = x;
147 obj.x = kr(x,ones(3,1)); 156 obj.x = kr(x,ones(3,1));
148 obj.p = @p;
149 obj.c = @c;
150 obj.gamma = gamma; 157 obj.gamma = gamma;
151 end 158 end
152 159
153 160
154 % Enforces the boundary conditions 161 % Enforces the boundary conditions
172 error('Unsupported bc type: %s', type); 179 error('Unsupported bc type: %s', type);
173 end 180 end
174 181
175 end 182 end
176 183
177 function closure = boundary_condition_char(obj,boundary,w_data) 184
185 % Sets the boundary condition Lq = g, where
186 % L = L(rho, u, e), g = g(t)
187 % p_in are the indecies of the ingoing characteristics.
188 function closure = boundary_condition_L(obj, boundary, L_fun, g_fun, p_in)
178 [e_s,e_S,s] = obj.get_boundary_ops(boundary); 189 [e_s,e_S,s] = obj.get_boundary_ops(boundary);
179 190
180 function o = closure_fun(q,t) 191 p_ot = 1:3;
181 q_s = e_S'*q; 192 p_ot(p_in) = [];
182 rho = q_s(1);
183 u = q_s(2)/rho;
184 e = q_s(3);
185
186 c = obj.c(q_s);
187
188 Lambda = [u, u+c, u-c];
189
190 p_in = find(s*Lambda < 0);
191 p_ot = find(s*Lambda >= 0);
192 p = [p_in p_ot];
193 pt(p) = 1:length(p);
194
195 T = obj.T(q_s);
196
197 tau1 = -2*diag(Lambda(p_in));
198 tau2 = zeros(length(p_ot),length(p_in)); % Penalty only on ingoing char.
199
200 tauHat = [tau1; tau2];
201
202 tau = -s*e_S*sparse(T*tauHat(pt,:));
203
204 w_s = inv(T)*q_s;
205 w_in = w_s(p_in);
206
207 w_s_data = w_data(t);
208 w_in_data = w_s_data(p_in);
209
210 o = obj.Hi * tau * (w_in - w_in_data);
211 end
212
213 closure = @closure_fun;
214
215 end
216
217 function closure = boundary_condition_inflow(obj, boundary, p_data, v_data)
218 [e_s,e_S,s] = obj.get_boundary_ops(boundary);
219
220 switch s
221 case -1
222 p_in = [1 2];
223 p_ot = [3];
224 case 1
225 p_in = [1 3];
226 p_ot = [2];
227 otherwise
228 error();
229 end
230 193
231 p = [p_in, p_ot]; % Permutation to sort 194 p = [p_in, p_ot]; % Permutation to sort
232 pt(p) = 1:length(p); % Inverse permutation 195 pt(p) = 1:length(p); % Inverse permutation
233
234 gamma = obj.gamma;
235 196
236 function o = closure_fun(q,t) 197 function o = closure_fun(q,t)
237 % Extract solution at the boundary 198 % Extract solution at the boundary
238 q_s = e_S'*q; 199 q_s = e_S'*q;
239 rho = q_s(1); 200 rho = q_s(1);
247 Tin = T(:,p_in); 208 Tin = T(:,p_in);
248 Tot = T(:,p_ot); 209 Tot = T(:,p_ot);
249 210
250 % Convert bc from ordinary form to characteristic form. 211 % Convert bc from ordinary form to characteristic form.
251 % Lq = g => w_in = Rw_ot + g_tilde 212 % Lq = g => w_in = Rw_ot + g_tilde
252 L = [ 213 L = L_fun(rho,u,e);
253 0 1 0; 214 g = g_fun(t);
254 0 -1/2*u 1; 215
255 ]; 216 Lambda = obj.Lambda(q_s);
256 g = [
257 v_data(t);
258 p_data(t);
259 ];
260 217
261 R =-inv(L*Tin)*(L*Tot); 218 R =-inv(L*Tin)*(L*Tot);
262 g_tilde = inv(L*Tin)*g; 219 g_tilde = inv(L*Tin)*g;
263 220
264 % Setup the penalty parameter 221 % Setup the penalty parameter
265 tau1 = -2*[ 222 tau1 = -2*Lambda(p_in,p_in);
266 u, 0; 223 tau2 = zeros(length(p_ot),length(p_in)); % Penalty only on ingoing char.
267 0, c + abs(u);
268 ];
269 tau2 = [0 0]; % Penalty only on ingoing char.
270 224
271 tauHat = [tau1; tau2]; 225 tauHat = [tau1; tau2];
272 tau = -s*e_S*sparse(T*tauHat(pt,:)); 226 tau = -s*e_S*sparse(T*tauHat(pt,:));
273 227
274 % Calculate the numerical caracteristics and apply the penalty 228 % Calculate the numerical caracteristics and apply the penalty
278 w_in = w_s(p_in); 232 w_in = w_s(p_in);
279 w_ot = w_s(p_ot); 233 w_ot = w_s(p_ot);
280 234
281 o = obj.Hi * tau * (w_in - R*w_ot - g_tilde); 235 o = obj.Hi * tau * (w_in - R*w_ot - g_tilde);
282 end 236 end
283
284 closure = @closure_fun; 237 closure = @closure_fun;
285 end 238 end
286 239
287 240 function closure = boundary_condition_char(obj,boundary,w_data)
288 function closure = boundary_condition_outflow(obj, boundary, p_data)
289 [e_s,e_S,s] = obj.get_boundary_ops(boundary); 241 [e_s,e_S,s] = obj.get_boundary_ops(boundary);
290 242
291 switch s
292 case -1
293 p_in = 2;
294 p_ot = [1 3];
295 case 1
296 p_in = 3;
297 p_ot = [1 2];
298 otherwise
299 error();
300 end
301
302 p = [p_in, p_ot]; % Permutation to sort
303 pt(p) = 1:length(p); % Inverse permutation
304
305 gamma = obj.gamma;
306
307
308 function o = closure_fun(q,t) 243 function o = closure_fun(q,t)
309 % Extract solution at the boundary
310 q_s = e_S'*q; 244 q_s = e_S'*q;
311 rho = q_s(1); 245 rho = q_s(1);
312 u = q_s(2)/rho; 246 u = q_s(2)/rho;
313 e = q_s(3); 247 e = q_s(3);
314 248
315 c = obj.c(q_s); 249 c = obj.c(q_s);
316 250
317 % Calculate transformation matrix 251 Lambda = [u, u+c, u-c];
252
253 p_in = find(s*Lambda < 0);
254 p_ot = find(s*Lambda >= 0);
255 p = [p_in p_ot];
256 pt(p) = 1:length(p);
257
318 T = obj.T(q_s); 258 T = obj.T(q_s);
319 Tin = T(:,p_in); 259
320 Tot = T(:,p_ot); 260 tau1 = -2*diag(Lambda(p_in));
321 261 tau2 = zeros(length(p_ot),length(p_in)); % Penalty only on ingoing char.
322 % Convert bc from ordinary form to characteristic form.
323 % Lq = g => w_in = Rw_ot + g_tilde
324 L = (gamma -1)*[0 -1/2*u 1];
325 g = [p_data(t)];
326
327 R =-inv(L*Tin)*(L*Tot);
328 g_tilde = inv(L*Tin)*g;
329
330 % Setup the penalty parameter
331 tau1 = [-2*(c - abs(u))];
332 tau2 = [0; 0]; % Penalty only on ingoing char.
333 262
334 tauHat = [tau1; tau2]; 263 tauHat = [tau1; tau2];
264
335 tau = -s*e_S*sparse(T*tauHat(pt,:)); 265 tau = -s*e_S*sparse(T*tauHat(pt,:));
336 266
337 % Calculate the numerical caracteristics and apply the penalty
338 w_s = inv(T)*q_s; 267 w_s = inv(T)*q_s;
339 % w_s = T\q_s;
340 % w_s = Tinv * q_s; % Med analytisk matris
341 w_in = w_s(p_in); 268 w_in = w_s(p_in);
342 w_ot = w_s(p_ot); 269
343 270 w_s_data = w_data(t);
344 o = obj.Hi * tau * (w_in - R*w_ot - g_tilde); 271 w_in_data = w_s_data(p_in);
272
273 o = obj.Hi * tau * (w_in - w_in_data);
345 end 274 end
346 275
347 closure = @closure_fun; 276 closure = @closure_fun;
277
278 end
279
280 function closure = boundary_condition_inflow(obj, boundary, p_data, v_data)
281 [~,~,s] = obj.get_boundary_ops(boundary);
282
283 switch s
284 case -1
285 p_in = [1 2];
286 case 1
287 p_in = [1 3];
288 end
289
290 a = obj.gamma - 1;
291 L = @(~,u,~)[
292 0 1 0;
293 0 -1/2*u*a a;
294 ];
295 g = @(t)[
296 v_data(t);
297 p_data(t);
298 ];
299
300 closure = boundary_condition_L(obj, boundary, L, g, p_in);
301 end
302
303
304 function closure = boundary_condition_outflow(obj, boundary, p_data)
305 [~,~,s] = obj.get_boundary_ops(boundary);
306
307 switch s
308 case -1
309 p_in = 2;
310 case 1
311 p_in = 3;
312 end
313
314 a = obj.gamma -1;
315 L = @(~,u,~)a*[0 -1/2*u 1];
316 g = @(t)[p_data(t)];
317
318
319 closure = boundary_condition_L(obj, boundary, L, g, p_in);
348 320
349 end 321 end
350 322
351 % Set wall boundary condition v = 0. 323 % Set wall boundary condition v = 0.
352 function closure = boundary_condition_wall(obj,boundary) 324 function closure = boundary_condition_wall(obj,boundary)