|
|
|
|
@ -3,7 +3,6 @@
|
|
|
|
|
#include "nmCalculationUtils.h"
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
#include "nmDataWellBase.h"
|
|
|
|
|
#include "nmDataVerticalWell.h"
|
|
|
|
|
#include "nmDataVerticalFracturedWell.h"
|
|
|
|
|
#include "nmDataHorizontalFracturedWell.h"
|
|
|
|
|
#include "nmDataReservoir.h"
|
|
|
|
|
@ -2776,7 +2775,34 @@ void nmCalculationAutoFitLM::updateWellParameters(const QVector<double>& paramet
|
|
|
|
|
|
|
|
|
|
if(!pWell) return;
|
|
|
|
|
|
|
|
|
|
//nmDataWellBase* pWell = wells[0]; // 使用第一口井
|
|
|
|
|
// 先在参数副本中组装本次候选值,全部解析完成后再写回现有井对象。
|
|
|
|
|
// 这样不会触发整井赋值,也不会删除并重建井内已有的射孔对象。
|
|
|
|
|
nmDataPerforation* pPerforation = pWell->getPerforation(0);
|
|
|
|
|
nmDataAttribute skinAttr;
|
|
|
|
|
bool updateSkin = false;
|
|
|
|
|
if(pPerforation) {
|
|
|
|
|
skinAttr = pPerforation->getSkin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmDataAttribute wellboreAttr = pWell->getWellboreStorage();
|
|
|
|
|
bool updateWellboreStorage = false;
|
|
|
|
|
|
|
|
|
|
nmDataVerticalFracturedWell* pVerticalFracturedWell =
|
|
|
|
|
dynamic_cast<nmDataVerticalFracturedWell*>(pWell);
|
|
|
|
|
nmDataHorizontalFracturedWell* pHorizontalFracturedWell =
|
|
|
|
|
dynamic_cast<nmDataHorizontalFracturedWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
nmDataAttribute dfcAttr;
|
|
|
|
|
nmDataAttribute fractureHalfLengthAttr;
|
|
|
|
|
if(pVerticalFracturedWell) {
|
|
|
|
|
dfcAttr = pVerticalFracturedWell->getDfc();
|
|
|
|
|
fractureHalfLengthAttr = pVerticalFracturedWell->getFractureHalfLength();
|
|
|
|
|
} else if(pHorizontalFracturedWell) {
|
|
|
|
|
dfcAttr = pHorizontalFracturedWell->getDfc();
|
|
|
|
|
fractureHalfLengthAttr = pHorizontalFracturedWell->getFractureHalfLength();
|
|
|
|
|
}
|
|
|
|
|
bool updateDfc = false;
|
|
|
|
|
bool updateFractureHalfLength = false;
|
|
|
|
|
|
|
|
|
|
int paramIndex = 0;
|
|
|
|
|
|
|
|
|
|
@ -2786,58 +2812,31 @@ void nmCalculationAutoFitLM::updateWellParameters(const QVector<double>& paramet
|
|
|
|
|
|
|
|
|
|
switch(i) {
|
|
|
|
|
case 1: { // 表皮系数
|
|
|
|
|
nmDataPerforation* perf = pWell->getPerforation(0);
|
|
|
|
|
|
|
|
|
|
if(perf) {
|
|
|
|
|
nmDataAttribute skinAttr = perf->getSkin();
|
|
|
|
|
if(pPerforation) {
|
|
|
|
|
skinAttr.setValue(value);
|
|
|
|
|
perf->setSkin(skinAttr);
|
|
|
|
|
updateSkin = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2: { // 井筒储集系数
|
|
|
|
|
nmDataAttribute wellboreAttr = pWell->getWellboreStorage();
|
|
|
|
|
wellboreAttr.setValue(value);
|
|
|
|
|
pWell->setWellboreStorage(wellboreAttr);
|
|
|
|
|
updateWellboreStorage = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 8: { // 裂缝导流能力
|
|
|
|
|
if(pWell->getWellType() == NM_WELL_MODEL::Vertical_Fractured_Well) {
|
|
|
|
|
nmDataVerticalFracturedWell* fracturedWell =
|
|
|
|
|
dynamic_cast<nmDataVerticalFracturedWell*>(pWell);
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
nmDataAttribute dfc = fracturedWell->getDfc();
|
|
|
|
|
dfc.setValue(value);
|
|
|
|
|
fracturedWell->setDfc(dfc);
|
|
|
|
|
}
|
|
|
|
|
} else if(pWell->getWellType() == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
nmDataHorizontalFracturedWell* fracturedWell =
|
|
|
|
|
dynamic_cast<nmDataHorizontalFracturedWell*>(pWell);
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
nmDataAttribute dfc = fracturedWell->getDfc();
|
|
|
|
|
dfc.setValue(value);
|
|
|
|
|
fracturedWell->setDfc(dfc);
|
|
|
|
|
}
|
|
|
|
|
if(pVerticalFracturedWell || pHorizontalFracturedWell) {
|
|
|
|
|
dfcAttr.setValue(value);
|
|
|
|
|
updateDfc = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 9: { // 裂缝半长
|
|
|
|
|
// 直接修改井对象中的属性,复用已有信号重算裂缝端点。
|
|
|
|
|
if(pWell->getWellType() == NM_WELL_MODEL::Vertical_Fractured_Well) {
|
|
|
|
|
nmDataVerticalFracturedWell* fracturedWell =
|
|
|
|
|
dynamic_cast<nmDataVerticalFracturedWell*>(pWell);
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
fracturedWell->getFractureHalfLength().setValue(value);
|
|
|
|
|
}
|
|
|
|
|
} else if(pWell->getWellType() == NM_WELL_MODEL::Horizontal_Fractured_Well) {
|
|
|
|
|
nmDataHorizontalFracturedWell* fracturedWell =
|
|
|
|
|
dynamic_cast<nmDataHorizontalFracturedWell*>(pWell);
|
|
|
|
|
if(fracturedWell) {
|
|
|
|
|
fracturedWell->getFractureHalfLength().setValue(value);
|
|
|
|
|
}
|
|
|
|
|
if(pVerticalFracturedWell || pHorizontalFracturedWell) {
|
|
|
|
|
fractureHalfLengthAttr.setValue(value);
|
|
|
|
|
updateFractureHalfLength = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
@ -2847,58 +2846,28 @@ void nmCalculationAutoFitLM::updateWellParameters(const QVector<double>& paramet
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据井类型更新到数据管理器
|
|
|
|
|
updateWellToDataManager(pWell);
|
|
|
|
|
if(updateSkin) {
|
|
|
|
|
pPerforation->getSkin().setValue(skinAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmCalculationAutoFitLM::updateWellToDataManager(nmDataWellBase* pWell)
|
|
|
|
|
{
|
|
|
|
|
if(!pWell) return;
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
NM_WELL_MODEL wellType = pWell->getWellType();
|
|
|
|
|
|
|
|
|
|
// DataManager 内部按井型维护不同容器。修改基类指针后,需要根据实际井型
|
|
|
|
|
// 调用对应 update 接口,才能让后续求解器组装读到最新 skin / wellboreC。
|
|
|
|
|
switch(wellType) {
|
|
|
|
|
case NM_WELL_MODEL::Vertical_Well: {
|
|
|
|
|
nmDataVerticalWell* pVerticalWell = dynamic_cast<nmDataVerticalWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
if(pVerticalWell) {
|
|
|
|
|
QVector<nmDataVerticalWell> wells;
|
|
|
|
|
wells.append(*pVerticalWell);
|
|
|
|
|
dataManager->updateVerticalWells(wells);
|
|
|
|
|
if(updateWellboreStorage) {
|
|
|
|
|
pWell->getWellboreStorage().setValue(wellboreAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
if(pVerticalFracturedWell) {
|
|
|
|
|
if(updateDfc) {
|
|
|
|
|
pVerticalFracturedWell->getDfc().setValue(dfcAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NM_WELL_MODEL::Vertical_Fractured_Well: {
|
|
|
|
|
nmDataVerticalFracturedWell* pVFracturedWell = dynamic_cast<nmDataVerticalFracturedWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
if(pVFracturedWell) {
|
|
|
|
|
QVector<nmDataVerticalFracturedWell> wells;
|
|
|
|
|
wells.append(*pVFracturedWell);
|
|
|
|
|
dataManager->updateVerticalFracturedWells(wells);
|
|
|
|
|
if(updateFractureHalfLength) {
|
|
|
|
|
pVerticalFracturedWell->getFractureHalfLength().setValue(
|
|
|
|
|
fractureHalfLengthAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
} else if(pHorizontalFracturedWell) {
|
|
|
|
|
if(updateDfc) {
|
|
|
|
|
pHorizontalFracturedWell->getDfc().setValue(dfcAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NM_WELL_MODEL::Horizontal_Fractured_Well: {
|
|
|
|
|
nmDataHorizontalFracturedWell* pHFracturedWell = dynamic_cast<nmDataHorizontalFracturedWell*>(pWell);
|
|
|
|
|
|
|
|
|
|
if(pHFracturedWell) {
|
|
|
|
|
QVector<nmDataHorizontalFracturedWell> wells;
|
|
|
|
|
wells.append(*pHFracturedWell);
|
|
|
|
|
dataManager->updateHorizontalFracturedWells(wells);
|
|
|
|
|
if(updateFractureHalfLength) {
|
|
|
|
|
pHorizontalFracturedWell->getFractureHalfLength().setValue(
|
|
|
|
|
fractureHalfLengthAttr.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|