diff +scheme/Burgers1d.m @ 1038:8537fdd6830a feature/burgers1d

Use opSets in Burgers1d. Note. Also changed from viscid formulation to inviscid formulation. Might be changed back later.
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Fri, 18 Jan 2019 09:04:38 +0100
parents 2b9bdb22baec
children 0a5503a08a36
line wrap: on
line diff
--- a/+scheme/Burgers1d.m	Fri Jan 18 09:02:02 2019 +0100
+++ b/+scheme/Burgers1d.m	Fri Jan 18 09:04:38 2019 +0100
@@ -1,136 +1,99 @@
 classdef Burgers1d < scheme.Scheme
     properties
-        grid % Physical grid
+        m % Number of points in each direction, possibly a vector
+        h % Grid spacing
+        grid % Grid
         order % Order accuracy for the approximation
+
+        H % Discrete norm
+        D
         
-        params
-
-        D % Non-stabalized scheme operator
-        H % Discrete norm
-        Hi % Norm inverse
+        D1
+        Hi
         e_l
         e_r
-        d_l
-        d_r
     end
 
     methods
-        function obj = Burgers1d(grid, pde_form, operator_type, order, dissipation, params)
-            assert(grid.D == 1);
-            assert(grid.size() == length(params.eps));
-            m = grid.size();
-            lim = grid.lim{1}; % Ugly, and only applicable for cartesian grids.
-            switch operator_type
-                case 'narrow'
-                    ops = sbp.D4Variable(m, lim, order);
-                    D1 = ops.D1;
-                    D2 = ops.D2;
-                    if (strcmp(dissipation,'on'))
-                        DissipationOp = -1*sbp.dissipationOperator(m, order, ops.HI);
-                    end
-                    d_l = ops.d1_l';
-                    d_r = ops.d1_r';
-                case 'upwind-'
-                    ops = sbp.D1Upwind(m, lim, order);
-                    D1 = (ops.Dp + ops.Dm)/2;
-                    D2 = @(eps) ops.Dp*spdiag(eps)*ops.Dm;
-                    if (strcmp(dissipation,'on'))
-                        DissipationOp = (ops.Dp-ops.Dm)/2;
-                    end
-                    d_l = ops.e_l'*ops.Dm;
-                    d_r = ops.e_r'*ops.Dm;
-                case 'upwind+'
-                    ops = sbp.D1Upwind(m, lim, order);
-                    D1 = (ops.Dp + ops.Dm)/2;
-                    D2 = @(eps) ops.Dm*spdiag(eps)*ops.Dp;
-                    if (strcmp(dissipation,'on'))
-                        DissipationOp = (ops.Dp-ops.Dm)/2;
-                    end
-                    d_l = ops.e_l'*ops.Dp;
-                    d_r = ops.e_r'*ops.Dp;
-                case 'upwind+-'
-                    ops = sbp.D1Upwind(m, lim, order);
-                    D1 = (ops.Dp + ops.Dm)/2;
-                    D2 = @(eps) (ops.Dp*spdiag(eps)*ops.Dm + ops.Dm*spdiag(eps)*ops.Dp)/2;
-                    if (strcmp(dissipation,'on'))
-                        DissipationOp = (ops.Dp-ops.Dm)/2;
-                    end
-                    d_l = ops.e_l'*D1;
-                    d_r = ops.e_r'*D1;
-                otherwise
-                    error('Other operator types not yet supported', operator_type);
+        function obj = Burgers1d(g, order, pde_form, fluxSplitting, opSet)
+            default_arg('opSet',@sbp.D2Standard);
+            default_arg('fluxSplitting',@(v)max(abs(v)));
+            assertType(g, 'grid.Cartesian');
+
+            m = g.size();
+            xl = g.getBoundary('l');
+            xr = g.getBoundary('r');
+            xlim = {xl, xr};
+
+            ops = opSet(m, xlim, order);
+
+            if (isequal(opSet, @sbp.D1Upwind))
+                obj.D1 = (ops.Dp + ops.Dm)/2;
+                DissOp = (ops.Dm - ops.Dp)/2;
+            else 
+                obj.D1 = ops.D1;
             end
-
+            
             switch pde_form
                 case 'skew-symmetric'
-                    if (strcmp(dissipation,'on'))
-                        D = @(v, viscosity) - 1/3*D1*v.^2 + (-1/3*v.*D1 + D2(params.eps + viscosity) + max(abs(v))*DissipationOp)*v;
+                    if (isequal(opSet, @sbp.D1Upwind))
+                        D = @(v) -(1/3*obj.D1*v.*v + (1/3*spdiag(v)*obj.D1  + fluxSplitting(v)*DissOp)*v);
                     else
-                        D = @(v, viscosity) - 1/3*D1*v.^2 + (-1/3*v.*D1 + D2(params.eps + viscosity))*v;
+                        D = @(v) -(1/3*obj.D1*v.*v + 1/3*spdiag(v)*obj.D1*v);
                     end
                 case 'conservative'
-                    if (strcmp(dissipation,'on'))
-                        D = @(v, viscosity) -1/2*D1*v.^2 + (D2(params.eps + viscosity) + max(abs(v))*DissipationOp)*v;
+                    if (isequal(opSet, @sbp.D1Upwind))
+                        D = @(v) -(1/2*obj.D1*v.*v + fluxSplitting(v)*DissOp*v);
                     else
-                        D = @(v, viscosity) -1/2*D1*v.^2 + D2(params.eps + viscosity)*v;
+                        D = @(v) -(1/2*obj.D1*v.*v);
                     end
                 otherwise
                     error('Not supported', pde_form);
             end
 
-            obj.grid = grid;
-            obj.order = order;
-            obj.params = params;
+            obj.grid = g;
 
             obj.D = D;
             obj.H =  ops.H;
             obj.Hi = ops.HI;
+
             obj.e_l = ops.e_l;
             obj.e_r = ops.e_r;
-            obj.d_l =  d_l;
-            obj.d_r =  d_r;
+
+            obj.m = m;
+            obj.h = ops.h;
+            obj.order = order;
         end
 
         % Closure functions return the operators applied to the own doamin to close the boundary
         % Penalty functions return the operators to force the solution. In the case of an interface it returns the operator applied to the other domain.
         %       boundary            is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'.
         %       type                is a string specifying the type of boundary condition if there are several.
-        %       data                is a function returning the data that should be applied at the boundary.
-        function [closure, penalty] = boundary_condition(obj,boundary,type,data)
+        function [closure, penalty] = boundary_condition(obj, boundary, type)
             default_arg('type','robin');
-            default_arg('data',0);
-            [e, d, i_b, s] = obj.get_boundary_ops(boundary);
+            [e, index, s] = obj.get_boundary_ops(boundary);
             switch type
-                % Stable robin-like boundary conditions ((u+-abs(u))*u/3 - eps*u_x)) with +- at left/right boundary
-                case {'R','robin'}
-                    p = s*obj.Hi*e;
-                    closure = @(v, viscosity) p*(((v(i_b)-s*abs(v(i_b)))/3)*(v(i_b)) - ((obj.params.eps(i_b) + viscosity(i_b))*d*v));
-                    switch class(data)
-                        case 'double'
-                            penalty = s*p*data;
-                        case 'function_handle'
-                            penalty = @(t) s*p*data(t);
-                        otherwise
-                            error('Wierd data argument!')
-                    end
+                % Stable dirhclet-like boundary conditions ((u+-abs(u))*u/3)) with +- at left/right boundary
+                case {'D', 'd', 'dirichlet', 'Dirichlet'}
+                    tau = s*e;
+                    closure = @(v) obj.Hi*tau*(((v(index)-s*abs(v(index)))/3)*v(index));
+                    penalty = -obj.Hi*tau;
                 otherwise
                     error('No such boundary condition: type = %s',type);
             end
         end
 
-        % Ruturns the boundary ops, boundary index and sign for the boundary specified by the string boundary.
+        % Returns the boundary ops, boundary index and sign for the boundary specified by the string boundary.
         % The right boundary is considered the positive boundary
-        function [e, d, i_b, s] = get_boundary_ops(obj,boundary)
+        function [e, index, s] = get_boundary_ops(obj,boundary)
             switch boundary
-                case 'l'
+                case {'l','L','left','Left'}
                     e = obj.e_l;
-                    d = obj.d_l;
-                    i_b = 1;
+                    index = 1;
                     s = -1;
-                case 'r'
+                case {'r','R','right','Right'}
                     e = obj.e_r;
-                    d = obj.d_r;
-                    i_b = length(e);
+                    index = length(e);
                     s = 1;
                 otherwise
                     error('No such boundary: boundary = %s',boundary);