changeset 290:d32f674bcbe5 feature/hypsyst

A first attempt to make a general scheme fo hyperbolic systems
author Ylva Rydin <ylva.rydin@telia.com>
date Fri, 16 Sep 2016 14:51:17 +0200
parents 70184f6c6cb5
children 807dfe8be3ec
files +scheme/Utux.m +scheme/hypsyst2d.m
diffstat 2 files changed, 232 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/+scheme/Utux.m	Mon Sep 12 12:58:18 2016 +0200
+++ b/+scheme/Utux.m	Fri Sep 16 14:51:17 2016 +0200
@@ -6,7 +6,6 @@
         order % Order accuracy for the approximation
 
         H % Discrete norm
-        M % Derivative norm
         D
 
         D1
@@ -20,21 +19,28 @@
     methods 
          function obj = Utux(m,xlim,order)
              default_arg('a',1);
-            [x, h] = util.get_grid(xlim{:},m);
-            ops = sbp.Ordinary(m,h,order);
+           
+           %Old operators  
+           % [x, h] = util.get_grid(xlim{:},m);
+           %ops = sbp.Ordinary(m,h,order);
+           
+            ops = sbp.D1Nonequidistant(m,xlim,order);
+           % ops = sbp.D2Standard(m,xlim,order);
+           
+            obj.x=ops.x;
 
-            obj.D1 = sparse(ops.derivatives.D1);
-            obj.H =  sparse(ops.norms.H);
-            obj.Hi = sparse(ops.norms.HI);
-            obj.M =  sparse(ops.norms.M);
-            obj.e_l = sparse(ops.boundary.e_1);
-            obj.e_r = sparse(ops.boundary.e_m);
+            obj.D1 = ops.D1;
+            obj.H =  ops.H;
+            obj.Hi = ops.HI;
+        
+            obj.e_l = ops.e_l;
+            obj.e_r = ops.e_r;
             obj.D=obj.D1;
 
             obj.m = m;
-            obj.h = h;
+            obj.h = ops.h;
             obj.order = order;
-            obj.x = x;
+            obj.x = ops.x;
 
         end
         % Closure functions return the opertors applied to the own doamin to close the boundary
@@ -47,7 +53,7 @@
         function [closure, penalty] = boundary_condition(obj,boundary,type,data)
             default_arg('type','neumann');
             default_arg('data',0);
-            tau = -1*obj.e_l;  
+            tau =-1*obj.e_l;  
             closure = obj.Hi*tau*obj.e_l';       
             penalty = 0*obj.e_l;
                 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/+scheme/hypsyst2d.m	Fri Sep 16 14:51:17 2016 +0200
@@ -0,0 +1,214 @@
+classdef hypsyst2d < scheme.Scheme
+    properties
+        m % Number of points in each direction, possibly a vector
+        h % Grid spacing
+        x,y % Grid
+        X,Y % Values of x and y for each grid point
+        order % Order accuracy for the approximation
+        
+        D % non-stabalized scheme operator
+        A, B, E
+        
+        H % Discrete norm
+        Hi
+        H_x, H_y % Norms in the x and y directions
+        Hx,Hy % Kroneckerd norms. 1'*Hx*v corresponds to integration in the x dir.
+        I_x,I_y
+        e_w, e_e, e_s, e_n
+        params %parameters for the coeficient matrices
+    end
+    
+    
+    methods
+        function obj = hypsyst2d(m,lim,order,matrices,params)
+            
+            xlim = lim{1};
+            ylim = lim{2};
+            
+            if length(m) == 1
+                m = [m m];
+            end
+            
+            m_x = m(1);
+            m_y = m(2);
+            
+            ops_x = sbp.D2Standard(m_x,xlim,order);
+            ops_y = sbp.D2Standard(m_y,ylim,order);
+            
+            obj.x=ops_x.x;
+            obj.y=ops_y.y;
+            
+            obj.X = kr(x,ones(m_y,1));
+            obj.Y = kr(ones(m_x,1),y);
+            
+            I_x = speye(m_x);
+            I_y = speye(m_y);
+            I_n=  eye(4);
+            
+            
+            D1_x = kr(kr(I_n,ops_x.D1),I_y);
+            obj.Hi_x= kr(kr(I_n,ops_x.HI),I_y);
+            D1_y=kr(I_n,kr(I_x,ops_y.D1));
+            obj.Hi_y=kr(I_n,kr(I_x,ops_y.HI));
+            
+            obj.e_w=kr(I_n,kr(ops_x.e_l,I_y));
+            obj.e_e=kr(I_n,kr(ops_x.e_r,I_y));
+            obj.e_s=kr(I_n,kr(I_x,ops_y.e_l));
+            obj.e_n=kr(I_n,kr(I_x,ops_y.e_r));
+            
+            obj.m=m;
+            obj.h=[ops_x.h ops_y.h];
+            obj.order=order;
+            obj.params=params;
+            
+            obj.A=matrixBuild(obj,matrices.A);
+            obj.B=matrixBuild(obj,matrices.B);
+            obj.E=matrixBuild(obj,matrices.E);
+            
+            obj.D=-obj.A*D1_x-obj.B*D1_y-E;
+            
+        end
+        % Closure functions return the opertors applied to the own doamin to close the boundary
+        % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin.
+        %       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.
+        %       neighbour_scheme    is an instance of Scheme that should be interfaced to.
+        %       neighbour_boundary  is a string specifying which boundary to interface to.
+        function [closure, penalty] = boundary_condition(obj,boundary,type,data)
+            default_arg('type','neumann');
+            default_arg('data',0);
+            
+            switch type
+                case{c,'char'}
+                    [tau,e_,Hi,CHM]=GetBoundarydata(obj,boundary,type);
+                    closure =Hi*e_*tau*CHM*e_';
+                    penalty =Hi*e_*tau*CHM*data;
+                otherwise
+                    error('No such boundary condition')
+            end
+        end
+        
+        function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
+            error('An interface function does not exist yet');
+        end
+        
+        function N = size(obj)
+            N = obj.m;
+        end
+        
+    end
+    
+    methods(Static)
+        % Calculates the matrcis need for the inteface coupling between boundary bound_u of scheme schm_u
+        % and bound_v of scheme schm_v.
+        %   [uu, uv, vv, vu] = inteface_couplong(A,'r',B,'l')
+        function [uu, uv, vv, vu] = interface_coupling(schm_u,bound_u,schm_v,bound_v)
+            [uu,uv] = schm_u.interface(bound_u,schm_v,bound_v);
+            [vv,vu] = schm_v.interface(bound_v,schm_u,bound_u);
+        end
+        
+        function [ret]=matrixBuild(obj,mat)
+            %extra info for coordinate transfomration mult my y_ny  and
+            %x,ny osv...
+            params=obj.params;
+            X=obj.X;
+            Y=obj.Y;
+            
+            if isa(mat,'function_handle')
+                matVec=mat(params,x,y);
+                side=length(x);
+            else
+                matVec=mat;
+                side=max(size(mat))/4;
+            end
+            
+            
+            ret=[diag(matVec(1,(1-1)*side+1:1*side)) diag(matVec(1,(2-1)*side+1:2*side)) diag(matVec(1,(3-1)*side+1:3*side)) diag(matVec(1,(4-1)*side+1:4*side))
+                diag(matVec(2,(1-1)*side+1:1*side)) diag(matVec(2,(2-1)*side+1:2*side)) diag(matVec(2,(3-1)*side+1:3*side)) diag(matVec(2,(4-1)*side+1:4*side))
+                diag(matVec(3,(1-1)*side+1:1*side)) diag(matVec(3,(2-1)*side+1:2*side)) diag(matVec(3,(3-1)*side+1:3*side)) diag(matVec(3,(4-1)*side+1:4*side))
+                diag(matVec(4,(1-1)*side+1:1*side)) diag(matVec(4,(2-1)*side+1:2*side)) diag(matVec(4,(3-1)*side+1:3*side)) diag(matVec(4,(4-1)*side+1:4*side))];
+        end
+        
+        function [tau,e_,Hi, CHM]=GetBoundarydata(obj,boundary)
+            params=obj.params;
+            x=obj.x;
+            y=obj.y;
+            
+            side=max(length(x),length(y));
+            
+            
+            switch boundary
+                case {'w','W','west'}
+                    e_=obj.e_w;
+                    mat=obj.A;
+                    [V,D]=matrixDiag(mat,params,x(1),y);
+                    Hi=obj.Hx;
+                    tau=zeros(4*side,pos*side);
+                    tau(1:pos*side,:)=-abs(D(1:pos*side,1:pos*side));
+                    CHM=V*((D+abs(D))/2)*V';
+                case {'e','E','east'}
+                    e_=obj.e_e;
+                    mat=obj.A;
+                    [V,D]=matrixDiag(mat,params,x(end),y);
+                    Hi=obj.Hy;
+                    tau=zeros(4*side,(4-pos));
+                    tau(pos*side+1:4*side)=-abs(D(pos*side+1:4*side,pos*side+1:4*side));
+                    CHM=V*((D-abs(D))/2)*V';
+                case {'s','S','south'}
+                    e_=obj.e_s;
+                    mat=obj.B;
+                    [V,D]=matrixDiag(mat,params,x,y(1));
+                    Hi=obj.Hx;
+                    tau=zeros(4*side,pos*side);
+                    tau(1:pos*side,:)=-abs(D(1:pos*side,1:pos*side));
+                    CHM=V*((D+abs(D))/2)*V';
+                case {'n','N','north'}
+                    e_=obj.e_n;
+                    mat=obj.B;
+                    [V,D]=matrixDiag(mat,params,x,y(end));
+                    Hi=obj.Hy;
+                    tau=zeros(4*side,(4-pos));
+                    tau(pos*side+1:4*side)=-abs(D(pos*side+1:4*side,pos*side+1:4*side));
+                    CHM=V*((D-abs(D))/2)*V';
+            end
+            
+            tau=V*tau*V';
+            
+        end
+        
+        function [V, D,pos]=matrixDiag(mat,params,x,y)
+            syms xs ys;
+            [V, D]=eig(mat(params,xs,ys));
+            xs=1;ys=1;
+            DD=eval(diag(D));
+            
+            pos=find(DD>=0); %Now zero eigenvalues are calculated as possitive, Maybe it should not????
+            neg=find(DD<0);
+            syms xs ys
+            DD=diag(D);
+            
+            D=diag([DD(pos); DD(neg)]);
+            V=[V(:,pos) V(:,neg)];
+            
+            xs=x; ys=y;
+            
+            side=max(length(x),length(y));
+            Dret=zeros(4,side*4);
+            Vret=zeros(4,side*4);
+            for ii=1:4
+                for jj=1:4
+                    Dret(jj,(ii-1)*side+1:side*ii)=eval(D(jj,ii));
+                    Vret(jj,(ii-1)*side+1:side*ii)=eval(V(jj,ii));
+                end
+            end
+            V=sparse(normc(Vret));
+            D=sparse(Dret);
+            
+            
+            V=matrixBuild([],[],[],V);
+            D=matrixBuild([],[],[],D);
+            pos=legth(pos);
+        end
+    end
+end
\ No newline at end of file