|
|
|
|
@ -119,7 +119,7 @@ void nmWxAutomaticFitting::updateParameterVisibility(QTableWidget* table, NM_SOL
|
|
|
|
|
setParameterRowVisible(table, row, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setParameterRowVisible(table, 4, eType == SMT_Oil_Water_TwoPhase); // Swi
|
|
|
|
|
setParameterRowVisible(table, 4, false); // 原含水饱和度索引保留,不再参与拟合。
|
|
|
|
|
|
|
|
|
|
// Dfc 只属于垂直压裂井和多段压裂水平井。普通井隐藏并取消勾选,
|
|
|
|
|
// 防止切换目标井后不可见的裂缝参数仍进入拟合参数向量。
|
|
|
|
|
@ -140,16 +140,16 @@ void nmWxAutomaticFitting::updateParameterVisibility(QTableWidget* table, NM_SOL
|
|
|
|
|
renumberVisibleParameterRows(table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取参数的系统物理边界,并为 Swi 叠加当前储层饱和度约束。
|
|
|
|
|
// 获取可拟合参数的系统物理边界,索引 4 不再作为拟合参数。
|
|
|
|
|
bool nmWxAutomaticFitting::getPhysicalParameterRange(int parameterIndex,
|
|
|
|
|
double& minValue, double& maxValue)
|
|
|
|
|
{
|
|
|
|
|
static const char* parameterNames[] = {
|
|
|
|
|
"Result_K", "Result_W_Skin", "Result_W_C", "Result_phi",
|
|
|
|
|
"Result_Swi", "Result_W_Dfc",
|
|
|
|
|
"", "Result_W_Dfc",
|
|
|
|
|
"W_FractureHalfLength"
|
|
|
|
|
};
|
|
|
|
|
if(parameterIndex < 0 || parameterIndex >= 7) {
|
|
|
|
|
if(parameterIndex < 0 || parameterIndex >= 7 || parameterIndex == 4) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -162,19 +162,6 @@ bool nmWxAutomaticFitting::getPhysicalParameterRange(int parameterIndex,
|
|
|
|
|
minValue = 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(parameterIndex == 4) {
|
|
|
|
|
double soi = reservoirData.getSoi().getValue().toDouble();
|
|
|
|
|
double sgi = reservoirData.getSgi().getValue().toDouble();
|
|
|
|
|
if(nmAutoFitUiIsFinite(soi) && nmAutoFitUiIsFinite(sgi)) {
|
|
|
|
|
if(soi < 0.0 || sgi < 0.0 || soi + sgi > 1.0) {
|
|
|
|
|
// Soi+Sgi 超过 1 时没有可行的 Swi,固定到物理下限,避免继续搜索非法区间。
|
|
|
|
|
minValue = 0.0;
|
|
|
|
|
maxValue = 0.0;
|
|
|
|
|
} else {
|
|
|
|
|
maxValue = qMin(maxValue, 1.0 - soi - sgi);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@ -219,10 +206,6 @@ void nmWxAutomaticFitting::setParameterRange(int parameterIndex,
|
|
|
|
|
automaticFittingData.getPorosityMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getPorosityMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
automaticFittingData.getSwiMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getSwiMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
automaticFittingData.getFractureConductivityMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getFractureConductivityMax().setValue(maxValue);
|
|
|
|
|
@ -279,16 +262,11 @@ void nmWxAutomaticFitting::updateRangeForParameter(int parameterIndex,
|
|
|
|
|
newMin = physicalMin;
|
|
|
|
|
newMax = qMin(physicalMax, reference + skinHalfRange);
|
|
|
|
|
} else if(reference > 0.0
|
|
|
|
|
&& !(parameterIndex == 4 && centerValue <= 0.0)
|
|
|
|
|
&& !(parameterIndex == 5 && centerValue <= 0.0)) {
|
|
|
|
|
const double lowerFactor = 0.1;
|
|
|
|
|
const double upperFactor = 10.0;
|
|
|
|
|
newMin = qMax(physicalMin, reference * lowerFactor);
|
|
|
|
|
newMax = qMin(physicalMax, reference * upperFactor);
|
|
|
|
|
} else if(parameterIndex == 4) {
|
|
|
|
|
// 没有可靠 Swi 初值时,不把搜索范围压缩到零附近。
|
|
|
|
|
newMin = physicalMin;
|
|
|
|
|
newMax = physicalMax;
|
|
|
|
|
} else if(parameterIndex == 5) {
|
|
|
|
|
// Dfc=0 表示无限导流,不存在以零为中心的连续倍率范围。
|
|
|
|
|
newMin = physicalMin;
|
|
|
|
|
@ -347,7 +325,7 @@ bool nmWxAutomaticFitting::validateParameterTable(QString& errorMessage, int par
|
|
|
|
|
|
|
|
|
|
static const char* parameterNames[] = {
|
|
|
|
|
"Permeability", "Skin", "Wellbore storage", "Porosity",
|
|
|
|
|
"Swi", "Fracture conductivity",
|
|
|
|
|
"", "Fracture conductivity",
|
|
|
|
|
"Fracture half length"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -581,15 +559,7 @@ void nmWxAutomaticFitting::setupParameterTable()
|
|
|
|
|
m_parameterTable->setItem(3, 4, new QTableWidgetItem(QString::number(automaticFittingData.getPorosityMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(3, 5, new QTableWidgetItem(""));
|
|
|
|
|
|
|
|
|
|
// 初始含水饱和度 (Swi)
|
|
|
|
|
m_parameterTable->setItem(4, 0, new QTableWidgetItem("5"));
|
|
|
|
|
m_swiCheckBox = new QCheckBox(tr("Swi"));
|
|
|
|
|
m_swiCheckBox->setChecked(automaticFittingData.getSwiSelected());
|
|
|
|
|
m_parameterTable->setCellWidget(4, 1, m_swiCheckBox);
|
|
|
|
|
m_parameterTable->setItem(4, 2, new QTableWidgetItem(QString::number(automaticFittingData.getSwiMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(4, 3, new QTableWidgetItem(QString::number(reservoirData.getSwi().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(4, 4, new QTableWidgetItem(QString::number(automaticFittingData.getSwiMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(4, 5, new QTableWidgetItem(""));
|
|
|
|
|
// 索引 4 留空,保持裂缝参数与优化器的现有索引一致。
|
|
|
|
|
|
|
|
|
|
// 裂缝导流能力 (Dfc)。该行只对压裂井显示,初值在 onWellSelected() 中
|
|
|
|
|
// 从当前目标井读取,其他裂缝几何参数保持固定,不进入自动拟合。
|
|
|
|
|
@ -822,7 +792,6 @@ void nmWxAutomaticFitting::onReverseSelection()
|
|
|
|
|
if(!m_parameterTable->isRowHidden(1)) m_sCheckBox->setChecked(!m_sCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(2)) m_cCheckBox->setChecked(!m_cCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(3)) m_phiCheckBox->setChecked(!m_phiCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(4)) m_swiCheckBox->setChecked(!m_swiCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(5)) m_dfcCheckBox->setChecked(!m_dfcCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(6)) m_fractureHalfLengthCheckBox->setChecked(!m_fractureHalfLengthCheckBox->isChecked());
|
|
|
|
|
}
|
|
|
|
|
@ -932,7 +901,7 @@ void nmWxAutomaticFitting::onAccept()
|
|
|
|
|
// 检查是否有参数被选中
|
|
|
|
|
bool hasSelectedParams = m_kCheckBox->isChecked() || m_sCheckBox->isChecked() ||
|
|
|
|
|
m_cCheckBox->isChecked() || m_phiCheckBox->isChecked() ||
|
|
|
|
|
m_swiCheckBox->isChecked() || m_dfcCheckBox->isChecked() ||
|
|
|
|
|
m_dfcCheckBox->isChecked() ||
|
|
|
|
|
m_fractureHalfLengthCheckBox->isChecked();
|
|
|
|
|
|
|
|
|
|
if(!hasSelectedParams) {
|
|
|
|
|
@ -947,7 +916,6 @@ void nmWxAutomaticFitting::onAccept()
|
|
|
|
|
if(m_sCheckBox->isChecked()) selectedParameterNames << tr("Skin");
|
|
|
|
|
if(m_cCheckBox->isChecked()) selectedParameterNames << tr("Wellbore storage");
|
|
|
|
|
if(m_phiCheckBox->isChecked()) selectedParameterNames << tr("Porosity");
|
|
|
|
|
if(m_swiCheckBox->isChecked()) selectedParameterNames << tr("Swi");
|
|
|
|
|
if(m_dfcCheckBox->isChecked()) selectedParameterNames << tr("Fracture conductivity");
|
|
|
|
|
if(m_fractureHalfLengthCheckBox->isChecked()) selectedParameterNames << tr("Fracture half length");
|
|
|
|
|
|
|
|
|
|
@ -1019,7 +987,6 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
automaticFittingData.setSkinSelected(m_sCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setWellboreStorageSelected(m_cCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setPorositySelected(m_phiCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setSwiSelected(m_swiCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setFractureConductivitySelected(m_dfcCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setFractureHalfLengthSelected(m_fractureHalfLengthCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setSurrogateScreeningEnabled(m_surrogateCombo && m_surrogateCombo->currentIndex() == 1);
|
|
|
|
|
@ -1040,10 +1007,6 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
automaticFittingData.getPorosityMin().setValue(m_parameterTable->item(3, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getPorosityMax().setValue(m_parameterTable->item(3, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存初始含水饱和度的最小值和最大值
|
|
|
|
|
automaticFittingData.getSwiMin().setValue(m_parameterTable->item(4, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getSwiMax().setValue(m_parameterTable->item(4, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存裂缝导流能力的最小值和最大值
|
|
|
|
|
automaticFittingData.getFractureConductivityMin().setValue(m_parameterTable->item(5, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureConductivityMax().setValue(m_parameterTable->item(5, 4)->text().toDouble());
|
|
|
|
|
@ -1056,10 +1019,9 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
automaticFittingData.getIterationCount().setValue(m_iterationEdit->text().toInt());
|
|
|
|
|
automaticFittingData.getErrorTolerance().setValue(m_errorLimitEdit->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 只写回仍可编辑的储层初值,厚度和压缩系数保留原始精度和值。
|
|
|
|
|
// 只写回可拟合的渗透率、孔隙度,含水饱和度沿用模型当前值。
|
|
|
|
|
reservoirData.getPermeability().setValue(m_parameterTable->item(0, 3)->text().toDouble()); // 渗透率
|
|
|
|
|
reservoirData.getPorosity().setValue(m_parameterTable->item(3, 3)->text().toDouble()); // 孔隙度
|
|
|
|
|
reservoirData.getSwi().setValue(m_parameterTable->item(4, 3)->text().toDouble()); // 初始含水饱和度
|
|
|
|
|
|
|
|
|
|
// 更新储层数据(全局)
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->updateReservoirData(reservoirData);
|
|
|
|
|
@ -1374,8 +1336,6 @@ void nmWxAutomaticFitting::refreshParametersFromModel()
|
|
|
|
|
reservoirData.getPermeability().getValue().toDouble(), 'g', 10));
|
|
|
|
|
m_parameterTable->item(3, 3)->setText(QString::number(
|
|
|
|
|
reservoirData.getPorosity().getValue().toDouble(), 'g', 10));
|
|
|
|
|
m_parameterTable->item(4, 3)->setText(QString::number(
|
|
|
|
|
reservoirData.getSwi().getValue().toDouble(), 'g', 10));
|
|
|
|
|
|
|
|
|
|
// 成功或失败都从当前目标井读取已落地的参数,不采用优化器尚未写回的最佳候选。
|
|
|
|
|
// 先刷新全部初值,再统一重建范围,避免即时校验读到新旧值混合的表格。
|
|
|
|
|
|