优化点5,6
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user