📄 pennymelt.m
字号:
function pennymelt(arg)% PENNYMELT Heat a penny.% Finite difference methods for the initial value problem for the% heat equation. The initial height is based on measurements made% at the National Institute of Science and Technology of the depth% of a mold for a U. S. one cent coin. You can choose either explicit% or alternating direction implicit time stepping and either a lighted% surface plot or a contour plot.%% PENNYMELT(delta) uses time step = delta. Default is delta = 0.25.%% What is the limiting value of the height as t -> inf ?% For what values of delta is the computation stable?if nargin == 0 | isa(arg,'double') clf shg load penny fud.U = flipud(P); fud.t = 0; set(gcf,'double','on','name','pennymelt','menu','none', ... 'numbertitle','off','colormap',copper(128),'userdata',fud) if nargin == 0 delta = .250; else delta = arg; end uicontrol('style','toggle','string','run','val',0, ... 'units','norm','pos',[.02 .02 .09 .05],'call','pennymelt(''run'')'); uicontrol('style','toggle','string','reset','val',0, ... 'units','norm','pos',[.12 .02 .09 .05],'call','pennymelt(''reset'')'); uicontrol('style','toggle','string','pause','val',1, ... 'units','norm','pos',[.22 .02 .09 .05],'call','pennymelt(''pause'')'); uicontrol('style','toggle','string','surf','val',1, ... 'units','norm','pos',[.34 .02 .09 .05],'call','pennymelt(''surf'')'); uicontrol('style','toggle','string','contour','val',0, ... 'units','norm','pos',[.44 .02 .09 .05],'call','pennymelt(''contour'')'); uicontrol('style','toggle','string','explicit','val',1, ... 'units','norm','pos',[.56 .02 .09 .05],'call','pennymelt(''explicit'')'); uicontrol('style','toggle','string','adi','val',0, ... 'units','norm','pos',[.66 .02 .09 .05],'call','pennymelt(''adi'')'); uicontrol('tag','delta','units','norm','pos',[.78 .02 .16 .05], ... 'style','edit','string',sprintf('delta = %7.3f',delta)) uicontrol('units','norm','pos',[.945 .020 .03 .025], ... 'string','-','fontsize',12,'callback','pennymelt(''delta-'')') uicontrol('units','norm','pos',[.945 .045 .03 .025], ... 'string','+','fontsize',12,'callback','pennymelt(''delta+'')') uicontrol('style','toggle','units','norm','pos',[.88 .93 .10 .05], ... 'string','close','tag','klose','call','pennymelt(''close'')') arg = 'surf';endif isequal(arg,'reset') fud = get(gcf,'userdata'); load penny fud.U = flipud(P); fud.t = 0; set(gcf,'userdata',fud) set(findobj('string','run'),'value',0) set(findobj('string','pause'),'value',0) if get(findobj('string','surf'),'value') == 1 arg = 'surf'; else arg = 'contour'; endendif isequal(arg,'close') run = findobj('string','run'); if get(run,'value') == 1 set(run,'value',0) else close(gcf) end returnendif isequal(arg,'pause') | isequal(arg,'run') pausep = isequal(arg,'pause'); if pausep set(findobj('string','run'),'value',0) set(findobj('string','reset'),'value',0) return else set(findobj('string','pause'),'value',0) set(findobj('string','reset'),'value',0) endendif isequal(arg,'surf') | isequal(arg,'contour') fud = get(gcf,'userdata'); U = fud.U; t = fud.t; if isequal(arg,'surf') set(findobj('string','contour'),'value',0) drawnow % Lighted surface plot surfu = surf(U); daspect([1,1,128]) colormap(copper) shading interp material metal lighting gouraud view(2) axis tight axis off set(gca,'zlimmode','auto','climmode','manual'); light('pos',[1,2,2000],'style','inf'); titl = title(sprintf('t = %10.3f',t)); set(surfu,'userdata',titl); set(gca,'userdata',surfu) elseif norm(del2(U)) > 2500 contour(U,[0 128]); text(10,60,{'del2(U) is too large', ... 'contour(U) takes too much time','revert to surf'}, ... 'color','red','fontsize',20) set(findobj('string','run'),'value',0) set(findobj('string','pause'),'value',1) set(findobj('string','contour'),'value',0) set(findobj('string','surf'),'value',1) else set(findobj('string','surf'),'value',0) drawnow % Contour plot contour(U,1:12:255); axis square set(gca,'xtick',[],'ytick',[]) title(sprintf('t = %10.3f',t)) end drawnow returnendif isequal(arg,'explicit') | isequal(arg,'adi') adi = isequal(arg,'adi'); if adi set(findobj('string','explicit'),'value',0) else set(findobj('string','adi'),'value',0) end returnendif isequal(arg,'delta+') | isequal(arg,'delta-') deltabox = findobj('tag','delta'); str = get(deltabox,'string'); k = strfind(str,'='); if ~isempty(k), str = str(k+1:end); end temp = str2num(str); if isequal(arg,'delta+') temp = temp + .001; else temp = temp - .001; end if isempty(temp) set(deltabox,'string',sprintf('delta = ???')) else delta = temp; set(deltabox,'string',sprintf('delta = %7.3f',delta)) end returnendrun = findobj('string','run');while get(run,'value') == 1 fud = get(gcf,'userdata'); U = fud.U; t = fud.t; % Finite difference indices [p,q] = size(U); n = [2:p p]; s = [1 1:p-1]; e = [2:q q]; w = [1 1:q-1]; deltabox = findobj('tag','delta'); str = get(deltabox,'string'); k = strfind(str,'='); if ~isempty(k), str = str(k+1:end); end temp = str2num(str); if isempty(temp) set(deltabox,'string',sprintf('delta = ???')) else delta = temp; set(deltabox,'string',sprintf('delta = %7.3f',delta)) end h = 1; sigma = delta/h^2; % Tridiagonal coefficients a = -sigma*ones(p,1); b = (1+2*sigma)*ones(p,1); c = a; % Diffusion if get(findobj('string','explicit'),'value') == 1 % Explicit U = U + sigma*(U(n,:)+U(s,:)+U(:,e)+U(:,w)-4*U); t = t + delta; else % Alternating Directions Implicit (ADI) for i = 1:p d = sigma*U(i,e) + (1-2*sigma)*U(i,:) + sigma*U(i,w); d(1) = d(1) + sigma*U(i,1); d(p) = d(p) + sigma*U(i,p); U(i,:) = tridisolve(a,b,c,d); end t = t + delta/2; for j = 1:p d = sigma*U(n,j) + (1-2*sigma)*U(:,j) + sigma*U(s,j); d(1) = d(1) + sigma*U(1,j); d(p) = d(p) + sigma*U(p,j); U(:,j) = tridisolve(a,b,c,d); end t = t + delta/2; end % Plot result if get(findobj('string','surf'),'value') == 1 surfu = get(gca,'userdata'); if isempty(surfu) pennymelt('surf') end surfu = get(gca,'userdata'); set(surfu,'zdata',U,'cdata',U) titl = get(surfu,'userdata'); set(titl,'string',sprintf('t = %10.3f',t)); elseif norm(del2(U)) > 2500 text(10,60,{'del2(U) is too large', ... 'contour(U) takes too much time','revert to surf'}, ... 'color','red','fontsize',20) set(findobj('string','run'),'value',0) set(findobj('string','pause'),'value',1) set(findobj('string','contour'),'value',0) set(findobj('string','surf'),'value',1) else contour(U,1:12:255); axis square set(gca,'xtick',[],'ytick',[]) title(sprintf('t = %10.3f %10.3f',t)); end fud.U = U; fud.t = t; set(gcf,'userdata',fud) drawnowendklose = findobj('tag','klose');if ~isempty(klose) & get(klose,'value') == 1 close(gcf)end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -