|
|
|
|
@ -3,6 +3,7 @@
|
|
|
|
|
#include "nmCalculationAutoFitLM.h"
|
|
|
|
|
#include "nmWxAutomaticfittingStart.h"
|
|
|
|
|
#include "nmWxParameterProperty.h"
|
|
|
|
|
#include "nmAttrRegistry.h"
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
#include "iSubWndFitting.h"
|
|
|
|
|
#include "iSysParaHelper.h"
|
|
|
|
|
@ -164,7 +165,7 @@ void nmWxAutomaticFitting::setParameterRowVisible(QTableWidget* table, int row,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 隐藏参数行后重新整理序号,让界面看起来像删除了不需要的参数。
|
|
|
|
|
// 按当前模型和井型可用的参数行重新整理显示序号。
|
|
|
|
|
void nmWxAutomaticFitting::renumberVisibleParameterRows(QTableWidget* table)
|
|
|
|
|
{
|
|
|
|
|
if(!table) {
|
|
|
|
|
@ -188,7 +189,7 @@ void nmWxAutomaticFitting::renumberVisibleParameterRows(QTableWidget* table)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据当前模型类型控制 Ct/Cf/Swi,并根据目标井类型控制裂缝导流能力显示。
|
|
|
|
|
// 拟合表仅包含可优化参数,按模型和目标井类型控制显示。
|
|
|
|
|
void nmWxAutomaticFitting::updateParameterVisibility(QTableWidget* table, NM_SOLVER_MODEL_TYPE eType)
|
|
|
|
|
{
|
|
|
|
|
if(!table) {
|
|
|
|
|
@ -199,35 +200,7 @@ void nmWxAutomaticFitting::updateParameterVisibility(QTableWidget* table, NM_SOL
|
|
|
|
|
setParameterRowVisible(table, row, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool showCt = false;
|
|
|
|
|
bool showCf = false;
|
|
|
|
|
bool showSwi = false;
|
|
|
|
|
|
|
|
|
|
switch(eType) {
|
|
|
|
|
case SMT_Oil_ConstPvt:
|
|
|
|
|
case SMT_Water_ConstPvt:
|
|
|
|
|
// 常量PVT使用综合压缩系数Ct。
|
|
|
|
|
showCt = true;
|
|
|
|
|
break;
|
|
|
|
|
case SMT_Oil_VariablePvt:
|
|
|
|
|
case SMT_Water_VariablePvt:
|
|
|
|
|
case SMT_Gas_VariablePvt:
|
|
|
|
|
// 变化PVT使用岩石压缩系数Cf。
|
|
|
|
|
showCf = true;
|
|
|
|
|
break;
|
|
|
|
|
case SMT_Oil_Water_TwoPhase:
|
|
|
|
|
// 油水两相使用Cf,并且只有它需要初始含水饱和度Swi。
|
|
|
|
|
showCf = true;
|
|
|
|
|
showSwi = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
showCf = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setParameterRowVisible(table, 5, showCt); // Ct
|
|
|
|
|
setParameterRowVisible(table, 6, showCf); // Cf
|
|
|
|
|
setParameterRowVisible(table, 7, showSwi); // Swi
|
|
|
|
|
setParameterRowVisible(table, 4, eType == SMT_Oil_Water_TwoPhase); // Swi
|
|
|
|
|
|
|
|
|
|
// Dfc 只属于垂直压裂井和多段压裂水平井。普通井隐藏并取消勾选,
|
|
|
|
|
// 防止切换目标井后不可见的裂缝参数仍进入拟合参数向量。
|
|
|
|
|
@ -242,8 +215,8 @@ void nmWxAutomaticFitting::updateParameterVisibility(QTableWidget* table, NM_SOL
|
|
|
|
|
wellType == NM_WELL_MODEL::Horizontal_Fractured_Well;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setParameterRowVisible(table, 8, showFractureConductivity); // Dfc
|
|
|
|
|
setParameterRowVisible(table, 9, showFractureConductivity); // 裂缝半长
|
|
|
|
|
setParameterRowVisible(table, 5, showFractureConductivity); // Dfc
|
|
|
|
|
setParameterRowVisible(table, 6, showFractureConductivity); // 裂缝半长
|
|
|
|
|
|
|
|
|
|
renumberVisibleParameterRows(table);
|
|
|
|
|
}
|
|
|
|
|
@ -254,10 +227,10 @@ bool nmWxAutomaticFitting::getPhysicalParameterRange(int parameterIndex,
|
|
|
|
|
{
|
|
|
|
|
static const char* parameterNames[] = {
|
|
|
|
|
"Result_K", "Result_W_Skin", "Result_W_C", "Result_phi",
|
|
|
|
|
"Result_h", "Result_Cti", "Result_Cf", "Result_Swi", "Result_W_Dfc",
|
|
|
|
|
"Result_Swi", "Result_W_Dfc",
|
|
|
|
|
"W_FractureHalfLength"
|
|
|
|
|
};
|
|
|
|
|
if(parameterIndex < 0 || parameterIndex >= 10) {
|
|
|
|
|
if(parameterIndex < 0 || parameterIndex >= 7) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -265,7 +238,7 @@ bool nmWxAutomaticFitting::getPhysicalParameterRange(int parameterIndex,
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(parameterIndex == 7) {
|
|
|
|
|
if(parameterIndex == 4) {
|
|
|
|
|
double soi = reservoirData.getSoi().getValue().toDouble();
|
|
|
|
|
double sgi = reservoirData.getSgi().getValue().toDouble();
|
|
|
|
|
if(nmAutoFitUiIsFinite(soi) && nmAutoFitUiIsFinite(sgi)) {
|
|
|
|
|
@ -323,26 +296,14 @@ void nmWxAutomaticFitting::setParameterRange(int parameterIndex,
|
|
|
|
|
automaticFittingData.getPorosityMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
automaticFittingData.getThicknessMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getThicknessMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
automaticFittingData.getCtMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getCtMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
automaticFittingData.getCfMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getCfMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
automaticFittingData.getSwiMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getSwiMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
case 5:
|
|
|
|
|
automaticFittingData.getFractureConductivityMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getFractureConductivityMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
case 6:
|
|
|
|
|
automaticFittingData.getFractureHalfLengthMin().setValue(minValue);
|
|
|
|
|
automaticFittingData.getFractureHalfLengthMax().setValue(maxValue);
|
|
|
|
|
break;
|
|
|
|
|
@ -358,7 +319,7 @@ void nmWxAutomaticFitting::setParameterRange(int parameterIndex,
|
|
|
|
|
void nmWxAutomaticFitting::updateRangeForParameter(int parameterIndex,
|
|
|
|
|
double centerValue)
|
|
|
|
|
{
|
|
|
|
|
if(!m_parameterTable || parameterIndex < 0 || parameterIndex >= 10
|
|
|
|
|
if(!m_parameterTable || parameterIndex < 0 || parameterIndex >= 7
|
|
|
|
|
|| !nmAutoFitUiIsFinite(centerValue)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -394,17 +355,17 @@ void nmWxAutomaticFitting::updateRangeForParameter(int parameterIndex,
|
|
|
|
|
newMin = qMax(physicalMin, reference - skinHalfRange);
|
|
|
|
|
newMax = qMin(physicalMax, reference + skinHalfRange);
|
|
|
|
|
} else if(reference > 0.0
|
|
|
|
|
&& !(parameterIndex == 7 && centerValue <= 0.0)
|
|
|
|
|
&& !(parameterIndex == 8 && centerValue <= 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 == 7) {
|
|
|
|
|
} else if(parameterIndex == 4) {
|
|
|
|
|
// 没有可靠 Swi 初值时,不把搜索范围压缩到零附近。
|
|
|
|
|
newMin = physicalMin;
|
|
|
|
|
newMax = physicalMax;
|
|
|
|
|
} else if(parameterIndex == 8) {
|
|
|
|
|
} else if(parameterIndex == 5) {
|
|
|
|
|
// Dfc=0 表示无限导流,不存在以零为中心的连续倍率范围。
|
|
|
|
|
newMin = physicalMin;
|
|
|
|
|
newMax = physicalMax;
|
|
|
|
|
@ -428,7 +389,7 @@ void nmWxAutomaticFitting::initializeSuggestedParameterRanges()
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(int parameterIndex = 0; parameterIndex < 10; ++parameterIndex) {
|
|
|
|
|
for(int parameterIndex = 0; parameterIndex < 7; ++parameterIndex) {
|
|
|
|
|
QTableWidgetItem* initialItem = m_parameterTable->item(parameterIndex, 3);
|
|
|
|
|
if(initialItem) {
|
|
|
|
|
bool initialOk = false;
|
|
|
|
|
@ -455,7 +416,7 @@ void nmWxAutomaticFitting::normalizeSavedParameterRanges()
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(int parameterIndex = 0; parameterIndex < 10; ++parameterIndex) {
|
|
|
|
|
for(int parameterIndex = 0; parameterIndex < 7; ++parameterIndex) {
|
|
|
|
|
QTableWidgetItem* minItem = m_parameterTable->item(parameterIndex, 2);
|
|
|
|
|
QTableWidgetItem* maxItem = m_parameterTable->item(parameterIndex, 4);
|
|
|
|
|
QTableWidgetItem* initialItem = m_parameterTable->item(parameterIndex, 3);
|
|
|
|
|
@ -477,7 +438,7 @@ void nmWxAutomaticFitting::normalizeSavedParameterRanges()
|
|
|
|
|
const bool savedRangeValid = savedMinOk && savedMaxOk
|
|
|
|
|
&& nmAutoFitUiIsFinite(savedMin) && nmAutoFitUiIsFinite(savedMax)
|
|
|
|
|
&& savedMax >= savedMin
|
|
|
|
|
&& !(parameterIndex == 8 && savedMax <= 1.0e-10);
|
|
|
|
|
&& !(parameterIndex == 5 && savedMax <= 1.0e-10);
|
|
|
|
|
|
|
|
|
|
if(savedRangeValid && physicalMax >= physicalMin) {
|
|
|
|
|
const double clippedMin = qMax(savedMin, physicalMin);
|
|
|
|
|
@ -506,19 +467,19 @@ bool nmWxAutomaticFitting::validateParameterTable(QString& errorMessage, int par
|
|
|
|
|
errorMessage = tr("The parameter table is unavailable.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(parameterIndex < -1 || parameterIndex >= 10) {
|
|
|
|
|
if(parameterIndex < -1 || parameterIndex >= 7) {
|
|
|
|
|
errorMessage = tr("The parameter row is invalid.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char* parameterNames[] = {
|
|
|
|
|
"Permeability", "Skin", "Wellbore storage", "Porosity",
|
|
|
|
|
"Thickness", "Ct", "Cf", "Swi", "Fracture conductivity",
|
|
|
|
|
"Swi", "Fracture conductivity",
|
|
|
|
|
"Fracture half length"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const int firstParameterIndex = parameterIndex < 0 ? 0 : parameterIndex;
|
|
|
|
|
const int lastParameterIndex = parameterIndex < 0 ? 10 : parameterIndex + 1;
|
|
|
|
|
const int lastParameterIndex = parameterIndex < 0 ? 7 : parameterIndex + 1;
|
|
|
|
|
for(int currentParameterIndex = firstParameterIndex;
|
|
|
|
|
currentParameterIndex < lastParameterIndex; ++currentParameterIndex) {
|
|
|
|
|
// 隐藏参数不参与当前模型拟合,不用它们的历史值阻塞当前设置。
|
|
|
|
|
@ -580,7 +541,7 @@ bool nmWxAutomaticFitting::validateParameterTable(QString& errorMessage, int par
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 底层用 Dfc=0 表示无限导流,这是离散模型选项,不属于有限导流拟合域。
|
|
|
|
|
if(currentParameterIndex == 8 && m_dfcCheckBox->isChecked()
|
|
|
|
|
if(currentParameterIndex == 5 && m_dfcCheckBox->isChecked()
|
|
|
|
|
&& (minValue <= 1.0e-10 || initialValue <= 1.0e-10)) {
|
|
|
|
|
errorMessage = tr("The minimum value of %1 must be greater than zero for automatic fitting.")
|
|
|
|
|
.arg(tr(parameterNames[currentParameterIndex]));
|
|
|
|
|
@ -631,20 +592,6 @@ nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent)
|
|
|
|
|
// 自动范围始终开启;用户在表格中修改上下限后,itemChanged 会临时切换为手工范围。
|
|
|
|
|
m_autoParameterRanges = true;
|
|
|
|
|
|
|
|
|
|
NM_SOLVER_MODEL_TYPE solverModelType = pManager->getSolverModelType();
|
|
|
|
|
// 未保存过配置时只保留参数选择的相态默认值,不再覆盖数据对象中的初值或范围。
|
|
|
|
|
if(!hasSavedFittingData) {
|
|
|
|
|
if(solverModelType == SMT_Oil_ConstPvt ||
|
|
|
|
|
solverModelType == SMT_Water_ConstPvt) {
|
|
|
|
|
// T1/T3 的综合压缩系数默认不参与拟合。
|
|
|
|
|
automaticFittingData.setCtSelected(false);
|
|
|
|
|
} else if(solverModelType == SMT_Oil_VariablePvt ||
|
|
|
|
|
solverModelType == SMT_Water_VariablePvt) {
|
|
|
|
|
// T2/T4 的岩石压缩系数默认参与拟合。
|
|
|
|
|
automaticFittingData.setCfSelected(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setupUI();
|
|
|
|
|
setWindowTitle(tr("Automatic fitting"));
|
|
|
|
|
setModal(true);
|
|
|
|
|
@ -715,7 +662,7 @@ void nmWxAutomaticFitting::setupUI()
|
|
|
|
|
void nmWxAutomaticFitting::setupParameterTable()
|
|
|
|
|
{
|
|
|
|
|
// 创建表格
|
|
|
|
|
m_parameterTable = new QTableWidget(10, 6, this);
|
|
|
|
|
m_parameterTable = new QTableWidget(7, 6, this);
|
|
|
|
|
|
|
|
|
|
// 设置表头
|
|
|
|
|
QStringList headers;
|
|
|
|
|
@ -784,66 +731,36 @@ void nmWxAutomaticFitting::setupParameterTable()
|
|
|
|
|
m_parameterTable->setItem(3, 4, new QTableWidgetItem(QString::number(automaticFittingData.getPorosityMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(3, 5, new QTableWidgetItem(""));
|
|
|
|
|
|
|
|
|
|
// 储层厚度 (Thickness)
|
|
|
|
|
m_parameterTable->setItem(4, 0, new QTableWidgetItem("5"));
|
|
|
|
|
m_hCheckBox = new QCheckBox(tr("Thickness"));
|
|
|
|
|
m_hCheckBox->setChecked(automaticFittingData.getThicknessSelected());
|
|
|
|
|
m_parameterTable->setCellWidget(4, 1, m_hCheckBox);
|
|
|
|
|
m_parameterTable->setItem(4, 2, new QTableWidgetItem(QString::number(automaticFittingData.getThicknessMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(4, 3, new QTableWidgetItem(QString::number(reservoirData.getThickness().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(4, 4, new QTableWidgetItem(QString::number(automaticFittingData.getThicknessMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(4, 5, new QTableWidgetItem(tr("m")));
|
|
|
|
|
|
|
|
|
|
// 综合压缩系数 (Ct)
|
|
|
|
|
m_parameterTable->setItem(5, 0, new QTableWidgetItem("6"));
|
|
|
|
|
m_ctCheckBox = new QCheckBox(tr("Ct"));
|
|
|
|
|
m_ctCheckBox->setChecked(automaticFittingData.getCtSelected());
|
|
|
|
|
m_parameterTable->setCellWidget(5, 1, m_ctCheckBox);
|
|
|
|
|
m_parameterTable->setItem(5, 2, new QTableWidgetItem(QString::number(automaticFittingData.getCtMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(5, 3, new QTableWidgetItem(QString::number(reservoirData.getCt().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(5, 4, new QTableWidgetItem(QString::number(automaticFittingData.getCtMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(5, 5, new QTableWidgetItem(""));
|
|
|
|
|
|
|
|
|
|
// 岩石压缩系数 (Cf)
|
|
|
|
|
m_parameterTable->setItem(6, 0, new QTableWidgetItem("7"));
|
|
|
|
|
m_cfCheckBox = new QCheckBox(tr("Cf"));
|
|
|
|
|
m_cfCheckBox->setChecked(automaticFittingData.getCfSelected());
|
|
|
|
|
m_parameterTable->setCellWidget(6, 1, m_cfCheckBox);
|
|
|
|
|
m_parameterTable->setItem(6, 2, new QTableWidgetItem(QString::number(automaticFittingData.getCfMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(6, 3, new QTableWidgetItem(QString::number(reservoirData.getCf().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(6, 4, new QTableWidgetItem(QString::number(automaticFittingData.getCfMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(6, 5, new QTableWidgetItem(""));
|
|
|
|
|
|
|
|
|
|
// 初始含水饱和度 (Swi)
|
|
|
|
|
m_parameterTable->setItem(7, 0, new QTableWidgetItem("8"));
|
|
|
|
|
m_parameterTable->setItem(4, 0, new QTableWidgetItem("5"));
|
|
|
|
|
m_swiCheckBox = new QCheckBox(tr("Swi"));
|
|
|
|
|
m_swiCheckBox->setChecked(automaticFittingData.getSwiSelected());
|
|
|
|
|
m_parameterTable->setCellWidget(7, 1, m_swiCheckBox);
|
|
|
|
|
m_parameterTable->setItem(7, 2, new QTableWidgetItem(QString::number(automaticFittingData.getSwiMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(7, 3, new QTableWidgetItem(QString::number(reservoirData.getSwi().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(7, 4, new QTableWidgetItem(QString::number(automaticFittingData.getSwiMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(7, 5, new QTableWidgetItem(""));
|
|
|
|
|
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(""));
|
|
|
|
|
|
|
|
|
|
// 裂缝导流能力 (Dfc)。该行只对压裂井显示,初值在 onWellSelected() 中
|
|
|
|
|
// 从当前目标井读取,其他裂缝几何参数保持固定,不进入自动拟合。
|
|
|
|
|
m_parameterTable->setItem(8, 0, new QTableWidgetItem("9"));
|
|
|
|
|
m_parameterTable->setItem(5, 0, new QTableWidgetItem("6"));
|
|
|
|
|
m_dfcCheckBox = new QCheckBox(tr("Fracture conductivity"));
|
|
|
|
|
m_dfcCheckBox->setChecked(automaticFittingData.getFractureConductivitySelected());
|
|
|
|
|
m_parameterTable->setCellWidget(8, 1, m_dfcCheckBox);
|
|
|
|
|
m_parameterTable->setItem(8, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureConductivityMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(8, 3, new QTableWidgetItem());
|
|
|
|
|
m_parameterTable->setItem(8, 4, new QTableWidgetItem(QString::number(automaticFittingData.getFractureConductivityMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(8, 5, new QTableWidgetItem(tr("md.m")));
|
|
|
|
|
m_parameterTable->setCellWidget(5, 1, m_dfcCheckBox);
|
|
|
|
|
m_parameterTable->setItem(5, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureConductivityMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(5, 3, new QTableWidgetItem());
|
|
|
|
|
m_parameterTable->setItem(5, 4, new QTableWidgetItem(QString::number(automaticFittingData.getFractureConductivityMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(5, 5, new QTableWidgetItem(tr("md.m")));
|
|
|
|
|
|
|
|
|
|
// 裂缝半长。该行与 Dfc 一样只对压裂井显示,初值从当前目标井读取。
|
|
|
|
|
m_parameterTable->setItem(9, 0, new QTableWidgetItem("10"));
|
|
|
|
|
m_parameterTable->setItem(6, 0, new QTableWidgetItem("7"));
|
|
|
|
|
m_fractureHalfLengthCheckBox = new QCheckBox(tr("Fracture half length"));
|
|
|
|
|
m_fractureHalfLengthCheckBox->setChecked(automaticFittingData.getFractureHalfLengthSelected());
|
|
|
|
|
m_parameterTable->setCellWidget(9, 1, m_fractureHalfLengthCheckBox);
|
|
|
|
|
m_parameterTable->setItem(9, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureHalfLengthMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(9, 3, new QTableWidgetItem());
|
|
|
|
|
m_parameterTable->setItem(9, 4, new QTableWidgetItem(QString::number(automaticFittingData.getFractureHalfLengthMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(9, 5, new QTableWidgetItem(tr("m")));
|
|
|
|
|
m_parameterTable->setCellWidget(6, 1, m_fractureHalfLengthCheckBox);
|
|
|
|
|
m_parameterTable->setItem(6, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureHalfLengthMin().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(6, 3, new QTableWidgetItem());
|
|
|
|
|
m_parameterTable->setItem(6, 4, new QTableWidgetItem(QString::number(automaticFittingData.getFractureHalfLengthMax().getValue().toDouble())));
|
|
|
|
|
m_parameterTable->setItem(6, 5, new QTableWidgetItem(tr("m")));
|
|
|
|
|
|
|
|
|
|
// 设置表格行为
|
|
|
|
|
for(int i = 0; i < m_parameterTable->rowCount(); ++i) {
|
|
|
|
|
@ -925,24 +842,29 @@ void nmWxAutomaticFitting::setupControlPanel()
|
|
|
|
|
QLabel* wellLabel = new QLabel(tr("Target Well:"));
|
|
|
|
|
m_targetWellCombo = new QComboBox();
|
|
|
|
|
|
|
|
|
|
// 添加垂直井
|
|
|
|
|
for(int i = 0; i < m_verticalWells.size(); ++i) {
|
|
|
|
|
m_targetWellCombo->addItem(m_verticalWells[i].getWellName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加水平井
|
|
|
|
|
for(int i = 0; i < m_horizontalWells.size(); ++i) {
|
|
|
|
|
m_targetWellCombo->addItem(m_horizontalWells[i].getWellName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加垂直压裂井
|
|
|
|
|
for(int i = 0; i < m_verticalFracturedWells.size(); ++i) {
|
|
|
|
|
m_targetWellCombo->addItem(m_verticalFracturedWells[i].getWellName());
|
|
|
|
|
}
|
|
|
|
|
// 目标井先加入当前分析主井,再加入已勾选且具备流量、压力数据的包含井。
|
|
|
|
|
nmDataAnalyzeManager* pManager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
if(pManager != nullptr) {
|
|
|
|
|
const QString sPrimaryWellCode = pManager->getPrimaryWellCode();
|
|
|
|
|
nmDataWellBase* pPrimaryWell = pManager->findWellByCode(sPrimaryWellCode);
|
|
|
|
|
if(pPrimaryWell != nullptr) {
|
|
|
|
|
m_targetWellCombo->addItem(pPrimaryWell->getWellName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加水平压裂井
|
|
|
|
|
for(int i = 0; i < m_horizontalFracturedWells.size(); ++i) {
|
|
|
|
|
m_targetWellCombo->addItem(m_horizontalFracturedWells[i].getWellName());
|
|
|
|
|
if(pManager->getIncludeOtherWells()) {
|
|
|
|
|
const QVector<nmCalculationWellRef> vecIncludedWells =
|
|
|
|
|
pManager->getIncludedCalculationWells();
|
|
|
|
|
for(int nIndex = 0; nIndex < vecIncludedWells.size(); ++nIndex) {
|
|
|
|
|
const QString& sWellCode = vecIncludedWells[nIndex].m_sWellCode;
|
|
|
|
|
nmDataWellBase* pWellData = pManager->findWellByCode(sWellCode);
|
|
|
|
|
if(pWellData == nullptr || sWellCode == sPrimaryWellCode ||
|
|
|
|
|
pWellData->getFlowSegmentCount() <= 0 ||
|
|
|
|
|
pWellData->getPressurePoints().size() < 2) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
m_targetWellCombo->addItem(pWellData->getWellName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connect(m_targetWellCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onWellSelected(int)));
|
|
|
|
|
@ -1041,12 +963,9 @@ 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_hCheckBox->setChecked(!m_hCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(5)) m_ctCheckBox->setChecked(!m_ctCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(6)) m_cfCheckBox->setChecked(!m_cfCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(7)) m_swiCheckBox->setChecked(!m_swiCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(8)) m_dfcCheckBox->setChecked(!m_dfcCheckBox->isChecked());
|
|
|
|
|
if(!m_parameterTable->isRowHidden(9)) m_fractureHalfLengthCheckBox->setChecked(!m_fractureHalfLengthCheckBox->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());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxAutomaticFitting::onParameterTableItemChanged(QTableWidgetItem* item)
|
|
|
|
|
@ -1163,8 +1082,6 @@ void nmWxAutomaticFitting::onAccept()
|
|
|
|
|
// 检查是否有参数被选中
|
|
|
|
|
bool hasSelectedParams = m_kCheckBox->isChecked() || m_sCheckBox->isChecked() ||
|
|
|
|
|
m_cCheckBox->isChecked() || m_phiCheckBox->isChecked() ||
|
|
|
|
|
m_hCheckBox->isChecked() ||
|
|
|
|
|
m_ctCheckBox->isChecked() || m_cfCheckBox->isChecked() ||
|
|
|
|
|
m_swiCheckBox->isChecked() || m_dfcCheckBox->isChecked() ||
|
|
|
|
|
m_fractureHalfLengthCheckBox->isChecked();
|
|
|
|
|
|
|
|
|
|
@ -1180,9 +1097,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_hCheckBox->isChecked()) selectedParameterNames << tr("Thickness");
|
|
|
|
|
if(m_ctCheckBox->isChecked()) selectedParameterNames << tr("Ct");
|
|
|
|
|
if(m_cfCheckBox->isChecked()) selectedParameterNames << tr("Cf");
|
|
|
|
|
if(m_swiCheckBox->isChecked()) selectedParameterNames << tr("Swi");
|
|
|
|
|
if(m_dfcCheckBox->isChecked()) selectedParameterNames << tr("Fracture conductivity");
|
|
|
|
|
if(m_fractureHalfLengthCheckBox->isChecked()) selectedParameterNames << tr("Fracture half length");
|
|
|
|
|
@ -1280,19 +1194,19 @@ void nmWxAutomaticFitting::onWellSelected(int index)
|
|
|
|
|
|
|
|
|
|
// 设置井筒储集系数(Wellbore storage)
|
|
|
|
|
m_parameterTable->item(2, 3)->setText(QString::number(wellboreStorageValue));
|
|
|
|
|
if(fracturedWell && m_parameterTable->item(8, 3)) {
|
|
|
|
|
m_parameterTable->item(8, 3)->setText(QString::number(fractureConductivityValue));
|
|
|
|
|
if(fracturedWell && m_parameterTable->item(5, 3)) {
|
|
|
|
|
m_parameterTable->item(5, 3)->setText(QString::number(fractureConductivityValue));
|
|
|
|
|
}
|
|
|
|
|
if(fracturedWell && m_parameterTable->item(9, 3)) {
|
|
|
|
|
m_parameterTable->item(9, 3)->setText(QString::number(fractureHalfLengthValue));
|
|
|
|
|
if(fracturedWell && m_parameterTable->item(6, 3)) {
|
|
|
|
|
m_parameterTable->item(6, 3)->setText(QString::number(fractureHalfLengthValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_autoParameterRanges) {
|
|
|
|
|
updateRangeForParameter(1, skinValue);
|
|
|
|
|
updateRangeForParameter(2, wellboreStorageValue);
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
updateRangeForParameter(8, fractureConductivityValue);
|
|
|
|
|
updateRangeForParameter(9, fractureHalfLengthValue);
|
|
|
|
|
updateRangeForParameter(5, fractureConductivityValue);
|
|
|
|
|
updateRangeForParameter(6, fractureHalfLengthValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -1300,14 +1214,11 @@ void nmWxAutomaticFitting::onWellSelected(int index)
|
|
|
|
|
|
|
|
|
|
void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
{
|
|
|
|
|
// 保存参数选择状态
|
|
|
|
|
// 保存剩余拟合参数的选择状态,LM 和 PSO 共用此配置。
|
|
|
|
|
automaticFittingData.setPermeabilitySelected(m_kCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setSkinSelected(m_sCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setWellboreStorageSelected(m_cCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setPorositySelected(m_phiCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setThicknessSelected(m_hCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setCtSelected(m_ctCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setCfSelected(m_cfCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setSwiSelected(m_swiCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setFractureConductivitySelected(m_dfcCheckBox->isChecked());
|
|
|
|
|
automaticFittingData.setFractureHalfLengthSelected(m_fractureHalfLengthCheckBox->isChecked());
|
|
|
|
|
@ -1329,41 +1240,26 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
automaticFittingData.getPorosityMin().setValue(m_parameterTable->item(3, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getPorosityMax().setValue(m_parameterTable->item(3, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存储层厚度的最小值和最大值
|
|
|
|
|
automaticFittingData.getThicknessMin().setValue(m_parameterTable->item(4, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getThicknessMax().setValue(m_parameterTable->item(4, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存综合压缩系数的最小值和最大值
|
|
|
|
|
automaticFittingData.getCtMin().setValue(m_parameterTable->item(5, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getCtMax().setValue(m_parameterTable->item(5, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存岩石压缩系数的最小值和最大值
|
|
|
|
|
automaticFittingData.getCfMin().setValue(m_parameterTable->item(6, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getCfMax().setValue(m_parameterTable->item(6, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存初始含水饱和度的最小值和最大值
|
|
|
|
|
automaticFittingData.getSwiMin().setValue(m_parameterTable->item(7, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getSwiMax().setValue(m_parameterTable->item(7, 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(8, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureConductivityMax().setValue(m_parameterTable->item(8, 4)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureConductivityMin().setValue(m_parameterTable->item(5, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureConductivityMax().setValue(m_parameterTable->item(5, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存裂缝半长的最小值和最大值
|
|
|
|
|
automaticFittingData.getFractureHalfLengthMin().setValue(m_parameterTable->item(9, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureHalfLengthMax().setValue(m_parameterTable->item(9, 4)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureHalfLengthMin().setValue(m_parameterTable->item(6, 2)->text().toDouble());
|
|
|
|
|
automaticFittingData.getFractureHalfLengthMax().setValue(m_parameterTable->item(6, 4)->text().toDouble());
|
|
|
|
|
|
|
|
|
|
// 保存迭代参数
|
|
|
|
|
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.getThickness().setValue(m_parameterTable->item(4, 3)->text().toDouble()); // 储层厚度
|
|
|
|
|
reservoirData.getCt().setValue(m_parameterTable->item(5, 3)->text().toDouble()); // 综合压缩系数
|
|
|
|
|
reservoirData.getCf().setValue(m_parameterTable->item(6, 3)->text().toDouble()); // 岩石压缩系数
|
|
|
|
|
reservoirData.getSwi().setValue(m_parameterTable->item(7, 3)->text().toDouble()); // 初始含水饱和度
|
|
|
|
|
reservoirData.getSwi().setValue(m_parameterTable->item(4, 3)->text().toDouble()); // 初始含水饱和度
|
|
|
|
|
|
|
|
|
|
// 更新储层数据(全局)
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->updateReservoirData(reservoirData);
|
|
|
|
|
@ -1376,28 +1272,27 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
if(!selectedWellName.isEmpty()) {
|
|
|
|
|
double newSkinValue = m_parameterTable->item(1, 3)->text().toDouble();
|
|
|
|
|
double newWellboreStorageValue = m_parameterTable->item(2, 3)->text().toDouble();
|
|
|
|
|
double newFractureConductivityValue = m_parameterTable->item(8, 3)->text().toDouble();
|
|
|
|
|
double newFractureHalfLengthValue = m_parameterTable->item(9, 3)->text().toDouble();
|
|
|
|
|
double newFractureConductivityValue = m_parameterTable->item(5, 3)->text().toDouble();
|
|
|
|
|
double newFractureHalfLengthValue = m_parameterTable->item(6, 3)->text().toDouble();
|
|
|
|
|
|
|
|
|
|
// 直接从数据管理器获取目标井
|
|
|
|
|
nmDataAnalyzeManager* manager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
nmDataWellBase* pTargetWell = manager->findWellByName(selectedWellName);
|
|
|
|
|
|
|
|
|
|
if(pTargetWell) {
|
|
|
|
|
// 更新Skin
|
|
|
|
|
// 先修改井参数副本,最后写回原对象中的现有属性,保持射孔对象地址不变。
|
|
|
|
|
nmDataPerforation* perf = pTargetWell->getPerforation(0);
|
|
|
|
|
if(perf) {
|
|
|
|
|
nmDataAttribute skinAttr = perf->getSkin();
|
|
|
|
|
skinAttr.setValue(newSkinValue);
|
|
|
|
|
perf->setSkin(skinAttr);
|
|
|
|
|
perf->getSkin().setValue(skinAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新井筒储集系数
|
|
|
|
|
nmDataAttribute wellboreAttr = pTargetWell->getWellboreStorage();
|
|
|
|
|
wellboreAttr.setValue(newWellboreStorageValue);
|
|
|
|
|
pTargetWell->setWellboreStorage(wellboreAttr);
|
|
|
|
|
pTargetWell->getWellboreStorage().setValue(wellboreAttr.getValue());
|
|
|
|
|
|
|
|
|
|
// 根据井类型单独更新这一口井
|
|
|
|
|
NM_WELL_MODEL wellType = pTargetWell->getWellType();
|
|
|
|
|
|
|
|
|
|
// Dfc 属于压裂井对象;只修改这一项,裂缝位置、长度和段数保持原值。
|
|
|
|
|
@ -1406,40 +1301,26 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
nmDataAttribute dfc = fracturedWell->getDfc();
|
|
|
|
|
dfc.setValue(newFractureConductivityValue);
|
|
|
|
|
fracturedWell->setDfc(dfc);
|
|
|
|
|
fracturedWell->getFractureHalfLength().setValue(newFractureHalfLengthValue);
|
|
|
|
|
fracturedWell->getDfc().setValue(dfc.getValue());
|
|
|
|
|
nmDataAttribute halfLength = fracturedWell->getFractureHalfLength();
|
|
|
|
|
halfLength.setValue(newFractureHalfLengthValue);
|
|
|
|
|
fracturedWell->getFractureHalfLength().setValue(halfLength.getValue());
|
|
|
|
|
}
|
|
|
|
|
} else if(wellType == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
nmDataHorizontalFracturedWell* fracturedWell = dynamic_cast<nmDataHorizontalFracturedWell*>(pTargetWell);
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
nmDataAttribute dfc = fracturedWell->getDfc();
|
|
|
|
|
dfc.setValue(newFractureConductivityValue);
|
|
|
|
|
fracturedWell->setDfc(dfc);
|
|
|
|
|
fracturedWell->getFractureHalfLength().setValue(newFractureHalfLengthValue);
|
|
|
|
|
fracturedWell->getDfc().setValue(dfc.getValue());
|
|
|
|
|
nmDataAttribute halfLength = fracturedWell->getFractureHalfLength();
|
|
|
|
|
halfLength.setValue(newFractureHalfLengthValue);
|
|
|
|
|
fracturedWell->getFractureHalfLength().setValue(halfLength.getValue());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(wellType == NM_WELL_MODEL::Vertical_Well) {
|
|
|
|
|
nmDataVerticalWell* pVerticalWell = dynamic_cast<nmDataVerticalWell*>(pTargetWell);
|
|
|
|
|
if(pVerticalWell != nullptr) {
|
|
|
|
|
QVector<nmDataVerticalWell> wells;
|
|
|
|
|
wells.append(*pVerticalWell);
|
|
|
|
|
manager->updateVerticalWells(wells);
|
|
|
|
|
}
|
|
|
|
|
} else if(wellType == NM_WELL_MODEL::Vertical_Fractured_Well) {
|
|
|
|
|
nmDataVerticalFracturedWell* pVerticalFracturedWell = dynamic_cast<nmDataVerticalFracturedWell*>(pTargetWell);
|
|
|
|
|
if(pVerticalFracturedWell != nullptr) {
|
|
|
|
|
QVector<nmDataVerticalFracturedWell> wells;
|
|
|
|
|
wells.append(*pVerticalFracturedWell);
|
|
|
|
|
manager->updateVerticalFracturedWells(wells);
|
|
|
|
|
}
|
|
|
|
|
} else if(wellType == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
nmDataHorizontalFracturedWell* pHorizontalFracturedWell = dynamic_cast<nmDataHorizontalFracturedWell*>(pTargetWell);
|
|
|
|
|
if(pHorizontalFracturedWell != nullptr) {
|
|
|
|
|
QVector<nmDataHorizontalFracturedWell> wells;
|
|
|
|
|
wells.append(*pHorizontalFracturedWell);
|
|
|
|
|
manager->updateHorizontalFracturedWells(wells);
|
|
|
|
|
}
|
|
|
|
|
// 全部井参数落地后统一刷新一次右侧参数面板。
|
|
|
|
|
if(manager->getAttrRegistry()) {
|
|
|
|
|
manager->getAttrRegistry()->refreshAll();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -1555,6 +1436,12 @@ void nmWxAutomaticFitting::onFittingFinished(bool success, const QString& messag
|
|
|
|
|
disconnect(m_autoFitterLM, SIGNAL(fittingFinished(bool, QString)),
|
|
|
|
|
this, SLOT(onFittingFinished(bool, QString)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 拟合候选值通过参数副本写回,结束时统一把最终值同步到右侧参数面板。
|
|
|
|
|
nmDataAnalyzeManager* manager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
if(manager && manager->getAttrRegistry()) {
|
|
|
|
|
manager->getAttrRegistry()->refreshAll();
|
|
|
|
|
}
|
|
|
|
|
if(success) {
|
|
|
|
|
// 只有成功拟合的结果才用于生成下一轮范围,失败结果不污染当前配置。
|
|
|
|
|
updateBestParametersToTable();
|
|
|
|
|
@ -1692,12 +1579,9 @@ void nmWxAutomaticFitting::updateBestParametersToTable()
|
|
|
|
|
if(m_sCheckBox->isChecked()) enabledParams.append(1); // 表皮系数
|
|
|
|
|
if(m_cCheckBox->isChecked()) enabledParams.append(2); // 井筒储集系数
|
|
|
|
|
if(m_phiCheckBox->isChecked()) enabledParams.append(3); // 孔隙度
|
|
|
|
|
if(m_hCheckBox->isChecked()) enabledParams.append(4); // 储层厚度
|
|
|
|
|
if(m_ctCheckBox->isChecked()) enabledParams.append(5); // 综合压缩系数
|
|
|
|
|
if(m_cfCheckBox->isChecked()) enabledParams.append(6); // 岩石压缩系数
|
|
|
|
|
if(m_swiCheckBox->isChecked()) enabledParams.append(7); // 初始含水饱和度
|
|
|
|
|
if(m_dfcCheckBox->isChecked()) enabledParams.append(8); // 裂缝导流能力
|
|
|
|
|
if(m_fractureHalfLengthCheckBox->isChecked()) enabledParams.append(9); // 裂缝半长
|
|
|
|
|
if(m_swiCheckBox->isChecked()) enabledParams.append(4); // 初始含水饱和度
|
|
|
|
|
if(m_dfcCheckBox->isChecked()) enabledParams.append(5); // 裂缝导流能力
|
|
|
|
|
if(m_fractureHalfLengthCheckBox->isChecked()) enabledParams.append(6); // 裂缝半长
|
|
|
|
|
|
|
|
|
|
// 更新参数值和范围
|
|
|
|
|
for (int i = 0; i < bestSolution.size() && i < enabledParams.size(); ++i) {
|
|
|
|
|
|