Files
3D_EDFM_SIM-X/gui_support/app/EDFMSimulatorApp.m
T
2026-03-16 16:57:25 +08:00

333 lines
22 KiB
Matlab

classdef EDFMSimulatorApp < matlab.apps.AppBase
properties (Access = public)
UIFigure matlab.ui.Figure
end
properties (Access = private)
UI struct
Config struct
Results struct
end
methods (Access = private)
function startup(app)
app.Config = load_case_template('case01');
app.Results = struct();
app.refreshUIFromConfig();
app.appendLog('Loaded default template: case01');
app.updateStatus('Ready');
end
function createComponents(app)
app.UIFigure = uifigure('Visible', 'off', 'Name', 'EDFM Simulator App');
app.UIFigure.Position = [100 100 1500 900];
root = uigridlayout(app.UIFigure, [2 1]);
root.RowHeight = {44, '1x'};
top = uigridlayout(root, [1 9]);
top.ColumnWidth = {140, 110, 110, 110, 90, 110, 110, '1x', 180};
app.UI.TemplateDropDown = uidropdown(top, 'Items', {'case01'}, 'Value', 'case01');
app.UI.TemplateDropDown.Layout.Column = 1;
app.UI.LoadTemplateButton = uibutton(top, 'push', 'Text', 'Load Template', ...
'ButtonPushedFcn', @(~,~) app.onLoadTemplate());
app.UI.LoadTemplateButton.Layout.Column = 2;
app.UI.ImportConfigButton = uibutton(top, 'push', 'Text', 'Import Config', ...
'ButtonPushedFcn', @(~,~) app.onImportConfig());
app.UI.ImportConfigButton.Layout.Column = 3;
app.UI.ExportConfigButton = uibutton(top, 'push', 'Text', 'Export Config', ...
'ButtonPushedFcn', @(~,~) app.onExportConfig());
app.UI.ExportConfigButton.Layout.Column = 4;
app.UI.RunButton = uibutton(top, 'push', 'Text', 'Run', ...
'ButtonPushedFcn', @(~,~) app.onRun());
app.UI.RunButton.Layout.Column = 5;
app.UI.ImportResultButton = uibutton(top, 'push', 'Text', 'Import Result', ...
'ButtonPushedFcn', @(~,~) app.onImportResult());
app.UI.ImportResultButton.Layout.Column = 6;
app.UI.ExportResultButton = uibutton(top, 'push', 'Text', 'Export Result', ...
'ButtonPushedFcn', @(~,~) app.onExportResult());
app.UI.ExportResultButton.Layout.Column = 7;
app.UI.StatusLabel = uilabel(top, 'Text', 'Status: Ready', 'HorizontalAlignment', 'right');
app.UI.StatusLabel.Layout.Column = 9;
tabs = uitabgroup(root);
tabs.Layout.Row = 2;
app.UI.Tabs = tabs;
app.UI.Part1Tab = uitab(tabs, 'Title', 'Part1 Model');
app.UI.Part2Tab = uitab(tabs, 'Title', 'Part2 Grid');
app.UI.Part3Tab = uitab(tabs, 'Title', 'Part3 Fracture');
app.UI.Part4Tab = uitab(tabs, 'Title', 'Part4 Discretization');
app.UI.Part5Tab = uitab(tabs, 'Title', 'Part5 Flow');
app.UI.Part6Tab = uitab(tabs, 'Title', 'Part6 Wells');
app.UI.Part7Tab = uitab(tabs, 'Title', 'Part7 Solver');
app.UI.RunTab = uitab(tabs, 'Title', 'Run');
app.UI.ResultTab = uitab(tabs, 'Title', 'Results');
app.buildPart1();
app.buildPart2();
app.buildPart3();
app.buildPart4();
app.buildPart5();
app.buildPart6();
app.buildPart7();
app.buildRunTab();
app.buildResultTab();
app.UIFigure.Visible = 'on';
end
function buildPart1(app)
g = uigridlayout(app.UI.Part1Tab, [4 2]); g.RowHeight = {30,30,30,'1x'}; g.ColumnWidth = {160,'1x'};
uilabel(g, 'Text', 'Model Flag'); app.UI.ModelFlag = uidropdown(g, 'Items', {'1'}); app.UI.ModelFlag.Layout.Column = 2;
lbl = uilabel(g, 'Text', 'Grid Model'); lbl.Layout.Row = 2; lbl.Layout.Column = 1;
app.UI.GridModel = uidropdown(g, 'Items', {'1','2'}); app.UI.GridModel.Layout.Row = 2; app.UI.GridModel.Layout.Column = 2;
lbl = uilabel(g, 'Text', 'Flow Model'); lbl.Layout.Row = 3; lbl.Layout.Column = 1;
app.UI.FlowModel = uidropdown(g, 'Items', {'1','2','3'}); app.UI.FlowModel.Layout.Row = 3; app.UI.FlowModel.Layout.Column = 2;
end
function buildPart2(app)
g = uigridlayout(app.UI.Part2Tab, [4 2]); g.ColumnWidth = {130,'1x'}; g.RowHeight = {100,100,100,'1x'};
app.createAreaField(g, 1, 'dx', 'Dx');
app.createAreaField(g, 2, 'dy', 'Dy');
app.createAreaField(g, 3, 'dz', 'Dz');
app.createAreaField(g, 4, 'ntg', 'NTG');
end
function buildPart3(app)
g = uigridlayout(app.UI.Part3Tab, [5 2]); g.ColumnWidth = {160,'1x'}; g.RowHeight = {30,120,120,120,80};
uilabel(g, 'Text', 'Input Style'); app.UI.InputStyle = uidropdown(g, 'Items', {'1','2','3','4'}); app.UI.InputStyle.Layout.Column = 2;
app.createAreaField(g, 2, 'fractureInput', 'Input Content');
app.createAreaField(g, 3, 'fractureLines', 'Fracture Lines');
app.createAreaField(g, 4, 'fractureHeights', 'Fracture Heights');
app.createAreaField(g, 5, 'flowBarrier', 'Flow Barrier Flags');
end
function buildPart4(app)
g = uigridlayout(app.UI.Part4Tab, [7 2]); g.ColumnWidth = {180,'1x'}; g.RowHeight = {90,60,70,70,70,30,'1x'};
app.createAreaField(g, 1, 'boundary', 'Boundary Polygon');
app.createAreaField(g, 2, 'invalidLayer', 'Invalid Layer');
app.createAreaField(g, 3, 'matrixKx', 'Matrix kx');
app.createAreaField(g, 4, 'matrixKy', 'Matrix ky');
app.createAreaField(g, 5, 'matrixKz', 'Matrix kz');
app.createAreaField(g, 6, 'matrixPori', 'Matrix pori');
panel = uipanel(g); panel.Layout.Row = 7; panel.Layout.Column = 2; sub = uigridlayout(panel, [1 6]);
uilabel(sub, 'Text', 'prpor'); app.UI.MatrixPrpor = uieditfield(sub, 'numeric');
uilabel(sub, 'Text', 'cpor'); app.UI.MatrixCpor = uieditfield(sub, 'numeric');
uilabel(sub, 'Text', 'rho'); app.UI.RockDensity = uieditfield(sub, 'numeric');
end
function buildPart5(app)
g = uigridlayout(app.UI.Part5Tab, [3 1]); g.RowHeight = {100,'1x',120};
init = uipanel(g, 'Title', 'Initial State'); initg = uigridlayout(init, [2 4]);
uilabel(initg, 'Text', 'Pressure'); uilabel(initg, 'Text', 'Sw'); uilabel(initg, 'Text', 'Cs'); uilabel(initg, 'Text', 'Cb');
app.UI.InitialPressure = uieditfield(initg, 'numeric'); app.UI.InitialPressure.Layout.Row = 2;
app.UI.InitialSw = uieditfield(initg, 'numeric'); app.UI.InitialSw.Layout.Row = 2;
app.UI.InitialCs = uieditfield(initg, 'numeric'); app.UI.InitialCs.Layout.Row = 2;
app.UI.InitialCb = uieditfield(initg, 'numeric'); app.UI.InitialCb.Layout.Row = 2;
subtabs = uitabgroup(g);
app.UI.GasTab = uitab(subtabs, 'Title', 'Gas-Water');
app.UI.OilTab = uitab(subtabs, 'Title', 'Oil-Water');
app.UI.MultiTab = uitab(subtabs, 'Title', 'Multi-Component');
app.UI.GasArea = uitextarea(uigridlayout(app.UI.GasTab, [1 1]));
app.UI.OilArea = uitextarea(uigridlayout(app.UI.OilTab, [1 1]));
mg = uigridlayout(app.UI.MultiTab, [2 3]);
app.UI.MultiAdsorption = uitextarea(mg); app.UI.MultiNc = uitextarea(mg); app.UI.MultiPc = uitextarea(mg);
app.UI.MultiKrNoSurf = uitextarea(mg); app.UI.MultiKrSurf = uitextarea(mg); app.UI.MultiNote = uitextarea(mg, 'Editable', 'off', 'Value', {'Active flow model only.'});
hint = uitextarea(g, 'Editable', 'off', 'Value', {'Flow models are mutually exclusive.', 'Only the selected model will be used at run time.'});
hint.Layout.Row = 3;
end
function buildPart6(app)
g = uigridlayout(app.UI.Part6Tab, [4 2]); g.ColumnWidth = {160,'1x'}; g.RowHeight = {110,110,140,'1x'};
app.createAreaField(g, 1, 'well1', 'Well1');
app.createAreaField(g, 2, 'welloc', 'Well Locations');
app.createAreaField(g, 3, 'well2', 'Well2');
p = uipanel(g); p.Layout.Row = 4; p.Layout.Column = 2; sub = uigridlayout(p, [1 4]);
app.UI.ScheduleArea = uitextarea(sub); app.UI.TimeArea = uitextarea(sub); app.UI.DtMinArea = uitextarea(sub); app.UI.DtMaxArea = uitextarea(sub);
lbl = uilabel(g, 'Text', 'Schedule / Time / dt'); lbl.Layout.Row = 4; lbl.Layout.Column = 1;
end
function buildPart7(app)
g = uigridlayout(app.UI.Part7Tab, [2 6]);
names = {'YitaP','YitaS','Omega','Nmax','EpsAve','EpsMax'};
for i = 1:numel(names)
lbl = uilabel(g, 'Text', names{i}); lbl.Layout.Row = 1; lbl.Layout.Column = i;
app.UI.(names{i}) = uieditfield(g, 'numeric');
app.UI.(names{i}).Layout.Row = 2; app.UI.(names{i}).Layout.Column = i;
end
end
function buildRunTab(app)
g = uigridlayout(app.UI.RunTab, [2 1]); g.RowHeight = {40,'1x'};
uibutton(g, 'push', 'Text', 'Run Current Config', 'ButtonPushedFcn', @(~,~) app.onRun());
app.UI.RunLog = uitextarea(g, 'Editable', 'off'); app.UI.RunLog.Layout.Row = 2;
end
function buildResultTab(app)
g = uigridlayout(app.UI.ResultTab, [1 2]); g.ColumnWidth = {360,'1x'};
app.UI.ResultSummary = uitextarea(g, 'Editable', 'off');
app.UI.ResultAxes = uiaxes(g); title(app.UI.ResultAxes, 'Results');
end
function createAreaField(app, parent, row, field_name, label_text)
lbl = uilabel(parent, 'Text', label_text);
lbl.Layout.Row = row;
lbl.Layout.Column = 1;
app.UI.(field_name) = uitextarea(parent);
app.UI.(field_name).Layout.Row = row;
app.UI.(field_name).Layout.Column = 2;
end
function onLoadTemplate(app)
app.Config = load_case_template(app.UI.TemplateDropDown.Value);
app.refreshUIFromConfig();
app.appendLog(['Loaded template: ', app.UI.TemplateDropDown.Value]);
app.updateStatus('Template loaded');
end
function onImportConfig(app)
[f, p] = uigetfile('*.mat', 'Import Config'); if isequal(f, 0), return; end
app.Config = load_config_mat(fullfile(p, f));
app.refreshUIFromConfig();
app.appendLog(['Imported config: ', fullfile(p, f)]);
app.updateStatus('Config imported');
end
function onExportConfig(app)
app.pushUIToConfig();
[f, p] = uiputfile('*.mat', 'Export Config', 'config.mat'); if isequal(f, 0), return; end
save_config_mat(app.Config, fullfile(p, f));
app.appendLog(['Exported config: ', fullfile(p, f)]);
app.updateStatus('Config exported');
end
function onImportResult(app)
[f, p] = uigetfile('*.mat', 'Import Result'); if isequal(f, 0), return; end
app.Results = load_results_mat(fullfile(p, f));
app.refreshResults();
app.updateStatus('Result imported');
end
function onExportResult(app)
if isempty(fieldnames(app.Results)), uialert(app.UIFigure, 'No results available.', 'Export Result'); return; end
[f, p] = uiputfile('*.mat', 'Export Result', 'results.mat'); if isequal(f, 0), return; end
save_results_mat(app.Results, fullfile(p, f));
app.appendLog(['Exported result: ', fullfile(p, f)]);
app.updateStatus('Result exported');
end
function onRun(app)
app.pushUIToConfig();
app.updateStatus('Running');
app.appendLog('Run started');
drawnow;
try
log_text = evalc('[r, Times, OutputRs, Wellpara, trun] = run_case(app.Config);');
app.Results = struct('r', r, 'Times', Times, 'OutputRs', {OutputRs}, 'Wellpara', {Wellpara}, 'trun', trun, 'captured_log', log_text);
app.appendLog(log_text);
app.refreshResults();
app.UI.Tabs.SelectedTab = app.UI.ResultTab;
app.updateStatus('Run completed');
catch ME
app.appendLog(getReport(ME, 'extended', 'hyperlinks', 'off'));
app.updateStatus('Run failed');
uialert(app.UIFigure, ME.message, 'Run Failed');
end
end
function refreshUIFromConfig(app)
c = app.Config;
app.UI.ModelFlag.Value = string(c.model.modelflag);
app.UI.GridModel.Value = string(c.model.grid_model);
app.UI.FlowModel.Value = string(c.model.flow_model);
app.UI.Dx.Value = splitlines(app.toExpr(c.grid.dx)); app.UI.Dy.Value = splitlines(app.toExpr(c.grid.dy)); app.UI.Dz.Value = splitlines(app.toExpr(c.grid.dz)); app.UI.Ntg.Value = splitlines(app.toExpr(c.grid.NTG));
app.UI.InputStyle.Value = string(c.fracture.input_style); app.UI.fractureInput.Value = splitlines(app.toExpr(c.fracture.input_content)); app.UI.fractureLines.Value = splitlines(app.toExpr(c.fracture.fractureLines)); app.UI.fractureHeights.Value = splitlines(app.toExpr(c.fracture.fractureHeights)); app.UI.flowBarrier.Value = splitlines(app.toExpr(c.fracture.flowBarrierFlags));
app.UI.boundary.Value = splitlines(app.toExpr(c.discretization.sp.boundary_polygon)); app.UI.invalidLayer.Value = splitlines(app.toExpr(c.discretization.sp.invalid_layer)); app.UI.matrixKx.Value = splitlines(app.toExpr(c.discretization.sp.matrix.kx)); app.UI.matrixKy.Value = splitlines(app.toExpr(c.discretization.sp.matrix.ky)); app.UI.matrixKz.Value = splitlines(app.toExpr(c.discretization.sp.matrix.kz)); app.UI.matrixPori.Value = splitlines(app.toExpr(c.discretization.sp.matrix.pori));
app.UI.MatrixPrpor.Value = c.discretization.sp.matrix.prpor; app.UI.MatrixCpor.Value = c.discretization.sp.matrix.cpor; app.UI.RockDensity.Value = c.discretization.sp.matrix.rock_density;
app.UI.GasArea.Value = splitlines(app.toExpr(c.flow.gas_water.matrix_relperm_table)); app.UI.OilArea.Value = splitlines(app.toExpr(c.flow.oil_water.matrix_relperm_table)); app.UI.MultiAdsorption.Value = splitlines(app.toExpr(c.flow.multi_component.c_ca_table)); app.UI.MultiNc.Value = splitlines(app.toExpr(c.flow.multi_component.cs_Nc)); app.UI.MultiPc.Value = splitlines(app.toExpr(c.flow.multi_component.PC)); app.UI.MultiKrNoSurf.Value = splitlines(app.toExpr(c.flow.multi_component.kr_nosurf)); app.UI.MultiKrSurf.Value = splitlines(app.toExpr(c.flow.multi_component.kr_surf));
app.UI.InitialPressure.Value = app.scalarValue(c.initial.pressure); app.UI.InitialSw.Value = app.scalarValue(c.initial.sw); app.UI.InitialCs.Value = app.scalarValue(c.initial.cs); app.UI.InitialCb.Value = app.scalarValue(c.initial.cb);
app.UI.well1.Value = splitlines(app.toExpr(c.wells.well1)); app.UI.welloc.Value = splitlines(app.toExpr(c.wells.welloc)); app.UI.well2.Value = splitlines(app.toExpr(c.wells.well2)); app.UI.ScheduleArea.Value = splitlines(app.toExpr(c.schedule.well_schedules)); app.UI.TimeArea.Value = splitlines(app.toExpr(c.schedule.time)); app.UI.DtMinArea.Value = splitlines(app.toExpr(c.schedule.dtmin)); app.UI.DtMaxArea.Value = splitlines(app.toExpr(c.schedule.dtmax));
app.UI.YitaP.Value = c.solver.yitap; app.UI.YitaS.Value = c.solver.yitas; app.UI.Omega.Value = c.solver.omega; app.UI.Nmax.Value = c.solver.Nmax; app.UI.EpsAve.Value = c.solver.epsave; app.UI.EpsMax.Value = c.solver.epsmax;
end
function pushUIToConfig(app)
c = app.Config;
c.model.modelflag = str2double(app.UI.ModelFlag.Value); c.model.grid_model = str2double(app.UI.GridModel.Value); c.model.flow_model = str2double(app.UI.FlowModel.Value);
c.grid.dx = app.parseExpr(app.UI.Dx.Value); c.grid.dy = app.parseExpr(app.UI.Dy.Value); c.grid.dz = app.parseExpr(app.UI.Dz.Value); c.grid.NTG = app.parseExpr(app.UI.Ntg.Value); c.grid.nx = numel(c.grid.dx); c.grid.ny = numel(c.grid.dy); c.grid.nz = numel(c.grid.dz);
c.fracture.input_style = str2double(app.UI.InputStyle.Value); c.fracture.input_content = app.parseExpr(app.UI.fractureInput.Value); c.fracture.fractureLines = app.parseExpr(app.UI.fractureLines.Value); c.fracture.fractureHeights = app.parseExpr(app.UI.fractureHeights.Value); c.fracture.flowBarrierFlags = app.parseExpr(app.UI.flowBarrier.Value);
c.discretization.sp.boundary_polygon = app.parseExpr(app.UI.boundary.Value); c.discretization.sp.invalid_layer = app.parseExpr(app.UI.invalidLayer.Value); c.discretization.sp.matrix.kx = app.parseExpr(app.UI.matrixKx.Value); c.discretization.sp.matrix.ky = app.parseExpr(app.UI.matrixKy.Value); c.discretization.sp.matrix.kz = app.parseExpr(app.UI.matrixKz.Value); c.discretization.sp.matrix.pori = app.parseExpr(app.UI.matrixPori.Value); c.discretization.sp.matrix.prpor = app.UI.MatrixPrpor.Value; c.discretization.sp.matrix.cpor = app.UI.MatrixCpor.Value; c.discretization.sp.matrix.rock_density = app.UI.RockDensity.Value;
c.flow.gas_water.matrix_relperm_table = app.parseExpr(app.UI.GasArea.Value); c.flow.oil_water.matrix_relperm_table = app.parseExpr(app.UI.OilArea.Value); c.flow.multi_component.c_ca_table = app.parseExpr(app.UI.MultiAdsorption.Value); c.flow.multi_component.cs_Nc = app.parseExpr(app.UI.MultiNc.Value); c.flow.multi_component.PC = app.parseExpr(app.UI.MultiPc.Value); c.flow.multi_component.kr_nosurf = app.parseExpr(app.UI.MultiKrNoSurf.Value); c.flow.multi_component.kr_surf = app.parseExpr(app.UI.MultiKrSurf.Value);
c.initial.pressure = app.UI.InitialPressure.Value; c.initial.sw = app.UI.InitialSw.Value; c.initial.cs = app.UI.InitialCs.Value; c.initial.cb = app.UI.InitialCb.Value;
c.wells.well1 = app.parseExpr(app.UI.well1.Value); c.wells.welloc = app.parseExpr(app.UI.welloc.Value); c.wells.num_fracture_wells = numel(c.wells.welloc); c.wells.well2 = app.parseExpr(app.UI.well2.Value);
c.schedule.well_schedules = app.parseExpr(app.UI.ScheduleArea.Value); c.schedule.time = app.parseExpr(app.UI.TimeArea.Value); c.schedule.dtmin = app.parseExpr(app.UI.DtMinArea.Value); c.schedule.dtmax = app.parseExpr(app.UI.DtMaxArea.Value); c.schedule.number_phases = size(c.schedule.well_schedules, 1);
c.solver.yitap = app.UI.YitaP.Value; c.solver.yitas = app.UI.YitaS.Value; c.solver.omega = app.UI.Omega.Value; c.solver.Nmax = app.UI.Nmax.Value; c.solver.epsave = app.UI.EpsAve.Value; c.solver.epsmax = app.UI.EpsMax.Value;
app.Config = c;
end
function refreshResults(app)
if isempty(fieldnames(app.Results)), app.UI.ResultSummary.Value = {'No results loaded.'}; cla(app.UI.ResultAxes); return; end
summary = {};
if isfield(app.Results, 'Times'), summary{end+1} = ['Time steps: ', num2str(numel(app.Results.Times))]; end %#ok<AGROW>
if isfield(app.Results, 'trun') && isstruct(app.Results.trun)
if isfield(app.Results.trun, 'run_time'), summary{end+1} = ['Run time: ', num2str(app.Results.trun.run_time)]; end %#ok<AGROW>
if isfield(app.Results.trun, 'Newton_step'), summary{end+1} = ['Newton steps: ', num2str(app.Results.trun.Newton_step)]; end %#ok<AGROW>
end
app.UI.ResultSummary.Value = summary;
cla(app.UI.ResultAxes);
if isfield(app.Results, 'trun') && isfield(app.Results.trun, 'Newtons_vs_time') && ~isempty(app.Results.trun.Newtons_vs_time)
plot(app.UI.ResultAxes, app.Results.trun.Newtons_vs_time(:,1), app.Results.trun.Newtons_vs_time(:,2), '-o'); title(app.UI.ResultAxes, 'Newtons vs Time'); xlabel(app.UI.ResultAxes, 'Time'); ylabel(app.UI.ResultAxes, 'Newton Count');
elseif isfield(app.Results, 'Times') && ~isempty(app.Results.Times)
plot(app.UI.ResultAxes, app.Results.Times, 1:numel(app.Results.Times), '-o'); title(app.UI.ResultAxes, 'Time Step Index'); xlabel(app.UI.ResultAxes, 'Time'); ylabel(app.UI.ResultAxes, 'Step');
end
end
function appendLog(app, txt)
lines = string(txt); lines = splitlines(lines);
current = string(app.UI.RunLog.Value);
if isequal(current, ""), app.UI.RunLog.Value = cellstr(lines); else, app.UI.RunLog.Value = cellstr([current; lines]); end
end
function updateStatus(app, txt)
app.UI.StatusLabel.Text = ['Status: ', txt];
end
function out = parseExpr(app, lines) %#ok<INUSL>
txt = strtrim(strjoin(string(lines), newline));
if txt == "", out = []; else, out = eval(txt); end %#ok<EVLDIR>
end
function txt = toExpr(app, value) %#ok<INUSL>
if isempty(value), txt = '[]'; return; end
if isnumeric(value) || islogical(value), txt = mat2str(value); return; end
if ischar(value), txt = ['''', strrep(value, '''', ''''''), '''']; return; end
if isstring(value) && isscalar(value), txt = ['''', strrep(char(value), '''', ''''''), '''']; return; end
if iscell(value)
rows = cell(size(value,1),1);
for i = 1:size(value,1)
cols = cell(1,size(value,2));
for j = 1:size(value,2), cols{j} = app.toExpr(value{i,j}); end
rows{i} = strjoin(cols, ', ');
end
txt = ['{', strjoin(rows, [';', newline]), '}']; return;
end
txt = evalc('disp(value)');
end
function value = scalarValue(app, raw) %#ok<INUSL>
if isempty(raw), value = 0; elseif isscalar(raw), value = raw; else, value = raw(1); end
end
end
methods (Access = public)
function app = EDFMSimulatorApp()
createComponents(app);
registerApp(app, app.UIFigure);
runStartupFcn(app, @(~,~) app.startup());
end
function delete(app)
delete(app.UIFigure);
end
end
end