部分挂载以及controller代码,存在bug等待修复。
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
# App Designer Binding Guide
|
||||
|
||||
## Fastest Path
|
||||
|
||||
按原计划要最快跑通,建议只先做这一条主线:
|
||||
|
||||
1. 保持真正界面文件为 [EDFM_Simulator_App.mlapp](C:\Users\15715\Documents\code\edfm_gui\gui_support\app\EDFM_Simulator_App.mlapp)。
|
||||
2. 不直接改解包后的 `.mlapp` 内容。
|
||||
3. 用新加的控制器 [EDFMAppController.m](C:\Users\15715\Documents\code\edfm_gui\gui_support\app\EDFMAppController.m) 负责绑定。
|
||||
4. 首先只保证 `case01` 的模板加载、配置导入导出、运行、结果导入导出、基础绘图跑通。
|
||||
5. 其他 case 和更细的参数编辑体验留到下一轮。
|
||||
|
||||
原因很直接:现在仓库里后端已经有统一 `config`、`case01` 模板、`run_case(config)`、MAT 导入导出,缺的主要就是 `.mlapp` 的回调连接和控件同步。
|
||||
|
||||
## 我已经补了什么
|
||||
|
||||
新增了 [EDFMAppController.m](C:\Users\15715\Documents\code\edfm_gui\gui_support\app\EDFMAppController.m),负责:
|
||||
|
||||
- 启动默认加载 `case01`
|
||||
- `New Config`
|
||||
- 模板加载
|
||||
- config 导入导出
|
||||
- result 导入导出
|
||||
- 从 UI 回写 `config`
|
||||
- 从 `config` 刷新 UI
|
||||
- 调用 `run_case(config)`
|
||||
- 基础结果摘要和绘图
|
||||
- SP/DP 页签切换
|
||||
- 三种流动模型页签切换
|
||||
|
||||
当前重点是让你现有 `.mlapp` 最快可运行,不是一次性把所有参数编辑体验做完。
|
||||
|
||||
## 你需要在 App Designer 里手动做的事
|
||||
|
||||
只在 [EDFM_Simulator_App.mlapp](C:\Users\15715\Documents\code\edfm_gui\gui_support\app\EDFM_Simulator_App.mlapp) 里做下面这些操作。
|
||||
|
||||
### 1. 添加控制器属性
|
||||
|
||||
在属性区加上:
|
||||
|
||||
```matlab
|
||||
Controller EDFMAppController
|
||||
```
|
||||
|
||||
如果已经有,就保留,不要改名。
|
||||
|
||||
### 2. 添加 startup 函数
|
||||
|
||||
在 Code View 里确认有:
|
||||
|
||||
```matlab
|
||||
function startupApp(app)
|
||||
app.Controller = EDFMAppController(app);
|
||||
app.Controller.startup();
|
||||
end
|
||||
```
|
||||
|
||||
并确认构造函数里有:
|
||||
|
||||
```matlab
|
||||
runStartupFcn(app, @(~,~)startupApp(app));
|
||||
```
|
||||
|
||||
### 3. 绑定按钮回调
|
||||
|
||||
把这些控件分别绑定到这些方法:
|
||||
|
||||
- `NewConfigButton` -> `onNewConfig`
|
||||
- `LoadTemplateButton` -> `onLoadTemplate`
|
||||
- `ImportConfigButton` -> `onImportConfig`
|
||||
- `ExportConfigButton` -> `onExportConfig`
|
||||
- `RunButton` -> `onRun`
|
||||
- `RunCurrentConfigButton` -> `onRun`
|
||||
- `ImportResultButton` -> `onImportResult`
|
||||
- `ExportResultButton` -> `onExportResult`
|
||||
- `PlotResultButton` -> `onPlotResult`
|
||||
|
||||
对应方法:
|
||||
|
||||
```matlab
|
||||
function onNewConfig(app)
|
||||
app.Controller.newConfig();
|
||||
end
|
||||
|
||||
function onLoadTemplate(app)
|
||||
app.Controller.loadTemplate(app.TemplateDropDown.Value);
|
||||
end
|
||||
|
||||
function onImportConfig(app)
|
||||
app.Controller.importConfig();
|
||||
end
|
||||
|
||||
function onExportConfig(app)
|
||||
app.Controller.exportConfig();
|
||||
end
|
||||
|
||||
function onRun(app)
|
||||
app.Controller.runCurrentConfig();
|
||||
end
|
||||
|
||||
function onImportResult(app)
|
||||
app.Controller.importResults();
|
||||
end
|
||||
|
||||
function onExportResult(app)
|
||||
app.Controller.exportResults();
|
||||
end
|
||||
|
||||
function onPlotResult(app)
|
||||
app.Controller.plotResults();
|
||||
end
|
||||
```
|
||||
|
||||
### 4. 绑定模型切换回调
|
||||
|
||||
给下面两个下拉框绑定 `onModelChanged`:
|
||||
|
||||
- `ModelFlowModelDropDown`
|
||||
- `ModelGridModelDropDown`
|
||||
|
||||
方法:
|
||||
|
||||
```matlab
|
||||
function onModelChanged(app)
|
||||
if ~isempty(app.Controller)
|
||||
app.Controller.syncModelTabs();
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
同时把:
|
||||
|
||||
- `ResultTypeDropDown` 的 `ValueChangedFcn`
|
||||
|
||||
绑定到 `onPlotResult`。
|
||||
|
||||
### 5. 保持控件名不变
|
||||
|
||||
控制器默认依赖这些命名,不要在 App Designer 里随意改:
|
||||
|
||||
- 顶栏:`TemplateDropDown`、`LoadTemplateButton`、`ImportConfigButton`、`ExportConfigButton`、`RunButton`、`ImportResultButton`、`ExportResultButton`、`StatusLabel`
|
||||
- 模型:`ModelFlagDropDown`、`ModelGridModelDropDown`、`ModelFlowModelDropDown`
|
||||
- 网格:`GridDxTextArea`、`GridDyTextArea`、`GridDzTextArea`、`GridNTGTextArea`
|
||||
- 裂缝:`FractureInputStyleDropDown`、`FractureInputTextArea`、`FractureLinesTextArea`、`FractureHeightsTextArea`、`FractureFlowBarrierFlagsTextArea`
|
||||
- SP:`SPBoundaryTextArea`、`SPInvalidLayerTextArea`、`SPMatrixKxTextArea`、`SPMatrixKyTextArea`、`SPMatrixKzTextArea`、`SPMatrixPoriTextArea`、`SPMatrixPrporEditField`、`SPMatrixCporEditField`、`SPRockDensityEditField`、`SPFractureKfTextArea`、`SPFractureWfTextArea`、`SPFracturePorfTextArea`、`SPFracturePrporEditField`、`SPFractureCporfEditField`、`SPStressFractureEditField`、`SPStressMatrixEditField`、`SPStressRefPressureEditField`
|
||||
- DP:`DPkxTextArea`、`DPkyTextArea`、`DPkzTextArea`、`DPkx_matrixLayerTextArea`、`DPky_matrixLayerTextArea`、`DPkz_matrixLayerTextArea`、`DPpori_matrixLayerTextArea`、`DPsigmaTextArea`、`DPNTGTextArea`、`DPprporEditField`、`DPcporEditField`、`DPKfTextArea`、`DPWfTextArea`、`DPPorfTextArea`、`DPprporfEditField`、`DPcporfEditField`、`DPstress_factor_fractureEditField`、`DPstress_factor_matrixEditField`、`DPstress_factor_ref_pressureEditField`
|
||||
- 初始值和多组分主控件:`InitialPressureEditField`、`InitialSwEditField`、`InitialCsEditField`、`InitialCbEditField`、`InitStatusLabel`、`MCcs_NcTextArea`、`MCkr_nosurfTextArea`、`MCkr_surfTextArea`、`MCPCTextArea`、`MCcs_Nc_fractureTextArea`、`MCkr_nosurf_fractureTextArea`、`MCkr_surf_fractureTextArea`、`MCPC_fractureTextArea`、`MCp_grad_thresholdEditField`、`MCgas_propVLEditField`、`MCgas_propPLEditField`、`MCgas_propKnEditField`、`MCstress_factor_fractureEditField`、`MCstress_factor_matrixEditField`、`MCstress_factor_ref_pressureEditField`、`MCbeta_non_darcy_flowEditField`、`MCdensity_g_scEditField`、`MCgas_modelDropDown`、`MCprgEditField`、`MCBgiEditField`、`MCcgEditField`、`MCvgiEditField`、`MCcvgEditField`、`MCPprTextArea`、`MCBGTextArea`、`MCMUGTextArea`、`MCdensity_w_scEditField`、`MCprwEditField`、`MCBwiEditField`、`MCcwEditField`、`MCvwiEditField`、`MCcvwEditField`
|
||||
- 井和排程:`Well1Table`、`FractureWellLocationTable`、`Well2Table`、`ScheduleTable`、`TimeTextArea`、`DtMinTextArea`、`DtMaxTextArea`
|
||||
- 求解器:`YitaPEditField`、`YitaSEditField`、`OmegaEditField`、`NmaxEditField`、`EpsAveEditField`、`EpsMaxEditField`
|
||||
- 运行和结果:`RunLogTextArea`、`RunProgressLabel`、`CurrentStageLabel`、`CurrentTimeLabel`、`CurrentDtLabel`、`ResultSummaryTextArea`、`ResultTypeDropDown`、`ResultAxes`、`ResultTab`
|
||||
- 页签组:`TabGroup2`、`TabGroup3`、`GasWaterTab`、`OilWaterTab`、`MultiComponentTab`、`SPTab`、`DPTab`
|
||||
|
||||
## 第一轮验证怎么做
|
||||
|
||||
1. 在 App Designer 打开 [EDFM_Simulator_App.mlapp](C:\Users\15715\Documents\code\edfm_gui\gui_support\app\EDFM_Simulator_App.mlapp)。
|
||||
2. 按上面的方式挂好属性、startup 和 callbacks。
|
||||
3. 直接运行 app。
|
||||
4. 看启动后是否自动加载 `case01`。
|
||||
5. 看 `ModelFlowModelDropDown = 3` 时是否自动切到多组分页。
|
||||
6. 不改参数直接点 `Run`,先验证统一链路能否起跑。
|
||||
|
||||
## 当前已知限制
|
||||
|
||||
- 模板仍然只有 `case01`。
|
||||
- 现在是“先跑通”的控制器,不是最终版用户体验。
|
||||
- `UITable` 里嵌套 cell 和矩阵的编辑体验还比较原始。
|
||||
- [launch_edfm_simulator_app.m](C:\Users\15715\Documents\code\edfm_gui\gui_support\app\launch_edfm_simulator_app.m) 目前仍指向手写 `.m` app,不适合你当前的 `.mlapp` 工作流,所以这一步先直接在 App Designer 里运行 `.mlapp`。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,759 @@
|
||||
classdef EDFMAppController < handle
|
||||
properties (Access = private)
|
||||
App
|
||||
Config struct = struct()
|
||||
Results struct = struct()
|
||||
ProjectRoot char
|
||||
end
|
||||
|
||||
methods
|
||||
function obj = EDFMAppController(app)
|
||||
obj.App = app;
|
||||
obj.ProjectRoot = fileparts(fileparts(fileparts(mfilename('fullpath'))));
|
||||
obj.addSupportPaths();
|
||||
end
|
||||
|
||||
function startup(obj)
|
||||
obj.setDropDownItems('TemplateDropDown', {'case01'}, 'case01');
|
||||
obj.setDropDownItems('ResultTypeDropDown', {'Time Steps', 'Newtons vs Time'}, 'Time Steps');
|
||||
obj.setDropDownItems('ModelFlagDropDown', {'1'}, '1');
|
||||
obj.setDropDownItems('ModelGridModelDropDown', {'1', '2'}, '1');
|
||||
obj.setDropDownItems('ModelFlowModelDropDown', {'1', '2', '3'}, '1');
|
||||
obj.setDropDownItems('FractureInputStyleDropDown', {'1', '2', '3', '4'}, '1');
|
||||
obj.setDropDownItems('GWgas_modelDropDown', {'1', '2'}, '1');
|
||||
obj.setDropDownItems('OWoil_modelDropDown', {'1', '2'}, '1');
|
||||
obj.setDropDownItems('MCgas_modelDropDown', {'1', '2'}, '1');
|
||||
|
||||
obj.Results = struct();
|
||||
obj.loadTemplate('case01');
|
||||
obj.appendLog('Controller startup completed.');
|
||||
obj.setStatus('Ready');
|
||||
end
|
||||
|
||||
function newConfig(obj)
|
||||
obj.Config = create_empty_config();
|
||||
obj.Results = struct();
|
||||
obj.refreshUIFromConfig();
|
||||
obj.refreshResults();
|
||||
obj.appendLog('Created empty config.');
|
||||
obj.setStatus('Empty config');
|
||||
end
|
||||
|
||||
function loadTemplate(obj, caseId)
|
||||
if nargin < 2 || strlength(string(caseId)) == 0
|
||||
caseId = 'case01';
|
||||
end
|
||||
obj.Config = load_case_template(caseId);
|
||||
obj.refreshUIFromConfig();
|
||||
obj.refreshResults();
|
||||
obj.appendLog(sprintf('Loaded template: %s', string(caseId)));
|
||||
obj.setStatus(sprintf('Template %s loaded', string(caseId)));
|
||||
end
|
||||
|
||||
function importConfig(obj)
|
||||
[fileName, folder] = uigetfile('*.mat', 'Import Config');
|
||||
if isequal(fileName, 0)
|
||||
return;
|
||||
end
|
||||
obj.Config = load_config_mat(fullfile(folder, fileName));
|
||||
obj.refreshUIFromConfig();
|
||||
obj.appendLog(sprintf('Imported config: %s', fullfile(folder, fileName)));
|
||||
obj.setStatus('Config imported');
|
||||
end
|
||||
|
||||
function exportConfig(obj)
|
||||
obj.pushUIToConfig();
|
||||
[fileName, folder] = uiputfile('*.mat', 'Export Config', 'config.mat');
|
||||
if isequal(fileName, 0)
|
||||
return;
|
||||
end
|
||||
save_config_mat(obj.Config, fullfile(folder, fileName));
|
||||
obj.appendLog(sprintf('Exported config: %s', fullfile(folder, fileName)));
|
||||
obj.setStatus('Config exported');
|
||||
end
|
||||
|
||||
function runCurrentConfig(obj)
|
||||
obj.pushUIToConfig();
|
||||
obj.setStatus('Running');
|
||||
obj.setRunProgress('Running...');
|
||||
obj.setRunHeader('-', '-', '-');
|
||||
obj.appendLog('Run started.');
|
||||
drawnow;
|
||||
|
||||
try
|
||||
logText = evalc('[r, Times, OutputRs, Wellpara, trun] = run_case(obj.Config);');
|
||||
obj.Results = struct( ...
|
||||
'r', r, ...
|
||||
'Times', Times, ...
|
||||
'OutputRs', {OutputRs}, ...
|
||||
'Wellpara', {Wellpara}, ...
|
||||
'trun', trun, ...
|
||||
'captured_log', logText);
|
||||
if ~isempty(strtrim(logText))
|
||||
obj.appendLog(logText);
|
||||
end
|
||||
obj.refreshResults();
|
||||
obj.setRunProgress('Completed');
|
||||
obj.setStatus('Run completed');
|
||||
catch ME
|
||||
obj.appendLog(getReport(ME, 'extended', 'hyperlinks', 'off'));
|
||||
obj.setRunProgress('Failed');
|
||||
obj.setStatus('Run failed');
|
||||
uialert(obj.App.UIFigure, ME.message, 'Run Failed');
|
||||
end
|
||||
end
|
||||
|
||||
function importResults(obj)
|
||||
[fileName, folder] = uigetfile('*.mat', 'Import Results');
|
||||
if isequal(fileName, 0)
|
||||
return;
|
||||
end
|
||||
obj.Results = load_results_mat(fullfile(folder, fileName));
|
||||
obj.refreshResults();
|
||||
obj.appendLog(sprintf('Imported results: %s', fullfile(folder, fileName)));
|
||||
obj.setStatus('Results imported');
|
||||
end
|
||||
|
||||
function exportResults(obj)
|
||||
if isempty(fieldnames(obj.Results))
|
||||
uialert(obj.App.UIFigure, 'No results available to export.', 'Export Results');
|
||||
return;
|
||||
end
|
||||
[fileName, folder] = uiputfile('*.mat', 'Export Results', 'results.mat');
|
||||
if isequal(fileName, 0)
|
||||
return;
|
||||
end
|
||||
save_results_mat(obj.Results, fullfile(folder, fileName));
|
||||
obj.appendLog(sprintf('Exported results: %s', fullfile(folder, fileName)));
|
||||
obj.setStatus('Results exported');
|
||||
end
|
||||
|
||||
function plotResults(obj)
|
||||
if isempty(fieldnames(obj.Results))
|
||||
obj.refreshResults();
|
||||
return;
|
||||
end
|
||||
if ~isprop(obj.App, 'ResultAxes') || isempty(obj.App.ResultAxes)
|
||||
return;
|
||||
end
|
||||
|
||||
axesHandle = obj.App.ResultAxes;
|
||||
cla(axesHandle);
|
||||
plotType = obj.getDropDownValue('ResultTypeDropDown', 'Time Steps');
|
||||
|
||||
if strcmp(plotType, 'Newtons vs Time') && isfield(obj.Results, 'trun') ...
|
||||
&& isstruct(obj.Results.trun) ...
|
||||
&& isfield(obj.Results.trun, 'Newtons_vs_time') ...
|
||||
&& ~isempty(obj.Results.trun.Newtons_vs_time)
|
||||
data = obj.Results.trun.Newtons_vs_time;
|
||||
plot(axesHandle, data(:, 1), data(:, 2), '-o', 'LineWidth', 1.2);
|
||||
title(axesHandle, 'Newtons vs Time');
|
||||
xlabel(axesHandle, 'Time');
|
||||
ylabel(axesHandle, 'Newton Count');
|
||||
elseif isfield(obj.Results, 'Times') && ~isempty(obj.Results.Times)
|
||||
times = obj.Results.Times(:);
|
||||
plot(axesHandle, times, 1:numel(times), '-o', 'LineWidth', 1.2);
|
||||
title(axesHandle, 'Time Step Index');
|
||||
xlabel(axesHandle, 'Time');
|
||||
ylabel(axesHandle, 'Step');
|
||||
else
|
||||
title(axesHandle, 'No plottable data');
|
||||
end
|
||||
end
|
||||
|
||||
function syncModelTabs(obj)
|
||||
gridModel = obj.getNumericDropDownValue('ModelGridModelDropDown', 1);
|
||||
flowModel = obj.getNumericDropDownValue('ModelFlowModelDropDown', 1);
|
||||
|
||||
if isprop(obj.App, 'TabGroup3')
|
||||
if gridModel == 2 && isprop(obj.App, 'DPTab')
|
||||
obj.App.TabGroup3.SelectedTab = obj.App.DPTab;
|
||||
elseif isprop(obj.App, 'SPTab')
|
||||
obj.App.TabGroup3.SelectedTab = obj.App.SPTab;
|
||||
end
|
||||
end
|
||||
|
||||
if isprop(obj.App, 'TabGroup2')
|
||||
switch flowModel
|
||||
case 1
|
||||
if isprop(obj.App, 'GasWaterTab')
|
||||
obj.App.TabGroup2.SelectedTab = obj.App.GasWaterTab;
|
||||
end
|
||||
case 2
|
||||
if isprop(obj.App, 'OilWaterTab')
|
||||
obj.App.TabGroup2.SelectedTab = obj.App.OilWaterTab;
|
||||
end
|
||||
otherwise
|
||||
if isprop(obj.App, 'MultiComponentTab')
|
||||
obj.App.TabGroup2.SelectedTab = obj.App.MultiComponentTab;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
obj.setEditableState('InitialCsEditField', flowModel == 3);
|
||||
obj.setEditableState('InitialCbEditField', flowModel == 3);
|
||||
|
||||
if isprop(obj.App, 'InitStatusLabel')
|
||||
switch flowModel
|
||||
case 1
|
||||
obj.App.InitStatusLabel.Text = 'Init: gas-water';
|
||||
case 2
|
||||
obj.App.InitStatusLabel.Text = 'Init: oil-water';
|
||||
otherwise
|
||||
obj.App.InitStatusLabel.Text = 'Init: multi-component';
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
methods (Access = private)
|
||||
function addSupportPaths(obj)
|
||||
addpath(fullfile(obj.ProjectRoot, 'gui_support', 'app'));
|
||||
addpath(fullfile(obj.ProjectRoot, 'gui_support', 'config'));
|
||||
addpath(fullfile(obj.ProjectRoot, 'gui_support', 'runtime'));
|
||||
addpath(fullfile(obj.ProjectRoot, 'gui_support', 'results'));
|
||||
addpath(fullfile(obj.ProjectRoot, 'gui_support', 'templates'));
|
||||
addpath(genpath(obj.ProjectRoot));
|
||||
end
|
||||
|
||||
function refreshUIFromConfig(obj)
|
||||
if isempty(fieldnames(obj.Config))
|
||||
return;
|
||||
end
|
||||
c = obj.Config;
|
||||
|
||||
obj.setDropDownValue('ModelFlagDropDown', c.model.modelflag);
|
||||
obj.setDropDownValue('ModelGridModelDropDown', c.model.grid_model);
|
||||
obj.setDropDownValue('ModelFlowModelDropDown', c.model.flow_model);
|
||||
|
||||
obj.setTextAreaExpr('GridDxTextArea', c.grid.dx);
|
||||
obj.setTextAreaExpr('GridDyTextArea', c.grid.dy);
|
||||
obj.setTextAreaExpr('GridDzTextArea', c.grid.dz);
|
||||
obj.setTextAreaExpr('GridNTGTextArea', c.grid.NTG);
|
||||
|
||||
obj.setDropDownValue('FractureInputStyleDropDown', c.fracture.input_style);
|
||||
obj.setTextAreaExpr('FractureInputTextArea', c.fracture.input_content);
|
||||
obj.setTextAreaExpr('FractureLinesTextArea', c.fracture.fractureLines);
|
||||
obj.setTextAreaExpr('FractureHeightsTextArea', c.fracture.fractureHeights);
|
||||
obj.setTextAreaExpr('FractureFlowBarrierFlagsTextArea', c.fracture.flowBarrierFlags);
|
||||
|
||||
obj.setTextAreaExpr('SPBoundaryTextArea', c.discretization.sp.boundary_polygon);
|
||||
obj.setTextAreaExpr('SPInvalidLayerTextArea', c.discretization.sp.invalid_layer);
|
||||
obj.setTextAreaExpr('SPMatrixKxTextArea', c.discretization.sp.matrix.kx);
|
||||
obj.setTextAreaExpr('SPMatrixKyTextArea', c.discretization.sp.matrix.ky);
|
||||
obj.setTextAreaExpr('SPMatrixKzTextArea', c.discretization.sp.matrix.kz);
|
||||
obj.setTextAreaExpr('SPMatrixPoriTextArea', c.discretization.sp.matrix.pori);
|
||||
obj.setNumericFieldValue('SPMatrixPrporEditField', c.discretization.sp.matrix.prpor);
|
||||
obj.setNumericFieldValue('SPMatrixCporEditField', c.discretization.sp.matrix.cpor);
|
||||
obj.setNumericFieldValue('SPRockDensityEditField', c.discretization.sp.matrix.rock_density);
|
||||
obj.setTextAreaExpr('SPFractureKfTextArea', c.discretization.sp.fracture.Kf);
|
||||
obj.setTextAreaExpr('SPFractureWfTextArea', c.discretization.sp.fracture.Wf);
|
||||
obj.setTextAreaExpr('SPFracturePorfTextArea', c.discretization.sp.fracture.Porf);
|
||||
obj.setNumericFieldValue('SPFracturePrporEditField', c.discretization.sp.fracture.prporf);
|
||||
obj.setNumericFieldValue('SPFractureCporfEditField', c.discretization.sp.fracture.cporf);
|
||||
obj.setNumericFieldValue('SPStressFractureEditField', c.discretization.sp.stress.fracture_factor);
|
||||
obj.setNumericFieldValue('SPStressMatrixEditField', c.discretization.sp.stress.matrix_factor);
|
||||
obj.setNumericFieldValue('SPStressRefPressureEditField', c.discretization.sp.stress.ref_pressure);
|
||||
|
||||
obj.setTextAreaExpr('DPkxTextArea', c.discretization.dp.fracture_layer.kx);
|
||||
obj.setTextAreaExpr('DPkyTextArea', c.discretization.dp.fracture_layer.ky);
|
||||
obj.setTextAreaExpr('DPkzTextArea', c.discretization.dp.fracture_layer.kz);
|
||||
obj.setTextAreaExpr('DPkx_matrixLayerTextArea', c.discretization.dp.matrix_layer.kx);
|
||||
obj.setTextAreaExpr('DPky_matrixLayerTextArea', c.discretization.dp.matrix_layer.ky);
|
||||
obj.setTextAreaExpr('DPkz_matrixLayerTextArea', c.discretization.dp.matrix_layer.kz);
|
||||
obj.setTextAreaExpr('DPpori_matrixLayerTextArea', c.discretization.dp.matrix_layer.pori);
|
||||
obj.setTextAreaExpr('DPsigmaTextArea', c.discretization.dp.shape_factor);
|
||||
obj.setTextAreaExpr('DPNTGTextArea', c.discretization.dp.NTG);
|
||||
obj.setNumericFieldValue('DPprporEditField', c.discretization.dp.prpor);
|
||||
obj.setNumericFieldValue('DPcporEditField', c.discretization.dp.cpor);
|
||||
obj.setTextAreaExpr('DPKfTextArea', c.discretization.dp.fracture.Kf);
|
||||
obj.setTextAreaExpr('DPWfTextArea', c.discretization.dp.fracture.Wf);
|
||||
obj.setTextAreaExpr('DPPorfTextArea', c.discretization.dp.fracture.Porf);
|
||||
obj.setNumericFieldValue('DPprporfEditField', c.discretization.dp.fracture.prporf);
|
||||
obj.setNumericFieldValue('DPcporfEditField', c.discretization.dp.fracture.cporf);
|
||||
obj.setNumericFieldValue('DPstress_factor_fractureEditField', c.discretization.dp.stress.fracture_factor);
|
||||
obj.setNumericFieldValue('DPstress_factor_matrixEditField', c.discretization.dp.stress.matrix_factor);
|
||||
obj.setNumericFieldValue('DPstress_factor_ref_pressureEditField', c.discretization.dp.stress.ref_pressure);
|
||||
|
||||
obj.setNumericFieldValue('InitialPressureEditField', obj.firstScalar(c.initial.pressure));
|
||||
obj.setNumericFieldValue('InitialSwEditField', obj.firstScalar(c.initial.sw));
|
||||
obj.setNumericFieldValue('InitialCsEditField', obj.firstScalar(c.initial.cs));
|
||||
obj.setNumericFieldValue('InitialCbEditField', obj.firstScalar(c.initial.cb));
|
||||
|
||||
obj.setTextAreaExpr('GWPRFTextArea', c.flow.gas_water.fracture_relperm_table);
|
||||
obj.setTextAreaExpr('GWRPGWTextArea', c.flow.gas_water.matrix_relperm_table);
|
||||
obj.setTextAreaExpr('OWPRFTextArea', c.flow.oil_water.fracture_relperm_table);
|
||||
obj.setTextAreaExpr('OWPRMTextArea', c.flow.oil_water.matrix_relperm_table);
|
||||
|
||||
obj.setTextAreaExpr('MCcs_NcTextArea', c.flow.multi_component.cs_Nc);
|
||||
obj.setTextAreaExpr('MCkr_nosurfTextArea', c.flow.multi_component.kr_nosurf);
|
||||
obj.setTextAreaExpr('MCkr_surfTextArea', c.flow.multi_component.kr_surf);
|
||||
obj.setTextAreaExpr('MCPCTextArea', c.flow.multi_component.PC);
|
||||
obj.setTextAreaExpr('MCcs_Nc_fractureTextArea', c.flow.multi_component.cs_Nc_fracture);
|
||||
obj.setTextAreaExpr('MCkr_nosurf_fractureTextArea', c.flow.multi_component.kr_nosurf_fracture);
|
||||
obj.setTextAreaExpr('MCkr_surf_fractureTextArea', c.flow.multi_component.kr_surf_fracture);
|
||||
obj.setTextAreaExpr('MCPC_fractureTextArea', c.flow.multi_component.PC_fracture);
|
||||
obj.setNumericFieldValue('MCp_grad_thresholdEditField', c.flow.multi_component.p_grad_threshold);
|
||||
obj.setNumericFieldValue('MCgas_propVLEditField', c.flow.multi_component.gas_prop.VL);
|
||||
obj.setNumericFieldValue('MCgas_propPLEditField', c.flow.multi_component.gas_prop.PL);
|
||||
obj.setNumericFieldValue('MCgas_propKnEditField', c.flow.multi_component.gas_prop.Kn);
|
||||
obj.setNumericFieldValue('MCstress_factor_fractureEditField', c.flow.multi_component.gas_prop.stress_factor_fracture);
|
||||
obj.setNumericFieldValue('MCstress_factor_matrixEditField', c.flow.multi_component.gas_prop.stress_factor_matrix);
|
||||
obj.setNumericFieldValue('MCstress_factor_ref_pressureEditField', c.flow.multi_component.gas_prop.stress_factor_ref_pressure);
|
||||
obj.setNumericFieldValue('MCbeta_non_darcy_flowEditField', c.flow.multi_component.gas_prop.beta_non_darcy_flow);
|
||||
obj.setNumericFieldValue('MCdensity_g_scEditField', c.flow.multi_component.density_g_sc);
|
||||
obj.setDropDownValue('MCgas_modelDropDown', c.flow.multi_component.gas_model);
|
||||
obj.setNumericFieldValue('MCprgEditField', obj.firstScalar(c.flow.multi_component.prg));
|
||||
obj.setNumericFieldValue('MCBgiEditField', obj.firstScalar(c.flow.multi_component.Bgi));
|
||||
obj.setNumericFieldValue('MCcgEditField', obj.firstScalar(c.flow.multi_component.cg));
|
||||
obj.setNumericFieldValue('MCvgiEditField', obj.firstScalar(c.flow.multi_component.vgi));
|
||||
obj.setNumericFieldValue('MCcvgEditField', obj.firstScalar(c.flow.multi_component.cvg));
|
||||
obj.setTextAreaExpr('MCPprTextArea', c.flow.multi_component.Ppr);
|
||||
obj.setTextAreaExpr('MCBGTextArea', c.flow.multi_component.BG);
|
||||
obj.setTextAreaExpr('MCMUGTextArea', c.flow.multi_component.MUG);
|
||||
obj.setNumericFieldValue('MCdensity_w_scEditField', c.flow.multi_component.density_w_sc);
|
||||
obj.setNumericFieldValue('MCprwEditField', obj.firstScalar(c.flow.multi_component.prw));
|
||||
obj.setNumericFieldValue('MCBwiEditField', obj.firstScalar(c.flow.multi_component.Bwi));
|
||||
obj.setNumericFieldValue('MCcwEditField', obj.firstScalar(c.flow.multi_component.cw));
|
||||
obj.setNumericFieldValue('MCvwiEditField', obj.firstScalar(c.flow.multi_component.vwi));
|
||||
obj.setNumericFieldValue('MCcvwEditField', obj.firstScalar(c.flow.multi_component.cvw));
|
||||
|
||||
obj.setTableValue('Well1Table', c.wells.well1);
|
||||
obj.setTableValue('FractureWellLocationTable', c.wells.welloc);
|
||||
obj.setTableValue('Well2Table', c.wells.well2);
|
||||
obj.setTableValue('ScheduleTable', c.schedule.well_schedules);
|
||||
obj.setTextAreaExpr('TimeTextArea', c.schedule.time);
|
||||
obj.setTextAreaExpr('DtMinTextArea', c.schedule.dtmin);
|
||||
obj.setTextAreaExpr('DtMaxTextArea', c.schedule.dtmax);
|
||||
|
||||
obj.setNumericFieldValue('YitaPEditField', c.solver.yitap);
|
||||
obj.setNumericFieldValue('YitaSEditField', c.solver.yitas);
|
||||
obj.setNumericFieldValue('OmegaEditField', c.solver.omega);
|
||||
obj.setNumericFieldValue('NmaxEditField', c.solver.Nmax);
|
||||
obj.setNumericFieldValue('EpsAveEditField', c.solver.epsave);
|
||||
obj.setNumericFieldValue('EpsMaxEditField', c.solver.epsmax);
|
||||
|
||||
obj.syncModelTabs();
|
||||
end
|
||||
|
||||
function pushUIToConfig(obj)
|
||||
if isempty(fieldnames(obj.Config))
|
||||
obj.Config = create_empty_config();
|
||||
end
|
||||
c = obj.Config;
|
||||
|
||||
c.model.modelflag = obj.getNumericDropDownValue('ModelFlagDropDown', c.model.modelflag);
|
||||
c.model.grid_model = obj.getNumericDropDownValue('ModelGridModelDropDown', c.model.grid_model);
|
||||
c.model.flow_model = obj.getNumericDropDownValue('ModelFlowModelDropDown', c.model.flow_model);
|
||||
|
||||
c.grid.dx = obj.getTextAreaExpr('GridDxTextArea', c.grid.dx);
|
||||
c.grid.dy = obj.getTextAreaExpr('GridDyTextArea', c.grid.dy);
|
||||
c.grid.dz = obj.getTextAreaExpr('GridDzTextArea', c.grid.dz);
|
||||
c.grid.NTG = obj.getTextAreaExpr('GridNTGTextArea', c.grid.NTG);
|
||||
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 = obj.getNumericDropDownValue('FractureInputStyleDropDown', c.fracture.input_style);
|
||||
c.fracture.input_content = obj.getTextAreaExpr('FractureInputTextArea', c.fracture.input_content);
|
||||
c.fracture.fractureLines = obj.getTextAreaExpr('FractureLinesTextArea', c.fracture.fractureLines);
|
||||
c.fracture.fractureHeights = obj.getTextAreaExpr('FractureHeightsTextArea', c.fracture.fractureHeights);
|
||||
c.fracture.flowBarrierFlags = obj.getTextAreaExpr('FractureFlowBarrierFlagsTextArea', c.fracture.flowBarrierFlags);
|
||||
|
||||
c.discretization.sp.boundary_polygon = obj.getTextAreaExpr('SPBoundaryTextArea', c.discretization.sp.boundary_polygon);
|
||||
c.discretization.sp.invalid_layer = obj.getTextAreaExpr('SPInvalidLayerTextArea', c.discretization.sp.invalid_layer);
|
||||
c.discretization.sp.matrix.kx = obj.getTextAreaExpr('SPMatrixKxTextArea', c.discretization.sp.matrix.kx);
|
||||
c.discretization.sp.matrix.ky = obj.getTextAreaExpr('SPMatrixKyTextArea', c.discretization.sp.matrix.ky);
|
||||
c.discretization.sp.matrix.kz = obj.getTextAreaExpr('SPMatrixKzTextArea', c.discretization.sp.matrix.kz);
|
||||
c.discretization.sp.matrix.pori = obj.getTextAreaExpr('SPMatrixPoriTextArea', c.discretization.sp.matrix.pori);
|
||||
c.discretization.sp.matrix.prpor = obj.getNumericFieldValue('SPMatrixPrporEditField', c.discretization.sp.matrix.prpor);
|
||||
c.discretization.sp.matrix.cpor = obj.getNumericFieldValue('SPMatrixCporEditField', c.discretization.sp.matrix.cpor);
|
||||
c.discretization.sp.matrix.rock_density = obj.getNumericFieldValue('SPRockDensityEditField', c.discretization.sp.matrix.rock_density);
|
||||
c.discretization.sp.fracture.Kf = obj.getTextAreaExpr('SPFractureKfTextArea', c.discretization.sp.fracture.Kf);
|
||||
c.discretization.sp.fracture.Wf = obj.getTextAreaExpr('SPFractureWfTextArea', c.discretization.sp.fracture.Wf);
|
||||
c.discretization.sp.fracture.Porf = obj.getTextAreaExpr('SPFracturePorfTextArea', c.discretization.sp.fracture.Porf);
|
||||
c.discretization.sp.fracture.prporf = obj.getNumericFieldValue('SPFracturePrporEditField', c.discretization.sp.fracture.prporf);
|
||||
c.discretization.sp.fracture.cporf = obj.getNumericFieldValue('SPFractureCporfEditField', c.discretization.sp.fracture.cporf);
|
||||
c.discretization.sp.stress.fracture_factor = obj.getNumericFieldValue('SPStressFractureEditField', c.discretization.sp.stress.fracture_factor);
|
||||
c.discretization.sp.stress.matrix_factor = obj.getNumericFieldValue('SPStressMatrixEditField', c.discretization.sp.stress.matrix_factor);
|
||||
c.discretization.sp.stress.ref_pressure = obj.getNumericFieldValue('SPStressRefPressureEditField', c.discretization.sp.stress.ref_pressure);
|
||||
|
||||
c.discretization.dp.fracture_layer.kx = obj.getTextAreaExpr('DPkxTextArea', c.discretization.dp.fracture_layer.kx);
|
||||
c.discretization.dp.fracture_layer.ky = obj.getTextAreaExpr('DPkyTextArea', c.discretization.dp.fracture_layer.ky);
|
||||
c.discretization.dp.fracture_layer.kz = obj.getTextAreaExpr('DPkzTextArea', c.discretization.dp.fracture_layer.kz);
|
||||
c.discretization.dp.matrix_layer.kx = obj.getTextAreaExpr('DPkx_matrixLayerTextArea', c.discretization.dp.matrix_layer.kx);
|
||||
c.discretization.dp.matrix_layer.ky = obj.getTextAreaExpr('DPky_matrixLayerTextArea', c.discretization.dp.matrix_layer.ky);
|
||||
c.discretization.dp.matrix_layer.kz = obj.getTextAreaExpr('DPkz_matrixLayerTextArea', c.discretization.dp.matrix_layer.kz);
|
||||
c.discretization.dp.matrix_layer.pori = obj.getTextAreaExpr('DPpori_matrixLayerTextArea', c.discretization.dp.matrix_layer.pori);
|
||||
c.discretization.dp.shape_factor = obj.getTextAreaExpr('DPsigmaTextArea', c.discretization.dp.shape_factor);
|
||||
c.discretization.dp.NTG = obj.getTextAreaExpr('DPNTGTextArea', c.discretization.dp.NTG);
|
||||
c.discretization.dp.prpor = obj.getNumericFieldValue('DPprporEditField', c.discretization.dp.prpor);
|
||||
c.discretization.dp.cpor = obj.getNumericFieldValue('DPcporEditField', c.discretization.dp.cpor);
|
||||
c.discretization.dp.fracture.Kf = obj.getTextAreaExpr('DPKfTextArea', c.discretization.dp.fracture.Kf);
|
||||
c.discretization.dp.fracture.Wf = obj.getTextAreaExpr('DPWfTextArea', c.discretization.dp.fracture.Wf);
|
||||
c.discretization.dp.fracture.Porf = obj.getTextAreaExpr('DPPorfTextArea', c.discretization.dp.fracture.Porf);
|
||||
c.discretization.dp.fracture.prporf = obj.getNumericFieldValue('DPprporfEditField', c.discretization.dp.fracture.prporf);
|
||||
c.discretization.dp.fracture.cporf = obj.getNumericFieldValue('DPcporfEditField', c.discretization.dp.fracture.cporf);
|
||||
c.discretization.dp.stress.fracture_factor = obj.getNumericFieldValue('DPstress_factor_fractureEditField', c.discretization.dp.stress.fracture_factor);
|
||||
c.discretization.dp.stress.matrix_factor = obj.getNumericFieldValue('DPstress_factor_matrixEditField', c.discretization.dp.stress.matrix_factor);
|
||||
c.discretization.dp.stress.ref_pressure = obj.getNumericFieldValue('DPstress_factor_ref_pressureEditField', c.discretization.dp.stress.ref_pressure);
|
||||
|
||||
c.initial.pressure = obj.getNumericFieldValue('InitialPressureEditField', c.initial.pressure);
|
||||
c.initial.sw = obj.getNumericFieldValue('InitialSwEditField', c.initial.sw);
|
||||
c.initial.cs = obj.getNumericFieldValue('InitialCsEditField', c.initial.cs);
|
||||
c.initial.cb = obj.getNumericFieldValue('InitialCbEditField', c.initial.cb);
|
||||
|
||||
c.flow.gas_water.matrix_relperm_table = obj.getTextAreaExpr('GWRPGWTextArea', c.flow.gas_water.matrix_relperm_table);
|
||||
c.flow.gas_water.fracture_relperm_table = obj.getTextAreaExpr('GWPRFTextArea', c.flow.gas_water.fracture_relperm_table);
|
||||
c.flow.oil_water.matrix_relperm_table = obj.getTextAreaExpr('OWPRMTextArea', c.flow.oil_water.matrix_relperm_table);
|
||||
c.flow.oil_water.fracture_relperm_table = obj.getTextAreaExpr('OWPRFTextArea', c.flow.oil_water.fracture_relperm_table);
|
||||
|
||||
c.flow.multi_component.cs_Nc = obj.getTextAreaExpr('MCcs_NcTextArea', c.flow.multi_component.cs_Nc);
|
||||
c.flow.multi_component.kr_nosurf = obj.getTextAreaExpr('MCkr_nosurfTextArea', c.flow.multi_component.kr_nosurf);
|
||||
c.flow.multi_component.kr_surf = obj.getTextAreaExpr('MCkr_surfTextArea', c.flow.multi_component.kr_surf);
|
||||
c.flow.multi_component.PC = obj.getTextAreaExpr('MCPCTextArea', c.flow.multi_component.PC);
|
||||
c.flow.multi_component.cs_Nc_fracture = obj.getTextAreaExpr('MCcs_Nc_fractureTextArea', c.flow.multi_component.cs_Nc_fracture);
|
||||
c.flow.multi_component.kr_nosurf_fracture = obj.getTextAreaExpr('MCkr_nosurf_fractureTextArea', c.flow.multi_component.kr_nosurf_fracture);
|
||||
c.flow.multi_component.kr_surf_fracture = obj.getTextAreaExpr('MCkr_surf_fractureTextArea', c.flow.multi_component.kr_surf_fracture);
|
||||
c.flow.multi_component.PC_fracture = obj.getTextAreaExpr('MCPC_fractureTextArea', c.flow.multi_component.PC_fracture);
|
||||
c.flow.multi_component.p_grad_threshold = obj.getNumericFieldValue('MCp_grad_thresholdEditField', c.flow.multi_component.p_grad_threshold);
|
||||
c.flow.multi_component.gas_prop.VL = obj.getNumericFieldValue('MCgas_propVLEditField', c.flow.multi_component.gas_prop.VL);
|
||||
c.flow.multi_component.gas_prop.PL = obj.getNumericFieldValue('MCgas_propPLEditField', c.flow.multi_component.gas_prop.PL);
|
||||
c.flow.multi_component.gas_prop.Kn = obj.getNumericFieldValue('MCgas_propKnEditField', c.flow.multi_component.gas_prop.Kn);
|
||||
c.flow.multi_component.gas_prop.stress_factor_fracture = obj.getNumericFieldValue('MCstress_factor_fractureEditField', c.flow.multi_component.gas_prop.stress_factor_fracture);
|
||||
c.flow.multi_component.gas_prop.stress_factor_matrix = obj.getNumericFieldValue('MCstress_factor_matrixEditField', c.flow.multi_component.gas_prop.stress_factor_matrix);
|
||||
c.flow.multi_component.gas_prop.stress_factor_ref_pressure = obj.getNumericFieldValue('MCstress_factor_ref_pressureEditField', c.flow.multi_component.gas_prop.stress_factor_ref_pressure);
|
||||
c.flow.multi_component.gas_prop.beta_non_darcy_flow = obj.getNumericFieldValue('MCbeta_non_darcy_flowEditField', c.flow.multi_component.gas_prop.beta_non_darcy_flow);
|
||||
c.flow.multi_component.density_g_sc = obj.getNumericFieldValue('MCdensity_g_scEditField', c.flow.multi_component.density_g_sc);
|
||||
c.flow.multi_component.gas_model = obj.getNumericDropDownValue('MCgas_modelDropDown', c.flow.multi_component.gas_model);
|
||||
c.flow.multi_component.prg = obj.getNumericFieldValue('MCprgEditField', c.flow.multi_component.prg);
|
||||
c.flow.multi_component.Bgi = obj.getNumericFieldValue('MCBgiEditField', c.flow.multi_component.Bgi);
|
||||
c.flow.multi_component.cg = obj.getNumericFieldValue('MCcgEditField', c.flow.multi_component.cg);
|
||||
c.flow.multi_component.vgi = obj.getNumericFieldValue('MCvgiEditField', c.flow.multi_component.vgi);
|
||||
c.flow.multi_component.cvg = obj.getNumericFieldValue('MCcvgEditField', c.flow.multi_component.cvg);
|
||||
c.flow.multi_component.Ppr = obj.getTextAreaExpr('MCPprTextArea', c.flow.multi_component.Ppr);
|
||||
c.flow.multi_component.BG = obj.getTextAreaExpr('MCBGTextArea', c.flow.multi_component.BG);
|
||||
c.flow.multi_component.MUG = obj.getTextAreaExpr('MCMUGTextArea', c.flow.multi_component.MUG);
|
||||
c.flow.multi_component.density_w_sc = obj.getNumericFieldValue('MCdensity_w_scEditField', c.flow.multi_component.density_w_sc);
|
||||
c.flow.multi_component.prw = obj.getNumericFieldValue('MCprwEditField', c.flow.multi_component.prw);
|
||||
c.flow.multi_component.Bwi = obj.getNumericFieldValue('MCBwiEditField', c.flow.multi_component.Bwi);
|
||||
c.flow.multi_component.cw = obj.getNumericFieldValue('MCcwEditField', c.flow.multi_component.cw);
|
||||
c.flow.multi_component.vwi = obj.getNumericFieldValue('MCvwiEditField', c.flow.multi_component.vwi);
|
||||
c.flow.multi_component.cvw = obj.getNumericFieldValue('MCcvwEditField', c.flow.multi_component.cvw);
|
||||
|
||||
c.wells.well1 = obj.getTableValue('Well1Table', c.wells.well1);
|
||||
c.wells.welloc = obj.getTableValue('FractureWellLocationTable', c.wells.welloc);
|
||||
c.wells.num_fracture_wells = numel(c.wells.welloc);
|
||||
c.wells.well2 = obj.getTableValue('Well2Table', c.wells.well2);
|
||||
|
||||
c.schedule.well_schedules = obj.getTableValue('ScheduleTable', c.schedule.well_schedules);
|
||||
c.schedule.number_phases = numel(c.schedule.well_schedules);
|
||||
c.schedule.time = obj.getTextAreaExpr('TimeTextArea', c.schedule.time);
|
||||
c.schedule.dtmin = obj.getTextAreaExpr('DtMinTextArea', c.schedule.dtmin);
|
||||
c.schedule.dtmax = obj.getTextAreaExpr('DtMaxTextArea', c.schedule.dtmax);
|
||||
|
||||
c.solver.yitap = obj.getNumericFieldValue('YitaPEditField', c.solver.yitap);
|
||||
c.solver.yitas = obj.getNumericFieldValue('YitaSEditField', c.solver.yitas);
|
||||
c.solver.omega = obj.getNumericFieldValue('OmegaEditField', c.solver.omega);
|
||||
c.solver.Nmax = obj.getNumericFieldValue('NmaxEditField', c.solver.Nmax);
|
||||
c.solver.epsave = obj.getNumericFieldValue('EpsAveEditField', c.solver.epsave);
|
||||
c.solver.epsmax = obj.getNumericFieldValue('EpsMaxEditField', c.solver.epsmax);
|
||||
|
||||
obj.Config = c;
|
||||
obj.syncModelTabs();
|
||||
end
|
||||
|
||||
function refreshResults(obj)
|
||||
summary = {};
|
||||
if isempty(fieldnames(obj.Results))
|
||||
summary = {'No results loaded.'};
|
||||
obj.setRunHeader('-', '-', '-');
|
||||
obj.setRunProgress('Idle');
|
||||
obj.setResultsTable({});
|
||||
if isprop(obj.App, 'ResultAxes')
|
||||
cla(obj.App.ResultAxes);
|
||||
title(obj.App.ResultAxes, 'Results');
|
||||
end
|
||||
else
|
||||
if isfield(obj.Results, 'Times') && ~isempty(obj.Results.Times)
|
||||
summary{end + 1} = sprintf('Time steps: %d', numel(obj.Results.Times)); %#ok<AGROW>
|
||||
end
|
||||
if isfield(obj.Results, 'trun') && isstruct(obj.Results.trun)
|
||||
if isfield(obj.Results.trun, 'run_time')
|
||||
summary{end + 1} = sprintf('Run time: %.3f s', obj.Results.trun.run_time); %#ok<AGROW>
|
||||
end
|
||||
if isfield(obj.Results.trun, 'Newton_step')
|
||||
summary{end + 1} = sprintf('Newton steps: %g', obj.Results.trun.Newton_step); %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
if isempty(summary)
|
||||
summary = {'Results loaded.'};
|
||||
end
|
||||
obj.populateRunHeaderFromResults();
|
||||
obj.setResultsTable(obj.buildResultsTableData());
|
||||
obj.plotResults();
|
||||
end
|
||||
|
||||
if isprop(obj.App, 'ResultSummaryTextArea')
|
||||
obj.App.ResultSummaryTextArea.Value = summary;
|
||||
end
|
||||
end
|
||||
|
||||
function populateRunHeaderFromResults(obj)
|
||||
stageText = '-';
|
||||
timeText = '-';
|
||||
dtText = '-';
|
||||
if isfield(obj.Results, 'Times') && ~isempty(obj.Results.Times)
|
||||
stageText = sprintf('%d', numel(obj.Results.Times));
|
||||
timeText = obj.valueToShortText(obj.Results.Times(end));
|
||||
if numel(obj.Results.Times) >= 2
|
||||
dtText = obj.valueToShortText(obj.Results.Times(end) - obj.Results.Times(end - 1));
|
||||
end
|
||||
end
|
||||
obj.setRunHeader(stageText, timeText, dtText);
|
||||
end
|
||||
|
||||
function tableData = buildResultsTableData(obj)
|
||||
tableData = {
|
||||
'has_r', isfield(obj.Results, 'r');
|
||||
'num_times', obj.safeLength(obj.Results, 'Times');
|
||||
'num_outputs', obj.safeLength(obj.Results, 'OutputRs');
|
||||
'num_wellpara', obj.safeLength(obj.Results, 'Wellpara')
|
||||
};
|
||||
end
|
||||
|
||||
function n = safeLength(~, s, fieldName)
|
||||
if isfield(s, fieldName) && ~isempty(s.(fieldName))
|
||||
n = numel(s.(fieldName));
|
||||
else
|
||||
n = 0;
|
||||
end
|
||||
end
|
||||
|
||||
function setStatus(obj, textValue)
|
||||
if isprop(obj.App, 'StatusLabel')
|
||||
obj.App.StatusLabel.Text = ['Status: ', char(string(textValue))];
|
||||
end
|
||||
end
|
||||
|
||||
function appendLog(obj, textValue)
|
||||
if ~isprop(obj.App, 'RunLogTextArea')
|
||||
return;
|
||||
end
|
||||
newLines = splitlines(string(textValue));
|
||||
if isempty(obj.App.RunLogTextArea.Value)
|
||||
obj.App.RunLogTextArea.Value = cellstr(newLines);
|
||||
else
|
||||
current = string(obj.App.RunLogTextArea.Value);
|
||||
obj.App.RunLogTextArea.Value = cellstr([current; newLines]);
|
||||
end
|
||||
drawnow limitrate;
|
||||
end
|
||||
|
||||
function setRunProgress(obj, textValue)
|
||||
if isprop(obj.App, 'RunProgressLabel')
|
||||
obj.App.RunProgressLabel.Text = ['RunProgress: ', char(string(textValue))];
|
||||
end
|
||||
end
|
||||
|
||||
function setRunHeader(obj, stageText, timeText, dtText)
|
||||
if isprop(obj.App, 'CurrentStageLabel')
|
||||
obj.App.CurrentStageLabel.Text = ['Stage: ', char(string(stageText))];
|
||||
end
|
||||
if isprop(obj.App, 'CurrentTimeLabel')
|
||||
obj.App.CurrentTimeLabel.Text = ['Time: ', char(string(timeText))];
|
||||
end
|
||||
if isprop(obj.App, 'CurrentDtLabel')
|
||||
obj.App.CurrentDtLabel.Text = ['dt: ', char(string(dtText))];
|
||||
end
|
||||
end
|
||||
|
||||
function setResultsTable(obj, data)
|
||||
if isprop(obj.App, 'ResultTab')
|
||||
obj.App.ResultTab.Data = data;
|
||||
end
|
||||
end
|
||||
|
||||
function setDropDownItems(obj, propName, items, defaultValue)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
end
|
||||
component = obj.App.(propName);
|
||||
component.Items = items;
|
||||
if nargin >= 4
|
||||
component.Value = char(string(defaultValue));
|
||||
end
|
||||
end
|
||||
|
||||
function setDropDownValue(obj, propName, value)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
end
|
||||
component = obj.App.(propName);
|
||||
stringValue = char(string(value));
|
||||
if ~any(strcmp(component.Items, stringValue))
|
||||
component.Items = unique([component.Items(:); {stringValue}], 'stable');
|
||||
end
|
||||
component.Value = stringValue;
|
||||
end
|
||||
|
||||
function value = getDropDownValue(obj, propName, fallback)
|
||||
if nargin < 3
|
||||
fallback = '';
|
||||
end
|
||||
if ~isprop(obj.App, propName)
|
||||
value = fallback;
|
||||
return;
|
||||
end
|
||||
value = obj.App.(propName).Value;
|
||||
if isempty(value)
|
||||
value = fallback;
|
||||
end
|
||||
end
|
||||
|
||||
function value = getNumericDropDownValue(obj, propName, fallback)
|
||||
value = str2double(obj.getDropDownValue(propName, num2str(fallback)));
|
||||
if isnan(value)
|
||||
value = fallback;
|
||||
end
|
||||
end
|
||||
|
||||
function setNumericFieldValue(obj, propName, value)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
end
|
||||
obj.App.(propName).Value = obj.firstScalar(value);
|
||||
end
|
||||
|
||||
function value = getNumericFieldValue(obj, propName, fallback)
|
||||
if ~isprop(obj.App, propName)
|
||||
value = fallback;
|
||||
return;
|
||||
end
|
||||
value = obj.App.(propName).Value;
|
||||
if isempty(value)
|
||||
value = fallback;
|
||||
end
|
||||
end
|
||||
|
||||
function setTextAreaExpr(obj, propName, value)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
end
|
||||
obj.App.(propName).Value = splitlines(string(obj.valueToExpression(value)));
|
||||
end
|
||||
|
||||
function value = getTextAreaExpr(obj, propName, fallback)
|
||||
if ~isprop(obj.App, propName)
|
||||
value = fallback;
|
||||
return;
|
||||
end
|
||||
textValue = strtrim(strjoin(string(obj.App.(propName).Value), newline));
|
||||
if textValue == ""
|
||||
value = fallback;
|
||||
return;
|
||||
end
|
||||
try
|
||||
value = eval(char(textValue)); %#ok<EVLDIR>
|
||||
catch ME
|
||||
error('EDFMAppController:ParseError', ...
|
||||
'Failed to parse %s. MATLAB expression expected. %s', propName, ME.message);
|
||||
end
|
||||
end
|
||||
|
||||
function setTableValue(obj, propName, value)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
end
|
||||
if isempty(value)
|
||||
obj.App.(propName).Data = {};
|
||||
elseif isnumeric(value)
|
||||
obj.App.(propName).Data = num2cell(value);
|
||||
else
|
||||
obj.App.(propName).Data = value;
|
||||
end
|
||||
end
|
||||
|
||||
function value = getTableValue(obj, propName, fallback)
|
||||
if ~isprop(obj.App, propName)
|
||||
value = fallback;
|
||||
return;
|
||||
end
|
||||
data = obj.App.(propName).Data;
|
||||
if isempty(data)
|
||||
value = fallback;
|
||||
else
|
||||
value = data;
|
||||
end
|
||||
end
|
||||
|
||||
function setEditableState(obj, propName, isEnabled)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
end
|
||||
component = obj.App.(propName);
|
||||
if isprop(component, 'Editable')
|
||||
component.Editable = matlab.lang.OnOffSwitchState(isEnabled);
|
||||
end
|
||||
if isprop(component, 'Enable')
|
||||
if isEnabled
|
||||
component.Enable = 'on';
|
||||
else
|
||||
component.Enable = 'off';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function value = firstScalar(~, rawValue)
|
||||
if isempty(rawValue)
|
||||
value = 0;
|
||||
elseif isscalar(rawValue)
|
||||
value = rawValue;
|
||||
else
|
||||
value = rawValue(1);
|
||||
end
|
||||
end
|
||||
|
||||
function textValue = valueToShortText(~, rawValue)
|
||||
if isempty(rawValue)
|
||||
textValue = '-';
|
||||
elseif isscalar(rawValue)
|
||||
textValue = num2str(rawValue);
|
||||
else
|
||||
textValue = sprintf('[%s]', strjoin(string(size(rawValue)), 'x'));
|
||||
end
|
||||
end
|
||||
|
||||
function textValue = valueToExpression(obj, value)
|
||||
if isempty(value)
|
||||
textValue = '[]';
|
||||
return;
|
||||
end
|
||||
if isnumeric(value) || islogical(value)
|
||||
textValue = mat2str(value);
|
||||
return;
|
||||
end
|
||||
if ischar(value)
|
||||
textValue = ['''', strrep(value, '''', ''''''), ''''];
|
||||
return;
|
||||
end
|
||||
if isstring(value) && isscalar(value)
|
||||
textValue = ['''', 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} = obj.valueToExpression(value{i, j});
|
||||
end
|
||||
rows{i} = strjoin(cols, ', ');
|
||||
end
|
||||
textValue = ['{', strjoin(rows, [';', newline]), '}'];
|
||||
return;
|
||||
end
|
||||
textValue = strtrim(evalc('disp(value)'));
|
||||
end
|
||||
end
|
||||
end
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user