diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..277122d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +edfm_gui_v1.1-2026.3.24.zip diff --git a/docs/parameter_registry.md b/docs/parameter_registry.md index ed29f84..1693bfe 100644 --- a/docs/parameter_registry.md +++ b/docs/parameter_registry.md @@ -27,10 +27,14 @@ It is intentionally field-oriented so the future GUI can be built against a stab | Config Path | Source Variable | Source File | Cases | Editable | Notes | | --- | --- | --- | --- | --- | --- | -| `model.modelflag` | `modelflag` | `main1.m` | 1-7 | yes | Current examples use `1` | | `model.grid_model` | `grid_model` | `main1.m` | 1-7 | yes | `1` SP, `2` DP | | `model.flow_model` | `flow_model` | `main1.m` | 1-7 | yes | `1` gas-water, `2` oil-water, `3` multi-component | +Current GUI/runtime simplification: + +- `modelflag` has been removed from the editable config schema. +- Runtime always uses `modelflag = 1`. + ## Grid Geometry | Config Path | Source Variable | Source File | Cases | Editable | Notes | @@ -63,16 +67,18 @@ Derived fields produced by `GridProp_pre.m`: | Config Path | Source Variable | Source File | Cases | Editable | Notes | | --- | --- | --- | --- | --- | --- | -| `fracture.input_style` | `input_style` | `main1.m` | 1-7 | yes | 1 engineering, 2 vector, 3 2D lines, 4 fab reserved | | `fracture.input_content` | `input_content` | `main1.m` | 1-7 | yes | Engineering fracture table | | `fracture.f` | `f` | `main1.m` / helper outputs | 1-7 | advanced | Vector fracture representation | | `fracture.fellip` | `fellip` | `main1.m` / helper outputs | 1-7 | advanced | Elliptic fractures | -| `fracture.fractureLines` | `fractureLines` | `main1.m` | 1-7 | yes | Used in mode 3 | -| `fracture.fractureHeights` | `fractureHeights` | `main1.m` | 1-7 | yes | Used in mode 3 | -| `fracture.flowBarrierFlags` | `flowBarrierFlags` | `main1.m` | 1-7 | yes | Optional | | `fracture.frac_information` | `frac_information` | helper outputs | 1-7 | no | Generated by helper functions | | `fracture.nf` | `nf` | `main1.m` | 1-7 | no | Derived fracture count | +Current GUI/runtime simplification: + +- `FractureInputStyle` has been removed from the editable config schema. +- Runtime always uses the engineering-table path that reads `fracture.input_content`. +- `fractureLines`, `fractureHeights`, and `flowBarrierFlags` have been removed from the editable schema. + ## Discretization Selection | Config Path | Source Variable | Source File | Cases | Editable | Notes | diff --git a/docs/project_status_overview.md b/docs/project_status_overview.md index d76ee15..0263c75 100644 --- a/docs/project_status_overview.md +++ b/docs/project_status_overview.md @@ -64,6 +64,12 @@ The three flow models are mutually exclusive: The GUI should only show the active flow model's parameters. Inactive model parameters should not be shown or used during runtime. +Current GUI simplifications now fixed in code: + +- `modelflag` is no longer exposed; runtime always uses `1`. +- fracture input now uses only `FractureInput` / `fracture.input_content` +- `FractureInputStyle`, `FractureLines`, `FractureHeights`, and `FlowBarrierFlags` are no longer part of the active editable workflow + ## What Has Been Completed ## 1. Parameter extraction and organization diff --git a/gui_support/app/EDFMAppController.m b/gui_support/app/EDFMAppController.m index dd7c406..fcb4217 100644 --- a/gui_support/app/EDFMAppController.m +++ b/gui_support/app/EDFMAppController.m @@ -19,14 +19,13 @@ classdef EDFMAppController < handle {'case01', 'case02', 'case03', 'case04', 'case05', 'case06', 'case07'}, ... '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.configureWellTables(); + obj.applyFixedUIState(); obj.Results = struct(); obj.loadTemplate('case01'); @@ -35,7 +34,7 @@ classdef EDFMAppController < handle end function newConfig(obj) - obj.Config = create_empty_config(); + obj.Config = normalize_config(create_empty_config()); obj.Results = struct(); obj.refreshUIFromConfig(); obj.refreshResults(); @@ -355,9 +354,9 @@ classdef EDFMAppController < handle if isempty(fieldnames(obj.Config)) return; end - c = obj.Config; + c = normalize_config(obj.Config); + obj.Config = c; - obj.setDropDownValue('ModelFlagDropDown', c.model.modelflag); obj.setDropDownValue('ModelGridModelDropDown', c.model.grid_model); obj.setDropDownValue('ModelFlowModelDropDown', c.model.flow_model); @@ -366,11 +365,7 @@ classdef EDFMAppController < handle 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); @@ -468,6 +463,7 @@ classdef EDFMAppController < handle obj.setNumericFieldValue('EpsAveEditField', c.solver.epsave); obj.setNumericFieldValue('EpsMaxEditField', c.solver.epsmax); + obj.applyFixedUIState(); obj.syncModelTabs(); end @@ -475,9 +471,8 @@ classdef EDFMAppController < handle if isempty(fieldnames(obj.Config)) obj.Config = create_empty_config(); end - c = obj.Config; + c = normalize_config(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); @@ -489,11 +484,7 @@ classdef EDFMAppController < handle 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); @@ -602,6 +593,22 @@ classdef EDFMAppController < handle obj.syncModelTabs(); end + function applyFixedUIState(obj) + obj.setControlVisible('ModelFlagDropDownLabel', false); + obj.setControlVisible('ModelFlagDropDown', false); + obj.setControlVisible('FractureInputStyleDropDownLabel', false); + obj.setControlVisible('FractureInputStyleDropDown', false); + obj.setControlVisible('FractureLinesTextAreaLabel', false); + obj.setControlVisible('FractureLinesTextArea', false); + obj.setControlVisible('FractureHeightsTextAreaLabel', false); + obj.setControlVisible('FractureHeightsTextArea', false); + obj.setControlVisible('FlowBarrierFlagsTextAreaLabel', false); + obj.setControlVisible('FractureFlowBarrierFlagsTextArea', false); + + obj.setEditableState('ModelFlagDropDown', false); + obj.setEditableState('FractureInputStyleDropDown', false); + end + function refreshResults(obj) summary = {}; if isempty(fieldnames(obj.Results)) diff --git a/gui_support/app/EDFMSimulatorApp.m b/gui_support/app/EDFMSimulatorApp.m deleted file mode 100644 index 6eadafa..0000000 --- a/gui_support/app/EDFMSimulatorApp.m +++ /dev/null @@ -1,332 +0,0 @@ -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 - 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 - if isfield(app.Results.trun, 'Newton_step'), summary{end+1} = ['Newton steps: ', num2str(app.Results.trun.Newton_step)]; end %#ok - 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 - txt = strtrim(strjoin(string(lines), newline)); - if txt == "", out = []; else, out = eval(txt); end %#ok - end - - function txt = toExpr(app, value) %#ok - 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 - 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 diff --git a/gui_support/app/EDFM_Simulator_App.m b/gui_support/app/EDFM_Simulator_App.m deleted file mode 100644 index 0731d68..0000000 --- a/gui_support/app/EDFM_Simulator_App.m +++ /dev/null @@ -1,917 +0,0 @@ -classdef EDFM_Simulator_App < matlab.apps.AppBase - - % Properties that correspond to app components - properties (Access = public) - UIFigure matlab.ui.Figure - MainGrid matlab.ui.container.GridLayout - TopGrid matlab.ui.container.GridLayout - - TemplateDropDown matlab.ui.control.DropDown - LoadTemplateButton matlab.ui.control.Button - ImportConfigButton matlab.ui.control.Button - ExportConfigButton matlab.ui.control.Button - RunButton matlab.ui.control.Button - ImportResultButton matlab.ui.control.Button - ExportResultButton matlab.ui.control.Button - StatusLabel matlab.ui.control.Label - - MainTabGroup matlab.ui.container.TabGroup - Part1Tab matlab.ui.container.Tab - Part2Tab matlab.ui.container.Tab - Part3Tab matlab.ui.container.Tab - Part4Tab matlab.ui.container.Tab - Part5Tab matlab.ui.container.Tab - Part6Tab matlab.ui.container.Tab - Part7Tab matlab.ui.container.Tab - RunTab matlab.ui.container.Tab - ResultTab matlab.ui.container.Tab - - Part1Grid matlab.ui.container.GridLayout - ModelFlagLabel matlab.ui.control.Label - ModelFlagDropDown matlab.ui.control.DropDown - GridModelLabel matlab.ui.control.Label - GridModelDropDown matlab.ui.control.DropDown - FlowModelLabel matlab.ui.control.Label - FlowModelDropDown matlab.ui.control.DropDown - - Part2Grid matlab.ui.container.GridLayout - DxLabel matlab.ui.control.Label - DxTextArea matlab.ui.control.TextArea - DyLabel matlab.ui.control.Label - DyTextArea matlab.ui.control.TextArea - DzLabel matlab.ui.control.Label - DzTextArea matlab.ui.control.TextArea - NTGLabel matlab.ui.control.Label - NTGTextArea matlab.ui.control.TextArea - - Part3Grid matlab.ui.container.GridLayout - FractureInputStyleLabel matlab.ui.control.Label - FractureInputStyleDropDown matlab.ui.control.DropDown - FractureInputLabel matlab.ui.control.Label - FractureInputTextArea matlab.ui.control.TextArea - FractureLinesLabel matlab.ui.control.Label - FractureLinesTextArea matlab.ui.control.TextArea - FractureHeightsLabel matlab.ui.control.Label - FractureHeightsTextArea matlab.ui.control.TextArea - FlowBarrierFlagsLabel matlab.ui.control.Label - FlowBarrierFlagsTextArea matlab.ui.control.TextArea - - Part4Grid matlab.ui.container.GridLayout - BoundaryLabel matlab.ui.control.Label - BoundaryTextArea matlab.ui.control.TextArea - InvalidLayerLabel matlab.ui.control.Label - InvalidLayerTextArea matlab.ui.control.TextArea - MatrixKxLabel matlab.ui.control.Label - MatrixKxTextArea matlab.ui.control.TextArea - MatrixKyLabel matlab.ui.control.Label - MatrixKyTextArea matlab.ui.control.TextArea - MatrixKzLabel matlab.ui.control.Label - MatrixKzTextArea matlab.ui.control.TextArea - MatrixPoriLabel matlab.ui.control.Label - MatrixPoriTextArea matlab.ui.control.TextArea - MatrixPrporLabel matlab.ui.control.Label - MatrixPrporField matlab.ui.control.NumericEditField - MatrixCporLabel matlab.ui.control.Label - MatrixCporField matlab.ui.control.NumericEditField - RockDensityLabel matlab.ui.control.Label - RockDensityField matlab.ui.control.NumericEditField - FractureKfLabel matlab.ui.control.Label - FractureKfTextArea matlab.ui.control.TextArea - FractureWfLabel matlab.ui.control.Label - FractureWfTextArea matlab.ui.control.TextArea - FracturePorfLabel matlab.ui.control.Label - FracturePorfTextArea matlab.ui.control.TextArea - - Part5Grid matlab.ui.container.GridLayout - InitialPanel matlab.ui.container.Panel - InitialGrid matlab.ui.container.GridLayout - InitialPressureLabel matlab.ui.control.Label - InitialPressureField matlab.ui.control.NumericEditField - InitialSwLabel matlab.ui.control.Label - InitialSwField matlab.ui.control.NumericEditField - InitialCsLabel matlab.ui.control.Label - InitialCsField matlab.ui.control.NumericEditField - InitialCbLabel matlab.ui.control.Label - InitialCbField matlab.ui.control.NumericEditField - - FlowSubTabGroup matlab.ui.container.TabGroup - GasWaterTab matlab.ui.container.Tab - OilWaterTab matlab.ui.container.Tab - MultiComponentTab matlab.ui.container.Tab - - GasWaterGrid matlab.ui.container.GridLayout - GasRelPermLabel matlab.ui.control.Label - GasRelPermTextArea matlab.ui.control.TextArea - GasPVTLabel matlab.ui.control.Label - GasPVTTextArea matlab.ui.control.TextArea - - OilWaterGrid matlab.ui.container.GridLayout - OilRelPermLabel matlab.ui.control.Label - OilRelPermTextArea matlab.ui.control.TextArea - OilPVTLabel matlab.ui.control.Label - OilPVTTextArea matlab.ui.control.TextArea - - MultiComponentGrid matlab.ui.container.GridLayout - AdsorptionLabel matlab.ui.control.Label - AdsorptionTextArea matlab.ui.control.TextArea - NcTableLabel matlab.ui.control.Label - NcTableTextArea matlab.ui.control.TextArea - KrNoSurfLabel matlab.ui.control.Label - KrNoSurfTextArea matlab.ui.control.TextArea - KrSurfLabel matlab.ui.control.Label - KrSurfTextArea matlab.ui.control.TextArea - PcTableLabel matlab.ui.control.Label - PcTableTextArea matlab.ui.control.TextArea - - Part6Grid matlab.ui.container.GridLayout - Well1Label matlab.ui.control.Label - Well1Table matlab.ui.control.Table - FractureWellLocationLabel matlab.ui.control.Label - FractureWellLocationTable matlab.ui.control.Table - Well2Label matlab.ui.control.Label - Well2Table matlab.ui.control.Table - ScheduleLabel matlab.ui.control.Label - ScheduleTable matlab.ui.control.Table - TimeLabel matlab.ui.control.Label - TimeTextArea matlab.ui.control.TextArea - DtMinLabel matlab.ui.control.Label - DtMinTextArea matlab.ui.control.TextArea - DtMaxLabel matlab.ui.control.Label - DtMaxTextArea matlab.ui.control.TextArea - - Part7Grid matlab.ui.container.GridLayout - YitaPLabel matlab.ui.control.Label - YitaPField matlab.ui.control.NumericEditField - YitaSLabel matlab.ui.control.Label - YitaSField matlab.ui.control.NumericEditField - OmegaLabel matlab.ui.control.Label - OmegaField matlab.ui.control.NumericEditField - NmaxLabel matlab.ui.control.Label - NmaxField matlab.ui.control.NumericEditField - EpsAveLabel matlab.ui.control.Label - EpsAveField matlab.ui.control.NumericEditField - EpsMaxLabel matlab.ui.control.Label - EpsMaxField matlab.ui.control.NumericEditField - - RunGrid matlab.ui.container.GridLayout - RunCurrentConfigButton matlab.ui.control.Button - CurrentStageLabel matlab.ui.control.Label - CurrentTimeLabel matlab.ui.control.Label - CurrentDtLabel matlab.ui.control.Label - RunLogTextArea matlab.ui.control.TextArea - - ResultGrid matlab.ui.container.GridLayout - ResultLeftGrid matlab.ui.container.GridLayout - ResultSummaryLabel matlab.ui.control.Label - ResultSummaryTextArea matlab.ui.control.TextArea - ResultTypeLabel matlab.ui.control.Label - ResultTypeDropDown matlab.ui.control.DropDown - PlotResultButton matlab.ui.control.Button - ResultAxes matlab.ui.control.UIAxes - end - - % Component initialization - methods (Access = private) - - % Create UIFigure and components - function createComponents(app) - - % Create UIFigure and hide until all components are created - app.UIFigure = uifigure('Visible', 'off'); - app.UIFigure.Position = [100 100 1500 920]; - app.UIFigure.Name = 'EDFM Simulator App'; - - % Create MainGrid - app.MainGrid = uigridlayout(app.UIFigure); - app.MainGrid.ColumnWidth = {'1x'}; - app.MainGrid.RowHeight = {48, '1x'}; - app.MainGrid.Padding = [8 8 8 8]; - - % Create TopGrid - app.TopGrid = uigridlayout(app.MainGrid); - app.TopGrid.Layout.Row = 1; - app.TopGrid.Layout.Column = 1; - app.TopGrid.RowHeight = {'1x'}; - app.TopGrid.ColumnWidth = {140, 110, 110, 110, 90, 110, 110, '1x', 180}; - app.TopGrid.ColumnSpacing = 8; - app.TopGrid.Padding = [0 0 0 0]; - - % Create top controls - app.TemplateDropDown = uidropdown(app.TopGrid); - app.TemplateDropDown.Layout.Row = 1; - app.TemplateDropDown.Layout.Column = 1; - app.TemplateDropDown.Items = {'case01'}; - app.TemplateDropDown.Value = 'case01'; - - app.LoadTemplateButton = uibutton(app.TopGrid, 'push'); - app.LoadTemplateButton.Layout.Row = 1; - app.LoadTemplateButton.Layout.Column = 2; - app.LoadTemplateButton.Text = 'Load Template'; - - app.ImportConfigButton = uibutton(app.TopGrid, 'push'); - app.ImportConfigButton.Layout.Row = 1; - app.ImportConfigButton.Layout.Column = 3; - app.ImportConfigButton.Text = 'Import Config'; - - app.ExportConfigButton = uibutton(app.TopGrid, 'push'); - app.ExportConfigButton.Layout.Row = 1; - app.ExportConfigButton.Layout.Column = 4; - app.ExportConfigButton.Text = 'Export Config'; - - app.RunButton = uibutton(app.TopGrid, 'push'); - app.RunButton.Layout.Row = 1; - app.RunButton.Layout.Column = 5; - app.RunButton.Text = 'Run'; - - app.ImportResultButton = uibutton(app.TopGrid, 'push'); - app.ImportResultButton.Layout.Row = 1; - app.ImportResultButton.Layout.Column = 6; - app.ImportResultButton.Text = 'Import Result'; - - app.ExportResultButton = uibutton(app.TopGrid, 'push'); - app.ExportResultButton.Layout.Row = 1; - app.ExportResultButton.Layout.Column = 7; - app.ExportResultButton.Text = 'Export Result'; - - app.StatusLabel = uilabel(app.TopGrid); - app.StatusLabel.Layout.Row = 1; - app.StatusLabel.Layout.Column = 9; - app.StatusLabel.HorizontalAlignment = 'right'; - app.StatusLabel.Text = 'Status: Ready'; - - % Create MainTabGroup - app.MainTabGroup = uitabgroup(app.MainGrid); - app.MainTabGroup.Layout.Row = 2; - app.MainTabGroup.Layout.Column = 1; - - % Create tabs - app.Part1Tab = uitab(app.MainTabGroup); - app.Part1Tab.Title = 'Part1 Model'; - - app.Part2Tab = uitab(app.MainTabGroup); - app.Part2Tab.Title = 'Part2 Grid'; - - app.Part3Tab = uitab(app.MainTabGroup); - app.Part3Tab.Title = 'Part3 Fracture'; - - app.Part4Tab = uitab(app.MainTabGroup); - app.Part4Tab.Title = 'Part4 Discretization'; - - app.Part5Tab = uitab(app.MainTabGroup); - app.Part5Tab.Title = 'Part5 Flow'; - - app.Part6Tab = uitab(app.MainTabGroup); - app.Part6Tab.Title = 'Part6 Wells'; - - app.Part7Tab = uitab(app.MainTabGroup); - app.Part7Tab.Title = 'Part7 Solver'; - - app.RunTab = uitab(app.MainTabGroup); - app.RunTab.Title = 'Run'; - - app.ResultTab = uitab(app.MainTabGroup); - app.ResultTab.Title = 'Results'; - - % ---------------- Part1 ---------------- - app.Part1Grid = uigridlayout(app.Part1Tab); - app.Part1Grid.ColumnWidth = {180, '1x'}; - app.Part1Grid.RowHeight = {32, 32, 32, '1x'}; - app.Part1Grid.Padding = [12 12 12 12]; - - app.ModelFlagLabel = uilabel(app.Part1Grid); - app.ModelFlagLabel.Layout.Row = 1; - app.ModelFlagLabel.Layout.Column = 1; - app.ModelFlagLabel.Text = 'Model Flag'; - - app.ModelFlagDropDown = uidropdown(app.Part1Grid); - app.ModelFlagDropDown.Layout.Row = 1; - app.ModelFlagDropDown.Layout.Column = 2; - app.ModelFlagDropDown.Items = {'1'}; - app.ModelFlagDropDown.Value = '1'; - - app.GridModelLabel = uilabel(app.Part1Grid); - app.GridModelLabel.Layout.Row = 2; - app.GridModelLabel.Layout.Column = 1; - app.GridModelLabel.Text = 'Grid Model'; - - app.GridModelDropDown = uidropdown(app.Part1Grid); - app.GridModelDropDown.Layout.Row = 2; - app.GridModelDropDown.Layout.Column = 2; - app.GridModelDropDown.Items = {'1', '2'}; - app.GridModelDropDown.Value = '1'; - - app.FlowModelLabel = uilabel(app.Part1Grid); - app.FlowModelLabel.Layout.Row = 3; - app.FlowModelLabel.Layout.Column = 1; - app.FlowModelLabel.Text = 'Flow Model'; - - app.FlowModelDropDown = uidropdown(app.Part1Grid); - app.FlowModelDropDown.Layout.Row = 3; - app.FlowModelDropDown.Layout.Column = 2; - app.FlowModelDropDown.Items = {'1', '2', '3'}; - app.FlowModelDropDown.Value = '3'; - - % ---------------- Part2 ---------------- - app.Part2Grid = uigridlayout(app.Part2Tab); - app.Part2Grid.ColumnWidth = {140, '1x'}; - app.Part2Grid.RowHeight = {110, 110, 110, '1x'}; - app.Part2Grid.Padding = [12 12 12 12]; - - app.DxLabel = uilabel(app.Part2Grid); - app.DxLabel.Layout.Row = 1; - app.DxLabel.Layout.Column = 1; - app.DxLabel.Text = 'dx'; - - app.DxTextArea = uitextarea(app.Part2Grid); - app.DxTextArea.Layout.Row = 1; - app.DxTextArea.Layout.Column = 2; - - app.DyLabel = uilabel(app.Part2Grid); - app.DyLabel.Layout.Row = 2; - app.DyLabel.Layout.Column = 1; - app.DyLabel.Text = 'dy'; - - app.DyTextArea = uitextarea(app.Part2Grid); - app.DyTextArea.Layout.Row = 2; - app.DyTextArea.Layout.Column = 2; - - app.DzLabel = uilabel(app.Part2Grid); - app.DzLabel.Layout.Row = 3; - app.DzLabel.Layout.Column = 1; - app.DzLabel.Text = 'dz'; - - app.DzTextArea = uitextarea(app.Part2Grid); - app.DzTextArea.Layout.Row = 3; - app.DzTextArea.Layout.Column = 2; - - app.NTGLabel = uilabel(app.Part2Grid); - app.NTGLabel.Layout.Row = 4; - app.NTGLabel.Layout.Column = 1; - app.NTGLabel.Text = 'NTG'; - - app.NTGTextArea = uitextarea(app.Part2Grid); - app.NTGTextArea.Layout.Row = 4; - app.NTGTextArea.Layout.Column = 2; - - % ---------------- Part3 ---------------- - app.Part3Grid = uigridlayout(app.Part3Tab); - app.Part3Grid.ColumnWidth = {170, '1x'}; - app.Part3Grid.RowHeight = {32, 120, 120, 120, 90}; - app.Part3Grid.Padding = [12 12 12 12]; - - app.FractureInputStyleLabel = uilabel(app.Part3Grid); - app.FractureInputStyleLabel.Layout.Row = 1; - app.FractureInputStyleLabel.Layout.Column = 1; - app.FractureInputStyleLabel.Text = 'Input Style'; - - app.FractureInputStyleDropDown = uidropdown(app.Part3Grid); - app.FractureInputStyleDropDown.Layout.Row = 1; - app.FractureInputStyleDropDown.Layout.Column = 2; - app.FractureInputStyleDropDown.Items = {'1', '2', '3', '4'}; - app.FractureInputStyleDropDown.Value = '1'; - - app.FractureInputLabel = uilabel(app.Part3Grid); - app.FractureInputLabel.Layout.Row = 2; - app.FractureInputLabel.Layout.Column = 1; - app.FractureInputLabel.Text = 'Input Content'; - - app.FractureInputTextArea = uitextarea(app.Part3Grid); - app.FractureInputTextArea.Layout.Row = 2; - app.FractureInputTextArea.Layout.Column = 2; - - app.FractureLinesLabel = uilabel(app.Part3Grid); - app.FractureLinesLabel.Layout.Row = 3; - app.FractureLinesLabel.Layout.Column = 1; - app.FractureLinesLabel.Text = 'Fracture Lines'; - - app.FractureLinesTextArea = uitextarea(app.Part3Grid); - app.FractureLinesTextArea.Layout.Row = 3; - app.FractureLinesTextArea.Layout.Column = 2; - - app.FractureHeightsLabel = uilabel(app.Part3Grid); - app.FractureHeightsLabel.Layout.Row = 4; - app.FractureHeightsLabel.Layout.Column = 1; - app.FractureHeightsLabel.Text = 'Fracture Heights'; - - app.FractureHeightsTextArea = uitextarea(app.Part3Grid); - app.FractureHeightsTextArea.Layout.Row = 4; - app.FractureHeightsTextArea.Layout.Column = 2; - - app.FlowBarrierFlagsLabel = uilabel(app.Part3Grid); - app.FlowBarrierFlagsLabel.Layout.Row = 5; - app.FlowBarrierFlagsLabel.Layout.Column = 1; - app.FlowBarrierFlagsLabel.Text = 'Flow Barrier Flags'; - - app.FlowBarrierFlagsTextArea = uitextarea(app.Part3Grid); - app.FlowBarrierFlagsTextArea.Layout.Row = 5; - app.FlowBarrierFlagsTextArea.Layout.Column = 2; - - % ---------------- Part4 ---------------- - app.Part4Grid = uigridlayout(app.Part4Tab); - app.Part4Grid.ColumnWidth = {180, '1x', 180, '1x'}; - app.Part4Grid.RowHeight = {90, 60, 90, 90, 90, 32, '1x'}; - app.Part4Grid.Padding = [12 12 12 12]; - - app.BoundaryLabel = uilabel(app.Part4Grid); - app.BoundaryLabel.Layout.Row = 1; - app.BoundaryLabel.Layout.Column = 1; - app.BoundaryLabel.Text = 'Boundary Polygon'; - - app.BoundaryTextArea = uitextarea(app.Part4Grid); - app.BoundaryTextArea.Layout.Row = 1; - app.BoundaryTextArea.Layout.Column = [2 4]; - - app.InvalidLayerLabel = uilabel(app.Part4Grid); - app.InvalidLayerLabel.Layout.Row = 2; - app.InvalidLayerLabel.Layout.Column = 1; - app.InvalidLayerLabel.Text = 'Invalid Layer'; - - app.InvalidLayerTextArea = uitextarea(app.Part4Grid); - app.InvalidLayerTextArea.Layout.Row = 2; - app.InvalidLayerTextArea.Layout.Column = [2 4]; - - app.MatrixKxLabel = uilabel(app.Part4Grid); - app.MatrixKxLabel.Layout.Row = 3; - app.MatrixKxLabel.Layout.Column = 1; - app.MatrixKxLabel.Text = 'Matrix kx'; - - app.MatrixKxTextArea = uitextarea(app.Part4Grid); - app.MatrixKxTextArea.Layout.Row = 3; - app.MatrixKxTextArea.Layout.Column = 2; - - app.MatrixKyLabel = uilabel(app.Part4Grid); - app.MatrixKyLabel.Layout.Row = 3; - app.MatrixKyLabel.Layout.Column = 3; - app.MatrixKyLabel.Text = 'Matrix ky'; - - app.MatrixKyTextArea = uitextarea(app.Part4Grid); - app.MatrixKyTextArea.Layout.Row = 3; - app.MatrixKyTextArea.Layout.Column = 4; - - app.MatrixKzLabel = uilabel(app.Part4Grid); - app.MatrixKzLabel.Layout.Row = 4; - app.MatrixKzLabel.Layout.Column = 1; - app.MatrixKzLabel.Text = 'Matrix kz'; - - app.MatrixKzTextArea = uitextarea(app.Part4Grid); - app.MatrixKzTextArea.Layout.Row = 4; - app.MatrixKzTextArea.Layout.Column = 2; - - app.MatrixPoriLabel = uilabel(app.Part4Grid); - app.MatrixPoriLabel.Layout.Row = 4; - app.MatrixPoriLabel.Layout.Column = 3; - app.MatrixPoriLabel.Text = 'Matrix pori'; - - app.MatrixPoriTextArea = uitextarea(app.Part4Grid); - app.MatrixPoriTextArea.Layout.Row = 4; - app.MatrixPoriTextArea.Layout.Column = 4; - - app.FractureKfLabel = uilabel(app.Part4Grid); - app.FractureKfLabel.Layout.Row = 5; - app.FractureKfLabel.Layout.Column = 1; - app.FractureKfLabel.Text = 'Fracture Kf'; - - app.FractureKfTextArea = uitextarea(app.Part4Grid); - app.FractureKfTextArea.Layout.Row = 5; - app.FractureKfTextArea.Layout.Column = 2; - - app.FractureWfLabel = uilabel(app.Part4Grid); - app.FractureWfLabel.Layout.Row = 5; - app.FractureWfLabel.Layout.Column = 3; - app.FractureWfLabel.Text = 'Fracture Wf'; - - app.FractureWfTextArea = uitextarea(app.Part4Grid); - app.FractureWfTextArea.Layout.Row = 5; - app.FractureWfTextArea.Layout.Column = 4; - - app.MatrixPrporLabel = uilabel(app.Part4Grid); - app.MatrixPrporLabel.Layout.Row = 6; - app.MatrixPrporLabel.Layout.Column = 1; - app.MatrixPrporLabel.Text = 'Matrix prpor'; - - app.MatrixPrporField = uieditfield(app.Part4Grid, 'numeric'); - app.MatrixPrporField.Layout.Row = 6; - app.MatrixPrporField.Layout.Column = 2; - - app.MatrixCporLabel = uilabel(app.Part4Grid); - app.MatrixCporLabel.Layout.Row = 6; - app.MatrixCporLabel.Layout.Column = 3; - app.MatrixCporLabel.Text = 'Matrix cpor'; - - app.MatrixCporField = uieditfield(app.Part4Grid, 'numeric'); - app.MatrixCporField.Layout.Row = 6; - app.MatrixCporField.Layout.Column = 4; - - app.RockDensityLabel = uilabel(app.Part4Grid); - app.RockDensityLabel.Layout.Row = 7; - app.RockDensityLabel.Layout.Column = 1; - app.RockDensityLabel.Text = 'Rock Density'; - - app.RockDensityField = uieditfield(app.Part4Grid, 'numeric'); - app.RockDensityField.Layout.Row = 7; - app.RockDensityField.Layout.Column = 2; - - app.FracturePorfLabel = uilabel(app.Part4Grid); - app.FracturePorfLabel.Layout.Row = 7; - app.FracturePorfLabel.Layout.Column = 3; - app.FracturePorfLabel.Text = 'Fracture Porf'; - - app.FracturePorfTextArea = uitextarea(app.Part4Grid); - app.FracturePorfTextArea.Layout.Row = 7; - app.FracturePorfTextArea.Layout.Column = 4; - - % ---------------- Part5 ---------------- - app.Part5Grid = uigridlayout(app.Part5Tab); - app.Part5Grid.ColumnWidth = {'1x'}; - app.Part5Grid.RowHeight = {110, '1x'}; - app.Part5Grid.Padding = [12 12 12 12]; - - app.InitialPanel = uipanel(app.Part5Grid); - app.InitialPanel.Layout.Row = 1; - app.InitialPanel.Layout.Column = 1; - app.InitialPanel.Title = 'Initial State'; - - app.InitialGrid = uigridlayout(app.InitialPanel); - app.InitialGrid.ColumnWidth = {120, 120, 120, 120}; - app.InitialGrid.RowHeight = {26, 32}; - - app.InitialPressureLabel = uilabel(app.InitialGrid); - app.InitialPressureLabel.Layout.Row = 1; - app.InitialPressureLabel.Layout.Column = 1; - app.InitialPressureLabel.Text = 'Pressure'; - - app.InitialPressureField = uieditfield(app.InitialGrid, 'numeric'); - app.InitialPressureField.Layout.Row = 2; - app.InitialPressureField.Layout.Column = 1; - - app.InitialSwLabel = uilabel(app.InitialGrid); - app.InitialSwLabel.Layout.Row = 1; - app.InitialSwLabel.Layout.Column = 2; - app.InitialSwLabel.Text = 'Sw'; - - app.InitialSwField = uieditfield(app.InitialGrid, 'numeric'); - app.InitialSwField.Layout.Row = 2; - app.InitialSwField.Layout.Column = 2; - - app.InitialCsLabel = uilabel(app.InitialGrid); - app.InitialCsLabel.Layout.Row = 1; - app.InitialCsLabel.Layout.Column = 3; - app.InitialCsLabel.Text = 'Cs'; - - app.InitialCsField = uieditfield(app.InitialGrid, 'numeric'); - app.InitialCsField.Layout.Row = 2; - app.InitialCsField.Layout.Column = 3; - - app.InitialCbLabel = uilabel(app.InitialGrid); - app.InitialCbLabel.Layout.Row = 1; - app.InitialCbLabel.Layout.Column = 4; - app.InitialCbLabel.Text = 'Cb'; - - app.InitialCbField = uieditfield(app.InitialGrid, 'numeric'); - app.InitialCbField.Layout.Row = 2; - app.InitialCbField.Layout.Column = 4; - - app.FlowSubTabGroup = uitabgroup(app.Part5Grid); - app.FlowSubTabGroup.Layout.Row = 2; - app.FlowSubTabGroup.Layout.Column = 1; - - app.GasWaterTab = uitab(app.FlowSubTabGroup); - app.GasWaterTab.Title = 'Gas-Water'; - - app.OilWaterTab = uitab(app.FlowSubTabGroup); - app.OilWaterTab.Title = 'Oil-Water'; - - app.MultiComponentTab = uitab(app.FlowSubTabGroup); - app.MultiComponentTab.Title = 'Multi-Component'; - - app.GasWaterGrid = uigridlayout(app.GasWaterTab); - app.GasWaterGrid.ColumnWidth = {180, '1x'}; - app.GasWaterGrid.RowHeight = {140, '1x'}; - app.GasWaterGrid.Padding = [12 12 12 12]; - - app.GasRelPermLabel = uilabel(app.GasWaterGrid); - app.GasRelPermLabel.Layout.Row = 1; - app.GasRelPermLabel.Layout.Column = 1; - app.GasRelPermLabel.Text = 'Gas RelPerm Table'; - - app.GasRelPermTextArea = uitextarea(app.GasWaterGrid); - app.GasRelPermTextArea.Layout.Row = 1; - app.GasRelPermTextArea.Layout.Column = 2; - - app.GasPVTLabel = uilabel(app.GasWaterGrid); - app.GasPVTLabel.Layout.Row = 2; - app.GasPVTLabel.Layout.Column = 1; - app.GasPVTLabel.Text = 'Gas PVT Text'; - - app.GasPVTTextArea = uitextarea(app.GasWaterGrid); - app.GasPVTTextArea.Layout.Row = 2; - app.GasPVTTextArea.Layout.Column = 2; - - app.OilWaterGrid = uigridlayout(app.OilWaterTab); - app.OilWaterGrid.ColumnWidth = {180, '1x'}; - app.OilWaterGrid.RowHeight = {140, '1x'}; - app.OilWaterGrid.Padding = [12 12 12 12]; - - app.OilRelPermLabel = uilabel(app.OilWaterGrid); - app.OilRelPermLabel.Layout.Row = 1; - app.OilRelPermLabel.Layout.Column = 1; - app.OilRelPermLabel.Text = 'Oil RelPerm Table'; - - app.OilRelPermTextArea = uitextarea(app.OilWaterGrid); - app.OilRelPermTextArea.Layout.Row = 1; - app.OilRelPermTextArea.Layout.Column = 2; - - app.OilPVTLabel = uilabel(app.OilWaterGrid); - app.OilPVTLabel.Layout.Row = 2; - app.OilPVTLabel.Layout.Column = 1; - app.OilPVTLabel.Text = 'Oil PVT Text'; - - app.OilPVTTextArea = uitextarea(app.OilWaterGrid); - app.OilPVTTextArea.Layout.Row = 2; - app.OilPVTTextArea.Layout.Column = 2; - - app.MultiComponentGrid = uigridlayout(app.MultiComponentTab); - app.MultiComponentGrid.ColumnWidth = {180, '1x', 180, '1x'}; - app.MultiComponentGrid.RowHeight = {120, 120, 120}; - app.MultiComponentGrid.Padding = [12 12 12 12]; - - app.AdsorptionLabel = uilabel(app.MultiComponentGrid); - app.AdsorptionLabel.Layout.Row = 1; - app.AdsorptionLabel.Layout.Column = 1; - app.AdsorptionLabel.Text = 'Adsorption Table'; - - app.AdsorptionTextArea = uitextarea(app.MultiComponentGrid); - app.AdsorptionTextArea.Layout.Row = 1; - app.AdsorptionTextArea.Layout.Column = 2; - - app.NcTableLabel = uilabel(app.MultiComponentGrid); - app.NcTableLabel.Layout.Row = 1; - app.NcTableLabel.Layout.Column = 3; - app.NcTableLabel.Text = 'Nc Table'; - - app.NcTableTextArea = uitextarea(app.MultiComponentGrid); - app.NcTableTextArea.Layout.Row = 1; - app.NcTableTextArea.Layout.Column = 4; - - app.KrNoSurfLabel = uilabel(app.MultiComponentGrid); - app.KrNoSurfLabel.Layout.Row = 2; - app.KrNoSurfLabel.Layout.Column = 1; - app.KrNoSurfLabel.Text = 'Kr No Surf'; - - app.KrNoSurfTextArea = uitextarea(app.MultiComponentGrid); - app.KrNoSurfTextArea.Layout.Row = 2; - app.KrNoSurfTextArea.Layout.Column = 2; - - app.KrSurfLabel = uilabel(app.MultiComponentGrid); - app.KrSurfLabel.Layout.Row = 2; - app.KrSurfLabel.Layout.Column = 3; - app.KrSurfLabel.Text = 'Kr Surf'; - - app.KrSurfTextArea = uitextarea(app.MultiComponentGrid); - app.KrSurfTextArea.Layout.Row = 2; - app.KrSurfTextArea.Layout.Column = 4; - - app.PcTableLabel = uilabel(app.MultiComponentGrid); - app.PcTableLabel.Layout.Row = 3; - app.PcTableLabel.Layout.Column = 1; - app.PcTableLabel.Text = 'Pc Table'; - - app.PcTableTextArea = uitextarea(app.MultiComponentGrid); - app.PcTableTextArea.Layout.Row = 3; - app.PcTableTextArea.Layout.Column = [2 4]; - - % ---------------- Part6 ---------------- - app.Part6Grid = uigridlayout(app.Part6Tab); - app.Part6Grid.ColumnWidth = {180, '1x'}; - app.Part6Grid.RowHeight = {120, 120, 120, 160, 80, 80, '1x'}; - app.Part6Grid.Padding = [12 12 12 12]; - - app.Well1Label = uilabel(app.Part6Grid); - app.Well1Label.Layout.Row = 1; - app.Well1Label.Layout.Column = 1; - app.Well1Label.Text = 'Well1'; - - app.Well1Table = uitable(app.Part6Grid); - app.Well1Table.Layout.Row = 1; - app.Well1Table.Layout.Column = 2; - - app.FractureWellLocationLabel = uilabel(app.Part6Grid); - app.FractureWellLocationLabel.Layout.Row = 2; - app.FractureWellLocationLabel.Layout.Column = 1; - app.FractureWellLocationLabel.Text = 'Fracture Well Locations'; - - app.FractureWellLocationTable = uitable(app.Part6Grid); - app.FractureWellLocationTable.Layout.Row = 2; - app.FractureWellLocationTable.Layout.Column = 2; - - app.Well2Label = uilabel(app.Part6Grid); - app.Well2Label.Layout.Row = 3; - app.Well2Label.Layout.Column = 1; - app.Well2Label.Text = 'Well2'; - - app.Well2Table = uitable(app.Part6Grid); - app.Well2Table.Layout.Row = 3; - app.Well2Table.Layout.Column = 2; - - app.ScheduleLabel = uilabel(app.Part6Grid); - app.ScheduleLabel.Layout.Row = 4; - app.ScheduleLabel.Layout.Column = 1; - app.ScheduleLabel.Text = 'Schedule'; - - app.ScheduleTable = uitable(app.Part6Grid); - app.ScheduleTable.Layout.Row = 4; - app.ScheduleTable.Layout.Column = 2; - - app.TimeLabel = uilabel(app.Part6Grid); - app.TimeLabel.Layout.Row = 5; - app.TimeLabel.Layout.Column = 1; - app.TimeLabel.Text = 'Time'; - - app.TimeTextArea = uitextarea(app.Part6Grid); - app.TimeTextArea.Layout.Row = 5; - app.TimeTextArea.Layout.Column = 2; - - app.DtMinLabel = uilabel(app.Part6Grid); - app.DtMinLabel.Layout.Row = 6; - app.DtMinLabel.Layout.Column = 1; - app.DtMinLabel.Text = 'dtmin'; - - app.DtMinTextArea = uitextarea(app.Part6Grid); - app.DtMinTextArea.Layout.Row = 6; - app.DtMinTextArea.Layout.Column = 2; - - app.DtMaxLabel = uilabel(app.Part6Grid); - app.DtMaxLabel.Layout.Row = 7; - app.DtMaxLabel.Layout.Column = 1; - app.DtMaxLabel.Text = 'dtmax'; - - app.DtMaxTextArea = uitextarea(app.Part6Grid); - app.DtMaxTextArea.Layout.Row = 7; - app.DtMaxTextArea.Layout.Column = 2; - - % ---------------- Part7 ---------------- - app.Part7Grid = uigridlayout(app.Part7Tab); - app.Part7Grid.ColumnWidth = {100, 100, 100, 100, 100, 100}; - app.Part7Grid.RowHeight = {26, 32, '1x'}; - app.Part7Grid.Padding = [12 12 12 12]; - - app.YitaPLabel = uilabel(app.Part7Grid); - app.YitaPLabel.Layout.Row = 1; - app.YitaPLabel.Layout.Column = 1; - app.YitaPLabel.Text = 'yitap'; - - app.YitaPField = uieditfield(app.Part7Grid, 'numeric'); - app.YitaPField.Layout.Row = 2; - app.YitaPField.Layout.Column = 1; - - app.YitaSLabel = uilabel(app.Part7Grid); - app.YitaSLabel.Layout.Row = 1; - app.YitaSLabel.Layout.Column = 2; - app.YitaSLabel.Text = 'yitas'; - - app.YitaSField = uieditfield(app.Part7Grid, 'numeric'); - app.YitaSField.Layout.Row = 2; - app.YitaSField.Layout.Column = 2; - - app.OmegaLabel = uilabel(app.Part7Grid); - app.OmegaLabel.Layout.Row = 1; - app.OmegaLabel.Layout.Column = 3; - app.OmegaLabel.Text = 'omega'; - - app.OmegaField = uieditfield(app.Part7Grid, 'numeric'); - app.OmegaField.Layout.Row = 2; - app.OmegaField.Layout.Column = 3; - - app.NmaxLabel = uilabel(app.Part7Grid); - app.NmaxLabel.Layout.Row = 1; - app.NmaxLabel.Layout.Column = 4; - app.NmaxLabel.Text = 'Nmax'; - - app.NmaxField = uieditfield(app.Part7Grid, 'numeric'); - app.NmaxField.Layout.Row = 2; - app.NmaxField.Layout.Column = 4; - - app.EpsAveLabel = uilabel(app.Part7Grid); - app.EpsAveLabel.Layout.Row = 1; - app.EpsAveLabel.Layout.Column = 5; - app.EpsAveLabel.Text = 'epsave'; - - app.EpsAveField = uieditfield(app.Part7Grid, 'numeric'); - app.EpsAveField.Layout.Row = 2; - app.EpsAveField.Layout.Column = 5; - - app.EpsMaxLabel = uilabel(app.Part7Grid); - app.EpsMaxLabel.Layout.Row = 1; - app.EpsMaxLabel.Layout.Column = 6; - app.EpsMaxLabel.Text = 'epsmax'; - - app.EpsMaxField = uieditfield(app.Part7Grid, 'numeric'); - app.EpsMaxField.Layout.Row = 2; - app.EpsMaxField.Layout.Column = 6; - - % ---------------- RunTab ---------------- - app.RunGrid = uigridlayout(app.RunTab); - app.RunGrid.ColumnWidth = {140, 180, 180, '1x'}; - app.RunGrid.RowHeight = {36, '1x'}; - app.RunGrid.Padding = [12 12 12 12]; - - app.RunCurrentConfigButton = uibutton(app.RunGrid, 'push'); - app.RunCurrentConfigButton.Layout.Row = 1; - app.RunCurrentConfigButton.Layout.Column = 1; - app.RunCurrentConfigButton.Text = 'Run Current Config'; - - app.CurrentStageLabel = uilabel(app.RunGrid); - app.CurrentStageLabel.Layout.Row = 1; - app.CurrentStageLabel.Layout.Column = 2; - app.CurrentStageLabel.Text = 'Stage: -'; - - app.CurrentTimeLabel = uilabel(app.RunGrid); - app.CurrentTimeLabel.Layout.Row = 1; - app.CurrentTimeLabel.Layout.Column = 3; - app.CurrentTimeLabel.Text = 'Time: -'; - - app.CurrentDtLabel = uilabel(app.RunGrid); - app.CurrentDtLabel.Layout.Row = 1; - app.CurrentDtLabel.Layout.Column = 4; - app.CurrentDtLabel.Text = 'dt: -'; - - app.RunLogTextArea = uitextarea(app.RunGrid); - app.RunLogTextArea.Layout.Row = 2; - app.RunLogTextArea.Layout.Column = [1 4]; - app.RunLogTextArea.Editable = 'off'; - - % ---------------- ResultTab ---------------- - app.ResultGrid = uigridlayout(app.ResultTab); - app.ResultGrid.ColumnWidth = {360, '1x'}; - app.ResultGrid.RowHeight = {'1x'}; - app.ResultGrid.Padding = [12 12 12 12]; - - app.ResultLeftGrid = uigridlayout(app.ResultGrid); - app.ResultLeftGrid.Layout.Row = 1; - app.ResultLeftGrid.Layout.Column = 1; - app.ResultLeftGrid.ColumnWidth = {'1x'}; - app.ResultLeftGrid.RowHeight = {24, 180, 24, 32, 36, '1x'}; - - app.ResultSummaryLabel = uilabel(app.ResultLeftGrid); - app.ResultSummaryLabel.Layout.Row = 1; - app.ResultSummaryLabel.Layout.Column = 1; - app.ResultSummaryLabel.Text = 'Result Summary'; - - app.ResultSummaryTextArea = uitextarea(app.ResultLeftGrid); - app.ResultSummaryTextArea.Layout.Row = 2; - app.ResultSummaryTextArea.Layout.Column = 1; - app.ResultSummaryTextArea.Editable = 'off'; - - app.ResultTypeLabel = uilabel(app.ResultLeftGrid); - app.ResultTypeLabel.Layout.Row = 3; - app.ResultTypeLabel.Layout.Column = 1; - app.ResultTypeLabel.Text = 'Result Type'; - - app.ResultTypeDropDown = uidropdown(app.ResultLeftGrid); - app.ResultTypeDropDown.Layout.Row = 4; - app.ResultTypeDropDown.Layout.Column = 1; - app.ResultTypeDropDown.Items = {'Time Steps', 'Newtons vs Time'}; - app.ResultTypeDropDown.Value = 'Time Steps'; - - app.PlotResultButton = uibutton(app.ResultLeftGrid, 'push'); - app.PlotResultButton.Layout.Row = 5; - app.PlotResultButton.Layout.Column = 1; - app.PlotResultButton.Text = 'Plot Result'; - - app.ResultAxes = uiaxes(app.ResultGrid); - app.ResultAxes.Layout.Row = 1; - app.ResultAxes.Layout.Column = 2; - title(app.ResultAxes, 'Results'); - xlabel(app.ResultAxes, 'X'); - ylabel(app.ResultAxes, 'Y'); - - % Show the figure after all components are created - app.UIFigure.Visible = 'on'; - end - end - - % App creation and deletion - methods (Access = public) - - % Construct app - function app = EDFM_Simulator_App - - % Create UIFigure and components - createComponents(app) - - % Register the app with App Designer - registerApp(app, app.UIFigure) - - if nargout == 0 - clear app - end - end - - % Code that executes before app deletion - function delete(app) - - % Delete UIFigure when app is deleted - delete(app.UIFigure) - end - end -end diff --git a/gui_support/app/EDFM_Simulator_App.mlapp b/gui_support/app/EDFM_Simulator_App.mlapp index 5ca2557..402e578 100644 Binary files a/gui_support/app/EDFM_Simulator_App.mlapp and b/gui_support/app/EDFM_Simulator_App.mlapp differ diff --git a/gui_support/config/create_empty_config.m b/gui_support/config/create_empty_config.m index 6198402..f7b2ce2 100644 --- a/gui_support/config/create_empty_config.m +++ b/gui_support/config/create_empty_config.m @@ -12,7 +12,6 @@ config.meta = struct( ... 'version', '0.1'); config.model = struct( ... - 'modelflag', 1, ... 'grid_model', 1, ... 'flow_model', 1); @@ -39,13 +38,9 @@ config.grid = struct( ... 'cell_mid_coords', []); config.fracture = struct( ... - 'input_style', 1, ... 'input_content', {{}}, ... 'f', [], ... 'fellip', [], ... - 'fractureLines', [], ... - 'fractureHeights', [], ... - 'flowBarrierFlags', [], ... 'frac_information', [], ... 'nf', 0); diff --git a/gui_support/config/load_config_json.m b/gui_support/config/load_config_json.m index a2ea820..b8a6d87 100644 --- a/gui_support/config/load_config_json.m +++ b/gui_support/config/load_config_json.m @@ -10,4 +10,4 @@ if ~exist(file_path, 'file') end json_text = fileread(file_path); -config = jsondecode(json_text); +config = normalize_config(jsondecode(json_text)); diff --git a/gui_support/config/load_config_mat.m b/gui_support/config/load_config_mat.m index f77948a..c805cf3 100644 --- a/gui_support/config/load_config_mat.m +++ b/gui_support/config/load_config_mat.m @@ -15,4 +15,4 @@ if ~isfield(data, 'config') 'MAT file does not contain variable ''config'': %s', file_path); end -config = data.config; +config = normalize_config(data.config); diff --git a/gui_support/config/normalize_config.m b/gui_support/config/normalize_config.m new file mode 100644 index 0000000..9790e8f --- /dev/null +++ b/gui_support/config/normalize_config.m @@ -0,0 +1,53 @@ +function config = normalize_config(config) +%NORMALIZE_CONFIG Normalize legacy GUI/runtime config to the current schema. + +if nargin == 0 || isempty(config) + config = create_empty_config(); + return; +end + +defaults = create_empty_config(); +config = merge_struct_defaults(config, defaults); + +config.model.grid_model = first_nonempty_scalar(config.model.grid_model, 1); +config.model.flow_model = first_nonempty_scalar(config.model.flow_model, 1); + +legacy_model_fields = {'modelflag'}; +legacy_fracture_fields = {'input_style', 'fractureLines', 'fractureHeights', 'flowBarrierFlags'}; + +for i = 1:numel(legacy_model_fields) + field_name = legacy_model_fields{i}; + if isfield(config.model, field_name) + config.model = rmfield(config.model, field_name); + end +end + +for i = 1:numel(legacy_fracture_fields) + field_name = legacy_fracture_fields{i}; + if isfield(config.fracture, field_name) + config.fracture = rmfield(config.fracture, field_name); + end +end +end + +function s = merge_struct_defaults(s, defaults) +default_fields = fieldnames(defaults); +for i = 1:numel(default_fields) + field_name = default_fields{i}; + if ~isfield(s, field_name) || isempty(s.(field_name)) + s.(field_name) = defaults.(field_name); + elseif isstruct(defaults.(field_name)) && isstruct(s.(field_name)) + s.(field_name) = merge_struct_defaults(s.(field_name), defaults.(field_name)); + end +end +end + +function value = first_nonempty_scalar(raw_value, fallback) +if isempty(raw_value) + value = fallback; +elseif isscalar(raw_value) + value = raw_value; +else + value = raw_value(1); +end +end diff --git a/gui_support/runtime/run_case.m b/gui_support/runtime/run_case.m index e0adfb3..a48720c 100644 --- a/gui_support/runtime/run_case.m +++ b/gui_support/runtime/run_case.m @@ -11,6 +11,8 @@ arguments progress_callback = [] end +config = normalize_config(config); + project_root = fileparts(fileparts(fileparts(mfilename('fullpath')))); source_case_folder = resolve_source_case_folder(project_root, config.meta); if isempty(source_case_folder) @@ -46,14 +48,13 @@ r = GridProp_pre( ... [f, fellip, frac_information, nf] = build_fracture_inputs(config.fracture); -modelflag = config.model.modelflag; grid_model = config.model.grid_model; flow_model = config.model.flow_model; if grid_model == 1 - r = grid_discretization_SP_model(modelflag, r, f, frac_information, fellip, nf); + r = grid_discretization_SP_model(1, r, f, frac_information, fellip, nf); elseif grid_model == 2 - r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf); + r = grid_discretization_DP_model(1, r, f, frac_information, fellip, nf); else error('run_case:UnsupportedGridModel', 'Unsupported grid model: %d', grid_model); end @@ -130,36 +131,11 @@ end end function [f, fellip, frac_information, nf] = build_fracture_inputs(fracture_config) -input_style = fracture_config.input_style; - -switch input_style - case 1 - [f, fellip] = sort_fracture(fracture_config.input_content); - m = size(f, 1); - n = size(fellip, 1); - nf = (m + n) / 5; - frac_information = fractureInformation_input_engineering_vector( ... - f, fellip, fracture_config.flowBarrierFlags); - case 2 - f = fracture_config.f; - fellip = fracture_config.fellip; - m = size(f, 1); - n = size(fellip, 1); - nf = (m + n) / 5; - frac_information = fractureInformation_input_engineering_vector(f, fellip); - case 3 - fellip = fracture_config.fellip; - [f, frac_information] = input_fracture_2D( ... - fracture_config.fractureLines, ... - fracture_config.fractureHeights, ... - fracture_config.flowBarrierFlags); - m = size(f, 1); - n = size(fellip, 1); - nf = (m + n) / 5; - otherwise - error('run_case:UnsupportedFractureInputStyle', ... - 'Unsupported fracture input style: %d', input_style); -end +[f, fellip] = sort_fracture(fracture_config.input_content); +m = size(f, 1); +n = size(fellip, 1); +nf = (m + n) / 5; +frac_information = fractureInformation_input_engineering_vector(f, fellip, []); end function [fluid_model, state0] = build_flow_inputs(flow_model, r, config) diff --git a/gui_support/templates/build_basic_case_template.m b/gui_support/templates/build_basic_case_template.m index 5429dc9..e336972 100644 --- a/gui_support/templates/build_basic_case_template.m +++ b/gui_support/templates/build_basic_case_template.m @@ -11,7 +11,6 @@ config.meta.description = description; config.meta.source_case_folder = sprintf('CASE%02d_FOLDER', case_num); config.meta.created_from_template = case_id; -config.model.modelflag = model.modelflag; config.model.grid_model = model.grid_model; config.model.flow_model = model.flow_model; @@ -23,9 +22,7 @@ config.grid.ny = numel(config.grid.dy); config.grid.nz = numel(config.grid.dz); config.grid.NTG = ones(config.grid.nx * config.grid.ny * config.grid.nz, 1); -config.fracture.input_style = 1; config.fracture.input_content = fracture.input_content; -config.fracture.flowBarrierFlags = []; config.initial.pressure = initial.pressure; config.initial.sw = initial.sw; diff --git a/gui_support/templates/load_case_template.m b/gui_support/templates/load_case_template.m index e275054..bfd4066 100644 --- a/gui_support/templates/load_case_template.m +++ b/gui_support/templates/load_case_template.m @@ -26,6 +26,8 @@ switch case_key error('load_case_template:UnsupportedCase', ... 'Unsupported case template: %s', string(case_key)); end + +config = normalize_config(config); end function case_key = normalize_case_id(case_id) diff --git a/gui_support/templates/load_case_template_case01.m b/gui_support/templates/load_case_template_case01.m index 26ce86e..255eb05 100644 --- a/gui_support/templates/load_case_template_case01.m +++ b/gui_support/templates/load_case_template_case01.m @@ -9,7 +9,6 @@ config.meta.description = 'Multicomponent flow with irregular heterogeneous doma config.meta.source_case_folder = 'CASE01_FOLDER'; config.meta.created_from_template = 'case01'; -config.model.modelflag = 1; config.model.grid_model = 1; config.model.flow_model = 3; @@ -21,7 +20,6 @@ config.grid.ny = numel(config.grid.dy); config.grid.nz = numel(config.grid.dz); config.grid.NTG = ones(config.grid.nx * config.grid.ny * config.grid.nz, 1); -config.fracture.input_style = 1; config.fracture.input_content = { [255,255,5],90,90,0,200,10,1; [305,255,5],90,90,0,200,10,1; @@ -35,7 +33,6 @@ config.fracture.input_content = { [705,255,5],90,90,0,200,10,1; [755,255,5],90,90,0,200,10,1; }; -config.fracture.flowBarrierFlags = []; config.discretization.mode = 1; config.discretization.sp.boundary_polygon = [