fix parse bug
This commit is contained in:
@@ -7,7 +7,35 @@ function h = dinterptable(X, Y, u)
|
||||
% b(b == 0) = 1;
|
||||
% b(b == n) = n - 1;
|
||||
% h = DYDX(b);
|
||||
X = X(:);
|
||||
Y = Y(:);
|
||||
u = u(:);
|
||||
|
||||
if numel(X) ~= numel(Y)
|
||||
error('dinterptable:SizeMismatch', ...
|
||||
'X and Y must have the same length. Got %d and %d.', numel(X), numel(Y));
|
||||
end
|
||||
if any(~isfinite(X)) || any(~isfinite(Y))
|
||||
error('dinterptable:InvalidTable', ...
|
||||
'Interpolation table contains NaN or Inf.');
|
||||
end
|
||||
if any(diff(X) < 0)
|
||||
error('dinterptable:NonMonotonicX', ...
|
||||
'Interpolation table X must be nondecreasing.');
|
||||
end
|
||||
|
||||
DYDX = diff(Y) ./ diff(X);
|
||||
DYDX = DYDX([1, 1:end, end]);
|
||||
[~, b] = histc(u, [-inf;X;inf]);
|
||||
|
||||
invalid_mask = ~isfinite(u) | b < 1 | b > numel(DYDX);
|
||||
if any(invalid_mask)
|
||||
bad_values = u(invalid_mask);
|
||||
bad_preview = bad_values(1:min(5, numel(bad_values)));
|
||||
error('dinterptable:InvalidQuery', ...
|
||||
['Interpolation query contains invalid values. ' ...
|
||||
'num_bad=%d, sample=%s, X_range=[%g, %g], Y_range=[%g, %g].'], ...
|
||||
numel(bad_values), mat2str(bad_preview.'), X(1), X(end), min(Y), max(Y));
|
||||
end
|
||||
|
||||
h = reshape(DYDX(b), [], 1);
|
||||
|
||||
@@ -96,10 +96,15 @@ classdef EDFMAppController < handle
|
||||
obj.setRunProgress('Completed');
|
||||
obj.setStatus('Run completed');
|
||||
catch ME
|
||||
obj.appendLog(getReport(ME, 'extended', 'hyperlinks', 'off'));
|
||||
errorReport = getReport(ME, 'extended', 'hyperlinks', 'off');
|
||||
errorSummary = obj.formatExceptionSummary(ME);
|
||||
obj.publishExceptionToBase(ME, errorReport);
|
||||
fprintf(2, '\n[EDFM GUI Run Error]\n%s\n', errorReport);
|
||||
obj.appendLog(errorSummary);
|
||||
obj.appendLog(errorReport);
|
||||
obj.setRunProgress('Failed');
|
||||
obj.setStatus('Run failed');
|
||||
uialert(obj.App.UIFigure, ME.message, 'Run Failed');
|
||||
uialert(obj.App.UIFigure, errorSummary, 'Run Failed', 'Interpreter', 'none');
|
||||
end
|
||||
end
|
||||
|
||||
@@ -319,9 +324,9 @@ classdef EDFMAppController < handle
|
||||
obj.setNumericFieldValue('MCcvwEditField', obj.firstScalar(c.flow.multi_component.cvw));
|
||||
|
||||
obj.setTableValue('Well1Table', c.wells.well1);
|
||||
obj.setTableValue('FractureWellLocationTable', c.wells.welloc{1});
|
||||
obj.setTableValue('FractureWellLocationTable', obj.unwrapFirstCell(c.wells.welloc));
|
||||
obj.setTableValue('Well2Table', c.wells.well2);
|
||||
obj.setTableValue('ScheduleTable', c.schedule.well_schedules{1});
|
||||
obj.setTableValue('ScheduleTable', obj.unwrapFirstCell(c.schedule.well_schedules));
|
||||
obj.setTextAreaExpr('TimeTextArea', c.schedule.time);
|
||||
obj.setTextAreaExpr('DtMinTextArea', c.schedule.dtmin);
|
||||
obj.setTextAreaExpr('DtMaxTextArea', c.schedule.dtmax);
|
||||
@@ -442,11 +447,15 @@ classdef EDFMAppController < handle
|
||||
c.flow.multi_component.cvw = obj.getNumericFieldValue('MCcvwEditField', c.flow.multi_component.cvw);
|
||||
|
||||
c.wells.well1 = obj.getTableValue('Well1Table', c.wells.well1);
|
||||
c.wells.welloc = obj.getTableValue('FractureWellLocationTable', c.wells.welloc);
|
||||
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.schedule.well_schedules = obj.getTableValue('ScheduleTable', c.schedule.well_schedules);
|
||||
firstPhaseSchedule = obj.getTableValue( ...
|
||||
'ScheduleTable', obj.unwrapFirstCell(c.schedule.well_schedules));
|
||||
c.schedule.well_schedules = obj.replaceFirstCell(c.schedule.well_schedules, firstPhaseSchedule);
|
||||
c.schedule.number_phases = numel(c.schedule.well_schedules);
|
||||
c.schedule.time = obj.getTextAreaExpr('TimeTextArea', c.schedule.time);
|
||||
c.schedule.dtmin = obj.getTextAreaExpr('DtMinTextArea', c.schedule.dtmin);
|
||||
@@ -631,7 +640,7 @@ classdef EDFMAppController < handle
|
||||
return;
|
||||
end
|
||||
value = obj.App.(propName).Value;
|
||||
if isempty(value)
|
||||
if isempty(value) || (isnumeric(value) && isscalar(value) && ~isfinite(value))
|
||||
value = fallback;
|
||||
end
|
||||
end
|
||||
@@ -687,6 +696,27 @@ classdef EDFMAppController < handle
|
||||
end
|
||||
end
|
||||
|
||||
function value = getNumericTableValue(obj, propName, fallback)
|
||||
value = obj.getTableValue(propName, fallback);
|
||||
if isempty(value)
|
||||
return;
|
||||
end
|
||||
if isnumeric(value)
|
||||
return;
|
||||
end
|
||||
if iscell(value)
|
||||
try
|
||||
value = cellfun(@obj.convertTableCellToDouble, value);
|
||||
catch ME
|
||||
error('EDFMAppController:NumericTableParseError', ...
|
||||
'Failed to parse %s as a numeric table. %s', propName, ME.message);
|
||||
end
|
||||
return;
|
||||
end
|
||||
error('EDFMAppController:NumericTableTypeError', ...
|
||||
'Unsupported table data type for %s: %s', propName, class(value));
|
||||
end
|
||||
|
||||
function setEditableState(obj, propName, isEnabled)
|
||||
if ~isprop(obj.App, propName)
|
||||
return;
|
||||
@@ -704,6 +734,68 @@ classdef EDFMAppController < handle
|
||||
end
|
||||
end
|
||||
|
||||
function textValue = formatExceptionSummary(~, ME)
|
||||
lines = {
|
||||
sprintf('Error: %s', ME.message)
|
||||
sprintf('Identifier: %s', ME.identifier)
|
||||
};
|
||||
if ~isempty(ME.stack)
|
||||
topFrame = ME.stack(1);
|
||||
lines{end + 1} = sprintf('Location: %s (line %d)', topFrame.name, topFrame.line); %#ok<AGROW>
|
||||
lines{end + 1} = sprintf('File: %s', topFrame.file); %#ok<AGROW>
|
||||
end
|
||||
textValue = strjoin(lines, newline);
|
||||
end
|
||||
|
||||
function publishExceptionToBase(obj, ME, errorReport)
|
||||
assignin('base', 'edfm_last_run_error', ME);
|
||||
assignin('base', 'edfm_last_run_error_report', errorReport);
|
||||
assignin('base', 'edfm_last_run_config', obj.Config);
|
||||
end
|
||||
|
||||
function value = unwrapFirstCell(~, rawValue)
|
||||
if iscell(rawValue) && ~isempty(rawValue)
|
||||
value = rawValue{1};
|
||||
else
|
||||
value = rawValue;
|
||||
end
|
||||
end
|
||||
|
||||
function values = replaceFirstCell(~, existingValues, firstValue)
|
||||
if isempty(existingValues)
|
||||
values = {firstValue};
|
||||
return;
|
||||
end
|
||||
if ~iscell(existingValues)
|
||||
values = {firstValue};
|
||||
return;
|
||||
end
|
||||
values = existingValues;
|
||||
values{1} = firstValue;
|
||||
end
|
||||
|
||||
function value = convertTableCellToDouble(~, cellValue)
|
||||
if isnumeric(cellValue) && isscalar(cellValue)
|
||||
value = double(cellValue);
|
||||
return;
|
||||
end
|
||||
if islogical(cellValue) && isscalar(cellValue)
|
||||
value = double(cellValue);
|
||||
return;
|
||||
end
|
||||
if isstring(cellValue) && isscalar(cellValue)
|
||||
cellValue = char(cellValue);
|
||||
end
|
||||
if ischar(cellValue)
|
||||
parsedValue = str2double(strtrim(cellValue));
|
||||
if ~isnan(parsedValue)
|
||||
value = parsedValue;
|
||||
return;
|
||||
end
|
||||
end
|
||||
error('Cell value "%s" is not a scalar numeric entry.', string(cellValue));
|
||||
end
|
||||
|
||||
function value = firstScalar(~, rawValue)
|
||||
if isempty(rawValue)
|
||||
value = 0;
|
||||
|
||||
@@ -352,6 +352,11 @@ 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;
|
||||
if isfield(gas_prop, 'beta_non_darcy_flow') && ~isfield(gas_prop, 'beta_non_Darcy_flow')
|
||||
gas_prop.beta_non_Darcy_flow = gas_prop.beta_non_darcy_flow;
|
||||
elseif ~isfield(gas_prop, 'beta_non_Darcy_flow')
|
||||
gas_prop.beta_non_Darcy_flow = 0;
|
||||
end
|
||||
|
||||
f.Dwsi = mc.density_w_sc;
|
||||
f.Dgsi = mc.density_g_sc;
|
||||
@@ -371,7 +376,7 @@ 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);
|
||||
cb0 = expand_initial_value(sanitize_positive_initial_value(initial_config.cb, 50.0), total_cells);
|
||||
state0 = initialRS(pressure0, sw0, cs0, cb0);
|
||||
end
|
||||
|
||||
@@ -383,6 +388,21 @@ else
|
||||
end
|
||||
end
|
||||
|
||||
function value = sanitize_positive_initial_value(raw_value, fallback)
|
||||
if isempty(raw_value)
|
||||
value = fallback;
|
||||
return;
|
||||
end
|
||||
|
||||
value = raw_value;
|
||||
invalid_mask = ~isfinite(value) | value <= 0;
|
||||
if all(invalid_mask(:))
|
||||
value = fallback;
|
||||
elseif any(invalid_mask(:))
|
||||
value(invalid_mask) = fallback;
|
||||
end
|
||||
end
|
||||
|
||||
function value = default_if_empty(s, field_name, fallback)
|
||||
if isfield(s, field_name) && ~isempty(s.(field_name))
|
||||
value = s.(field_name);
|
||||
|
||||
@@ -142,7 +142,7 @@ 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.initial.cb = 50.0;
|
||||
|
||||
config.wells.well1 = {};
|
||||
config.wells.num_fracture_wells = 1;
|
||||
|
||||
Reference in New Issue
Block a user