优化点5,6

This commit is contained in:
xinxiao
2026-04-03 15:51:34 +08:00
parent 2622ee0c79
commit 88382efb44
5 changed files with 892 additions and 38 deletions
+416 -6
View File
@@ -5,6 +5,7 @@ classdef EDFMAppController < handle
Results struct = struct()
ProjectRoot char
CurrentPlotAction string = ""
CurrentFracWellIndex double = 1
end
methods
@@ -25,6 +26,7 @@ classdef EDFMAppController < handle
obj.setDropDownItems('OWoil_modelDropDown', {'1', '2'}, '1');
obj.setDropDownItems('MCgas_modelDropDown', {'1'}, '1');
obj.configureWellTables();
obj.configureFracWellControls();
obj.applyFixedUIState();
obj.Results = struct();
@@ -180,6 +182,9 @@ classdef EDFMAppController < handle
obj.App.(tableName).UserData = [];
else
obj.App.(tableName).UserData = indices(1, 1);
if strcmp(tableName, 'Well2Table')
obj.setSelectedFracWellIndex(indices(1, 1), true);
end
end
end
@@ -188,6 +193,37 @@ classdef EDFMAppController < handle
return;
end
switch tableName
case 'Well2Table'
obj.pushUIToConfig();
c = normalize_config(obj.Config);
well2 = obj.getTableValue('Well2Table', c.wells.well2);
newRow = obj.getDefaultRowForTable(tableName);
nextIndex = size(well2, 1) + 1;
if isempty(newRow{1})
newRow{1} = sprintf('wf%d', nextIndex);
end
if isempty(well2)
well2 = newRow;
else
well2(end + 1, :) = newRow;
end
c.wells.well2 = well2;
c.wells.welloc = obj.resizeWellocCell(c.wells.welloc, size(well2, 1));
c.wells.num_fracture_wells = size(well2, 1);
obj.Config = c;
obj.CurrentFracWellIndex = c.wells.num_fracture_wells;
obj.refreshUIFromConfig();
return;
case 'FractureWellLocationTable'
if obj.getFractureWellCount() == 0
uialert(obj.App.UIFigure, ...
'Please add a fracture well before editing perforation coordinates.', ...
'No Fracture Well');
return;
end
end
data = obj.App.(tableName).Data;
newRow = obj.getDefaultRowForTable(tableName);
@@ -209,6 +245,38 @@ classdef EDFMAppController < handle
return;
end
if strcmp(tableName, 'Well2Table')
obj.pushUIToConfig();
c = normalize_config(obj.Config);
selectedRow = [];
if isprop(obj.App.(tableName), 'UserData')
selectedRow = obj.App.(tableName).UserData;
end
if isempty(selectedRow) || ~isscalar(selectedRow) || selectedRow < 1
uialert(obj.App.UIFigure, ...
sprintf('Please select a row in %s first.', tableName), ...
'Delete Row');
return;
end
if selectedRow > size(c.wells.well2, 1)
return;
end
c.wells.well2(selectedRow, :) = [];
if iscell(c.wells.welloc) && numel(c.wells.welloc) >= selectedRow
c.wells.welloc(selectedRow, :) = [];
end
c.wells.welloc = obj.resizeWellocCell(c.wells.welloc, size(c.wells.well2, 1));
c.wells.num_fracture_wells = size(c.wells.well2, 1);
if c.wells.num_fracture_wells == 0
obj.CurrentFracWellIndex = 1;
else
obj.CurrentFracWellIndex = min(selectedRow, c.wells.num_fracture_wells);
end
obj.Config = c;
obj.refreshUIFromConfig();
return;
end
data = obj.App.(tableName).Data;
if isempty(data)
return;
@@ -455,8 +523,10 @@ classdef EDFMAppController < handle
obj.setNumericFieldValue('MCstress_factor_ref_pressureEditField', c.flow.multi_component.gas_prop.stress_factor_ref_pressure);
obj.setTableValue('Well1Table', c.wells.well1);
obj.setTableValue('FractureWellLocationTable', obj.unwrapFirstCell(c.wells.welloc));
obj.setTableValue('Well2Table', c.wells.well2);
c = obj.normalizeScheduleConfig(c);
obj.Config = c;
obj.refreshFracWellControlsFromConfig();
obj.setTableValue('ScheduleTable', obj.unwrapFirstCell(c.schedule.well_schedules));
obj.setTextAreaExpr('TimeTextArea', c.schedule.time);
obj.setTextAreaExpr('DtMinTextArea', c.schedule.dtmin);
@@ -648,11 +718,11 @@ classdef EDFMAppController < handle
c.flow.multi_component.cvw = commonCvw;
c.wells.well1 = obj.getTableValue('Well1Table', c.wells.well1);
fractureWellLocation = obj.getNumericTableValue( ...
'FractureWellLocationTable', obj.unwrapFirstCell(c.wells.welloc));
c.wells.welloc = obj.replaceFirstCell(c.wells.welloc, fractureWellLocation);
c.wells.num_fracture_wells = numel(c.wells.welloc);
c.wells.well2 = obj.getTableValue('Well2Table', c.wells.well2);
c.wells.num_fracture_wells = size(c.wells.well2, 1);
c.wells.welloc = obj.resizeWellocCell(c.wells.welloc, c.wells.num_fracture_wells);
c = obj.persistCurrentFractureWellLocation(c);
c.wells.welloc = obj.resizeWellocCell(c.wells.welloc, c.wells.num_fracture_wells);
firstPhaseSchedule = obj.getTableValue( ...
'ScheduleTable', obj.unwrapFirstCell(c.schedule.well_schedules));
@@ -661,6 +731,7 @@ classdef EDFMAppController < handle
c.schedule.time = obj.getTextAreaExpr('TimeTextArea', c.schedule.time);
c.schedule.dtmin = obj.getTextAreaExpr('DtMinTextArea', c.schedule.dtmin);
c.schedule.dtmax = obj.getTextAreaExpr('DtMaxTextArea', c.schedule.dtmax);
c = obj.normalizeScheduleConfig(c);
c.solver.yitap = obj.getNumericFieldValue('YitaPEditField', c.solver.yitap);
c.solver.yitas = obj.getNumericFieldValue('YitaSEditField', c.solver.yitas);
@@ -673,6 +744,16 @@ classdef EDFMAppController < handle
obj.syncModelTabs();
end
function onSelectedFracWellChanged(obj)
if isempty(fieldnames(obj.Config))
obj.Config = normalize_config(create_empty_config());
else
obj.Config = obj.persistCurrentFractureWellLocation(normalize_config(obj.Config));
end
obj.CurrentFracWellIndex = obj.getSelectedFracWellIndexFromUI();
obj.refreshFracWellControlsFromConfig();
end
function applyFixedUIState(obj)
obj.setControlVisible('ModelFlagDropDownLabel', false);
obj.setControlVisible('ModelFlagDropDown', false);
@@ -1505,6 +1586,14 @@ classdef EDFMAppController < handle
end
end
function configureFracWellControls(obj)
if isprop(obj.App, 'SelectedFracWellDropDown')
obj.App.SelectedFracWellDropDown.Items = {''};
obj.App.SelectedFracWellDropDown.Value = '';
obj.App.SelectedFracWellDropDown.ValueChangedFcn = @(src, event) obj.onSelectedFracWellChanged();
end
end
function configureSingleTable(obj, tableName)
if ~isprop(obj.App, tableName)
return;
@@ -1518,7 +1607,12 @@ classdef EDFMAppController < handle
tableHandle = obj.App.(tableName);
tableHandle.ColumnName = columnNames;
tableHandle.RowName = {};
tableHandle.ColumnEditable = true(1, numel(columnNames));
switch tableName
case 'Well2Table'
tableHandle.ColumnEditable = [true, false, false, true, true, true];
otherwise
tableHandle.ColumnEditable = true(1, numel(columnNames));
end
end
function columnNames = getColumnNamesForTable(~, tableName)
@@ -1589,5 +1683,321 @@ classdef EDFMAppController < handle
end
textValue = strtrim(evalc('disp(value)'));
end
function c = persistCurrentFractureWellLocation(obj, c)
c = normalize_config(c);
fractureWellCount = size(c.wells.well2, 1);
c.wells.welloc = obj.resizeWellocCell(c.wells.welloc, fractureWellCount);
if fractureWellCount == 0
c.wells.welloc = cell(0, 1);
c.wells.num_fracture_wells = 0;
return;
end
selectedIndex = min(max(obj.getSelectedFracWellIndex(), 1), fractureWellCount);
fractureWellLocation = obj.getNumericTableValue('FractureWellLocationTable', []);
c.wells.welloc{selectedIndex, 1} = fractureWellLocation;
c.wells.num_fracture_wells = fractureWellCount;
end
function refreshFracWellControlsFromConfig(obj)
c = normalize_config(obj.Config);
fractureWellCount = size(c.wells.well2, 1);
c.wells.welloc = obj.resizeWellocCell(c.wells.welloc, fractureWellCount);
c.wells.num_fracture_wells = fractureWellCount;
obj.Config = c;
obj.refreshFracWellDropDown(fractureWellCount, c.wells.well2);
if fractureWellCount == 0
obj.CurrentFracWellIndex = 1;
obj.setTableValue('FractureWellLocationTable', []);
obj.setControlEnabled('SelectedFracWellDropDown', false);
obj.setControlEnabled('FractureWellLocationTable', false);
obj.setControlEnabled('AddFracLocRowButton', false);
obj.setControlEnabled('DeleteFracLocRowButton', false);
return;
end
obj.CurrentFracWellIndex = min(max(obj.CurrentFracWellIndex, 1), fractureWellCount);
obj.setSelectedFracWellIndex(obj.CurrentFracWellIndex, false);
obj.setControlEnabled('SelectedFracWellDropDown', true);
obj.setControlEnabled('FractureWellLocationTable', true);
obj.setControlEnabled('AddFracLocRowButton', true);
obj.setControlEnabled('DeleteFracLocRowButton', true);
obj.setTableValue('FractureWellLocationTable', c.wells.welloc{obj.CurrentFracWellIndex, 1});
end
function refreshFracWellDropDown(obj, fractureWellCount, well2)
if ~isprop(obj.App, 'SelectedFracWellDropDown')
return;
end
if fractureWellCount == 0
obj.App.SelectedFracWellDropDown.Items = {''};
obj.App.SelectedFracWellDropDown.Value = '';
return;
end
items = cell(fractureWellCount, 1);
for i = 1:fractureWellCount
wellName = sprintf('wf%d', i);
if size(well2, 1) >= i && size(well2, 2) >= 1 && ~isempty(well2{i, 1})
wellName = char(string(well2{i, 1}));
end
items{i} = sprintf('%d: %s', i, wellName);
end
obj.App.SelectedFracWellDropDown.Items = items;
selectedValue = items{min(max(obj.CurrentFracWellIndex, 1), fractureWellCount)};
obj.App.SelectedFracWellDropDown.Value = selectedValue;
end
function count = getFractureWellCount(obj)
if isempty(fieldnames(obj.Config))
count = 0;
return;
end
c = normalize_config(obj.Config);
count = size(c.wells.well2, 1);
end
function index = getSelectedFracWellIndex(obj)
fractureWellCount = obj.getFractureWellCount();
if fractureWellCount == 0
index = 1;
return;
end
index = min(max(obj.CurrentFracWellIndex, 1), fractureWellCount);
end
function index = getSelectedFracWellIndexFromUI(obj)
if ~isprop(obj.App, 'SelectedFracWellDropDown')
index = obj.CurrentFracWellIndex;
return;
end
value = string(obj.App.SelectedFracWellDropDown.Value);
token = regexp(char(value), '^\s*(\d+)', 'tokens', 'once');
if isempty(token)
index = obj.CurrentFracWellIndex;
else
index = str2double(token{1});
end
if isnan(index) || index < 1
index = obj.CurrentFracWellIndex;
end
end
function setSelectedFracWellIndex(obj, index, refreshTable)
if nargin < 3
refreshTable = true;
end
fractureWellCount = obj.getFractureWellCount();
if fractureWellCount == 0
obj.CurrentFracWellIndex = 1;
return;
end
obj.CurrentFracWellIndex = min(max(index, 1), fractureWellCount);
if isprop(obj.App, 'SelectedFracWellDropDown') && ~isempty(obj.App.SelectedFracWellDropDown.Items)
items = obj.App.SelectedFracWellDropDown.Items;
obj.App.SelectedFracWellDropDown.Value = items{obj.CurrentFracWellIndex};
end
if refreshTable
obj.onSelectedFracWellChanged();
end
end
function welloc = resizeWellocCell(~, welloc, targetCount)
if nargin < 3 || isempty(targetCount) || targetCount <= 0
welloc = cell(0, 1);
return;
end
if isempty(welloc) || ~iscell(welloc)
welloc = cell(targetCount, 1);
else
welloc = welloc(:);
currentCount = numel(welloc);
if currentCount < targetCount
welloc(currentCount + 1:targetCount, 1) = {[]};
elseif currentCount > targetCount
welloc = welloc(1:targetCount, 1);
end
end
for i = 1:targetCount
if isempty(welloc{i, 1})
welloc{i, 1} = [];
end
end
end
function setControlEnabled(obj, propName, isEnabled)
if ~isprop(obj.App, propName)
return;
end
component = obj.App.(propName);
if isprop(component, 'Enable')
if isEnabled
component.Enable = 'on';
else
component.Enable = 'off';
end
end
end
function c = normalizeScheduleConfig(obj, c)
c = normalize_config(c);
wellNames = obj.getAllConfiguredWellNames(c);
totalWells = numel(wellNames);
phaseCount = max([ ...
numel(c.schedule.well_schedules), ...
numel(c.schedule.time), ...
numel(c.schedule.dtmin), ...
numel(c.schedule.dtmax), ...
c.schedule.number_phases, ...
1]);
if ~iscell(c.schedule.well_schedules)
c.schedule.well_schedules = cell(phaseCount, 1);
elseif numel(c.schedule.well_schedules) < phaseCount
c.schedule.well_schedules(end + 1:phaseCount, 1) = {[]};
elseif numel(c.schedule.well_schedules) > phaseCount
c.schedule.well_schedules = c.schedule.well_schedules(1:phaseCount, 1);
else
c.schedule.well_schedules = c.schedule.well_schedules(:);
end
for k = 1:phaseCount
c.schedule.well_schedules{k, 1} = obj.normalizeSinglePhaseSchedule( ...
c.schedule.well_schedules{k, 1}, wellNames, totalWells);
end
c.schedule.number_phases = phaseCount;
end
function phaseSchedule = normalizeSinglePhaseSchedule(obj, phaseSchedule, wellNames, totalWells)
if totalWells == 0
phaseSchedule = cell(0, 10);
return;
end
phaseSchedule = obj.ensureScheduleCellMatrix(phaseSchedule);
normalized = cell(totalWells, 10);
usedRows = false(size(phaseSchedule, 1), 1);
for i = 1:totalWells
matchedRow = [];
for rowIndex = 1:size(phaseSchedule, 1)
if usedRows(rowIndex)
continue;
end
if size(phaseSchedule, 2) >= 1 && strcmp(string(phaseSchedule{rowIndex, 1}), string(wellNames{i}))
matchedRow = rowIndex;
break;
end
end
if isempty(matchedRow) && i <= size(phaseSchedule, 1) && ~usedRows(i)
matchedRow = i;
end
if isempty(matchedRow)
normalized(i, :) = obj.getDefaultClosedScheduleRow(wellNames{i});
else
rowData = obj.padScheduleRow(phaseSchedule(matchedRow, :));
rowData{1} = wellNames{i};
normalized(i, :) = rowData;
usedRows(matchedRow) = true;
end
end
phaseSchedule = normalized;
end
function phaseSchedule = ensureScheduleCellMatrix(~, phaseSchedule)
if isempty(phaseSchedule)
phaseSchedule = cell(0, 10);
return;
end
if ~iscell(phaseSchedule)
phaseSchedule = num2cell(phaseSchedule);
end
if isvector(phaseSchedule) && size(phaseSchedule, 1) == 1
if size(phaseSchedule, 2) == 10
return;
end
end
if isvector(phaseSchedule) && size(phaseSchedule, 2) == 1
phaseSchedule = phaseSchedule';
end
if size(phaseSchedule, 2) > 10
phaseSchedule = phaseSchedule(:, 1:10);
elseif size(phaseSchedule, 2) < 10
phaseSchedule(:, end + 1:10) = {[]};
end
end
function rowData = padScheduleRow(~, rowData)
if ~iscell(rowData)
rowData = num2cell(rowData);
end
if size(rowData, 1) ~= 1
rowData = rowData(1, :);
end
if size(rowData, 2) > 10
rowData = rowData(:, 1:10);
elseif size(rowData, 2) < 10
rowData(:, end + 1:10) = {[]};
end
end
function row = getDefaultClosedScheduleRow(~, wellName)
row = {char(string(wellName)), 'close', 'pro', 'const_pwf', 0, 0, '', '', '', ''};
end
function wellNames = getAllConfiguredWellNames(~, c)
well1Names = {};
well2Names = {};
if isfield(c.wells, 'well1') && iscell(c.wells.well1) && ~isempty(c.wells.well1)
well1Names = cell(size(c.wells.well1, 1), 1);
for i = 1:size(c.wells.well1, 1)
name = '';
if size(c.wells.well1, 2) >= 1 && ~isempty(c.wells.well1{i, 1})
name = char(string(c.wells.well1{i, 1}));
end
if isempty(name)
name = sprintf('w%d', i);
end
well1Names{i} = name;
end
end
if isfield(c.wells, 'well2') && iscell(c.wells.well2) && ~isempty(c.wells.well2)
well2Names = cell(size(c.wells.well2, 1), 1);
for i = 1:size(c.wells.well2, 1)
name = '';
if size(c.wells.well2, 2) >= 1 && ~isempty(c.wells.well2{i, 1})
name = char(string(c.wells.well2{i, 1}));
end
if isempty(name)
name = sprintf('wf%d', i);
c.wells.well2{i, 1} = name;
end
well2Names{i} = name;
end
end
wellNames = [well1Names; well2Names];
end
end
end
Binary file not shown.
+33 -25
View File
@@ -183,10 +183,11 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
MCcs_NcTextArea matlab.ui.control.TextArea
cs_NcTextAreaLabel matlab.ui.control.Label
WellsTab matlab.ui.container.Tab
SelectedFracWellDropDown matlab.ui.control.DropDown
SelectedFractureWellLabel matlab.ui.control.Label
ScheduleLabel matlab.ui.control.Label
WellLocationLabel matlab.ui.control.Label
Well2Label matlab.ui.control.Label
Well1Label matlab.ui.control.Label
FractureWellsLabel matlab.ui.control.Label
ConventionalWellsLabel matlab.ui.control.Label
ScheduleTimeConfigLabel matlab.ui.control.Label
AddFracLocRowButton matlab.ui.control.Button
DeleteFracLocRowButton matlab.ui.control.Button
@@ -1390,7 +1391,7 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
app.Well1Table.RowName = {};
app.Well1Table.ColumnEditable = true;
app.Well1Table.CellSelectionCallback = createCallbackFcn(app, @Well1TableCellSelection, true);
app.Well1Table.Position = [35 475 372 182];
app.Well1Table.Position = [43 194 446 167];
% Create FractureWellLocationTable
app.FractureWellLocationTable = uitable(app.WellsTab);
@@ -1398,7 +1399,7 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
app.FractureWellLocationTable.RowName = {};
app.FractureWellLocationTable.ColumnEditable = true;
app.FractureWellLocationTable.CellSelectionCallback = createCallbackFcn(app, @FractureWellLocationTableCellSelection, true);
app.FractureWellLocationTable.Position = [44 179 366 185];
app.FractureWellLocationTable.Position = [737 520 445 100];
% Create Well2Table
app.Well2Table = uitable(app.WellsTab);
@@ -1406,7 +1407,7 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
app.Well2Table.RowName = {};
app.Well2Table.ColumnEditable = true;
app.Well2Table.CellSelectionCallback = createCallbackFcn(app, @Well2TableCellSelection, true);
app.Well2Table.Position = [552 472 594 185];
app.Well2Table.Position = [35 476 594 185];
% Create ScheduleTable
app.ScheduleTable = uitable(app.WellsTab);
@@ -1449,25 +1450,25 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
% Create AddWell1RowButton
app.AddWell1RowButton = uibutton(app.WellsTab, 'push');
app.AddWell1RowButton.ButtonPushedFcn = createCallbackFcn(app, @AddWell1RowButtonPushed, true);
app.AddWell1RowButton.Position = [136 420 100 23];
app.AddWell1RowButton.Position = [144 128 100 41];
app.AddWell1RowButton.Text = 'AddWell1Row';
% Create DeleteWell1RowButton
app.DeleteWell1RowButton = uibutton(app.WellsTab, 'push');
app.DeleteWell1RowButton.ButtonPushedFcn = createCallbackFcn(app, @DeleteWell1RowButtonPushed, true);
app.DeleteWell1RowButton.Position = [301 418 103 23];
app.DeleteWell1RowButton.Position = [309 126 103 41];
app.DeleteWell1RowButton.Text = 'DeleteWell1Row';
% Create DeleteWell2RowButton
app.DeleteWell2RowButton = uibutton(app.WellsTab, 'push');
app.DeleteWell2RowButton.ButtonPushedFcn = createCallbackFcn(app, @DeleteWell2RowButtonPushed, true);
app.DeleteWell2RowButton.Position = [931 421 103 23];
app.DeleteWell2RowButton.Position = [414 425 103 23];
app.DeleteWell2RowButton.Text = 'DeleteWell2Row';
% Create AddWell2RowButton
app.AddWell2RowButton = uibutton(app.WellsTab, 'push');
app.AddWell2RowButton.ButtonPushedFcn = createCallbackFcn(app, @AddWell2RowButtonPushed, true);
app.AddWell2RowButton.Position = [705 423 100 23];
app.AddWell2RowButton.Position = [188 427 100 23];
app.AddWell2RowButton.Text = 'AddWell2Row';
% Create AddScheduleRowButton
@@ -1485,13 +1486,13 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
% Create DeleteFracLocRowButton
app.DeleteFracLocRowButton = uibutton(app.WellsTab, 'push');
app.DeleteFracLocRowButton.ButtonPushedFcn = createCallbackFcn(app, @DeleteFracLocRowButtonPushed, true);
app.DeleteFracLocRowButton.Position = [288 123 117 23];
app.DeleteFracLocRowButton.Position = [1096 466 117 23];
app.DeleteFracLocRowButton.Text = 'DeleteFracLocRow';
% Create AddFracLocRowButton
app.AddFracLocRowButton = uibutton(app.WellsTab, 'push');
app.AddFracLocRowButton.ButtonPushedFcn = createCallbackFcn(app, @AddFracLocRowButtonPushed, true);
app.AddFracLocRowButton.Position = [149 123 104 23];
app.AddFracLocRowButton.Position = [954 464 104 23];
app.AddFracLocRowButton.Text = 'AddFracLocRow';
% Create ScheduleTimeConfigLabel
@@ -1499,26 +1500,33 @@ classdef EDFM_Simulator_App < matlab.apps.AppBase
app.ScheduleTimeConfigLabel.Position = [1003 331 131 30];
app.ScheduleTimeConfigLabel.Text = 'Schedule Time Config';
% Create Well1Label
app.Well1Label = uilabel(app.WellsTab);
app.Well1Label.Position = [41 422 35 22];
app.Well1Label.Text = 'Well1';
% Create ConventionalWellsLabel
app.ConventionalWellsLabel = uilabel(app.WellsTab);
app.ConventionalWellsLabel.Position = [27 130 108 40];
app.ConventionalWellsLabel.Text = 'Conventional Wells';
% Create Well2Label
app.Well2Label = uilabel(app.WellsTab);
app.Well2Label.Position = [560 424 35 22];
app.Well2Label.Text = 'Well2';
% Create WellLocationLabel
app.WellLocationLabel = uilabel(app.WellsTab);
app.WellLocationLabel.Position = [48 125 73 22];
app.WellLocationLabel.Text = 'WellLocation';
% Create FractureWellsLabel
app.FractureWellsLabel = uilabel(app.WellsTab);
app.FractureWellsLabel.Position = [43 428 82 22];
app.FractureWellsLabel.Text = 'Fracture Wells';
% Create ScheduleLabel
app.ScheduleLabel = uilabel(app.WellsTab);
app.ScheduleLabel.Position = [555 127 55 22];
app.ScheduleLabel.Text = 'Schedule';
% Create SelectedFractureWellLabel
app.SelectedFractureWellLabel = uilabel(app.WellsTab);
app.SelectedFractureWellLabel.HorizontalAlignment = 'right';
app.SelectedFractureWellLabel.Position = [723 464 126 22];
app.SelectedFractureWellLabel.Text = 'Selected Fracture Well';
% Create SelectedFracWellDropDown
app.SelectedFracWellDropDown = uidropdown(app.WellsTab);
app.SelectedFracWellDropDown.Items = {''};
app.SelectedFracWellDropDown.Position = [864 464 70 22];
app.SelectedFracWellDropDown.Value = '';
% Create SolverRunTab
app.SolverRunTab = uitab(app.TabGroup);
app.SolverRunTab.Title = 'Solver&Run';
+51 -7
View File
@@ -48,29 +48,32 @@ switch metric
case "GPR"
field_name = 'qg';
y_label = 'Gas production rate, m^3/d';
for i = 1:n, data(i) = wellpara{i}{1, well_index}.(field_name); end
for i = 1:n, data(i) = get_well_metric_value(wellpara, i, well_index, field_name); end
plot(ax, times, data, 'k^-', 'LineWidth', 1.2);
case "OPR"
field_name = 'qo';
y_label = 'Oil production rate, m^3/d';
for i = 1:n, data(i) = wellpara{i}{1, well_index}.(field_name); end
for i = 1:n, data(i) = get_well_metric_value(wellpara, i, well_index, field_name); end
plot(ax, times, data, 'k^-', 'LineWidth', 1.2);
case "WPR"
field_name = 'qw';
y_label = 'Water production rate, m^3/d';
for i = 1:n, data(i) = wellpara{i}{1, well_index}.(field_name); end
for i = 1:n, data(i) = get_well_metric_value(wellpara, i, well_index, field_name); end
plot(ax, times, data, 'k^-', 'LineWidth', 1.2);
case "DPWF"
y_label = 'Pressure derivative, MPa';
for i = 1:n
if i == 1
data(i) = (wellpara{i + 1}{1, well_index}.pwf - wellpara{i}{1, well_index}.pwf) / ...
data(i) = (get_well_metric_value(wellpara, i + 1, well_index, 'pwf') - ...
get_well_metric_value(wellpara, i, well_index, 'pwf')) / ...
(log(times(i + 1)) - log(times(i)));
elseif i == n
data(i) = (wellpara{i}{1, well_index}.pwf - wellpara{i - 1}{1, well_index}.pwf) / ...
data(i) = (get_well_metric_value(wellpara, i, well_index, 'pwf') - ...
get_well_metric_value(wellpara, i - 1, well_index, 'pwf')) / ...
(log(times(i)) - log(times(i - 1)));
else
data(i) = (wellpara{i + 1}{1, well_index}.pwf - wellpara{i - 1}{1, well_index}.pwf) / ...
data(i) = (get_well_metric_value(wellpara, i + 1, well_index, 'pwf') - ...
get_well_metric_value(wellpara, i - 1, well_index, 'pwf')) / ...
(log(times(i + 1)) - log(times(i - 1)));
end
end
@@ -79,7 +82,7 @@ switch metric
otherwise
field_name = 'pwf';
y_label = 'BHP, MPa';
for i = 1:n, data(i) = wellpara{i}{1, well_index}.(field_name); end
for i = 1:n, data(i) = get_well_metric_value(wellpara, i, well_index, field_name); end
plot(ax, times, data, 'k^-', 'LineWidth', 1.2);
end
@@ -89,6 +92,47 @@ ylabel(ax, y_label);
title(ax, sprintf('Well Response: well %d, %s', well_index, metric));
end
function value = get_well_metric_value(wellpara, time_index, well_index, field_name)
well_entry = get_well_entry(wellpara, time_index, well_index);
if isempty(well_entry)
value = NaN;
return;
end
if ~isstruct(well_entry)
value = NaN;
return;
end
if ~isfield(well_entry, field_name)
value = NaN;
return;
end
value = well_entry.(field_name);
end
function well_entry = get_well_entry(wellpara, time_index, well_index)
time_entry = wellpara{time_index};
if iscell(time_entry)
if isempty(time_entry)
well_entry = [];
return;
end
if well_index > numel(time_entry)
well_entry = [];
return;
end
well_entry = time_entry{well_index};
elseif isstruct(time_entry)
if numel(time_entry) < well_index
well_entry = [];
return;
end
well_entry = time_entry(well_index);
else
well_entry = [];
end
end
function render_2d_layer(ax, config, results, options)
r = results.r;
output = results.OutputRs{get_option(options, 'time_step', numel(results.OutputRs))};