初版gui
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
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
|
||||
@@ -0,0 +1,917 @@
|
||||
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.
@@ -0,0 +1,5 @@
|
||||
function app = launch_edfm_simulator_app()
|
||||
%LAUNCH_EDFM_SIMULATOR_APP Launch the EDFM Simulator App.
|
||||
|
||||
startup;
|
||||
app = EDFMSimulatorApp();
|
||||
@@ -0,0 +1,248 @@
|
||||
function config = create_empty_config()
|
||||
%CREATE_EMPTY_CONFIG Create a unified GUI/runtime config skeleton.
|
||||
|
||||
config = struct();
|
||||
|
||||
config.meta = struct( ...
|
||||
'case_name', '', ...
|
||||
'case_id', '', ...
|
||||
'description', '', ...
|
||||
'source_case_folder', '', ...
|
||||
'created_from_template', '', ...
|
||||
'version', '0.1');
|
||||
|
||||
config.model = struct( ...
|
||||
'modelflag', 1, ...
|
||||
'grid_model', 1, ...
|
||||
'flow_model', 1);
|
||||
|
||||
config.grid = struct( ...
|
||||
'dx', [], ...
|
||||
'dy', [], ...
|
||||
'dz', [], ...
|
||||
'nx', 0, ...
|
||||
'ny', 0, ...
|
||||
'nz', 0, ...
|
||||
'NTG', [], ...
|
||||
'coordinates', [], ...
|
||||
'nodes', [], ...
|
||||
'nP', 0, ...
|
||||
'nmc', 0, ...
|
||||
'dxv', [], ...
|
||||
'dyv', [], ...
|
||||
'dzv', [], ...
|
||||
'zm', [], ...
|
||||
'vm', [], ...
|
||||
'xrao', [], ...
|
||||
'yrao', [], ...
|
||||
'zrao', [], ...
|
||||
'cell_mid_coords', []);
|
||||
|
||||
config.fracture = struct( ...
|
||||
'input_style', 1, ...
|
||||
'input_content', {{}}, ...
|
||||
'f', [], ...
|
||||
'fellip', [], ...
|
||||
'fractureLines', [], ...
|
||||
'fractureHeights', [], ...
|
||||
'flowBarrierFlags', [], ...
|
||||
'frac_information', [], ...
|
||||
'nf', 0);
|
||||
|
||||
config.discretization = struct( ...
|
||||
'mode', 1, ...
|
||||
'use_operator', true, ...
|
||||
'sp', struct( ...
|
||||
'boundary_polygon', [], ...
|
||||
'invalid_layer', [], ...
|
||||
'valid_grids', [], ...
|
||||
'matrix', struct( ...
|
||||
'kx', [], ...
|
||||
'ky', [], ...
|
||||
'kz', [], ...
|
||||
'pori', [], ...
|
||||
'prpor', 20, ...
|
||||
'cpor', 1.0e-5, ...
|
||||
'rock_density', 2700), ...
|
||||
'fracture', struct( ...
|
||||
'Kf', [], ...
|
||||
'Wf', [], ...
|
||||
'Porf', [], ...
|
||||
'prporf', 20, ...
|
||||
'cporf', 1.0e-5), ...
|
||||
'stress', struct( ...
|
||||
'fracture_factor', 0, ...
|
||||
'matrix_factor', 0, ...
|
||||
'ref_pressure', 20)), ...
|
||||
'dp', struct( ...
|
||||
'valid_grids', [], ...
|
||||
'NTG', [], ...
|
||||
'prpor', 20, ...
|
||||
'cpor', 1.0e-5, ...
|
||||
'rock_density', 2700, ...
|
||||
'fracture_layer', struct( ...
|
||||
'kx', [], ...
|
||||
'ky', [], ...
|
||||
'kz', [], ...
|
||||
'pori', []), ...
|
||||
'matrix_layer', struct( ...
|
||||
'kx', [], ...
|
||||
'ky', [], ...
|
||||
'kz', [], ...
|
||||
'pori', []), ...
|
||||
'shape_factor', [], ...
|
||||
'fracture', struct( ...
|
||||
'Kf', [], ...
|
||||
'Wf', [], ...
|
||||
'Porf', [], ...
|
||||
'prporf', 20, ...
|
||||
'cporf', 1.0e-5), ...
|
||||
'stress', struct( ...
|
||||
'fracture_factor', 0, ...
|
||||
'matrix_factor', 0, ...
|
||||
'ref_pressure', 20)), ...
|
||||
'notes', '');
|
||||
|
||||
config.flow = struct( ...
|
||||
'gas_water', struct( ...
|
||||
'gas_prop', struct( ...
|
||||
'VL', 0, ...
|
||||
'PL', 0, ...
|
||||
'Kn', 0, ...
|
||||
'Kn_modified_factor', 1, ...
|
||||
'beta_non_darcy_flow', 0), ...
|
||||
'p_grad_threshold', 0, ...
|
||||
'density_g_sc', 0, ...
|
||||
'density_w_sc', 1000, ...
|
||||
'gas_model', 1, ...
|
||||
'prg', [], ...
|
||||
'Bgi', [], ...
|
||||
'cg', [], ...
|
||||
'vgi', [], ...
|
||||
'cvg', [], ...
|
||||
'Ppr', [], ...
|
||||
'BG', [], ...
|
||||
'MUG', [], ...
|
||||
'prw', [], ...
|
||||
'Bwi', [], ...
|
||||
'cw', [], ...
|
||||
'vwi', [], ...
|
||||
'cvw', [], ...
|
||||
'ifpcgl', 0, ...
|
||||
'Ppr', [], ...
|
||||
'BG', [], ...
|
||||
'MUG', [], ...
|
||||
'matrix_relperm_table', [], ...
|
||||
'fracture_relperm_table', []), ...
|
||||
'oil_water', struct( ...
|
||||
'density_o_sc', 0, ...
|
||||
'density_w_sc', 1000, ...
|
||||
'oil_model', 1, ...
|
||||
'pro', [], ...
|
||||
'Boi', [], ...
|
||||
'co', [], ...
|
||||
'voi', [], ...
|
||||
'cvo', [], ...
|
||||
'Ppr', [], ...
|
||||
'BO', [], ...
|
||||
'MUO', [], ...
|
||||
'prw', [], ...
|
||||
'Bwi', [], ...
|
||||
'cw', [], ...
|
||||
'vwi', [], ...
|
||||
'cvw', [], ...
|
||||
'ifpcow', 0, ...
|
||||
'Ppr', [], ...
|
||||
'BO', [], ...
|
||||
'MUO', [], ...
|
||||
'matrix_relperm_table', [], ...
|
||||
'fracture_relperm_table', [], ...
|
||||
'beta_non_darcy_flow', 0, ...
|
||||
'p_grad_threshold', 0), ...
|
||||
'multi_component', struct( ...
|
||||
'Ds', [], ...
|
||||
'Db', [], ...
|
||||
'c_ca_table', [], ...
|
||||
'cs_data', [], ...
|
||||
'cb_data', [], ...
|
||||
'csa_data', [], ...
|
||||
'cba_data', [], ...
|
||||
'R', [], ...
|
||||
'Vm', [], ...
|
||||
'Temperature', [], ...
|
||||
'chemistry_cof', [], ...
|
||||
'x_matrix', 0.9, ...
|
||||
'x_fracture', 1.0, ...
|
||||
'cs_Nc', [], ...
|
||||
'Nc_nosurf', [], ...
|
||||
'Nc_surf', [], ...
|
||||
'kr_nosurf', [], ...
|
||||
'kr_surf', [], ...
|
||||
'PC', [], ...
|
||||
'cs_Nc_fracture', [], ...
|
||||
'kr_nosurf_fracture', [], ...
|
||||
'kr_surf_fracture', [], ...
|
||||
'PC_fracture', [], ...
|
||||
'ifpcgl', 0, ...
|
||||
'p_grad_threshold', 0, ...
|
||||
'gas_prop', struct( ...
|
||||
'VL', 0, ...
|
||||
'PL', 0, ...
|
||||
'Kn', 0, ...
|
||||
'Kn_modified_factor', 1, ...
|
||||
'stress_factor_fracture', 0, ...
|
||||
'stress_factor_matrix', 0, ...
|
||||
'stress_factor_ref_pressure', 20, ...
|
||||
'beta_non_darcy_flow', 0), ...
|
||||
'density_g_sc', 0, ...
|
||||
'density_w_sc', 1000, ...
|
||||
'gas_model', 1, ...
|
||||
'prg', [], ...
|
||||
'Bgi', [], ...
|
||||
'cg', [], ...
|
||||
'vgi', [], ...
|
||||
'cvg', [], ...
|
||||
'Ppr', [], ...
|
||||
'BG', [], ...
|
||||
'MUG', [], ...
|
||||
'prw', [], ...
|
||||
'Bwi', [], ...
|
||||
'cw', [], ...
|
||||
'vwi', [], ...
|
||||
'cvw', [], ...
|
||||
'number_state_variables', 4));
|
||||
|
||||
config.initial = struct( ...
|
||||
'pressure', [], ...
|
||||
'sw', [], ...
|
||||
'cs', [], ...
|
||||
'cb', []);
|
||||
|
||||
config.wells = struct( ...
|
||||
'well1', {{}}, ...
|
||||
'num_fracture_wells', 0, ...
|
||||
'welloc', {{}}, ...
|
||||
'perfnum', {{}}, ...
|
||||
'well2', {{}}, ...
|
||||
'Wellc', []);
|
||||
|
||||
config.schedule = struct( ...
|
||||
'number_phases', 0, ...
|
||||
'well_schedules', {{}}, ...
|
||||
'time', [], ...
|
||||
'dtmax', [], ...
|
||||
'dtmin', []);
|
||||
|
||||
config.solver = struct( ...
|
||||
'yitap', 5, ...
|
||||
'yitas', 0.04, ...
|
||||
'omega', 0.5, ...
|
||||
'Nmax', 50, ...
|
||||
'epsave', 1e-6, ...
|
||||
'epsmax', 1e-6);
|
||||
|
||||
config.output = struct( ...
|
||||
'save_input_path', '', ...
|
||||
'save_result_path', '', ...
|
||||
'result_name', '', ...
|
||||
'plot_requests', {{}});
|
||||
@@ -0,0 +1,13 @@
|
||||
function config = load_config_json(file_path)
|
||||
%LOAD_CONFIG_JSON Load a config struct from a JSON file.
|
||||
|
||||
arguments
|
||||
file_path (1,:) char
|
||||
end
|
||||
|
||||
if ~exist(file_path, 'file')
|
||||
error('load_config_json:FileNotFound', 'Config file not found: %s', file_path);
|
||||
end
|
||||
|
||||
json_text = fileread(file_path);
|
||||
config = jsondecode(json_text);
|
||||
@@ -0,0 +1,18 @@
|
||||
function config = load_config_mat(file_path)
|
||||
%LOAD_CONFIG_MAT Load config struct from a MAT file.
|
||||
|
||||
arguments
|
||||
file_path (1,:) char
|
||||
end
|
||||
|
||||
if ~exist(file_path, 'file')
|
||||
error('load_config_mat:FileNotFound', 'Config file not found: %s', file_path);
|
||||
end
|
||||
|
||||
data = load(file_path, '-mat');
|
||||
if ~isfield(data, 'config')
|
||||
error('load_config_mat:MissingConfigVariable', ...
|
||||
'MAT file does not contain variable ''config'': %s', file_path);
|
||||
end
|
||||
|
||||
config = data.config;
|
||||
@@ -0,0 +1,21 @@
|
||||
function save_config_json(config, file_path)
|
||||
%SAVE_CONFIG_JSON Save a config struct to a JSON file.
|
||||
|
||||
arguments
|
||||
config (1,1) struct
|
||||
file_path (1,:) char
|
||||
end
|
||||
|
||||
folder_path = fileparts(file_path);
|
||||
if ~isempty(folder_path) && ~exist(folder_path, 'dir')
|
||||
mkdir(folder_path);
|
||||
end
|
||||
|
||||
json_text = jsonencode(config, PrettyPrint=true);
|
||||
fid = fopen(file_path, 'w');
|
||||
if fid == -1
|
||||
error('save_config_json:FileOpenFailed', 'Cannot open file: %s', file_path);
|
||||
end
|
||||
|
||||
cleanup_obj = onCleanup(@() fclose(fid));
|
||||
fprintf(fid, '%s', json_text);
|
||||
@@ -0,0 +1,14 @@
|
||||
function save_config_mat(config, file_path)
|
||||
%SAVE_CONFIG_MAT Save config struct to a MAT file.
|
||||
|
||||
arguments
|
||||
config (1,1) struct
|
||||
file_path (1,:) char
|
||||
end
|
||||
|
||||
folder_path = fileparts(file_path);
|
||||
if ~isempty(folder_path) && ~exist(folder_path, 'dir')
|
||||
mkdir(folder_path);
|
||||
end
|
||||
|
||||
save(file_path, 'config', '-mat');
|
||||
@@ -0,0 +1,18 @@
|
||||
function results = load_results_mat(file_path)
|
||||
%LOAD_RESULTS_MAT Load results struct from a MAT file.
|
||||
|
||||
arguments
|
||||
file_path (1,:) char
|
||||
end
|
||||
|
||||
if ~exist(file_path, 'file')
|
||||
error('load_results_mat:FileNotFound', 'Results file not found: %s', file_path);
|
||||
end
|
||||
|
||||
data = load(file_path, '-mat');
|
||||
if ~isfield(data, 'results')
|
||||
error('load_results_mat:MissingResultsVariable', ...
|
||||
'MAT file does not contain variable ''results'': %s', file_path);
|
||||
end
|
||||
|
||||
results = data.results;
|
||||
@@ -0,0 +1,14 @@
|
||||
function save_results_mat(results, file_path)
|
||||
%SAVE_RESULTS_MAT Save results struct to a MAT file.
|
||||
|
||||
arguments
|
||||
results (1,1) struct
|
||||
file_path (1,:) char
|
||||
end
|
||||
|
||||
folder_path = fileparts(file_path);
|
||||
if ~isempty(folder_path) && ~exist(folder_path, 'dir')
|
||||
mkdir(folder_path);
|
||||
end
|
||||
|
||||
save(file_path, 'results', '-mat');
|
||||
@@ -0,0 +1,413 @@
|
||||
function [r, Times, OutputRs, Wellpara, trun] = run_case(config)
|
||||
%RUN_CASE Execute a simulation from unified config.
|
||||
%
|
||||
% This is the first migration step from hard-coded main1.m scripts toward a
|
||||
% unified GUI entry point. The current implementation is intended to
|
||||
% reproduce case-template runs while the remaining flow-model internals are
|
||||
% still being normalized.
|
||||
|
||||
arguments
|
||||
config (1,1) struct
|
||||
end
|
||||
|
||||
project_root = fileparts(fileparts(fileparts(mfilename('fullpath'))));
|
||||
source_case_folder = resolve_source_case_folder(project_root, config.meta);
|
||||
if isempty(source_case_folder)
|
||||
error('run_case:MissingSourceCaseFolder', ...
|
||||
'config.meta.source_case_folder is required.');
|
||||
end
|
||||
|
||||
if ~isfolder(source_case_folder)
|
||||
error('run_case:SourceCaseFolderNotFound', ...
|
||||
'Source case folder not found: %s', source_case_folder);
|
||||
end
|
||||
|
||||
addpath(genpath(project_root));
|
||||
|
||||
old_dir = pwd;
|
||||
cleanup_obj = onCleanup(@() cd(old_dir));
|
||||
cd(source_case_folder);
|
||||
|
||||
overall_tic = tic;
|
||||
|
||||
config.grid.nx = numel(config.grid.dx);
|
||||
config.grid.ny = numel(config.grid.dy);
|
||||
config.grid.nz = numel(config.grid.dz);
|
||||
|
||||
r = GridProp_pre( ...
|
||||
config.grid.dx, ...
|
||||
config.grid.dy, ...
|
||||
config.grid.dz, ...
|
||||
config.grid.nx, ...
|
||||
config.grid.ny, ...
|
||||
config.grid.nz, ...
|
||||
config.grid.NTG);
|
||||
|
||||
[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);
|
||||
elseif grid_model == 2
|
||||
r = grid_discretization_DP_model(modelflag, r, f, frac_information, fellip, nf);
|
||||
else
|
||||
error('run_case:UnsupportedGridModel', 'Unsupported grid model: %d', grid_model);
|
||||
end
|
||||
|
||||
os = OperatorRS(r.N, r.nex, r.nc);
|
||||
|
||||
[fluid_model, state0] = build_flow_inputs(flow_model, r, config);
|
||||
|
||||
well1 = handle_well1(config.wells.well1, r);
|
||||
[well2, welloc] = build_fracture_wells(config.wells, r);
|
||||
Wellc = handle_well1_well2(well1, well2, welloc, r);
|
||||
|
||||
[Times, OutputRs, Wellpara, trun] = solver_NR( ...
|
||||
r, ...
|
||||
flow_model, ...
|
||||
fluid_model, ...
|
||||
os, ...
|
||||
state0, ...
|
||||
config.solver.yitap, ...
|
||||
config.solver.yitas, ...
|
||||
config.solver.omega, ...
|
||||
config.solver.Nmax, ...
|
||||
config.solver.epsave, ...
|
||||
config.solver.epsmax, ...
|
||||
config.schedule.dtmin, ...
|
||||
config.schedule.dtmax, ...
|
||||
Wellc, ...
|
||||
config.schedule.time, ...
|
||||
config.schedule.well_schedules);
|
||||
|
||||
trun.run_time = toc(overall_tic);
|
||||
end
|
||||
|
||||
function source_case_folder = resolve_source_case_folder(project_root, meta_config)
|
||||
source_case_folder = meta_config.source_case_folder;
|
||||
|
||||
if isfolder(source_case_folder)
|
||||
return;
|
||||
end
|
||||
|
||||
case_id = lower(string(meta_config.case_id));
|
||||
switch case_id
|
||||
case "case01"
|
||||
source_case_folder = find_case_folder_by_index(project_root, 1);
|
||||
otherwise
|
||||
if isempty(source_case_folder) || startsWith(string(source_case_folder), "CASE")
|
||||
source_case_folder = '';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function source_case_folder = find_case_folder_by_index(project_root, case_index)
|
||||
folder_candidates = dir(fullfile(project_root, sprintf('*%d-*', case_index)));
|
||||
folder_candidates = folder_candidates([folder_candidates.isdir]);
|
||||
|
||||
if isempty(folder_candidates)
|
||||
source_case_folder = '';
|
||||
else
|
||||
source_case_folder = fullfile(project_root, folder_candidates(1).name);
|
||||
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
|
||||
end
|
||||
|
||||
function [fluid_model, state0] = build_flow_inputs(flow_model, r, config)
|
||||
switch flow_model
|
||||
case 1
|
||||
if has_complete_gas_water_config(config.flow.gas_water)
|
||||
[fluid_model, state0] = build_gas_water_flow_from_config( ...
|
||||
config.flow.gas_water, config.initial, r);
|
||||
else
|
||||
[fluid_model, state0] = gas_water_flow(r);
|
||||
end
|
||||
case 2
|
||||
if has_complete_oil_water_config(config.flow.oil_water)
|
||||
[fluid_model, state0] = build_oil_water_flow_from_config( ...
|
||||
config.flow.oil_water, config.initial, r);
|
||||
else
|
||||
[fluid_model, state0] = oil_water_flow(r);
|
||||
end
|
||||
case 3
|
||||
if has_complete_multicomponent_config(config.flow.multi_component)
|
||||
[fluid_model, state0] = build_multi_component_flow_from_config( ...
|
||||
config.flow.multi_component, config.initial, r);
|
||||
else
|
||||
[fluid_model, state0] = multi_component_flow(r);
|
||||
end
|
||||
otherwise
|
||||
error('run_case:UnsupportedFlowModel', ...
|
||||
'Unsupported flow model: %d', flow_model);
|
||||
end
|
||||
end
|
||||
|
||||
function tf = has_complete_gas_water_config(gw)
|
||||
required_fields = { ...
|
||||
'density_g_sc', 'density_w_sc', 'gas_model', 'prw', 'Bwi', 'cw', ...
|
||||
'vwi', 'cvw', 'ifpcgl', 'matrix_relperm_table', 'fracture_relperm_table', ...
|
||||
'p_grad_threshold'};
|
||||
|
||||
tf = true;
|
||||
for i = 1:numel(required_fields)
|
||||
field_name = required_fields{i};
|
||||
if ~isfield(gw, field_name) || isempty(gw.(field_name))
|
||||
tf = false;
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if ~isfield(gw, 'gas_prop') || isempty(gw.gas_prop)
|
||||
tf = false;
|
||||
return;
|
||||
end
|
||||
|
||||
if gw.gas_model == 1
|
||||
tf = all(isfield(gw, {'prg', 'Bgi', 'cg', 'vgi', 'cvg'})) && ...
|
||||
~isempty(gw.prg) && ~isempty(gw.Bgi) && ~isempty(gw.cg) && ...
|
||||
~isempty(gw.vgi) && ~isempty(gw.cvg);
|
||||
else
|
||||
tf = all(isfield(gw, {'Ppr', 'BG', 'MUG'})) && ...
|
||||
~isempty(gw.Ppr) && ~isempty(gw.BG) && ~isempty(gw.MUG);
|
||||
end
|
||||
end
|
||||
|
||||
function tf = has_complete_oil_water_config(ow)
|
||||
required_fields = { ...
|
||||
'density_o_sc', 'density_w_sc', 'oil_model', 'prw', 'Bwi', 'cw', ...
|
||||
'vwi', 'cvw', 'ifpcow', 'matrix_relperm_table', 'fracture_relperm_table', ...
|
||||
'beta_non_darcy_flow', 'p_grad_threshold'};
|
||||
|
||||
tf = true;
|
||||
for i = 1:numel(required_fields)
|
||||
field_name = required_fields{i};
|
||||
if ~isfield(ow, field_name) || isempty(ow.(field_name))
|
||||
tf = false;
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if ow.oil_model == 1
|
||||
tf = all(isfield(ow, {'pro', 'Boi', 'co', 'voi', 'cvo'})) && ...
|
||||
~isempty(ow.pro) && ~isempty(ow.Boi) && ~isempty(ow.co) && ...
|
||||
~isempty(ow.voi) && ~isempty(ow.cvo);
|
||||
else
|
||||
tf = all(isfield(ow, {'Ppr', 'BO', 'MUO'})) && ...
|
||||
~isempty(ow.Ppr) && ~isempty(ow.BO) && ~isempty(ow.MUO);
|
||||
end
|
||||
end
|
||||
|
||||
function [f, state0] = build_gas_water_flow_from_config(gw, initial_config, r)
|
||||
if gw.gas_model == 1
|
||||
[Ppr, BG, MUG] = cal_gas_prop(gw.prg, gw.Bgi, gw.cg, gw.vgi, gw.cvg);
|
||||
else
|
||||
Ppr = gw.Ppr;
|
||||
BG = gw.BG;
|
||||
MUG = gw.MUG;
|
||||
end
|
||||
|
||||
matrix_table = gw.matrix_relperm_table;
|
||||
fracture_table = gw.fracture_relperm_table;
|
||||
|
||||
f = fluidPVT_gas_water_flow( ...
|
||||
Ppr, BG, MUG, gw.Bwi, gw.prw, gw.cw, gw.vwi, gw.cvw, ...
|
||||
matrix_table(:, 1), matrix_table(:, 3), matrix_table(:, 2), matrix_table(:, 4), ...
|
||||
fracture_table(:, 1), fracture_table(:, 3), fracture_table(:, 2), fracture_table(:, 4), ...
|
||||
gw.density_g_sc, gw.ifpcgl, r.rpt);
|
||||
|
||||
gas_prop = gw.gas_prop;
|
||||
c1 = 1;
|
||||
c2 = 8 / 9;
|
||||
gas_prop.Kn_modified_factor = 1 + 8 * c1 * gas_prop.Kn + 16 * c2 * gas_prop.Kn^2;
|
||||
|
||||
f.Dwsi = gw.density_w_sc;
|
||||
f.Dgsi = gw.density_g_sc;
|
||||
f.gas_prop = gas_prop;
|
||||
f.p_grad_threshold = gw.p_grad_threshold;
|
||||
|
||||
total_cells = r.nmc + r.nfc;
|
||||
pressure0 = expand_initial_value(initial_config.pressure, total_cells);
|
||||
sw0 = expand_initial_value(initial_config.sw, total_cells);
|
||||
state0 = initialRS_gas_water_flow(pressure0, sw0);
|
||||
end
|
||||
|
||||
function [f, state0] = build_oil_water_flow_from_config(ow, initial_config, r)
|
||||
if ow.oil_model == 1
|
||||
[Ppr, BO, MUO] = cal_oil_prop(ow.pro, ow.Boi, ow.co, ow.voi, ow.cvo);
|
||||
else
|
||||
Ppr = ow.Ppr;
|
||||
BO = ow.BO;
|
||||
MUO = ow.MUO;
|
||||
end
|
||||
|
||||
matrix_table = ow.matrix_relperm_table;
|
||||
fracture_table = ow.fracture_relperm_table;
|
||||
|
||||
f = fluidPVT_oil_water_flow( ...
|
||||
Ppr, BO, MUO, ow.Bwi, ow.prw, ow.cw, ow.vwi, ow.cvw, ...
|
||||
matrix_table(:, 1), matrix_table(:, 3), matrix_table(:, 2), matrix_table(:, 4), ...
|
||||
fracture_table(:, 1), fracture_table(:, 3), fracture_table(:, 2), fracture_table(:, 4), ...
|
||||
ow.density_o_sc, ow.ifpcow, r.rpt);
|
||||
|
||||
f.beta_non_Darcy_flow = ow.beta_non_darcy_flow;
|
||||
f.Dwsi = ow.density_w_sc;
|
||||
f.Dosi = ow.density_o_sc;
|
||||
f.p_grad_threshold = ow.p_grad_threshold;
|
||||
|
||||
total_cells = r.nmc + r.nfc;
|
||||
pressure0 = expand_initial_value(initial_config.pressure, total_cells);
|
||||
sw0 = expand_initial_value(initial_config.sw, total_cells);
|
||||
state0 = initialRS_oil_water_flow(pressure0, sw0);
|
||||
end
|
||||
|
||||
function tf = has_complete_multicomponent_config(mc)
|
||||
required_fields = { ...
|
||||
'Ds', 'Db', 'c_ca_table', 'R', 'Vm', 'Temperature', ...
|
||||
'cs_Nc', 'kr_nosurf', 'kr_surf', 'PC', ...
|
||||
'cs_Nc_fracture', 'kr_nosurf_fracture', 'kr_surf_fracture', 'PC_fracture', ...
|
||||
'density_g_sc', 'density_w_sc', 'gas_model', 'prw', 'Bwi', 'cw', 'vwi', 'cvw'};
|
||||
|
||||
tf = true;
|
||||
for i = 1:numel(required_fields)
|
||||
field_name = required_fields{i};
|
||||
if ~isfield(mc, field_name) || isempty(mc.(field_name))
|
||||
tf = false;
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if ~isfield(mc, 'gas_prop') || isempty(mc.gas_prop)
|
||||
tf = false;
|
||||
return;
|
||||
end
|
||||
|
||||
if mc.gas_model == 1
|
||||
tf = all(isfield(mc, {'prg', 'Bgi', 'cg', 'vgi', 'cvg'})) && ...
|
||||
~isempty(mc.prg) && ~isempty(mc.Bgi) && ~isempty(mc.cg) && ...
|
||||
~isempty(mc.vgi) && ~isempty(mc.cvg);
|
||||
else
|
||||
tf = all(isfield(mc, {'Ppr', 'BG', 'MUG'})) && ...
|
||||
~isempty(mc.Ppr) && ~isempty(mc.BG) && ~isempty(mc.MUG);
|
||||
end
|
||||
end
|
||||
|
||||
function [f, state0] = build_multi_component_flow_from_config(mc, initial_config, r)
|
||||
cs_data = mc.c_ca_table(:, 1);
|
||||
cb_data = mc.c_ca_table(:, 1);
|
||||
csa_data = mc.c_ca_table(:, 2) * 1e-3;
|
||||
cba_data = mc.c_ca_table(:, 3) * 1e-3;
|
||||
Nc_nosurf = min(mc.cs_Nc(:, 2));
|
||||
Nc_surf = max(mc.cs_Nc(:, 2));
|
||||
|
||||
if mc.gas_model == 1
|
||||
[Ppr, BG, MUG] = cal_gas_prop(mc.prg, mc.Bgi, mc.cg, mc.vgi, mc.cvg);
|
||||
else
|
||||
Ppr = mc.Ppr;
|
||||
BG = mc.BG;
|
||||
MUG = mc.MUG;
|
||||
end
|
||||
|
||||
f = fluidPVT_new( ...
|
||||
Ppr, BG, MUG, mc.Bwi, mc.prw, mc.cw, mc.vwi, mc.cvw, ...
|
||||
mc.ifpcgl, r.rpt, cs_data, csa_data, cb_data, cba_data, ...
|
||||
mc.cs_Nc, Nc_nosurf, Nc_surf, mc.kr_nosurf, mc.kr_surf, mc.PC, ...
|
||||
mc.cs_Nc_fracture, mc.kr_nosurf_fracture, mc.kr_surf_fracture, mc.PC_fracture);
|
||||
|
||||
gas_prop = mc.gas_prop;
|
||||
c1 = 1;
|
||||
c2 = 8 / 9;
|
||||
gas_prop.Kn_modified_factor = 1 + 8 * c1 * gas_prop.Kn + 16 * c2 * gas_prop.Kn^2;
|
||||
|
||||
f.Dwsi = mc.density_w_sc;
|
||||
f.Dgsi = mc.density_g_sc;
|
||||
f.gas_prop = gas_prop;
|
||||
f.Ds = mc.Ds;
|
||||
f.Db = mc.Db;
|
||||
f.chemistry_cof = mc.R * mc.Temperature / mc.Vm * 1e-3 / 10;
|
||||
f.p_grad_threshold = mc.p_grad_threshold;
|
||||
f.number_state_variables = mc.number_state_variables;
|
||||
|
||||
total_cells = r.nmc + r.nfc;
|
||||
matrix_x = default_if_empty(mc, 'x_matrix', 0.9);
|
||||
fracture_x = default_if_empty(mc, 'x_fracture', 1.0);
|
||||
f.x_total = [matrix_x * ones(r.nmc, 1); fracture_x * ones(r.nfc, 1)];
|
||||
f.chemistry_potential = f.chemistry_cof * log(f.x_total);
|
||||
|
||||
pressure0 = expand_initial_value(initial_config.pressure, total_cells);
|
||||
sw0 = expand_initial_value(initial_config.sw, total_cells);
|
||||
cs0 = expand_initial_value(initial_config.cs, total_cells);
|
||||
cb0 = expand_initial_value(initial_config.cb, total_cells);
|
||||
state0 = initialRS(pressure0, sw0, cs0, cb0);
|
||||
end
|
||||
|
||||
function value = expand_initial_value(raw_value, total_cells)
|
||||
if isscalar(raw_value)
|
||||
value = raw_value * ones(total_cells, 1);
|
||||
else
|
||||
value = raw_value;
|
||||
end
|
||||
end
|
||||
|
||||
function value = default_if_empty(s, field_name, fallback)
|
||||
if isfield(s, field_name) && ~isempty(s.(field_name))
|
||||
value = s.(field_name);
|
||||
else
|
||||
value = fallback;
|
||||
end
|
||||
end
|
||||
|
||||
function [well2, welloc] = build_fracture_wells(wells_config, r)
|
||||
num_fracture_wells = wells_config.num_fracture_wells;
|
||||
welloc = wells_config.welloc;
|
||||
perfnum = cell(num_fracture_wells, 1);
|
||||
|
||||
for i = 1:num_fracture_wells
|
||||
perfnum{i, 1} = findWelloc(r, welloc{i, 1});
|
||||
end
|
||||
|
||||
well2 = cell(num_fracture_wells, 6);
|
||||
for i = 1:num_fracture_wells
|
||||
if numel(wells_config.well2) >= i && ~isempty(wells_config.well2{i, 1})
|
||||
well2(i, :) = wells_config.well2(i, :);
|
||||
well2{i, 2} = length(perfnum{i, 1});
|
||||
well2{i, 3} = perfnum{i, 1};
|
||||
else
|
||||
well2(i, :) = {sprintf('wf%d', i), length(perfnum{i, 1}), perfnum{i, 1}, 0.178/2, 0, 4};
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,25 @@
|
||||
function config = load_case_template(case_id)
|
||||
%LOAD_CASE_TEMPLATE Load a predefined case template into unified config.
|
||||
|
||||
arguments
|
||||
case_id
|
||||
end
|
||||
|
||||
case_key = normalize_case_id(case_id);
|
||||
|
||||
switch case_key
|
||||
case "case01"
|
||||
config = load_case_template_case01();
|
||||
otherwise
|
||||
error('load_case_template:UnsupportedCase', ...
|
||||
'Unsupported case template: %s', string(case_key));
|
||||
end
|
||||
end
|
||||
|
||||
function case_key = normalize_case_id(case_id)
|
||||
if isnumeric(case_id)
|
||||
case_key = "case" + compose("%02d", case_id);
|
||||
else
|
||||
case_key = lower(string(case_id));
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,189 @@
|
||||
function config = load_case_template_case01()
|
||||
%LOAD_CASE_TEMPLATE_CASE01 Build config for case 1.
|
||||
|
||||
config = create_empty_config();
|
||||
|
||||
config.meta.case_name = 'case01_multicomponent_irregular_domain';
|
||||
config.meta.case_id = 'case01';
|
||||
config.meta.description = 'Multicomponent flow with irregular heterogeneous domain';
|
||||
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;
|
||||
|
||||
config.grid.dx = 50 * ones(1, 20);
|
||||
config.grid.dy = 50 * ones(1, 10);
|
||||
config.grid.dz = 10 * ones(1, 1);
|
||||
config.grid.nx = numel(config.grid.dx);
|
||||
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;
|
||||
[355,255,5],90,90,0,200,10,1;
|
||||
[405,255,5],90,90,0,200,10,1;
|
||||
[455,255,5],90,90,0,200,10,1;
|
||||
[505,255,5],90,90,0,200,10,1;
|
||||
[555,255,5],90,90,0,200,10,1;
|
||||
[605,255,5],90,90,0,200,10,1;
|
||||
[655,255,5],90,90,0,200,10,1;
|
||||
[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 = [
|
||||
0,100;
|
||||
800,50;
|
||||
1000,150;
|
||||
1000,350;
|
||||
800,450;
|
||||
0,400;
|
||||
0,100];
|
||||
config.discretization.sp.invalid_layer = [];
|
||||
config.discretization.sp.matrix.prpor = 20;
|
||||
config.discretization.sp.matrix.cpor = 1.0e-5;
|
||||
config.discretization.sp.matrix.rock_density = 2700;
|
||||
config.discretization.sp.fracture.prporf = 20;
|
||||
config.discretization.sp.fracture.cporf = 1.0e-5;
|
||||
config.discretization.sp.stress.fracture_factor = 0.0;
|
||||
config.discretization.sp.stress.matrix_factor = 0.0;
|
||||
config.discretization.sp.stress.ref_pressure = 20;
|
||||
|
||||
config.flow.multi_component.Ds = 0.76e-9;
|
||||
config.flow.multi_component.Db = 2.2e-9;
|
||||
config.flow.multi_component.c_ca_table = [
|
||||
0 0 0;
|
||||
0.05 1 0.075;
|
||||
0.1 1.75 0.125;
|
||||
0.2 3 0.2;
|
||||
0.5 4.35 0.325;
|
||||
1 4.55 0.365];
|
||||
config.flow.multi_component.R = 0.008314;
|
||||
config.flow.multi_component.Vm = 18.02e-6;
|
||||
config.flow.multi_component.Temperature = 293.15;
|
||||
config.flow.multi_component.x_matrix = 0.9;
|
||||
config.flow.multi_component.x_fracture = 1.0;
|
||||
config.flow.multi_component.cs_Nc = [
|
||||
0 1.6e-6 30;
|
||||
0.1 9.5e-6 10;
|
||||
0.2 2.5e-5 4;
|
||||
0.5 5.8e-5 1.4;
|
||||
1 8.2e-5 1;
|
||||
2 8.8e-5 0.75];
|
||||
config.flow.multi_component.kr_nosurf = [
|
||||
0 0 0.64;
|
||||
0.25 0 0.64;
|
||||
0.30 0.072 0.6;
|
||||
0.40 0.14 0.56;
|
||||
0.50 0.26 0.48;
|
||||
0.60 0.4 0.38;
|
||||
0.70 0.56 0.26;
|
||||
0.85 0.88 0;
|
||||
1 0.88 0];
|
||||
config.flow.multi_component.kr_surf = [
|
||||
0 0 0.6;
|
||||
0.18 0 0.6;
|
||||
0.25 0.056 0.56;
|
||||
0.30 0.1 0.52;
|
||||
0.40 0.19 0.42;
|
||||
0.50 0.29 0.3;
|
||||
0.60 0.37 0.19;
|
||||
0.75 0.46 0;
|
||||
1 0.46 0];
|
||||
config.flow.multi_component.PC = [
|
||||
0 3.8916;
|
||||
0.2 3.8916;
|
||||
0.316 0.5796;
|
||||
0.435 0.3724;
|
||||
0.562 0.2425;
|
||||
0.614 0.0608;
|
||||
0.702 0.0372;
|
||||
0.812 0.0137;
|
||||
0.875 0.0104;
|
||||
0.906 0.009;
|
||||
0.937 0.0075;
|
||||
0.969 0.0059;
|
||||
1 0];
|
||||
config.flow.multi_component.cs_Nc_fracture = config.flow.multi_component.cs_Nc;
|
||||
config.flow.multi_component.kr_nosurf_fracture = config.flow.multi_component.kr_nosurf;
|
||||
config.flow.multi_component.kr_surf_fracture = config.flow.multi_component.kr_surf;
|
||||
config.flow.multi_component.PC_fracture = config.flow.multi_component.PC;
|
||||
config.flow.multi_component.ifpcgl = 0;
|
||||
config.flow.multi_component.p_grad_threshold = 0.01;
|
||||
config.flow.multi_component.gas_prop.VL = 0.0;
|
||||
config.flow.multi_component.gas_prop.PL = 3.5;
|
||||
config.flow.multi_component.gas_prop.Kn = 0;
|
||||
config.flow.multi_component.gas_prop.stress_factor_fracture = 0.0;
|
||||
config.flow.multi_component.gas_prop.stress_factor_matrix = 0.0;
|
||||
config.flow.multi_component.gas_prop.stress_factor_ref_pressure = 20;
|
||||
config.flow.multi_component.gas_prop.beta_non_darcy_flow = 0;
|
||||
config.flow.multi_component.density_g_sc = 800;
|
||||
config.flow.multi_component.gas_model = 1;
|
||||
config.flow.multi_component.prg = 20;
|
||||
config.flow.multi_component.Bgi = 1;
|
||||
config.flow.multi_component.cg = 5e-4;
|
||||
config.flow.multi_component.vgi = 6;
|
||||
config.flow.multi_component.cvg = 0;
|
||||
config.flow.multi_component.density_w_sc = 1000;
|
||||
config.flow.multi_component.prw = 20;
|
||||
config.flow.multi_component.Bwi = 1.0;
|
||||
config.flow.multi_component.cw = 4.0e-4;
|
||||
config.flow.multi_component.vwi = 1;
|
||||
config.flow.multi_component.cvw = 0;
|
||||
config.flow.multi_component.number_state_variables = 4;
|
||||
|
||||
config.initial.pressure = 20;
|
||||
config.initial.sw = 0.2;
|
||||
config.initial.cs = 0.0;
|
||||
config.initial.cb = 0.0;
|
||||
|
||||
config.wells.well1 = {};
|
||||
config.wells.num_fracture_wells = 1;
|
||||
config.wells.welloc = {
|
||||
[
|
||||
255,255,5;
|
||||
305,255,5;
|
||||
355,255,5;
|
||||
405,255,5;
|
||||
455,255,5;
|
||||
505,255,5;
|
||||
555,255,5;
|
||||
605,255,5;
|
||||
655,255,5;
|
||||
705,255,5;
|
||||
755,255,5
|
||||
]};
|
||||
config.wells.well2 = {
|
||||
'w1', 0, [], 0.178/2, 0, 4
|
||||
};
|
||||
|
||||
config.schedule.number_phases = 3;
|
||||
config.schedule.time = [10; 30; 200];
|
||||
config.schedule.dtmax = [0.1; 0.5; 0.5];
|
||||
config.schedule.dtmin = [0.001; 0.001; 0.001];
|
||||
config.schedule.well_schedules = {
|
||||
{
|
||||
'w1','open','inj','const_pwf',40,40,'Cs_inj',0.5,'Cb_inj',1
|
||||
};
|
||||
{
|
||||
'w1','open','pro','const_q',0,0
|
||||
};
|
||||
{
|
||||
'w1','open','pro','const_pwf',10,10
|
||||
}};
|
||||
|
||||
config.solver.yitap = 5;
|
||||
config.solver.yitas = 0.04;
|
||||
config.solver.omega = 0.5;
|
||||
config.solver.Nmax = 50;
|
||||
config.solver.epsave = 1e-6;
|
||||
config.solver.epsmax = 1e-6;
|
||||
|
||||
config.output.result_name = 'case01_default_run';
|
||||
Reference in New Issue
Block a user