现在出现了关于MATLAB应用的三个问题:矩阵奇异警告、数值输入框居中对齐问题,以及仿真后无图像显示,请你帮我修复并给出完整的代码,源代码如下classdef ChladniLab < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
GridLayout matlab.ui.container.GridLayout
LeftPanel matlab.ui.container.Panel
MaterialPanel matlab.ui.container.Panel
DensityEditFieldLabel matlab.ui.control.Label
DensityEditField matlab.ui.control.NumericEditField
PoissonRatioEditFieldLabel matlab.ui.control.Label
PoissonRatioEditField matlab.ui.control.NumericEditField
ElasticEditFieldLabel matlab.ui.control.Label
ElasticEditField matlab.ui.control.NumericEditField
PlatePanel matlab.ui.container.Panel
LengthEditFieldLabel matlab.ui.control.Label
LengthEditField matlab.ui.control.NumericEditField
ThicknessEditFieldLabel matlab.ui.control.Label
ThicknessEditField matlab.ui.control.NumericEditField
VibrationPanel matlab.ui.container.Panel
FrequencyEditFieldLabel matlab.ui.control.Label
FrequencyEditField matlab.ui.control.NumericEditField
AmplitudeEditFieldLabel matlab.ui.control.Label
AmplitudeEditField matlab.ui.control.NumericEditField
SimulationPanel matlab.ui.container.Panel
ResolutionEditFieldLabel matlab.ui.control.Label
ResolutionEditField matlab.ui.control.NumericEditField
SimTimeEditFieldLabel matlab.ui.control.Label
SimTimeEditField matlab.ui.control.NumericEditField
ControlPanel matlab.ui.container.Panel
RunButton matlab.ui.control.Button
StopButton matlab.ui.control.Button
ResetButton matlab.ui.control.Button
RightPanel matlab.ui.container.Panel
UIAxes matlab.ui.control.UIAxes
ModeDropDownLabel matlab.ui.control.Label
ModeDropDown matlab.ui.control.DropDown
StatusLabel matlab.ui.control.Label
ProgressBar matlab.ui.control.Label
end
% 应用状态属性
properties (Access = private)
Running = false; % 仿真运行状态
StopRequested = false; % 停止请求标志
LastResult; % 存储上次仿真结果
end
% 回调方法
methods (Access = private)
% 创建UI组件
function createComponents(app)
% 创建主窗口
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [100 100 1200 700];
app.UIFigure.Name = 'Chladni Lab - 克拉尼图形仿真平台';
app.UIFigure.Resize = 'on'; % 允许窗口调整大小
% 创建主网格布局
app.GridLayout = uigridlayout(app.UIFigure, [1, 2]);
app.GridLayout.ColumnWidth = {'1x', '2x'};
app.GridLayout.RowHeight = {'1x'};
app.GridLayout.ColumnSpacing = 10;
app.GridLayout.RowSpacing = 10;
app.GridLayout.Padding = [10 10 10 10];
% 创建左侧面板
app.LeftPanel = uipanel(app.GridLayout);
app.LeftPanel.Layout.Row = 1;
app.LeftPanel.Layout.Column = 1;
app.LeftPanel.Title = '控制面板';
app.LeftPanel.FontWeight = 'bold';
app.LeftPanel.Scrollable = 'on';
% 创建左侧垂直网格布局 (替代 uix.VBox)
leftGrid = uigridlayout(app.LeftPanel, [5, 1]);
leftGrid.RowHeight = {120, 100, 100, 100, 'fit'};
leftGrid.ColumnWidth = {'1x'};
leftGrid.Padding = [10 10 10 10];
leftGrid.RowSpacing = 15;
% 创建材料参数面板
app.MaterialPanel = uipanel(leftGrid);
app.MaterialPanel.Layout.Row = 1;
app.MaterialPanel.Layout.Column = 1;
app.MaterialPanel.Title = '材料参数';
app.MaterialPanel.BackgroundColor = [0.96 0.96 0.96];
app.MaterialPanel.FontWeight = 'bold';
materialGrid = uigridlayout(app.MaterialPanel, [3, 2]);
materialGrid.ColumnWidth = {'1x', '1.5x'};
materialGrid.RowHeight = repmat({'fit'}, 1, 3);
materialGrid.Padding = [10 10 10 10];
% 密度输入
app.DensityEditFieldLabel = uilabel(materialGrid);
app.DensityEditFieldLabel.HorizontalAlignment = 'right';
app.DensityEditFieldLabel.Layout.Row = 1;
app.DensityEditFieldLabel.Layout.Column = 1;
app.DensityEditFieldLabel.Text = '密度 (kg/m³)';
app.DensityEditField = uieditfield(materialGrid, 'numeric');
app.DensityEditField.Limits = [1 20000];
app.DensityEditField.Value = 2700;
app.DensityEditField.Layout.Row = 1;
app.DensityEditField.Layout.Column = 2;
app.DensityEditField.Tag = 'density';
% 泊松比输入
app.PoissonRatioEditFieldLabel = uilabel(materialGrid);
app.PoissonRatioEditFieldLabel.HorizontalAlignment = 'right';
app.PoissonRatioEditFieldLabel.Layout.Row = 2;
app.PoissonRatioEditFieldLabel.Layout.Column = 1;
app.PoissonRatioEditFieldLabel.Text = '泊松比';
app.PoissonRatioEditField = uieditfield(materialGrid, 'numeric');
app.PoissonRatioEditField.Limits = [0.1 0.5];
app.PoissonRatioEditField.Value = 0.33;
app.PoissonRatioEditField.Layout.Row = 2;
app.PoissonRatioEditField.Layout.Column = 2;
app.PoissonRatioEditField.Tag = 'poisson';
% 弹性模量输入
app.ElasticEditFieldLabel = uilabel(materialGrid);
app.ElasticEditFieldLabel.HorizontalAlignment = 'right';
app.ElasticEditFieldLabel.Layout.Row = 3;
app.ElasticEditFieldLabel.Layout.Column = 1;
app.ElasticEditFieldLabel.Text = '弹性模量 (Pa)';
app.ElasticEditField = uieditfield(materialGrid, 'numeric');
app.ElasticEditField.Limits = [1e9 500e9];
app.ElasticEditField.Value = 70e9;
app.ElasticEditField.Layout.Row = 3;
app.ElasticEditField.Layout.Column = 2;
app.ElasticEditField.Tag = 'elastic';
% 创建平板参数面板
app.PlatePanel = uipanel(leftGrid);
app.PlatePanel.Layout.Row = 2;
app.PlatePanel.Layout.Column = 1;
app.PlatePanel.Title = '平板参数';
app.PlatePanel.BackgroundColor = [0.96 0.96 0.96];
app.PlatePanel.FontWeight = 'bold';
plateGrid = uigridlayout(app.PlatePanel, [2, 2]);
plateGrid.ColumnWidth = {'1x', '1.5x'};
plateGrid.RowHeight = repmat({'fit'}, 1, 2);
plateGrid.Padding = [10 10 10 10];
% 边长输入
app.LengthEditFieldLabel = uilabel(plateGrid);
app.LengthEditFieldLabel.HorizontalAlignment = 'right';
app.LengthEditFieldLabel.Layout.Row = 1;
app.LengthEditFieldLabel.Layout.Column = 1;
app.LengthEditFieldLabel.Text = '边长 (m)';
app.LengthEditField = uieditfield(plateGrid, 'numeric');
app.LengthEditField.Limits = [0.01 1];
app.LengthEditField.Value = 0.15;
app.LengthEditField.Layout.Row = 1;
app.LengthEditField.Layout.Column = 2;
app.LengthEditField.Tag = 'length';
% 厚度输入
app.ThicknessEditFieldLabel = uilabel(plateGrid);
app.ThicknessEditFieldLabel.HorizontalAlignment = 'right';
app.ThicknessEditFieldLabel.Layout.Row = 2;
app.ThicknessEditFieldLabel.Layout.Column = 1;
app.ThicknessEditFieldLabel.Text = '厚度 (m)';
app.ThicknessEditField = uieditfield(plateGrid, 'numeric');
app.ThicknessEditField.Limits = [0.0001 0.1];
app.ThicknessEditField.Value = 0.001;
app.ThicknessEditField.Layout.Row = 2;
app.ThicknessEditField.Layout.Column = 2;
app.ThicknessEditField.Tag = 'thickness';
% 创建振动参数面板
app.VibrationPanel = uipanel(leftGrid);
app.VibrationPanel.Layout.Row = 3;
app.VibrationPanel.Layout.Column = 1;
app.VibrationPanel.Title = '振动参数';
app.VibrationPanel.BackgroundColor = [0.96 0.96 0.96];
app.VibrationPanel.FontWeight = 'bold';
vibrationGrid = uigridlayout(app.VibrationPanel, [2, 2]);
vibrationGrid.ColumnWidth = {'1x', '1.5x'};
vibrationGrid.RowHeight = repmat({'fit'}, 1, 2);
vibrationGrid.Padding = [10 10 10 10];
% 频率输入
app.FrequencyEditFieldLabel = uilabel(vibrationGrid);
app.FrequencyEditFieldLabel.HorizontalAlignment = 'right';
app.FrequencyEditFieldLabel.Layout.Row = 1;
app.FrequencyEditFieldLabel.Layout.Column = 1;
app.FrequencyEditFieldLabel.Text = '频率 (Hz)';
app.FrequencyEditField = uieditfield(vibrationGrid, 'numeric');
app.FrequencyEditField.Limits = [1 5000];
app.FrequencyEditField.Value = 650;
app.FrequencyEditField.Layout.Row = 1;
app.FrequencyEditField.Layout.Column = 2;
app.FrequencyEditField.Tag = 'frequency';
% 振幅输入
app.AmplitudeEditFieldLabel = uilabel(vibrationGrid);
app.AmplitudeEditFieldLabel.HorizontalAlignment = 'right';
app.AmplitudeEditFieldLabel.Layout.Row = 2;
app.AmplitudeEditFieldLabel.Layout.Column = 1;
app.AmplitudeEditFieldLabel.Text = '振幅 (m)';
app.AmplitudeEditField = uieditfield(vibrationGrid, 'numeric');
app.AmplitudeEditField.Limits = [0.001 0.1];
app.AmplitudeEditField.Value = 0.01;
app.AmplitudeEditField.Layout.Row = 2;
app.AmplitudeEditField.Layout.Column = 2;
app.AmplitudeEditField.Tag = 'amplitude';
% 创建仿真参数面板
app.SimulationPanel = uipanel(leftGrid);
app.SimulationPanel.Layout.Row = 4;
app.SimulationPanel.Layout.Column = 1;
app.SimulationPanel.Title = '仿真参数';
app.SimulationPanel.BackgroundColor = [0.96 0.96 0.96];
app.SimulationPanel.FontWeight = 'bold';
simGrid = uigridlayout(app.SimulationPanel, [2, 2]);
simGrid.ColumnWidth = {'1x', '1.5x'};
simGrid.RowHeight = repmat({'fit'}, 1, 2);
simGrid.Padding = [10 10 10 10];
% 分辨率输入
app.ResolutionEditFieldLabel = uilabel(simGrid);
app.ResolutionEditFieldLabel.HorizontalAlignment = 'right';
app.ResolutionEditFieldLabel.Layout.Row = 1;
app.ResolutionEditFieldLabel.Layout.Column = 1;
app.ResolutionEditFieldLabel.Text = '网格分辨率';
app.ResolutionEditField = uieditfield(simGrid, 'numeric');
app.ResolutionEditField.Limits = [4 32];
app.ResolutionEditField.RoundFractionalValues = 'on';
app.ResolutionEditField.Value = 16;
app.ResolutionEditField.Layout.Row = 1;
app.ResolutionEditField.Layout.Column = 2;
app.ResolutionEditField.Tag = 'resolution';
% 仿真时间输入
app.SimTimeEditFieldLabel = uilabel(simGrid);
app.SimTimeEditFieldLabel.HorizontalAlignment = 'right';
app.SimTimeEditFieldLabel.Layout.Row = 2;
app.SimTimeEditFieldLabel.Layout.Column = 1;
app.SimTimeEditFieldLabel.Text = '仿真时间 (s)';
app.SimTimeEditField = uieditfield(simGrid, 'numeric');
app.SimTimeEditField.Limits = [0.01 1];
app.SimTimeEditField.Value = 0.03;
app.SimTimeEditField.Layout.Row = 2;
app.SimTimeEditField.Layout.Column = 2;
app.SimTimeEditField.Tag = 'simtime';
% 创建控制按钮面板
app.ControlPanel = uipanel(leftGrid);
app.ControlPanel.Layout.Row = 5;
app.ControlPanel.Layout.Column = 1;
app.ControlPanel.BackgroundColor = [0.96 0.96 0.96];
app.ControlPanel.FontWeight = 'bold';
controlGrid = uigridlayout(app.ControlPanel, [1, 3]);
controlGrid.ColumnWidth = {'1x', '1x', '1x'};
controlGrid.RowHeight = {'fit'};
controlGrid.Padding = [10 5 10 10];
% 创建控制按钮
app.RunButton = uibutton(controlGrid, 'push');
app.RunButton.ButtonPushedFcn = createCallbackFcn(app, @RunButtonPushed, true);
app.RunButton.Layout.Row = 1;
app.RunButton.Layout.Column = 1;
app.RunButton.Text = '开始仿真';
app.RunButton.BackgroundColor = [0.47 0.67 0.19];
app.RunButton.FontWeight = 'bold';
app.StopButton = uibutton(controlGrid, 'push');
app.StopButton.ButtonPushedFcn = createCallbackFcn(app, @StopButtonPushed, true);
app.StopButton.Layout.Row = 1;
app.StopButton.Layout.Column = 2;
app.StopButton.Text = '停止仿真';
app.RunButton.BackgroundColor = [0.47 0.67 0.19];
app.StopButton.BackgroundColor = [0.85 0.33 0.10];
app.StopButton.FontWeight = 'bold';
app.ResetButton = uibutton(controlGrid, 'push');
app.ResetButton.ButtonPushedFcn = createCallbackFcn(app, @ResetButtonPushed, true);
app.ResetButton.Layout.Row = 1;
app.ResetButton.Layout.Column = 3;
app.ResetButton.Text = '重置参数';
app.ResetButton.FontWeight = 'bold';
% 创建右侧面板
app.RightPanel = uipanel(app.GridLayout);
app.RightPanel.Layout.Row = 1;
app.RightPanel.Layout.Column = 2;
app.RightPanel.Title = '克拉尼图形可视化';
app.RightPanel.FontWeight = 'bold';
% 创建坐标轴
app.UIAxes = uiaxes(app.RightPanel);
app.UIAxes.Position = [50 100 700 550];
title(app.UIAxes, '克拉尼图形')
xlabel(app.UIAxes, 'X (m)')
ylabel(app.UIAxes, 'Y (m)')
colormap(app.UIAxes, 'jet');
colorbar(app.UIAxes);
app.UIAxes.FontSize = 12;
app.UIAxes.TitleFontSizeMultiplier = 1.2;
% 创建显示模式下拉菜单
app.ModeDropDownLabel = uilabel(app.RightPanel);
app.ModeDropDownLabel.HorizontalAlignment = 'right';
app.ModeDropDownLabel.Position = [50 70 100 22];
app.ModeDropDownLabel.Text = '显示模式:';
app.ModeDropDownLabel.FontWeight = 'bold';
app.ModeDropDown = uidropdown(app.RightPanel);
app.ModeDropDown.Items = {'动态波动', '振幅分布', '节点线图'};
app.ModeDropDown.ValueChangedFcn = createCallbackFcn(app, @ModeDropDownValueChanged, true);
app.ModeDropDown.Position = [160 70 150 22];
app.ModeDropDown.Value = '振幅分布';
app.ModeDropDown.FontWeight = 'bold';
% 状态标签
app.StatusLabel = uilabel(app.RightPanel);
app.StatusLabel.Position = [50 40 300 22];
app.StatusLabel.Text = '就绪';
app.StatusLabel.FontSize = 14;
app.StatusLabel.FontWeight = 'bold';
app.StatusLabel.FontColor = [0 0.5 0];
% 进度条
app.ProgressBar = uilabel(app.RightPanel);
app.ProgressBar.Position = [400 40 300 22];
app.ProgressBar.Text = '';
app.ProgressBar.FontSize = 12;
app.ProgressBar.FontWeight = 'bold';
% 显示主窗口
app.UIFigure.Visible = 'on';
end
% 运行按钮回调
function RunButtonPushed(app, ~)
if app.Running
return;
end
% 验证参数
if ~app.validateParameters()
return;
end
app.Running = true;
app.StopRequested = false;
app.StatusLabel.Text = '仿真运行中...';
app.StatusLabel.FontColor = [0 0 1];
app.ProgressBar.Text = '初始化... 0%';
drawnow;
try
% 获取用户输入参数
L = app.LengthEditField.Value;
h = app.ThicknessEditField.Value;
mu = app.PoissonRatioEditField.Value;
rho = app.DensityEditField.Value;
E = app.ElasticEditField.Value;
Amp = app.AmplitudeEditField.Value;
Freq = app.FrequencyEditField.Value;
N = app.ResolutionEditField.Value;
t_end = app.SimTimeEditField.Value;
% 计算弯曲刚度
D = E*h^3/(12*(1-mu^2));
% 构建网格
dt = 1e-6; % 时间步长
dx = L/N; % 网格大小
x = dx*(0:N);
[X,Y] = meshgrid(x,x);
% 初始化位移
[Sq,Bq] = app.Equation_Sq0(N,mu,-Amp); % 调用类方法
U0 = Sq\Bq;
U1 = U0;
U2 = U1;
% 初始化存储
U_Out1 = zeros(N+1,N+1);
U_Out2 = zeros(N+5,N+5);
U_Save = zeros((N+1)^2, 200);
t_Save = 1;
% 准备绘图
cla(app.UIAxes);
hold(app.UIAxes, 'on');
axis(app.UIAxes, 'equal');
% 根据显示模式选择绘图方式
displayMode = app.ModeDropDown.Value;
% 计算动态方程
t_start = 0;
jishu = 1;
totalSteps = round((t_end-t_start)/dt);
progressStep = round(totalSteps/10);
for t_k = t_start:dt:t_end
if app.StopRequested
break;
end
% 更新进度
if mod(jishu, progressStep) == 0
progress = round(jishu/totalSteps * 100);
app.ProgressBar.Text = sprintf('计算中... %d%%', progress);
drawnow;
end
% 0点处的运动位置
u0 = Amp*cos(2*pi*Freq*t_k+pi);
L_Sq = N+5; % 实际计算时网格的尺寸
if jishu == 1 % 第一步计算
[Sq,Bq] = app.Equation_Sq0(N,mu,u0);
for k = 1:L_Sq^2
[r_k,c_k] = ind2sub([L_Sq,L_Sq],k);
if (r_k>=3 && r_k<=L_Sq-2) && (c_k>=3 && c_k<=L_Sq-2)
Sq(k,k) = 20+rho*h*dx^4/D/dt^2;
Sq(k,[k+1,k-1,k+L_Sq,k-L_Sq]) = -8;
Sq(k,[k+L_Sq+1,k+L_Sq-1,k-L_Sq+1,k-L_Sq-1]) = 2;
Sq(k,[k+2,k-2,k-2*L_Sq,k+2*L_Sq]) = 1;
Fd = -100*sign(U2(k)-U1(k))*(U2(k)-U1(k))^2/dt^2;
Bq(k) = dx^4/D*(rho*h/dt^2*(2*U2(k)-U1(k))+Fd);
end
end
Indx_Center = sub2ind([L_Sq,L_Sq],3,3);
Sq(Indx_Center,:) = 0;
Sq(Indx_Center,Indx_Center) = 1;
Bq(Indx_Center) = u0;
else
for k = 1:L_Sq^2
[r_k,c_k] = ind2sub([L_Sq,L_Sq],k);
if (r_k>=3 && r_k<=L_Sq-2) && (c_k>=3 && c_k<=L_Sq-2)
Fd = -100*sign(U2(k)-U1(k))*(U2(k)-U1(k))^2/dt^2;
Bq(k) = dx^4/D*(rho*h/dt^2*(2*U2(k)-U1(k))+Fd);
end
end
Bq(1+2+2*L_Sq) = u0;
end
U3 = Sq\Bq;
U1 = U2;
U2 = U3;
% 储存,用作输出
U_Out2(:) = U3(:);
U_Out = U_Out2(3:end-2,3:end-2);
% 每100步更新一次图形
if mod(jishu,100) == 1
switch displayMode
case '动态波动'
surf(app.UIAxes, X, Y, U_Out);
shading(app.UIAxes, 'interp');
zlim(app.UIAxes, [-0.2 0.2]);
title(app.UIAxes, '平板动态波动');
view(app.UIAxes, 3);
case '振幅分布'
pcolor(app.UIAxes, X, Y, U_Out);
shading(app.UIAxes, 'interp');
title(app.UIAxes, '振幅分布');
colorbar(app.UIAxes);
view(app.UIAxes, 2);
case '节点线图'
contour(app.UIAxes, X, Y, U_Out, 10, 'LineWidth', 1.5);
title(app.UIAxes, '节点线图');
colorbar(app.UIAxes);
view(app.UIAxes, 2);
end
drawnow;
end
jishu = jishu+1;
% 记最后200个数据储存
if jishu+50*200 >= totalSteps
if mod(jishu,50) == 1
U_Save(:,t_Save) = U_Out(:);
t_Save = t_Save+1;
end
end
end
% 保存结果用于后续分析
app.LastResult.X = X;
app.LastResult.Y = Y;
app.LastResult.U_Save = U_Save;
app.LastResult.dx = dx;
app.LastResult.N = N;
% 计算振幅分布
U_Out_A = U_Out;
U_Out_A(:) = max(U_Save,[],2)-min(U_Save,[],2);
U_Out_A2 = [fliplr(U_Out_A(:,2:end)), U_Out_A];
U_Out_A3 = [flipud(U_Out_A2(2:end,:)); U_Out_A2];
app.LastResult.U_Amplitude = U_Out_A3;
app.StatusLabel.Text = '仿真完成!';
app.StatusLabel.FontColor = [0 0.5 0];
app.ProgressBar.Text = '';
catch ME
app.StatusLabel.Text = ['错误: ' ME.message];
app.StatusLabel.FontColor = [1 0 0];
app.ProgressBar.Text = '';
disp(ME.getReport());
end
app.Running = false;
end
% 参数验证
function valid = validateParameters(app)
valid = true;
% 检查网格分辨率是否为偶数
if mod(app.ResolutionEditField.Value, 2) ~= 0
app.StatusLabel.Text = '错误: 网格分辨率必须是偶数';
app.StatusLabel.FontColor = [1 0 0];
valid = false;
return;
end
% 检查时间步长是否合理
if app.SimTimeEditField.Value < 0.01
app.StatusLabel.Text = '错误: 仿真时间必须至少0.01秒';
app.StatusLabel.FontColor = [1 0 0];
valid = false;
return;
end
% 检查频率是否在合理范围内
if app.FrequencyEditField.Value < 1 || app.FrequencyEditField.Value > 5000
app.StatusLabel.Text = '错误: 频率必须在1-5000Hz范围内';
app.StatusLabel.FontColor = [1 0 0];
valid = false;
return;
end
end
% 停止按钮回调
function StopButtonPushed(app, ~)
app.StopRequested = true;
app.StatusLabel.Text = '仿真已停止';
app.StatusLabel.FontColor = [0.5 0.5 0.5];
app.ProgressBar.Text = '';
end
% 重置按钮回调
function ResetButtonPushed(app, ~)
app.LengthEditField.Value = 0.15;
app.ThicknessEditField.Value = 0.001;
app.PoissonRatioEditField.Value = 0.33;
app.DensityEditField.Value = 2700;
app.ElasticEditField.Value = 70e9;
app.FrequencyEditField.Value = 650;
app.AmplitudeEditField.Value = 0.01;
app.ResolutionEditField.Value = 16;
app.SimTimeEditField.Value = 0.03;
cla(app.UIAxes);
app.StatusLabel.Text = '参数已重置';
app.StatusLabel.FontColor = [0 0.5 0];
app.ProgressBar.Text = '';
end
% 显示模式改变回调
function ModeDropDownValueChanged(app, ~)
if ~isempty(app.LastResult) && ~isempty(app.LastResult.U_Amplitude)
displayMode = app.ModeDropDown.Value;
cla(app.UIAxes);
hold(app.UIAxes, 'on');
axis(app.UIAxes, 'equal');
x = app.LastResult.dx*(-app.LastResult.N:app.LastResult.N);
[X3,Y3] = meshgrid(x,x);
switch displayMode
case '动态波动'
title(app.UIAxes, '动态波动 - 请重新运行仿真');
app.StatusLabel.Text = '动态波动模式需要实时仿真';
app.StatusLabel.FontColor = [0 0 1];
case '振幅分布'
surf(app.UIAxes, X3, Y3, app.LastResult.U_Amplitude);
shading(app.UIAxes, 'interp');
title(app.UIAxes, '振幅分布');
colorbar(app.UIAxes);
view(app.UIAxes, 2);
app.StatusLabel.Text = '显示振幅分布';
app.StatusLabel.FontColor = [0 0.5 0];
case '节点线图'
contour(app.UIAxes, X3, Y3, app.LastResult.U_Amplitude, 10, 'LineWidth', 1.5);
title(app.UIAxes, '节点线图');
colorbar(app.UIAxes);
view(app.UIAxes, 2);
app.StatusLabel.Text = '显示节点线图';
app.StatusLabel.FontColor = [0 0.5 0];
end
end
end
% 辅助函数Equation_Sq0(作为类方法)
function [Sq,Bq] = Equation_Sq0(app, N, mu, u0)
% 外拓展两圈后平板网格的索引
L_Sq = N+5;
% 定义边界点类型
Point_Corner0 = [L_Sq,L_Sq; L_Sq-1,L_Sq; L_Sq,L_Sq-1];
Point_CornerC = [L_Sq-1,L_Sq-2; L_Sq-2,L_Sq-1];
Point_Out1 = [(L_Sq-1)*ones(L_Sq-5,1),(3:L_Sq-3)'; (3:L_Sq-3)',(L_Sq-1)*ones(L_Sq-5,1)];
Point_Corner = [L_Sq-1,L_Sq-1];
Point_Out2 = [L_Sq*ones(L_Sq-4,1),(3:L_Sq-2)'; (3:L_Sq-2)',L_Sq*ones(L_Sq-4,1)];
Point_Mirror1 = [2*ones(L_Sq-2,1),(3:L_Sq)'; (3:L_Sq)',2*ones(L_Sq-2,1)];
Point_Mirror2 = [1*ones(L_Sq-2,1),(3:L_Sq)'; (3:L_Sq)',1*ones(L_Sq-2,1)];
Point_MirrorC = [1,1;1,2;2,1;2,2];
% 初始化矩阵
Sq = zeros(L_Sq^2);
Bq = zeros(L_Sq^2,1);
for k = 1:L_Sq^2
[r_k,c_k] = ind2sub([L_Sq,L_Sq],k);
% 四周边界点处理
if app.IsRowInRowList(Point_Corner0, [r_k,c_k])
Sq(k,k) = 1;
Bq(k) = 0;
% 自由角垂直外边界
elseif app.IsRowInRowList(Point_CornerC, [r_k,c_k])
if r_k == L_Sq-1
Sq(k,k-2:k) = [1,-2,1];
elseif c_k == L_Sq-1
Sq(k,[k-2*L_Sq,k-L_Sq,k]) = [1,-2,1];
end
Bq(k) = 0;
% 第一层边界点
elseif app.IsRowInRowList(Point_Out1, [r_k,c_k])
if r_k == 2
Sq(k,[k+1-L_Sq,k+1,k+1+L_Sq]) = [-mu,2+2*mu,-mu];
Sq(k,k) = -1; Sq(k,k+2) = -1;
elseif r_k == L_Sq-1
Sq(k,[k-1-L_Sq,k-1,k-1+L_Sq]) = [-mu,2+2*mu,-mu];
Sq(k,k) = -1; Sq(k,k-2) = -1;
elseif c_k == 2
Sq(k,[k,k+L_Sq,k+2*L_Sq]) = [-1,2+2*mu,-1];
Sq(k,k+L_Sq-1) = -mu; Sq(k,k+L_Sq+1) = -mu;
elseif c_k == L_Sq-1
Sq(k,[k,k-L_Sq,k-2*L_Sq]) = [-1,2+2*mu,-1];
Sq(k,k-L_Sq-1) = -mu; Sq(k,k-L_Sq+1) = -mu;
end
Bq(k) = 0;
% 自由角对角线外边界
elseif app.IsRowInRowList(Point_Corner, [r_k,c_k])
if r_k == L_Sq-1 && c_k == L_Sq-1
Sq(k,[k,k-2*L_Sq-2]) = [1,1];
Sq(k,[k-2,k-2*L_Sq]) = [-1,-1];
end
Bq(k) = 0;
% 第二层边界点
elseif app.IsRowInRowList(Point_Out2, [r_k,c_k])
if r_k == 1
Sq(k,k) = 1;
Sq(k,[k+1-L_Sq,k+1,k+1+L_Sq]) = [2-mu,2*mu-6,2-mu];
Sq(k,[k+3-L_Sq,k+3,k+3+L_Sq]) = [mu-2,-2*mu+6,mu-2];
Sq(k,k+4) = -1;
end
Bq(k) = 0;
% 正常平板上的点
elseif (r_k>=3 && r_k<=L_Sq-2) && (c_k>=3 && c_k<=L_Sq-2)
Sq(k,k) = 20;
Sq(k,[k+1,k-1,k+L_Sq,k-L_Sq]) = -8;
Sq(k,[k+L_Sq+1,k+L_Sq-1,k-L_Sq+1,k-L_Sq-1]) = 2;
Sq(k,[k+2,k-2,k-2*L_Sq,k+2*L_Sq]) = 1;
Bq(k) = 0;
% 对称边界处理
elseif app.IsRowInRowList(Point_Mirror1, [r_k,c_k])
if r_k == 2
Sq(k,k) = 1; Sq(k,k+2) = -1;
elseif c_k == 2
Sq(k,k) = 1; Sq(k,k+2*L_Sq) = -1;
end
Bq(k) = 0;
elseif app.IsRowInRowList(Point_Mirror2, [r_k,c_k])
if r_k == 1
Sq(k,k) = 1; Sq(k,k+4) = -1;
elseif c_k == 1
Sq(k,k) = 1; Sq(k,k+4*L_Sq) = -1;
end
Bq(k) = 0;
elseif app.IsRowInRowList(Point_MirrorC, [r_k,c_k])
if r_k == 1 && c_k == 1
Sq(k,k) = 1; Sq(k,k+4+4*L_Sq) = -1;
end
Bq(k) = 0;
end
end
% 中心点约束
Indx_Center = sub2ind([L_Sq,L_Sq],3,3);
Sq(Indx_Center,:) = 0;
Sq(Indx_Center,Indx_Center) = 1;
Bq(Indx_Center) = u0;
end
% 辅助函数IsRowInRowList(作为类方法)
function TF = IsRowInRowList(~, List, Point)
TF1 = (List(:,1) == Point(1));
TF = any(List(TF1,2) == Point(2));
end
end
% 应用初始化和启动
methods (Access = public)
% 构造函数
function app = ChladniLab
% 创建UI组件
createComponents(app)
% 注册应用
registerApp(app, app.UIFigure)
if nargout == 0
clear app
end
end
% 运行代码
function run(app)
app.UIFigure.Visible = 'on';
end
end
% 组件销毁
methods (Access = public)
function delete(app)
delete(app.UIFigure)
end
end
end
最新发布