📄 navier2d.m
字号:
'gradient' ,gradient);
% Set GUI data
set(gcf,'UserData',bcdata);
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function help_bc(varargin)
% Quick help for the BC window
helptext = {'Quick help for boundary conditions.'
''
['This console shows the boundary edges of the mesh, with the ' , ...
'edge midpoints plotted. Boundary conditions must be specified ', ...
'for each edge.']
''
['Edges are first selected using the mouse by pressing the ' , ...
'"Select" button. Multiple edges can be selected/de-selected ', ...
'using this mode. "Clear" will clear the selection.']
''
['Boundary conditions are then specified for the highlighted edges ', ...
'by pressing the "Set" button. This will prompt the user for the ', ...
'boundary condition type.']
''
'Velocity boundary conditions are used when the velocity is known'
'Pressure boundary conditions are used for outlets/outflows'
''
['If a velocity type is chosen the user is then asked to enter the ', ...
'xy velocity components.']
''
'Velocity conditions are shown in blue, pressure conditions in green.'
''
'Boundary conditions can be reassigned.'
};
uiwait(msgbox(helptext,'Help','none'));
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function clear_sel(varargin)
% Clear current mouse selection
% Get GUI data
fig = gcf;
ax = gca;
bcdata = get(fig,'UserData');
% Boundary edge geometry
e = bcdata.e;
be = bcdata.be;
p = bcdata.p;
pe = bcdata.pe;
pm = 0.5*(p(e(be,1),:)+p(e(be,2),:));
% Clear selection
in = false(size(pm,1),1);
bcdata.in = in;
% Plot midpoints
plot(pe(bcdata.unassigned,1),pe(bcdata.unassigned,2),'k.', ...
pe(bcdata.velocity,1) ,pe(bcdata.velocity,2) ,'b.', ...
pe(bcdata.pressure,1) ,pe(bcdata.pressure,2) ,'g.', ...
pe(bcdata.gradient,1) ,pe(bcdata.gradient,2) ,'y.', ...
pm(in,1) ,pm(in,2) ,'r.');
set(fig,'UserData',bcdata);
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function select(varargin)
% Select boundary midpoints using the mouse
% Get GUI data
fig = gcf;
ax = gca;
bcdata = get(fig,'UserData');
% Boundary edge geometry
e = bcdata.e;
be = bcdata.be;
p = bcdata.p;
pe = bcdata.pe;
in = bcdata.in;
pm = 0.5*(p(e(be,1),:)+p(e(be,2),:));
% Plot midpoints
plot(pe(bcdata.unassigned,1),pe(bcdata.unassigned,2),'k.', ...
pe(bcdata.velocity,1) ,pe(bcdata.velocity,2) ,'b.', ...
pe(bcdata.pressure,1) ,pe(bcdata.pressure,2) ,'g.', ...
pe(bcdata.gradient,1) ,pe(bcdata.gradient,2) ,'y.', ...
pm(in,1) ,pm(in,2) ,'r.');
title('Right click to confirm')
% Set mouse to "crosshair"
set(fig,'Pointer','crosshair');
while true
% Wait for mouse click
waitforbuttonpress
% Grab type of mouse click
btn = get(fig,'SelectionType');
if strcmp(btn,'normal')
% Draw selection box
p1 = get(ax,'CurrentPoint');
rbbox
p2 = get(ax,'CurrentPoint');
% xy co-ords within axis
p1 = p1(1,1:2); p2 = p2(1,1:2);
% Sorted (left, right, bottom, top)
x1 = min(p1(1),p2(1)); x2 = max(p1(1),p2(1));
y1 = min(p1(2),p2(2)); y2 = max(p1(2),p2(2));
% Find nodes within selection
in = xor((pm(:,1)>=x1&pm(:,1)<=x2&pm(:,2)>=y1&pm(:,2)<=y2),in);
% Show selected
plot(pe(bcdata.unassigned,1),pe(bcdata.unassigned,2),'k.', ...
pe(bcdata.velocity,1) ,pe(bcdata.velocity,2) ,'b.', ...
pe(bcdata.pressure,1) ,pe(bcdata.pressure,2) ,'g.', ...
pe(bcdata.gradient,1) ,pe(bcdata.gradient,2) ,'y.', ...
pm(in,1) ,pm(in,2) ,'r.');
else
break
end
end
bcdata.in = in; title('')
% Pass selection as userdata
set(fig,'UserData',bcdata,'Pointer','arrow');
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bc_type(varargin)
% Set the BC type and value
% Get GUI data from the "set bc" window
fig = gcf;
bcdata = get(fig,'UserData');
% Boundary edge geometry
e = bcdata.e;
be = bcdata.be;
p = bcdata.p;
pe = bcdata.pe;
in = bcdata.in;
pm = 0.5*(p(e(be,1),:)+p(e(be,2),:));
if sum(in)==0
errordlg('No edges selected.')
return
end
% Get main GUI data
data = get(figure(1),'Userdata'); figure(fig);
% Prompt with listbox
[i,ok] = listdlg('PromptString' , 'BC type:' , ...
'Name' , 'Boundary Conditions' , ...
'SelectionMode', 'Single' , ...
'ListString' , {'Velocity','Outflow (extrapolated)','Outflow (fixed pressure)'});
if ok
if i==1 % Velocity
while true
% Prompt for symmetry or wall
[j,ok] = listdlg('PromptString' , 'BC type: (CTRL+click)', ...
'Name' , 'Boundary Conditions' , ...
'ListString' , {'U','dU/dn = 0','V','dV/dn = 0'});
if ~ok
return
end
if length(j)~=2 || (j(1)~=1)&&(j(1)~=2) || (j(2)~=3)&&(j(2)~=4)
uiwait(errordlg('Must make selections for U and V','Error'));
else
break
end
end
% BC type
if j(1)==2, utype = 0; else utype = 1; end
if j(2)==4, vtype = 0; else vtype = 1; end
% Prompt for user input
if (utype==1) && (vtype==1)
value = inputdlg({'U velocity (m/s)','V velocity (m/s)'},'Velocity components',1,{'0','0'});
elseif utype==1
value = inputdlg('U velocity (m/s)','Velocity components',1,{'0'});
elseif vtype==1
value = inputdlg('V velocity (m/s)','Velocity components',1,{'0'});
else
value = ['0','0'];
end
% Convert to double
if ~isempty(value)
value = str2double(value);
if (utype==1) && (vtype==0), value = [value,0]; end
if (vtype==1) && (utype==0), value = [0,value]; end
% Assign to main GUI data
data.bc(be(in),1:6) = repmat([utype,value(1),vtype,value(2),0,0],sum(in),1);
else
return
end
else % Pressure
if i==2
% Assign to main GUI data
data.bc(be(in),1:6) = repmat([0,0,0,0,2,0],sum(in),1); % Extrapolated BC
else
% Assign to main GUI data
data.bc(be(in),1:6) = repmat([0,0,0,0,1,0],sum(in),1); % Fixed pressure BC
end
end
end
% Re-evaluate
boundary = false(size(e,1),1);
boundary(be) = true;
unassigned = data.bc(:,1)==-1 & boundary;
velocity = data.bc(:,1)== 1;
pressure = data.bc(:,5) > 0;
gradient = xor(data.bc(:,1),data.bc(:,3));
% Clear selection
in = false(size(pm,1),1);
bcdata.in = in;
bcdata.unassigned = unassigned;
bcdata.velocity = velocity;
bcdata.pressure = pressure;
bcdata.gradient = gradient;
% Plot midpoints
hold off
plot(pe(bcdata.unassigned,1),pe(bcdata.unassigned,2),'k.', ...
pe(bcdata.velocity,1) ,pe(bcdata.velocity,2) ,'b.', ...
pe(bcdata.pressure,1) ,pe(bcdata.pressure,2) ,'g.', ...
pe(bcdata.gradient,1) ,pe(bcdata.gradient,2) ,'y.', ...
pm(in,1) ,pm(in,2) ,'r.'), axis equal, axis off, hold on
% Plot edges
patch('faces',e(unassigned,:),'vertices',data.mesh.p,'facecolor','none','edgecolor','k');
patch('faces',e(velocity,:) ,'vertices',data.mesh.p,'facecolor','none','edgecolor','b');
patch('faces',e(pressure,:) ,'vertices',data.mesh.p,'facecolor','none','edgecolor','g');
patch('faces',e(gradient,:) ,'vertices',data.mesh.p,'facecolor','none','edgecolor','y');
% Plot arrows for velocity type
if any(velocity)
quiver(pe(velocity,1),pe(velocity,2),data.bc(velocity,2),data.bc(velocity,4))
end
set(fig,'UserData',bcdata);
% Set main GUI data
set(figure(1),'UserData',data); figure(fig)
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function set_bc_tracer(varargin)
% Set the boundary conditions
data = get(figure(1),'UserData');
if isempty(data.mesh)
errordlg('No mesh file loaded.','Error')
return
end
set(figure, ...
'Name' ,'Boundary Conditions (tracer)', ...
'DoubleBuffer','On' , ...
'Units' ,'Normalized');
axes('Units' ,'Normalized', ...
'Position',[0.25,0.1,0.7,0.8]);
btnx = 0.1;
btny = 0.05;
% Buttons
b1 = uicontrol('Style','PushButton' , ...
'Units','Normalized' , ...
'Position',[0.05,0.3,btnx,btny], ...
'String','Select' , ...
'Callback',@select);
b2 = uicontrol('Style','PushButton' , ...
'Units','Normalized' , ...
'Position',[0.05,0.1,btnx,btny], ...
'String','Set' , ...
'Callback',@bc_type_tracer);
b3 = uicontrol('Style','PushButton' , ...
'Units','Normalized' , ...
'Position',[0.05,0.2,btnx,btny], ...
'String','Clear' , ...
'Callback',@clear_sel);
b4 = uicontrol('Style' ,'PushButton' , ...
'Units' ,'Normalized' , ...
'Position',[0.05,0.4,btnx,btny], ...
'String' ,'Help' , ...
'Callback',@help_bc);
% Headers
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[0.025,0.8,0.2,0.05], ...
'String' ,'Black = Unassigned', ...
'BackgroundColor',[0.8,0.8,0.8]);
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[0.025,0.75,0.2,0.05], ...
'String' ,'Blue = Value' , ...
'BackgroundColor',[0.8,0.8,0.8]);
uicontrol('Style' ,'Text' , ...
'Units' ,'Normalized' , ...
'Position' ,[0.025,0.7,0.2,0.05], ...
'String' ,'Yellow = Gradient' , ...
'BackgroundColor',[0.8,0.8,0.8]);
% Boundary edge geometry
e = data.mesh.e;
be = data.mesh.be;
p = data.mesh.p;
pe = data.mesh.pe;
pm = 0.5*(p(e(be,1),:)+p(e(be,2),:));
boundary = false(size(e,1),1);
pressure = boundary; % "Pressure" type doesn't exist for tracer. Set = false
boundary(be) = true;
unassigned = data.bc(:,7)==-1 & boundary;
velocity = data.bc(:,7)== 1; % Re-use "velocity" as value so that the other
gradient = data.bc(:,7)== 0; % sub-functions will work...
% Plot midpoints
plot(pe(unassigned,1),pe(unassigned,2),'k.', ...
pe(velocity,1) ,pe(velocity,2) ,'b.', ...
pe(gradient,1) ,pe(gradient,2) ,'y.'), axis equal, axis off, hold on
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -