⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdegui.m

📁 有趣的可视的数值方法 出自网站http://www.mathworks.com/moler
💻 M
字号:
function pdegui(action)%PDEGUI  Demonstrate solution of model partial differential equations.% PDEGUI demonstrates the finite difference solution of model problems% involving Laplace's operator:%      del^2_U = partial^2_U/partial_x^2 + partial^2_U/partial_y^2.%% The PDEs are:%      Poisson equation, del^2_U = f, f = -1.%      Heat equation, partial_U/dt = del^2_U - f.%      Wave equation, partial^2_U/partial_t^2 = del^2_U.%      Eigenvalue equation, del^2_U + lambda U = 0.%% The regions are: %      Square.%      L-shaped.%      H-shaped.%      Disc.%      Annulus.%      Heart.%      An pair of "isospectral" drums with the same eigenvalues.%% The boundary values are u = 0 outside the region.  The initial values for% the heat and wave equations are impulses at random points in the region.% You can vary the grid spacing, h.  Decreasing h increases accuracy,% but also increases memory requirements and computation time.% For the heat equation, you can set sigma = delta_t/h^2.% For the wave equation, you can set sigma = delta_t^2/h^2.% If sigma is too large, the time-stepping methods are unstable.% For the eigenvalue problem, you can set the eigenvalue index.if nargin == 0   Initialize_GUI   action = 'restart';enddrawnowif isequal(action,'restart') | ...   isequal(action,'h+') | isequal(action,'h-')   % Find the buttons   regionobj = findobj('tag','region');   regionstr = get(regionobj,'string');   region = regionstr{get(regionobj,'value')};   eqnobj = findobj('tag','eqn');   eqn = get(eqnobj,'value');   hobj = findobj('tag','h');   sigind = findobj('tag','sigind');   indxobj = findobj('tag','indx');   sigmaobj = findobj('tag','sigma');   plusobj = findobj('tag','plus');   minusobj = findobj('tag','minus');   stopobj = findobj('string','stop');   % Set button visibility    switch eqn      case {1,5}  % Poisson, Grid         set([sigind,indxobj,sigmaobj,plusobj,minusobj,stopobj],'vis','off');      case 2      % Heat         set(sigind,'vis','on','string','sigma =');         set(indxobj,'vis','off');         set(sigmaobj,'vis','on','string','0.250','userdata',0.250);         set([plusobj,minusobj,stopobj],'vis','on');      case 3      % Wave         set(sigind,'vis','on','string','sigma =');         set(indxobj,'vis','off');         set(sigmaobj,'vis','on','string','0.500','userdata',0.500);         set([plusobj,minusobj,stopobj],'vis','on');      case 4      % Eigenvalue         set(sigind,'vis','on','string','index =');         set([sigmaobj,stopobj],'vis','off');         set([indxobj,plusobj,minusobj],'vis','on');   end   % Adjust h   h = str2num(get(hobj,'string'));   if isequal(action,'h+')      h = 1/round(1/h+3);      set(hobj,'string',sprintf('1/%.0f',1/h))   elseif isequal(action,'h-') & (h < 1/3)      h = 1/round(1/h-3);      set(hobj,'string',sprintf('1/%.0f',1/h))   end   % Generate the mesh   [x,y] = meshgrid(-1:h:1);   [xv,yv,scale] = vertices(region);   [in,on] = inregion(x,y,xv,yv);   if isequal(region,'Annulus')      in = in - inregion(x,y,xv/2,yv/2);      xv = [xv NaN xv/2];      yv = [yv NaN yv/2];   end   p = find(in-on);   G = zeros(size(x));   G(p) = 1:length(p);      % Generate the discrete Laplacian.   A = -delsq(G);   n = size(A,1)      % Initialize the solution   t = 0;   lambda = [];   switch eqn      case {2,3}      % Heat, Wave         p = find(G>0);         n = length(p);         q = ceil(n*rand);         x0 = x(p(q));         y0 = y(p(q));         r = (x(p)-x0).^2 + (y(p)-y0).^2;         if eqn == 2, c = 1; else c = 1/6; end         u = c*exp(-5*r);         v = zeros(n,1);      otherwise         u = [];         v = [];   end   % Save everything in figure's userdata.   data.eqn = eqn; data.G = G; data.A = A; data.x = x; data.y = y;   data.h = h; data.n = n; data.u = u; data.v = v; data.t = t;   data.lambda = lambda; data.xv = xv; data.yv = yv; data.scale = scale;   set(gcf,'userdata',data);else   % Adjust sigma or index.   eqn = get(findobj('tag','eqn'),'value');   if eqn == 4      indxobj = findobj('tag','indx');      indx = str2num(get(indxobj,'string'));      if isequal(action,'+')         indx = indx + 1;      elseif isequal(action,'-')         indx = max(1,indx - 1);      end      set(indxobj,'string',int2str(indx));   else      sigmaobj = findobj('tag','sigma');      sigma = str2num(get(sigmaobj,'string'));      if isequal(action,'+')         sigma = sigma + .001;      elseif isequal(action,'-')         sigma = sigma - .001;      end      set(sigmaobj,'string',sprintf('%6.3f',sigma));   endend% Retrieve parameters      data = get(gcf,'userdata');A = data.A; u = data.u; v = data.v; t = data.t; scale = data.scale;n = data.n; h = data.h; x = data.x; y = data.y; G = data.G;xv = data.xv; yv = data.yv;% Begin main loopstopobj = findobj('string','stop');closeobj = findobj('string','close');set(stopobj,'userdata',0)set(closeobj,'vis','off')while get(stopobj,'userdata') == 0   switch eqn      case 1         % Solve sparse linear system Au = f with f = -1,         % scaled so that max(abs(u)) = 1.         f = -h^2*scale*ones(n,1);         u = A\f;         set(stopobj,'userdata',1)      case 2         % One step for heat equation         sigmaobj = findobj('tag','sigma');         sigma = str2num(get(sigmaobj,'string'));         f = -h^2*scale*ones(n,1);         t = t + sigma*h^2;         u = u + sigma*(A*u - f);         data.t = t;         data.u = u;      case 3         % One step for wave equation         sigmaobj = findobj('tag','sigma');         sigma = str2num(get(sigmaobj,'string'));         t = t + sqrt(sigma)*h;         w = u;         u = 2*u - v + sigma*A*u;         v = w;         data.t = t;         data.u = u;         data.v = v;      case 4         % Some eigenvalues already computed; maybe need more.         indxobj = findobj('tag','indx');         indx = str2num(get(indxobj,'string'));         if indx >= n            indx = n-1;            set(indxobj,'string',num2str(n-1))         end         while indx > length(data.lambda)            k = min(length(data.lambda)+10,n-1);            [u,lambda] = eigswatch(-(1/h^2)*A,k);            data.lambda = lambda;            data.u = u;          end         lambda = data.lambda(indx);         u = data.u(:,indx);         u = u/u(min(find(abs(u(:))==max(abs(u(:))))));         set(stopobj,'userdata',1)      case 5         % Show grid, no computation         u = ones(n,1);         set(stopobj,'userdata',1)   end   % Map the solution onto the grid and display it.   U = zeros(size(x));   p = find(G>0);   U(p) = u;   U(U>1) = 1;   U(U<-1) = -1;   set(gcf,'renderer','painters')   if eqn < 5      contourf(x,y,U,-1:1/8:1)   else      ms = max(4,min(14,ceil(100*h)));      plot(x(p),y(p),'.','markersize',ms,'color',[0 2/3 0])   end   line(xv,yv,'color','black')   set(gca,'color',get(gcf,'color'),'xtick',[],'ytick',[])   axis square   caxis([-1 1])   switch eqn      case {2,3}         xlabel(sprintf('t = %9.4f',t));      case 4         xlabel(sprintf('lambda(%2d) = %9.4f',indx,lambda))      case 5         xlabel(sprintf('n = %.0f',n));      otherwise   end   drawnow   set(gcf,'userdata',data)endset(stopobj,'vis','off')set(closeobj,'vis','on')% ------------------------------------------------------------------------function Initialize_GUIclf resetset(gcf,'doublebuffer','on','menubar','none', ...   'numbertitle','off','name','PDE gui','userdata',1);set(gca,'pos',[.11 .11 .6 .815])uicontrol( ...     'tag','region', ...     'style','list', ...     'units','normal', ...     'position',[.75 .55 .23 .35], ...     'string',{'Square','L','H','Disc','Annulus', ...        'Heart','Drum1','Drum2'}, ...     'fontsize',12, ...     'value',1, ...     'callback','pdegui(''restart'')')uicontrol( ...     'tag','eqn', ...     'style','list', ...     'units','normal', ...     'position',[.75 .30 .23 .22], ...     'string',{'Poisson','Heat','Wave','Eigenvalue','Grid'}, ...     'fontsize',12, ...     'value',1, ...     'callback','pdegui(''restart'')')uicontrol( ...     'style','text', ...     'units','normal', ...     'position',[.75 .22 .10 .06], ...     'background',get(gcf,'color'), ...     'string','   h = ', ...     'fontsize',12)uicontrol( ...     'tag','h', ...     'style','edit', ...     'units','normal', ...     'position',[.85 .22 .08 .06], ...     'string','1/24', ...     'backgroundcolor',[1 1 1], ...     'fontsize',12, ...     'callback','pdegui(''restart'')')uicontrol( ...     'tag','hminus', ...     'style','pushbutton', ...     'units','normal', ...     'position',[.93 .22 .03 .03], ...     'string','-', ...     'fontsize',12, ...     'callback','pdegui(''h-'')')uicontrol( ...     'tag','hplus', ...     'style','pushbutton', ...     'units','normal', ...     'position',[.93 .25 .03 .03], ...     'string','+', ...     'fontsize',12, ...     'callback','pdegui(''h+'')')uicontrol( ...     'tag','sigind', ...     'style','text', ...     'units','normal', ...     'position',[.75 .14 .10 .06], ...     'background',get(gcf,'color'), ...     'string','', ...     'fontsize',12)uicontrol( ...     'tag','indx', ...     'style','edit', ...     'units','normal', ...     'position',[.85 .14 .08 .06], ...     'string','1', ...     'userdata',1, ...     'backgroundcolor',[1 1 1], ...     'fontsize',12, ...     'callback','pdegui(''indx'')')uicontrol( ...     'tag','sigma', ...     'style','edit', ...     'units','normal', ...     'position',[.85 .14 .08 .06], ...     'string','0.250', ...     'userdata',0.250, ...     'backgroundcolor',[1 1 1], ...     'fontsize',12);uicontrol( ...     'tag','minus', ...     'style','pushbutton', ...     'units','normal', ...     'position',[.93 .14 .03 .03], ...     'string','-', ...     'fontsize',12, ...     'callback','pdegui(''-'')')uicontrol( ...     'tag','plus', ...     'style','pushbutton', ...     'units','normal', ...     'position',[.93 .17 .03 .03], ...     'string','+', ...     'fontsize',12, ...     'callback','pdegui(''+'')')uicontrol( ...     'style','pushbutton', ...     'units','normal', ...     'position',[.80 .05 .12 .06], ...     'string','stop', ...     'fontsize',12, ...     'userdata',0, ...     'callback','set(findobj(''string'',''stop''),''userdata'',1)');uicontrol( ...     'style','toggle', ...     'units','normal', ...     'position',[.80 .05 .12 .06], ...     'string','close', ...     'fontsize',12, ...     'userdata',0, ...     'callback','close(gcf)');% ------------------------------------------------------------------------function [u,lambda] = eigswatch(A,k)% [u,lambda] = eigswatch(A,k)% Modify pointer and text while computing k smallest% eigenvalues and eigenvectors of sparse matrix A.ps = get(gcf,'pointer');set(gcf,'pointer','watch')sigind = findobj('tag','sigind');str = get(sigind,'string');set(sigind,'string','computing')drawnowopts.disp = 0;[u,lambda] = eigs(A,k,0,opts);[lambda,p] = sort(diag(lambda));u = u(:,p);set(sigind,'string',str)set(gcf,'pointer',ps)% ------------------------------------------------------------------------function [xv,yv,scale] = vertices(region)% (xv,yv) = vertices of where region% scale = max(U) where del^2 U = -1 in region.switch region   case 'Square'      xv = [-1 1 1 -1 -1];      yv = [-1 -1 1 1 -1];      scale = 3.394;    case 'L'      xv = [0 1 1 -1 -1 0 0];      yv = [0 0 1 1 -1 -1 0];      scale = 6.702;   case 'H'      xv = [0 1 1 2 2 1 1 -1 -1 -2 -2 -1 -1 0]/2;       yv = [1 1 2 2 -2 -2 -1 -1 -2 -2 2 2 1 1]/2;      scale = 8.387;   case 'Disc'      z = exp(2*pi*i*(0:128)/128);      xv = real(z);      yv = imag(z);      scale = 3.960;   case 'Annulus'      z = exp(2*pi*i*(0:128)/128);      xv = real(z);      yv = imag(z);      scale = 30.12;   case 'Heart'      t = 0:pi/64:pi;      xv = sin(t);      yv = sin(t)-2*cos(t)/3;      xv = [-fliplr(xv) xv];      yv = [fliplr(yv) yv]-1/3;       scale = 8.926;   case 'Drum1'      xv = [-3 -3 1 1 3 1 -1 -1 -3]/3;      yv = [-3 -1 3 1 1 -1 -1 -3 -3]/3;      scale = 14.96;   case 'Drum2'      xv = [-1 -3 -3 1 1 3 1 -1 -1]/3;      yv = [-3 -1 1 1 3 1 -1 -1 -3]/3;      scale = 15.35;end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -