优化点1,2.

This commit is contained in:
xinxiao
2026-04-01 18:58:03 +08:00
parent a166fe007e
commit 0b23161eee
15 changed files with 106 additions and 1315 deletions
+1
View File
@@ -0,0 +1 @@
edfm_gui_v1.1-2026.3.24.zip
+11 -5
View File
@@ -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 |
+6
View File
@@ -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
+22 -15
View File
@@ -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))
-332
View File
@@ -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<AGROW>
if isfield(app.Results, 'trun') && isstruct(app.Results.trun)
if isfield(app.Results.trun, 'run_time'), summary{end+1} = ['Run time: ', num2str(app.Results.trun.run_time)]; end %#ok<AGROW>
if isfield(app.Results.trun, 'Newton_step'), summary{end+1} = ['Newton steps: ', num2str(app.Results.trun.Newton_step)]; end %#ok<AGROW>
end
app.UI.ResultSummary.Value = summary;
cla(app.UI.ResultAxes);
if isfield(app.Results, 'trun') && isfield(app.Results.trun, 'Newtons_vs_time') && ~isempty(app.Results.trun.Newtons_vs_time)
plot(app.UI.ResultAxes, app.Results.trun.Newtons_vs_time(:,1), app.Results.trun.Newtons_vs_time(:,2), '-o'); title(app.UI.ResultAxes, 'Newtons vs Time'); xlabel(app.UI.ResultAxes, 'Time'); ylabel(app.UI.ResultAxes, 'Newton Count');
elseif isfield(app.Results, 'Times') && ~isempty(app.Results.Times)
plot(app.UI.ResultAxes, app.Results.Times, 1:numel(app.Results.Times), '-o'); title(app.UI.ResultAxes, 'Time Step Index'); xlabel(app.UI.ResultAxes, 'Time'); ylabel(app.UI.ResultAxes, 'Step');
end
end
function appendLog(app, txt)
lines = string(txt); lines = splitlines(lines);
current = string(app.UI.RunLog.Value);
if isequal(current, ""), app.UI.RunLog.Value = cellstr(lines); else, app.UI.RunLog.Value = cellstr([current; lines]); end
end
function updateStatus(app, txt)
app.UI.StatusLabel.Text = ['Status: ', txt];
end
function out = parseExpr(app, lines) %#ok<INUSL>
txt = strtrim(strjoin(string(lines), newline));
if txt == "", out = []; else, out = eval(txt); end %#ok<EVLDIR>
end
function txt = toExpr(app, value) %#ok<INUSL>
if isempty(value), txt = '[]'; return; end
if isnumeric(value) || islogical(value), txt = mat2str(value); return; end
if ischar(value), txt = ['''', strrep(value, '''', ''''''), '''']; return; end
if isstring(value) && isscalar(value), txt = ['''', strrep(char(value), '''', ''''''), '''']; return; end
if iscell(value)
rows = cell(size(value,1),1);
for i = 1:size(value,1)
cols = cell(1,size(value,2));
for j = 1:size(value,2), cols{j} = app.toExpr(value{i,j}); end
rows{i} = strjoin(cols, ', ');
end
txt = ['{', strjoin(rows, [';', newline]), '}']; return;
end
txt = evalc('disp(value)');
end
function value = scalarValue(app, raw) %#ok<INUSL>
if isempty(raw), value = 0; elseif isscalar(raw), value = raw; else, value = raw(1); end
end
end
methods (Access = public)
function app = EDFMSimulatorApp()
createComponents(app);
registerApp(app, app.UIFigure);
runStartupFcn(app, @(~,~) app.startup());
end
function delete(app)
delete(app.UIFigure);
end
end
end
-917
View File
@@ -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
Binary file not shown.
-5
View File
@@ -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);
+1 -1
View File
@@ -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));
+1 -1
View File
@@ -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);
+53
View File
@@ -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
+9 -33
View File
@@ -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)
@@ -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;
@@ -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)
@@ -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 = [