📄 navier2d.m
字号:
function Navier2d
% This is the GUI for Navier2d.
%
% Type "navier2d" to start the program.
%
% See the *.pdf tutorial for more information.
%
% The actual Navier-Stokes solver is in tvd_rk2.m and is where most of
% the work is done, although the mesh based data structures are setup
% in this function.
%
%
% Darren Engwirda - 2006
%
% Naver2d is Copyright (C) 2005-2006 Darren Engwirda. See "copyright.m" for
% full details.
clc, close all
% All units "normalized"
% GUI data structure
data = struct('buttons' ,[], ...
'init' ,[], ... % Initial conditions & flow variables
'animation',[], ... % Animation settings
'settings' ,[], ... % Integration settings
'mesh' ,[], ... % Mesh data
'bc' ,[], ... % Boundary conditions
'flag' ,[]); % Edges marked for lift/drag calc
% Main window
set(figure(1), ...
'Name' ,'Navier2d' , ...
'Units' ,'Normalized', ...
'NumberTitle','Off' , ...
'UserData',data); axis off
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Frames
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
frmcol = [0.9,0.9,0.825];
% Mesh frame
mfrm = [0.1,0.6,0.35,0.3];
uicontrol('Style' ,'Frame' , ...
'Units' ,'Normalized' , ...
'Position' ,mfrm , ...
'BackgroundColor',frmcol);
% BC frame
bfrm = [0.1,0.2,0.35,0.3];
uicontrol('Style' ,'Frame' , ...
'Units' ,'Normalized' , ...
'Position' ,bfrm , ...
'BackgroundColor',frmcol);
% Integration frame
ifrm = [0.55,0.6,0.35,0.3];
uicontrol('Style' ,'Frame' , ...
'Units' ,'Normalized' , ...
'Position' ,ifrm , ...
'BackgroundColor',frmcol);
% Animation frame
afrm = [0.55,0.2,0.35,0.3];
uicontrol('Style' ,'Frame' , ...
'Units' ,'Normalized' , ...
'Position' ,afrm , ...
'BackgroundColor',frmcol);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Frame Headers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Mesh
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[mfrm(1:2)+0.05,mfrm(3:4)-0.1], ...
'String' ,'Mesh Options' , ...
'FontSize' ,12 , ...
'BackgroundColor',frmcol);
% Integration
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[ifrm(1:2)+0.05,ifrm(3:4)-0.1], ...
'String' ,'Integration Settings' , ...
'FontSize' ,12 , ...
'BackgroundColor',frmcol);
% Boundary conditions
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[bfrm(1:2)+0.05,bfrm(3:4)-0.1], ...
'String' ,'Boundary Conditions' , ...
'FontSize' ,12 , ...
'BackgroundColor',frmcol);
% Animation Settings
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[afrm(1:2)+0.05,afrm(3:4)-0.1], ...
'String' ,'Animation Settings' , ...
'FontSize' ,12 , ...
'BackgroundColor',frmcol);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Buttons
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
btnx = 0.1;
btny = 0.05;
% Integration settings
data.button(1) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[ifrm(1)+0.05,ifrm(2)+0.05,btnx,btny], ...
'String' ,'Set' , ...
'Callback',@set_integration);
% Main run
data.button(2) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[0.45,0.05,btnx,btny], ...
'String' ,'Run' , ...
'Callback',@run);
% Load mesh
data.button(3) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[mfrm(1)+0.025,mfrm(2)+0.05,btnx,btny], ...
'String' ,'Load' , ...
'Callback',@load_mesh);
% Show mesh
data.button(5) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[mfrm(1)+0.125,mfrm(2)+0.05,btnx,btny], ...
'String' ,'View' , ...
'Callback',@show_mesh);
% Median mesh
data.button(6) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[mfrm(1)+0.225,mfrm(2)+0.05,btnx,btny], ...
'String' ,'Median' , ...
'Callback',@show_median);
% Set boundary conditions
data.button(7) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[bfrm(1)+0.075,bfrm(2)+0.05,btnx+0.1,btny], ...
'String' ,'Velocity/Pressure' , ...
'Callback',@set_bc);
% Animation select
data.button(8) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[afrm(1)+0.05,afrm(2)+0.125,btnx,btny], ...
'String' ,'Set' , ...
'Callback',@set_anim);
% Main help button
data.button(9) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[0.8,0.05,btnx,btny], ...
'String' ,'Help' , ...
'Callback',@help_main);
% Initial conditions
data.button(10) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[ifrm(1)+0.05,ifrm(2)+0.125,btnx,btny], ...
'String' ,'Initial' , ...
'Callback',@init);
% Animation popup
data.button(11) = uicontrol('Style' ,'Popup' , ...
'Units' ,'Normalized' , ...
'Position' ,[afrm(1)+0.2,afrm(2)+0.125,btnx+0.025,btny], ...
'String' ,{'Mesh';'Surf';'Contour'} , ...
'BackgroundColor' ,frmcol);
% Animation popup
data.button(12) = uicontrol('Style' ,'Popup' , ...
'Units' ,'Normalized' , ...
'Position' ,[afrm(1)+0.2,afrm(2)+0.05,btnx+0.025,btny], ...
'String' ,{'2D view','3D view'} , ...
'BackgroundColor' ,frmcol);
% Save
data.button(15) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[0.1,0.05,btnx,btny], ...
'String' ,'Save' , ...
'Callback',@save_data);
% Flow type (UVP, tracer, thermal coupled)
data.button(16) = uicontrol('Style' ,'Popup' , ...
'Units' ,'Normalized' , ...
'Position' ,[ifrm(1)+0.2,ifrm(2)+0.125,btnx+0.025,btny], ...
'String' ,{'Normal','Tracer','Thermal'} , ...
'BackgroundColor' ,frmcol);
% Set boundary conditions (tracer)
data.button(17) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[bfrm(1)+0.125,bfrm(2)+0.125,btnx,btny], ...
'String' ,'Tracer' , ...
'Callback',@set_bc_tracer);
% Select edges for lift/drag calculation
data.button(18) = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[afrm(1)+0.05,afrm(2)+0.05,btnx,btny], ...
'String' ,'Monitors' , ...
'Callback',@residuals);
% Pass button handles
set(figure(1),'UserData',data);
% GNU Copyright
copyright = {'Navier2d version 2.3, Copyright (C) 2005-2006 Darren Engwirda.'
''
'Navier2d comes with ABSOLUTELY NO WARRANTY; for details see the'
'GNU license included. This is free software, and you are welcome to'
'redistribute it under certain conditions; see the GNU license for details.'
};
uiwait(msgbox(copyright,'Copyright','none'));
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function save_data(varargin)
% Save flow data
data = get(figure(1),'UserData');
if ~isfield(data.init,'time')
errordlg('Simulation has not been run.','Error')
return
end
% Load vars into current workspace
p = data.mesh.p;
t = data.mesh.t;
U = data.init.U;
V = data.init.V;
S = data.init.S;
P = data.init.P;
W = data.init.W;
time = data.init.time;
resx = data.init.resx;
resy = data.init.resy;
% Clear others
clear('data'); clear('varargin');
% Prompt for save dlg
uisave
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function set_integration(varargin)
% Prompt user for the integration settings
% Get current GUI data
data = get(figure(1),'UserData');
prompts = {'Maximum number of steps'
'Maximum integration time (seconds)'
'CFL Number'
'Kinematic viscosity (m^2/s)'
'Output frequency (steps)'
'Kinematic viscosity (m^2/s) (tracer)'
'Temperature/velocity coupling'};
% Default answers
if isempty(data.settings)
defaults = {'100','Inf','1.0','0.01','25','0.01','1'};
else
for k = 1:length(prompts)
defaults{k} = num2str(data.settings(k));
end
end
% Prompt for user input
settings = inputdlg(prompts,'Integration Settings',1,defaults);
% Convert to double
if ~isempty(settings)
data.settings = str2double(settings);
else
return
end
% Set new GUI data
set(figure(1),'UserData',data);
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function init(varargin)
% Prompt for initial conditions
% Get GUI data
data = get(figure(1),'UserData');
if isempty(data.mesh)
errordlg('Mesh file has not been loaded.','Error')
return
end
% Prompt
init = inputdlg({'U velocity (m/s)'; 'V velocity (m/s)'; 'S (tracer)'}, ...
'Initial Conditions (Use ".*" and "./" in functions!)',1,{'0'; '0'; '0'});
% Nodes
x = data.mesh.p(:,1);
y = data.mesh.p(:,2);
numn = length(x);
% Convert to double
if ~isempty(init)
% Evaluate inputs
if checkvar(init{1}), U = eval(init{1}); else return, end
if checkvar(init{2}), V = eval(init{2}); else return, end
if checkvar(init{3}), S = eval(init{3}); else return, end
% Deal with scalar inputs
if numel(U)==1
U = repmat(U,numn,1);
end
if numel(V)==1
V = repmat(V,numn,1);
end
if numel(S)==1
S = repmat(S,numn,1);
end
else
return
end
% UVP fields
data.init.U = U;
data.init.V = V;
data.init.S = S;
data.init.P = repmat(0,numn,1);
% Set new GUI data
set(figure(1),'UserData',data);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -