Mercurial > repos > public > sbplib
comparison +scheme/LaplaceCurvilinearVirtaMin.m @ 1137:2ff1f366e64a feature/laplace_curvilinear_test
Fix minimum and correct borrowing in VirtaMin scheme.
author | Martin Almquist <malmquist@stanford.edu> |
---|---|
date | Mon, 10 Jun 2019 13:27:29 +0200 |
parents | eee71789f13b |
children | afd06a84b69c |
comparison
equal
deleted
inserted
replaced
1136:eee71789f13b | 1137:2ff1f366e64a |
---|---|
35 du_w, dv_w | 35 du_w, dv_w |
36 du_e, dv_e | 36 du_e, dv_e |
37 du_s, dv_s | 37 du_s, dv_s |
38 du_n, dv_n | 38 du_n, dv_n |
39 gamm_u, gamm_v | 39 gamm_u, gamm_v |
40 h11_u, h11_v | |
40 lambda | 41 lambda |
42 | |
43 % Number of boundary points in minumum check | |
44 bp | |
41 | 45 |
42 end | 46 end |
43 | 47 |
44 methods | 48 methods |
45 % Implements a*div(b*grad(u)) as a SBP scheme | 49 % Implements a*div(b*grad(u)) as a SBP scheme |
50 default_arg('a', 1); | 54 default_arg('a', 1); |
51 default_arg('b', 1); | 55 default_arg('b', 1); |
52 | 56 |
53 if b ~=1 | 57 if b ~=1 |
54 error('Not implemented yet') | 58 error('Not implemented yet') |
59 end | |
60 | |
61 % Number of boundary points in minimum check | |
62 switch order | |
63 case 2 | |
64 obj.bp = 2; | |
65 case 4 | |
66 obj.bp = 4; | |
67 case 6 | |
68 obj.bp = 7; | |
55 end | 69 end |
56 | 70 |
57 % assert(isa(g, 'grid.Curvilinear')) | 71 % assert(isa(g, 'grid.Curvilinear')) |
58 if isa(a, 'function_handle') | 72 if isa(a, 'function_handle') |
59 a = grid.evalOn(g, a); | 73 a = grid.evalOn(g, a); |
222 obj.a22 = a22; | 236 obj.a22 = a22; |
223 obj.lambda = lambda; | 237 obj.lambda = lambda; |
224 | 238 |
225 obj.gamm_u = h_u*ops_u.borrowing.M.d1; | 239 obj.gamm_u = h_u*ops_u.borrowing.M.d1; |
226 obj.gamm_v = h_v*ops_v.borrowing.M.d1; | 240 obj.gamm_v = h_v*ops_v.borrowing.M.d1; |
241 | |
242 obj.h11_u = h_u*ops_u.borrowing.H11; | |
243 obj.h11_v = h_v*ops_v.borrowing.H11; | |
227 end | 244 end |
228 | 245 |
229 | 246 |
230 % Closure functions return the opertors applied to the own doamin to close the boundary | 247 % Closure functions return the opertors applied to the own doamin to close the boundary |
231 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. | 248 % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. |
238 default_arg('type','neumann'); | 255 default_arg('type','neumann'); |
239 default_arg('parameter', []); | 256 default_arg('parameter', []); |
240 | 257 |
241 [e, d] = obj.getBoundaryOperator({'e', 'd'}, boundary); | 258 [e, d] = obj.getBoundaryOperator({'e', 'd'}, boundary); |
242 H_b = obj.getBoundaryQuadrature(boundary); | 259 H_b = obj.getBoundaryQuadrature(boundary); |
243 gamm = obj.getBoundaryBorrowing(boundary); | 260 [gamm, h11] = obj.getBoundaryBorrowing(boundary); |
261 | |
262 lambda = obj.lambda; | |
263 mx = obj.m(1); | |
264 my = obj.m(2); | |
265 bp = obj.bp; | |
266 | |
267 lambda_mat = reshape(lambda, my, mx); | |
268 switch boundary | |
269 case 'w' | |
270 lambda_min = min(lambda_mat(:,1:bp), [], 2); | |
271 lambda_mat = repmat(lambda_min, 1, mx); | |
272 case 'e' | |
273 lambda_min = min(lambda_mat(:,end-bp+1:end), [], 2); | |
274 lambda_mat = repmat(lambda_min, 1, mx); | |
275 case 's' | |
276 lambda_min = min(lambda_mat(1:bp,:), [], 1); | |
277 lambda_mat = repmat(lambda_min, my, 1); | |
278 case 'n' | |
279 lambda_min = min(lambda_mat(end-bp+1:end,:), [], 1); | |
280 lambda_mat = repmat(lambda_min, my, 1); | |
281 end | |
282 lambda_min = lambda_mat(:); | |
244 | 283 |
245 switch type | 284 switch type |
246 % Dirichlet boundary condition | 285 % Dirichlet boundary condition |
247 case {'D','d','dirichlet'} | 286 case {'D','d','dirichlet'} |
248 tuning = 1.0; | 287 tuning = 1.0; |
249 | 288 |
250 b1 = gamm*obj.lambda./obj.a11.^2; | 289 switch boundary |
251 b2 = gamm*obj.lambda./obj.a22.^2; | 290 case {'w', 'e'} |
291 b1 = gamm*lambda_min./obj.a11.^2; | |
292 b2 = h11 *lambda./obj.a22.^2; | |
293 case {'s', 'n'} | |
294 b1 = h11 *lambda./obj.a11.^2; | |
295 b2 = gamm*lambda_min./obj.a22.^2; | |
296 end | |
252 | 297 |
253 tau1 = tuning * spdiag(-1./b1 - 1./b2); | 298 tau1 = tuning * spdiag(-1./b1 - 1./b2); |
254 tau2 = 1; | 299 tau2 = 1; |
255 | 300 |
256 tau = (tau1*e + tau2*d)*H_b; | 301 tau = (tau1*e + tau2*d)*H_b; |
279 % Fields: | 324 % Fields: |
280 % -- tuning: penalty strength, defaults to 1.2 | 325 % -- tuning: penalty strength, defaults to 1.2 |
281 % -- interpolation: type of interpolation, default 'none' | 326 % -- interpolation: type of interpolation, default 'none' |
282 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary,type) | 327 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary,type) |
283 | 328 |
284 defaultType.tuning = 1.2; | 329 defaultType.tuning = 1.0; |
285 defaultType.interpolation = 'none'; | 330 defaultType.interpolation = 'none'; |
286 default_struct('type', defaultType); | 331 default_struct('type', defaultType); |
287 | 332 |
288 switch type.interpolation | 333 switch type.interpolation |
289 case {'none', ''} | 334 case {'none', ''} |
301 % u denotes the solution in the own domain | 346 % u denotes the solution in the own domain |
302 % v denotes the solution in the neighbour domain | 347 % v denotes the solution in the neighbour domain |
303 [e_u, d_u] = obj.getBoundaryOperator({'e', 'd'}, boundary); | 348 [e_u, d_u] = obj.getBoundaryOperator({'e', 'd'}, boundary); |
304 H_b_u = obj.getBoundaryQuadrature(boundary); | 349 H_b_u = obj.getBoundaryQuadrature(boundary); |
305 I_u = obj.getBoundaryIndices(boundary); | 350 I_u = obj.getBoundaryIndices(boundary); |
306 gamm_u = obj.getBoundaryBorrowing(boundary); | 351 [gamm_u, h11_u] = obj.getBoundaryBorrowing(boundary); |
307 | 352 |
308 [e_v, d_v] = neighbour_scheme.getBoundaryOperator({'e', 'd'}, neighbour_boundary); | 353 [e_v, d_v] = neighbour_scheme.getBoundaryOperator({'e', 'd'}, neighbour_boundary); |
309 H_b_v = neighbour_scheme.getBoundaryQuadrature(neighbour_boundary); | 354 H_b_v = neighbour_scheme.getBoundaryQuadrature(neighbour_boundary); |
310 I_v = neighbour_scheme.getBoundaryIndices(neighbour_boundary); | 355 I_v = neighbour_scheme.getBoundaryIndices(neighbour_boundary); |
311 gamm_v = neighbour_scheme.getBoundaryBorrowing(neighbour_boundary); | 356 [gamm_v, h11_v] = neighbour_scheme.getBoundaryBorrowing(neighbour_boundary); |
312 | 357 |
313 u = obj; | 358 u = obj; |
314 v = neighbour_scheme; | 359 v = neighbour_scheme; |
315 | 360 |
316 b1_u = gamm_u*u.lambda(I_u)./u.a11(I_u).^2; | 361 % Minimum check for u |
317 b2_u = gamm_u*u.lambda(I_u)./u.a22(I_u).^2; | 362 lambda_u = obj.lambda; |
318 b1_v = gamm_v*v.lambda(I_v)./v.a11(I_v).^2; | 363 mx = obj.m(1); |
319 b2_v = gamm_v*v.lambda(I_v)./v.a22(I_v).^2; | 364 my = obj.m(2); |
365 bp = obj.bp; | |
366 | |
367 lambda_mat = reshape(lambda_u, my, mx); | |
368 switch boundary | |
369 case 'w' | |
370 lambda_min = min(lambda_mat(:,1:bp), [], 2); | |
371 lambda_mat = repmat(lambda_min, 1, mx); | |
372 case 'e' | |
373 lambda_min = min(lambda_mat(:,end-bp+1:end), [], 2); | |
374 lambda_mat = repmat(lambda_min, 1, mx); | |
375 case 's' | |
376 lambda_min = min(lambda_mat(1:bp,:), [], 1); | |
377 lambda_mat = repmat(lambda_min, my, 1); | |
378 case 'n' | |
379 lambda_min = min(lambda_mat(end-bp+1:end,:), [], 1); | |
380 lambda_mat = repmat(lambda_min, my, 1); | |
381 end | |
382 lambda_min_u = lambda_mat(:); | |
383 | |
384 % Minimum check for v | |
385 lambda_v = v.lambda; | |
386 mx = v.m(1); | |
387 my = v.m(2); | |
388 bp = v.bp; | |
389 | |
390 lambda_mat = reshape(lambda_v, my, mx); | |
391 switch boundary | |
392 case 'w' | |
393 lambda_min = min(lambda_mat(:,1:bp), [], 2); | |
394 lambda_mat = repmat(lambda_min, 1, mx); | |
395 case 'e' | |
396 lambda_min = min(lambda_mat(:,end-bp+1:end), [], 2); | |
397 lambda_mat = repmat(lambda_min, 1, mx); | |
398 case 's' | |
399 lambda_min = min(lambda_mat(1:bp,:), [], 1); | |
400 lambda_mat = repmat(lambda_min, my, 1); | |
401 case 'n' | |
402 lambda_min = min(lambda_mat(end-bp+1:end,:), [], 1); | |
403 lambda_mat = repmat(lambda_min, my, 1); | |
404 end | |
405 lambda_min_v = lambda_mat(:); | |
406 | |
407 switch boundary | |
408 case {'w', 'e'} | |
409 b1_u = gamm_u*u.lambda_min_u(I_u)./u.a11(I_u).^2; | |
410 b2_u = h11_u *u.lambda(I_u)./u.a22(I_u).^2; | |
411 case {'s', 'n'} | |
412 b1_u = h11_u *u.lambda(I_u)./u.a11(I_u).^2; | |
413 b2_u = gamm_u*u.lambda_min(I_u)./u.a22(I_u).^2; | |
414 end | |
415 | |
416 switch neighbour_boundary | |
417 case {'w', 'e'} | |
418 b1_v = gamm_v*v.lambda_min_v(I_v)./v.a11(I_v).^2; | |
419 b2_v = h11_v *v.lambda(I_v)./v.a22(I_v).^2; | |
420 case {'s', 'n'} | |
421 b1_v = h11_v *v.lambda(I_v)./v.a11(I_v).^2; | |
422 b2_v = gamm_v*v.lambda_min(I_v)./v.a22(I_v).^2; | |
423 end | |
320 | 424 |
321 tau1 = -1./(4*b1_u) -1./(4*b1_v) -1./(4*b2_u) -1./(4*b2_v); | 425 tau1 = -1./(4*b1_u) -1./(4*b1_v) -1./(4*b2_u) -1./(4*b2_v); |
322 tau1 = tuning * spdiag(tau1); | 426 tau1 = tuning * spdiag(tau1); |
323 tau2 = 1/2; | 427 tau2 = 1/2; |
324 | 428 |
477 end | 581 end |
478 end | 582 end |
479 | 583 |
480 % Returns borrowing constant gamma | 584 % Returns borrowing constant gamma |
481 % boundary -- string | 585 % boundary -- string |
482 function gamm = getBoundaryBorrowing(obj, boundary) | 586 function [gamm, h11] = getBoundaryBorrowing(obj, boundary) |
483 switch boundary | 587 switch boundary |
484 case {'w','e'} | 588 case {'w','e'} |
485 gamm = obj.gamm_u; | 589 gamm = obj.gamm_u; |
590 h11 = obj.h11_u; | |
486 case {'s','n'} | 591 case {'s','n'} |
487 gamm = obj.gamm_v; | 592 gamm = obj.gamm_v; |
593 h11 = obj.h11_v; | |
488 otherwise | 594 otherwise |
489 error('No such boundary: boundary = %s',boundary); | 595 error('No such boundary: boundary = %s',boundary); |
490 end | 596 end |
491 end | 597 end |
492 | 598 |