Mercurial > repos > public > sbplib
changeset 720:07f8311374c6 feature/utux2D
Add interpolation to LaplaceCurveilinear.
author | Martin Almquist <malmquist@stanford.edu> |
---|---|
date | Wed, 14 Mar 2018 21:01:34 -0700 |
parents | b3f8fb9cefd2 |
children | f4595f14d696 |
files | +scheme/LaplaceCurvilinear.m |
diffstat | 1 files changed, 81 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
diff -r b3f8fb9cefd2 -r 07f8311374c6 +scheme/LaplaceCurvilinear.m --- a/+scheme/LaplaceCurvilinear.m Sun Mar 11 21:39:49 2018 -0700 +++ b/+scheme/LaplaceCurvilinear.m Wed Mar 14 21:01:34 2018 -0700 @@ -38,22 +38,25 @@ du_n, dv_n gamm_u, gamm_v lambda + + interpolation_type end methods % Implements a*div(b*grad(u)) as a SBP scheme % TODO: Implement proper H, it should be the real physical quadrature, the logic quadrature may be but in a separate variable (H_logic?) - function obj = LaplaceCurvilinear(g ,order, a, b, opSet) + function obj = LaplaceCurvilinear(g ,order, a, b, opSet, interpolation_type) default_arg('opSet',@sbp.D2Variable); default_arg('a', 1); default_arg('b', 1); + default_arg('interpolation_type','AWW'); if b ~=1 error('Not implemented yet') end - assert(isa(g, 'grid.Curvilinear')) + % assert(isa(g, 'grid.Curvilinear')) m = g.size(); m_u = m(1); @@ -209,6 +212,7 @@ obj.h = [h_u h_v]; obj.order = order; obj.grid = g; + obj.interpolation_type = interpolation_type; obj.a = a; obj.b = b; @@ -269,13 +273,70 @@ end function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + + [e_u, d_u, gamm_u, H_b_u, I_u] = obj.get_boundary_ops(boundary); + [e_v, d_v, gamm_v, H_b_v, I_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary); + Hi = obj.Hi; + a = obj.a; + + m_u = length(H_b_u); + m_v = length(H_b_v); + + grid_ratio = m_u/m_v; + if grid_ratio ~= 1 + + [ms, index] = sort([m_u, m_v]); + orders = [obj.order, neighbour_scheme.order]; + orders = orders(index); + + switch obj.interpolation_type + case 'MC' + interpOpSet = sbp.InterpMC(ms(1),ms(2),orders(1),orders(2)); + if grid_ratio < 1 + I_v2u_good = interpOpSet.IF2C; + I_v2u_bad = interpOpSet.IF2C; + I_u2v_good = interpOpSet.IC2F; + I_u2v_bad = interpOpSet.IC2F; + elseif grid_ratio > 1 + I_v2u_good = interpOpSet.IC2F; + I_v2u_bad = interpOpSet.IC2F; + I_u2v_good = interpOpSet.IF2C; + I_u2v_bad = interpOpSet.IF2C; + end + case 'AWW' + %String 'C2F' indicates that ICF2 is more accurate. + interpOpSetF2C = sbp.InterpAWW(ms(1),ms(2),orders(1),orders(2),'F2C'); + interpOpSetC2F = sbp.InterpAWW(ms(1),ms(2),orders(1),orders(2),'C2F'); + if grid_ratio < 1 + % Local is coarser than neighbour + I_v2u_good = interpOpSetF2C.IF2C; + I_v2u_bad = interpOpSetC2F.IF2C; + I_u2v_good = interpOpSetC2F.IC2F; + I_u2v_bad = interpOpSetF2C.IC2F; + elseif grid_ratio > 1 + % Local is finer than neighbour + I_v2u_good = interpOpSetC2F.IC2F; + I_v2u_bad = interpOpSetF2C.IC2F; + I_u2v_good = interpOpSetF2C.IF2C; + I_u2v_bad = interpOpSetC2F.IF2C; + end + otherwise + error(['Interpolation type ' obj.interpolation_type ... + ' is not available.' ]); + end + + else + % No interpolation required + I_v2u_good = speye(m_u,m_u); + I_v2u_bad = speye(m_u,m_u); + I_u2v_good = speye(m_u,m_u); + I_u2v_bad = speye(m_u,m_u); + end + % u denotes the solution in the own domain % v denotes the solution in the neighbour domain tuning = 1.2; % tuning = 20.2; - [e_u, d_u, gamm_u, H_b_u, I_u] = obj.get_boundary_ops(boundary); - [e_v, d_v, gamm_v, H_b_v, I_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary); - u = obj; v = neighbour_scheme; @@ -284,18 +345,24 @@ b1_v = gamm_v*v.lambda(I_v)./v.a11(I_v).^2; b2_v = gamm_v*v.lambda(I_v)./v.a22(I_v).^2; - tau1 = -1./(4*b1_u) -1./(4*b1_v) -1./(4*b2_u) -1./(4*b2_v); - tau1 = tuning * spdiag(tau1); - tau2 = 1/2; + tau_u = -1./(4*b1_u) -1./(4*b2_u); + tau_v = -1./(4*b1_v) -1./(4*b2_v); + + tau_u = tuning * spdiag(tau_u); + tau_v = tuning * spdiag(tau_v); + beta_u = tau_v; - sig1 = -1/2; - sig2 = 0; + closure = a*Hi*e_u*tau_u*H_b_u*e_u' + ... + a*Hi*e_u*H_b_u*I_v2u_bad*beta_u*I_u2v_good*e_u' + ... + a*1/2*Hi*d_u*H_b_u*e_u' + ... + -a*1/2*Hi*e_u*H_b_u*d_u'; - tau = (e_u*tau1 + tau2*d_u)*H_b_u; - sig = (sig1*e_u + sig2*d_u)*H_b_u; + penalty = -a*Hi*e_u*tau_u*H_b_u*I_v2u_good*e_v' + ... + -a*Hi*e_u*H_b_u*I_v2u_bad*beta_u*e_v' + ... + -a*1/2*Hi*d_u*H_b_u*I_v2u_good*e_v' + ... + -a*1/2*Hi*e_u*H_b_u*I_v2u_bad*d_v'; + - closure = obj.a*obj.Hi*( tau*e_u' + sig*d_u'); - penalty = obj.a*obj.Hi*(-tau*e_v' + sig*d_v'); end % Ruturns the boundary ops and sign for the boundary specified by the string boundary.