Mercurial > repos > public > sbplib
view +scheme/Hypsyst3dCurve.m @ 577:e45c9b56d50d feature/grids
Add an Empty grid class
The need turned up for the flexural code when we may or may not have a grid for the open water and want to plot that solution.
In case there is no open water we need an empty grid to plot the empty gridfunction against to avoid errors.
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Thu, 07 Sep 2017 09:16:12 +0200 |
parents | 9d1fc984f40d |
children | feebfca90080 459eeb99130f |
line wrap: on
line source
classdef Hypsyst3dCurve < scheme.Scheme properties m % Number of points in each direction, possibly a vector n %size of system h % Grid spacing X, Y, Z% Values of x and y for each grid point Yx, Zx, Xy, Zy, Xz, Yz %Grid values for boundary surfaces xi,eta,zeta Xi, Eta, Zeta Eta_xi, Zeta_xi, Xi_eta, Zeta_eta, Xi_zeta, Eta_zeta % Metric terms X_xi, X_eta, X_zeta,Y_xi,Y_eta,Y_zeta,Z_xi,Z_eta,Z_zeta % Metric terms order % Order accuracy for the approximation D % non-stabalized scheme operator Aevaluated, Bevaluated, Cevaluated, Eevaluated % Numeric Coeffiecient matrices Ahat, Bhat, Chat % Symbolic Transformed Coefficient matrices A, B, C, E % Symbolic coeffiecient matrices J, Ji % JAcobian and inverse Jacobian H % Discrete norm % Norms in the x, y and z directions Hxii,Hetai,Hzetai, Hzi % Kroneckerd norms. 1'*Hx*v corresponds to integration in the x dir. Hxi,Heta,Hzeta I_xi,I_eta,I_zeta, I_N,onesN e_w, e_e, e_s, e_n, e_b, e_t index_w, index_e,index_s,index_n, index_b, index_t params %parameters for the coeficient matrice end methods function obj = Hypsyst3dCurve(m, order, A, B,C, E, params,ti,operator) xilim ={0 1}; etalim = {0 1}; zetalim = {0 1}; if length(m) == 1 m = [m m m]; end m_xi = m(1); m_eta = m(2); m_zeta = m(3); m_tot = m_xi*m_eta*m_zeta; obj.params = params; obj.n = length(A(obj,0,0,0)); obj.m = m; obj.order = order; obj.onesN = ones(obj.n); switch operator case 'upwind' ops_xi = sbp.D1Upwind(m_xi,xilim,order); ops_eta = sbp.D1Upwind(m_eta,etalim,order); ops_zeta = sbp.D1Upwind(m_zeta,zetalim,order); case 'standard' ops_xi = sbp.D2Standard(m_xi,xilim,order); ops_eta = sbp.D2Standard(m_eta,etalim,order); ops_zeta = sbp.D2Standard(m_zeta,zetalim,order); otherwise error('Operator not available') end obj.xi = ops_xi.x; obj.eta = ops_eta.x; obj.zeta = ops_zeta.x; obj.Xi = kr(obj.xi,ones(m_eta,1),ones(m_zeta,1)); obj.Eta = kr(ones(m_xi,1),obj.eta,ones(m_zeta,1)); obj.Zeta = kr(ones(m_xi,1),ones(m_eta,1),obj.zeta); [X,Y,Z] = ti.map(obj.Xi,obj.Eta,obj.Zeta); obj.X = X; obj.Y = Y; obj.Z = Z; I_n = eye(obj.n); I_xi = speye(m_xi); obj.I_xi = I_xi; I_eta = speye(m_eta); obj.I_eta = I_eta; I_zeta = speye(m_zeta); obj.I_zeta = I_zeta; I_N=kr(I_n,I_xi,I_eta,I_zeta); O_xi = ones(m_xi,1); O_eta = ones(m_eta,1); O_zeta = ones(m_zeta,1); obj.Hxi = ops_xi.H; obj.Heta = ops_eta.H; obj.Hzeta = ops_zeta.H; obj.h = [ops_xi.h ops_eta.h ops_zeta.h]; switch operator case 'upwind' D1_xi = kr((ops_xi.Dp+ops_xi.Dm)/2, I_eta,I_zeta); D1_eta = kr(I_xi, (ops_eta.Dp+ops_eta.Dm)/2,I_zeta); D1_zeta = kr(I_xi, I_eta,(ops_zeta.Dp+ops_zeta.Dm)/2); otherwise D1_xi = kr(ops_xi.D1, I_eta,I_zeta); D1_eta = kr(I_xi, ops_eta.D1,I_zeta); D1_zeta = kr(I_xi, I_eta,ops_zeta.D1); end obj.A = A; obj.B = B; obj.C = C; obj.X_xi = D1_xi*X; obj.X_eta = D1_eta*X; obj.X_zeta = D1_zeta*X; obj.Y_xi = D1_xi*Y; obj.Y_eta = D1_eta*Y; obj.Y_zeta = D1_zeta*Y; obj.Z_xi = D1_xi*Z; obj.Z_eta = D1_eta*Z; obj.Z_zeta = D1_zeta*Z; obj.Ahat = @transform_coefficient_matrix; obj.Bhat = @transform_coefficient_matrix; obj.Chat = @transform_coefficient_matrix; obj.E = @(obj,x,y,z,~,~,~,~,~,~)E(obj,x,y,z); obj.Aevaluated = obj.evaluateCoefficientMatrix(obj.Ahat,obj.X, obj.Y,obj.Z, obj.X_eta,obj.X_zeta,obj.Y_eta,obj.Y_zeta,obj.Z_eta,obj.Z_zeta); obj.Bevaluated = obj.evaluateCoefficientMatrix(obj.Bhat,obj.X, obj.Y,obj.Z, obj.X_zeta,obj.X_xi,obj.Y_zeta,obj.Y_xi,obj.Z_zeta,obj.Z_xi); obj.Cevaluated = obj.evaluateCoefficientMatrix(obj.Chat,obj.X,obj.Y,obj.Z, obj.X_xi,obj.X_eta,obj.Y_xi,obj.Y_eta,obj.Z_xi,obj.Z_eta); switch operator case 'upwind' clear D1_xi D1_eta D1_zeta alphaA = max(abs(eig(obj.Ahat(obj,obj.X(end), obj.Y(end),obj.Z(end), obj.X_eta(end),obj.X_zeta(end),obj.Y_eta(end),obj.Y_zeta(end),obj.Z_eta(end),obj.Z_zeta(end))))); alphaB = max(abs(eig(obj.Bhat(obj,obj.X(end), obj.Y(end),obj.Z(end), obj.X_zeta(end),obj.X_xi(end),obj.Y_zeta(end),obj.Y_xi(end),obj.Z_zeta(end),obj.Z_xi(end))))); alphaC = max(abs(eig(obj.Chat(obj,obj.X(end), obj.Y(end),obj.Z(end), obj.X_xi(end),obj.X_eta(end),obj.Y_xi(end),obj.Y_eta(end),obj.Z_xi(end),obj.Z_eta(end))))); Ap = (obj.Aevaluated+alphaA*I_N)/2; Dmxi = kr(I_n, ops_xi.Dm, I_eta,I_zeta); diffSum = -Ap*Dmxi; clear Ap Dmxi Am = (obj.Aevaluated-alphaA*I_N)/2; obj.Aevaluated = []; Dpxi = kr(I_n, ops_xi.Dp, I_eta,I_zeta); temp = Am*Dpxi; diffSum = diffSum-temp; clear Am Dpxi Bp = (obj.Bevaluated+alphaB*I_N)/2; Dmeta = kr(I_n, I_xi, ops_eta.Dm,I_zeta); temp = Bp*Dmeta; diffSum = diffSum-temp; clear Bp Dmeta Bm = (obj.Bevaluated-alphaB*I_N)/2; obj.Bevaluated = []; Dpeta = kr(I_n, I_xi, ops_eta.Dp,I_zeta); temp = Bm*Dpeta; diffSum = diffSum-temp; clear Bm Dpeta Cp = (obj.Cevaluated+alphaC*I_N)/2; Dmzeta = kr(I_n, I_xi, I_eta,ops_zeta.Dm); temp = Cp*Dmzeta; diffSum = diffSum-temp; clear Cp Dmzeta Cm = (obj.Cevaluated-alphaC*I_N)/2; clear I_N obj.Cevaluated = []; Dpzeta = kr(I_n, I_xi, I_eta,ops_zeta.Dp); temp = Cm*Dpzeta; diffSum = diffSum-temp; clear Cm Dpzeta temp obj.J = obj.X_xi.*obj.Y_eta.*obj.Z_zeta... +obj.X_zeta.*obj.Y_xi.*obj.Z_eta... +obj.X_eta.*obj.Y_zeta.*obj.Z_xi... -obj.X_xi.*obj.Y_zeta.*obj.Z_eta... -obj.X_eta.*obj.Y_xi.*obj.Z_zeta... -obj.X_zeta.*obj.Y_eta.*obj.Z_xi; obj.Ji = kr(I_n,spdiags(1./obj.J,0,m_tot,m_tot)); obj.Eevaluated = obj.evaluateCoefficientMatrix(obj.E, obj.X, obj.Y,obj.Z,[],[],[],[],[],[]); obj.D = obj.Ji*diffSum-obj.Eevaluated; case 'standard' D1_xi = kr(I_n,D1_xi); D1_eta = kr(I_n,D1_eta); D1_zeta = kr(I_n,D1_zeta); obj.J = obj.X_xi.*obj.Y_eta.*obj.Z_zeta... +obj.X_zeta.*obj.Y_xi.*obj.Z_eta... +obj.X_eta.*obj.Y_zeta.*obj.Z_xi... -obj.X_xi.*obj.Y_zeta.*obj.Z_eta... -obj.X_eta.*obj.Y_xi.*obj.Z_zeta... -obj.X_zeta.*obj.Y_eta.*obj.Z_xi; obj.Ji = kr(I_n,spdiags(1./obj.J,0,m_tot,m_tot)); obj.Eevaluated = obj.evaluateCoefficientMatrix(obj.E, obj.X, obj.Y,obj.Z,[],[],[],[],[],[]); obj.D = obj.Ji*(-obj.Aevaluated*D1_xi-obj.Bevaluated*D1_eta -obj.Cevaluated*D1_zeta)-obj.Eevaluated; otherwise error('Operator not supported') end obj.Hxii = kr(I_n, ops_xi.HI, I_eta,I_zeta); obj.Hetai = kr(I_n, I_xi, ops_eta.HI,I_zeta); obj.Hzetai = kr(I_n, I_xi,I_eta, ops_zeta.HI); obj.index_w = (kr(ops_xi.e_l, O_eta,O_zeta)==1); obj.index_e = (kr(ops_xi.e_r, O_eta,O_zeta)==1); obj.index_s = (kr(O_xi, ops_eta.e_l,O_zeta)==1); obj.index_n = (kr(O_xi, ops_eta.e_r,O_zeta)==1); obj.index_b = (kr(O_xi, O_eta, ops_zeta.e_l)==1); obj.index_t = (kr(O_xi, O_eta, ops_zeta.e_r)==1); obj.e_w = kr(I_n, ops_xi.e_l, I_eta,I_zeta); obj.e_e = kr(I_n, ops_xi.e_r, I_eta,I_zeta); obj.e_s = kr(I_n, I_xi, ops_eta.e_l,I_zeta); obj.e_n = kr(I_n, I_xi, ops_eta.e_r,I_zeta); obj.e_b = kr(I_n, I_xi, I_eta, ops_zeta.e_l); obj.e_t = kr(I_n, I_xi, I_eta, ops_zeta.e_r); obj.Eta_xi = kr(obj.eta,ones(m_xi,1)); obj.Zeta_xi = kr(ones(m_eta,1),obj.zeta); obj.Xi_eta = kr(obj.xi,ones(m_zeta,1)); obj.Zeta_eta = kr(ones(m_xi,1),obj.zeta); obj.Xi_zeta = kr(obj.xi,ones(m_eta,1)); obj.Eta_zeta = kr(ones(m_zeta,1),obj.eta); end function [ret] = transform_coefficient_matrix(obj,x,y,z,x_1,x_2,y_1,y_2,z_1,z_2) ret = obj.A(obj,x,y,z).*(y_1.*z_2-z_1.*y_2); ret = ret+obj.B(obj,x,y,z).*(x_2.*z_1-x_1.*z_2); ret = ret+obj.C(obj,x,y,z).*(x_1.*y_2-x_2.*y_1); 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. function [closure, penalty] = boundary_condition(obj,boundary,type,L) default_arg('type','char'); BM = boundary_matrices(obj,boundary); switch type case{'c','char'} [closure,penalty] = boundary_condition_char(obj,BM); case{'general'} [closure,penalty] = boundary_condition_general(obj,BM,boundary,L); 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 % Evaluates the symbolic Coeffiecient matrix mat function [ret] = evaluateCoefficientMatrix(obj,mat, X, Y, Z , x_1 , x_2 , y_1 , y_2 , z_1 , z_2) params = obj.params; side = max(length(X),length(Y)); if isa(mat,'function_handle') [rows,cols] = size(mat(obj,0,0,0,0,0,0,0,0,0)); x_1 = kr(obj.onesN,x_1); x_2 = kr(obj.onesN,x_2); y_1 = kr(obj.onesN,y_1); y_2 = kr(obj.onesN,y_2); z_1 = kr(obj.onesN,z_1); z_2 = kr(obj.onesN,z_2); matVec = mat(obj,X',Y',Z',x_1',x_2',y_1',y_2',z_1',z_2'); matVec = sparse(matVec); else matVec = mat; [rows,cols] = size(matVec); side = max(length(X),length(Y)); cols = cols/side; end matVec(abs(matVec)<10^(-10)) = 0; ret = cell(rows,cols); for ii = 1:rows for jj = 1:cols ret{ii,jj} = diag(matVec(ii,(jj-1)*side+1:jj*side)); end end ret = cell2mat(ret); end function [BM] = boundary_matrices(obj,boundary) params = obj.params; BM.boundary = boundary; switch boundary case {'w','W','west'} BM.e_ = obj.e_w; mat = obj.Ahat; BM.boundpos = 'l'; BM.Hi = obj.Hxii; BM.index = obj.index_w; BM.x_1 = obj.X_eta(BM.index); BM.x_2 = obj.X_zeta(BM.index); BM.y_1 = obj.Y_eta(BM.index); BM.y_2 = obj.Y_zeta(BM.index); BM.z_1 = obj.Z_eta(BM.index); BM.z_2 = obj.Z_zeta(BM.index); case {'e','E','east'} BM.e_ = obj.e_e; mat = obj.Ahat; BM.boundpos = 'r'; BM.Hi = obj.Hxii; BM.index = obj.index_e; BM.x_1 = obj.X_eta(BM.index); BM.x_2 = obj.X_zeta(BM.index); BM.y_1 = obj.Y_eta(BM.index); BM.y_2 = obj.Y_zeta(BM.index); BM.z_1 = obj.Z_eta(BM.index); BM.z_2 = obj.Z_zeta(BM.index); case {'s','S','south'} BM.e_ = obj.e_s; mat = obj.Bhat; BM.boundpos = 'l'; BM.Hi = obj.Hetai; BM.index = obj.index_s; BM.x_1 = obj.X_zeta(BM.index); BM.x_2 = obj.X_xi(BM.index); BM.y_1 = obj.Y_zeta(BM.index); BM.y_2 = obj.Y_xi(BM.index); BM.z_1 = obj.Z_zeta(BM.index); BM.z_2 = obj.Z_xi(BM.index); case {'n','N','north'} BM.e_ = obj.e_n; mat = obj.Bhat; BM.boundpos = 'r'; BM.Hi = obj.Hetai; BM.index = obj.index_n; BM.x_1 = obj.X_zeta(BM.index); BM.x_2 = obj.X_xi(BM.index); BM.y_1 = obj.Y_zeta(BM.index); BM.y_2 = obj.Y_xi(BM.index); BM.z_1 = obj.Z_zeta(BM.index); BM.z_2 = obj.Z_xi(BM.index); case{'b','B','Bottom'} BM.e_ = obj.e_b; mat = obj.Chat; BM.boundpos = 'l'; BM.Hi = obj.Hzetai; BM.index = obj.index_b; BM.x_1 = obj.X_xi(BM.index); BM.x_2 = obj.X_eta(BM.index); BM.y_1 = obj.Y_xi(BM.index); BM.y_2 = obj.Y_eta(BM.index); BM.z_1 = obj.Z_xi(BM.index); BM.z_2 = obj.Z_eta(BM.index); case{'t','T','Top'} BM.e_ = obj.e_t; mat = obj.Chat; BM.boundpos = 'r'; BM.Hi = obj.Hzetai; BM.index = obj.index_t; BM.x_1 = obj.X_xi(BM.index); BM.x_2 = obj.X_eta(BM.index); BM.y_1 = obj.Y_xi(BM.index); BM.y_2 = obj.Y_eta(BM.index); BM.z_1 = obj.Z_xi(BM.index); BM.z_2 = obj.Z_eta(BM.index); end [BM.V,BM.Vi,BM.D,signVec] = obj.matrixDiag(mat,obj.X(BM.index),obj.Y(BM.index),obj.Z(BM.index),... BM.x_1,BM.x_2,BM.y_1,BM.y_2,BM.z_1,BM.z_2); BM.side = sum(BM.index); BM.pos = signVec(1); BM.zeroval=signVec(2); BM.neg=signVec(3); end % Characteristic boundary condition function [closure, penalty] = boundary_condition_char(obj,BM) side = BM.side; pos = BM.pos; neg = BM.neg; zeroval = BM.zeroval; V = BM.V; Vi = BM.Vi; Hi = BM.Hi; D = BM.D; e_ = BM.e_; switch BM.boundpos case {'l'} tau = sparse(obj.n*side,pos); Vi_plus = Vi(1:pos,:); tau(1:pos,:) = -abs(D(1:pos,1:pos)); closure = Hi*e_*V*tau*Vi_plus*e_'; penalty = -Hi*e_*V*tau*Vi_plus; case {'r'} tau = sparse(obj.n*side,neg); tau((pos+zeroval)+1:obj.n*side,:) = -abs(D((pos+zeroval)+1:obj.n*side,(pos+zeroval)+1:obj.n*side)); Vi_minus = Vi((pos+zeroval)+1:obj.n*side,:); closure = Hi*e_*V*tau*Vi_minus*e_'; penalty = -Hi*e_*V*tau*Vi_minus; end end % General boundary condition in the form Lu=g(x) function [closure,penalty] = boundary_condition_general(obj,BM,boundary,L) side = BM.side; pos = BM.pos; neg = BM.neg; zeroval = BM.zeroval; V = BM.V; Vi = BM.Vi; Hi = BM.Hi; D = BM.D; e_ = BM.e_; index = BM.index; switch BM.boundary case{'b','B','bottom'} Ji_vec = diag(obj.Ji); Ji = diag(Ji_vec(index)); Zeta_x = Ji*(obj.Y_xi(index).*obj.Z_eta(index)-obj.Z_xi(index).*obj.Y_eta(index)); Zeta_y = Ji*(obj.X_eta(index).*obj.Z_xi(index)-obj.X_xi(index).*obj.Z_eta(index)); Zeta_z = Ji*(obj.X_xi(index).*obj.Y_eta(index)-obj.Y_xi(index).*obj.X_eta(index)); L = obj.evaluateCoefficientMatrix(L,Zeta_x,Zeta_y,Zeta_z,[],[],[],[],[],[]); end switch BM.boundpos case {'l'} tau = sparse(obj.n*side,pos); Vi_plus = Vi(1:pos,:); Vi_minus = Vi(pos+zeroval+1:obj.n*side,:); V_plus = V(:,1:pos); V_minus = V(:,(pos+zeroval)+1:obj.n*side); tau(1:pos,:) = -abs(D(1:pos,1:pos)); R = -inv(L*V_plus)*(L*V_minus); closure = Hi*e_*V*tau*(Vi_plus-R*Vi_minus)*e_'; penalty = -Hi*e_*V*tau*inv(L*V_plus)*L; case {'r'} tau = sparse(obj.n*side,neg); tau((pos+zeroval)+1:obj.n*side,:) = -abs(D((pos+zeroval)+1:obj.n*side,(pos+zeroval)+1:obj.n*side)); Vi_plus = Vi(1:pos,:); Vi_minus = Vi((pos+zeroval)+1:obj.n*side,:); V_plus = V(:,1:pos); V_minus = V(:,(pos+zeroval)+1:obj.n*side); R = -inv(L*V_minus)*(L*V_plus); closure = Hi*e_*V*tau*(Vi_minus-R*Vi_plus)*e_'; penalty = -Hi*e_*V*tau*inv(L*V_minus)*L; end end % Function that diagonalizes a symbolic matrix A as A=V*D*Vi % D is a diagonal matrix with the eigenvalues on A on the diagonal sorted by their sign % [d+ ] % D = [ d0 ] % [ d-] % signVec is a vector specifying the number of possitive, zero and negative eigenvalues of D function [V,Vi, D,signVec] = matrixDiag(obj,mat,x,y,z,x_1,x_2,y_1,y_2,z_1,z_2) params = obj.params; eps = 10^(-10); if(sum(abs(x_1))>eps) syms x_1s else x_1s = 0; end if(sum(abs(x_2))>eps) syms x_2s; else x_2s = 0; end if(sum(abs(y_1))>eps) syms y_1s else y_1s = 0; end if(sum(abs(y_2))>eps) syms y_2s; else y_2s = 0; end if(sum(abs(z_1))>eps) syms z_1s else z_1s = 0; end if(sum(abs(z_2))>eps) syms z_2s; else z_2s = 0; end syms xs ys zs [V, D] = eig(mat(obj,xs,ys,zs,x_1s,x_2s,y_1s,y_2s,z_1s,z_2s)); Vi = inv(V); xs = x; ys = y; zs = z; x_1s = x_1; x_2s = x_2; y_1s = y_1; y_2s = y_2; z_1s = z_1; z_2s = z_2; side = max(length(x),length(y)); Dret = zeros(obj.n,side*obj.n); Vret = zeros(obj.n,side*obj.n); Viret = zeros(obj.n,side*obj.n); for ii=1:obj.n for jj=1:obj.n Dret(jj,(ii-1)*side+1:side*ii) = eval(D(jj,ii)); Vret(jj,(ii-1)*side+1:side*ii) = eval(V(jj,ii)); Viret(jj,(ii-1)*side+1:side*ii) = eval(Vi(jj,ii)); end end D = sparse(Dret); V = sparse(Vret); Vi = sparse(Viret); V = obj.evaluateCoefficientMatrix(V,x,y,z,x_1,x_2,y_1,y_2,z_1,z_2); D = obj.evaluateCoefficientMatrix(D,x,y,z,x_1,x_2,y_1,y_2,z_1,z_2); Vi = obj.evaluateCoefficientMatrix(Vi,x,y,z,x_1,x_2,y_1,y_2,z_1,z_2); DD = diag(D); poseig = (DD>0); zeroeig = (DD==0); negeig = (DD<0); D = diag([DD(poseig); DD(zeroeig); DD(negeig)]); V = [V(:,poseig) V(:,zeroeig) V(:,negeig)]; Vi = [Vi(poseig,:); Vi(zeroeig,:); Vi(negeig,:)]; signVec = [sum(poseig),sum(zeroeig),sum(negeig)]; end end end