diff --git a/Include/nmNum/nmData/nmDataAnalyzeManager.h b/Include/nmNum/nmData/nmDataAnalyzeManager.h index 8df5c8c..00e08b7 100644 --- a/Include/nmNum/nmData/nmDataAnalyzeManager.h +++ b/Include/nmNum/nmData/nmDataAnalyzeManager.h @@ -50,6 +50,19 @@ struct BackgroundImageInfo { QImage objImage; // 具体的QImage对象 }; +enum NM_SOLVER_MODEL_TYPE { + SMT_Oil_ConstPvt = 1, + SMT_Oil_VariablePvt = 2, + SMT_Water_ConstPvt = 3, + SMT_Water_VariablePvt = 4, + SMT_Gas_VariablePvt = 5, + SMT_Gas_PseudoPressure = 6, + SMT_Oil_Gas_TwoPhase = 7, + SMT_Oil_Water_TwoPhase = 8, + SMT_Gas_Water_TwoPhase = 9, + SMT_Oil_Gas_Water_ThreePhase = 10 +}; + class nmDataWellBase; class ZxDataWell; class nmDataReservoir; @@ -290,6 +303,10 @@ class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin NM_Grid_Type getGridType(); void setGridType(NM_Grid_Type newGridType); + // 求解模型类型 + NM_SOLVER_MODEL_TYPE getSolverModelType() const; + void setSolverModelType(NM_SOLVER_MODEL_TYPE newSolverModelType); + // 获取Pebi网格求解数据接口 // 获取压力历史数据 QVector> getPebiSolverHistoryDataByName(const QString& wellName); @@ -578,6 +595,9 @@ class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin // 网格类型 NM_Grid_Type m_eGridType; + // 求解模型类型 + NM_SOLVER_MODEL_TYPE m_eSolverModelType; + // Pvt数据(Pebi) nmDataPvtParaForPebi* m_pebiPvtPara; diff --git a/Src/nmNum/nmCalculation/nmCalculationDllPebiSolverTask.cpp b/Src/nmNum/nmCalculation/nmCalculationDllPebiSolverTask.cpp index c779f4b..a88df79 100644 --- a/Src/nmNum/nmCalculation/nmCalculationDllPebiSolverTask.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationDllPebiSolverTask.cpp @@ -43,22 +43,6 @@ void assignPvtVectorIfNotEmpty(dVec1& target, const QVector& source) } } -// 将内部储层相态转换为求解器T类型 -int pebiModelTypeFromPhase(NM_PHASE_TYPE phaseType) -{ - switch(phaseType) { - case PHASE_Water: - return 4; - case PHASE_Gas: - return 5; - case PHASE_Oil_Water: - return 8; - case PHASE_Oil: - default: - return 1; - } -} - bool isFiniteSolverNumber(double value) { #ifdef _MSC_VER @@ -154,9 +138,8 @@ bool nmCalculationDllPebiSolverTask::execPebiMode() HX_NWTM_MODEL_OUTPUT p1; HX_NWTM_MODEL_INPUT p0(pGridInstance->getGridOutput2()); nmDataReservoir* pReservoirData = pDataInstance->getReservoirData(); - NM_PHASE_TYPE phaseType = pReservoirData != nullptr ? pReservoirData->getPhaseType() : PHASE_Oil; - // 根据界面相态选择求解器模型类型 - p0.T = pebiModelTypeFromPhase(phaseType); + // 根据PVT参数获取结果选择求解器模型类型 + p0.T = static_cast(pDataInstance->getSolverModelType()); // 获取PEBI网格存入井的顺序 QVector> vecWellsOrder = pDataInstance->getCalculationWells(); diff --git a/Src/nmNum/nmData/nmDataAnalyzeManager.cpp b/Src/nmNum/nmData/nmDataAnalyzeManager.cpp index 0bfdfc8..0de06d6 100644 --- a/Src/nmNum/nmData/nmDataAnalyzeManager.cpp +++ b/Src/nmNum/nmData/nmDataAnalyzeManager.cpp @@ -113,39 +113,7 @@ void setPebiPressureIfEmpty(nmDataPvtParaForPebi* pPvtPara, const QVectorsetPressure(vecX); } } - -// 根据当前PVT相态决定需要访问哪些相态页。 -// 这里只控制PVT页面读取范围,后续参数默认值和PEBI赋值逻辑保持不变。 -void resolvePvtPhaseReadFlags(PvtFluidType eType, bool& bReadOil, bool& bReadGas, bool& bReadWater) -{ - bReadOil = false; - bReadGas = false; - bReadWater = false; - - switch(eType) { - case WFT_Oil: - // 单相油:只访问油相页,避免访问不存在的气/水相页 - bReadOil = true; - break; - case WFT_Gas: - // 单相气:只访问气相页 - bReadGas = true; - break; - case WFT_Water: - // 单相水:只访问水相页 - bReadWater = true; - break; - case WFT_Oil_Water: - // 油水:访问油相和水相页,不访问气相页 - bReadOil = true; - bReadWater = true; - break; - default: - // 未识别相态不主动读取相态页,避免PVT工具输出缺失子窗口日志 - break; - } -} - + // 从Diffusion右侧结果表中提取指定列数据 bool extractDiffusionColumn(const VVecDouble& vvec, int nColumn, QVector& vecValues) { @@ -268,6 +236,7 @@ ZX_DEFINE_DYNAMIC(DataAnalyzeManager, nmDataAnalyzeManager) // 初始化储层数据 m_pLayerData = new nmDataLayer; m_eGridType = NM_Grid_Type::NM_Grid_PEBI; //默认网格类型为PEBI + m_eSolverModelType = NM_SOLVER_MODEL_TYPE::SMT_Oil_ConstPvt; this->initDefaultDisplaySettings(); // 初始化中英文翻译映射 nmTranslationManager::initTranslations(); @@ -1144,20 +1113,22 @@ void nmDataAnalyzeManager::createReservoir() //QString sPftDesc = pSubWndFitting->getBasicPftDesc(); // 只读取当前相态存在的PVT页,避免PVT工具输出PhaseGas/PhaseWater缺失日志 QStringList listParas; - bool bReadOilPvt = false; - bool bReadGasPvt = false; - bool bReadWaterPvt = false; - resolvePvtPhaseReadFlags(eType, bReadOilPvt, bReadGasPvt, bReadWaterPvt); - // 储层基础数据这里只需要体积系数和粘度;不属于当前相态的参数继续走默认值 - if(bReadOilPvt) { + switch(eType) { + case WFT_Oil: listParas << "Bo" << "Miuo"; - } - if(bReadGasPvt) { + break; + case WFT_Gas: listParas << "Bg" << "Miug"; - } - if(bReadWaterPvt) { + break; + case WFT_Water: listParas << "Bw" << "Miuw"; + break; + case WFT_Oil_Water: + listParas << "Bo" << "Miuo" << "Bw" << "Miuw"; + break; + default: + break; } listParas << "Ct"; pContextProvider->getPvtParaValues(pSubWndFitting, listParas, mapParaValues); @@ -1639,29 +1610,16 @@ void nmDataAnalyzeManager::initPvtParaFromSubFit() PvtFluidType eType = WFT_Null; pContextProvider->getBasicPft(pSubWndFitting, eType); - bool bReadOilPvt = false; - bool bReadGasPvt = false; - bool bReadWaterPvt = false; - resolvePvtPhaseReadFlags(eType, bReadOilPvt, bReadGasPvt, bReadWaterPvt); - - //QVector vecPressure; // 压力, MPa - QVector vecRso; // 溶解气油比, m^3/m^3 QVector vecBo; // 油体积系数, m^3/m^3 QVector vecCo; // 油压缩系数, 1/MPa QVector vecMiuo; // 油粘度, mPa·s - QVector vecRouo; // 油密度, kg/m^3 - QVector vecRv; // 凝析油气比, m^3/m^3 QVector vecBg; // 气体积系数, m^3/m^3 QVector vecCg; // 气压缩系数, 1/MPa QVector vecMiug; // 气粘度, mPa·s - QVector vecRoug; // 气密度, kg/m^3 - QVector vecZ; // 气偏差因子, 1 - QVector vecRsw; // 溶解气水比, m^3/m^3 QVector vecBw; // 水体积系数, m^3/m^3 QVector vecCw; // 水压缩系数, 1/MPa QVector vecMiuw; // 水粘度, mPa·s - QVector vecRouw; // 水密度, kg/m^3 VecDouble vecX; @@ -1672,36 +1630,41 @@ void nmDataAnalyzeManager::initPvtParaFromSubFit() } m_pebiPvtPara = new nmDataPvtParaForPebi; - - // 气油比不按相态区分,所有情况都尝试读取 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Rs", vecX, vecRso); - m_pebiPvtPara->setRso(vecRso); - setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - - // 其他PVT结果曲线只读取当前相态已有的页,缺失相态保留PEBI默认数据 - if(bReadOilPvt) { + setSolverModelType(SMT_Oil_ConstPvt); + + bool bFetchedBo = false; + bool bFetchedCo = false; + bool bFetchedMiuo = false; + bool bFetchedBw = false; + bool bFetchedCw = false; + bool bFetchedMiuw = false; + + // PVT结果曲线直接按当前相态分支读取,缺失相态保留PEBI默认数据 + switch(eType) { + case WFT_Oil: // 油体积系数 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Bo", vecX, vecBo); + bFetchedBo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Bo", vecX, vecBo); m_pebiPvtPara->setBo(vecBo); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); // 油压缩系数 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Co", vecX, vecCo); + bFetchedCo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Co", vecX, vecCo); m_pebiPvtPara->setCo(vecCo); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 油密度 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Rhoo", vecX, vecRouo); - m_pebiPvtPara->setRouo(vecRouo); - setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 油粘度 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Miuo", vecX, vecMiuo); + bFetchedMiuo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Miuo", vecX, vecMiuo); m_pebiPvtPara->setMiuo(vecMiuo); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - } - - if(bReadGasPvt) { + setSolverModelType( + bFetchedBo + && bFetchedCo + && bFetchedMiuo + ? SMT_Oil_VariablePvt + : SMT_Oil_ConstPvt); + break; + case WFT_Gas: + setSolverModelType(SMT_Gas_VariablePvt); // 气体积系数 pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Bg", vecX, vecBg); @@ -1717,52 +1680,62 @@ void nmDataAnalyzeManager::initPvtParaFromSubFit() pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Miug", vecX, vecMiug); m_pebiPvtPara->setMiug(vecMiug); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); + break; + case WFT_Water: + // 水体积系数 + bFetchedBw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Bw", vecX, vecBw); + m_pebiPvtPara->setBw(vecBw); + setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 气密度 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Rhog", vecX, vecRoug); - m_pebiPvtPara->setRoug(vecRoug); + // 水压缩系数 + bFetchedCw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Cw", vecX, vecCw); + m_pebiPvtPara->setCw(vecCw); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 气偏差因子 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Zg", vecX, vecZ); - m_pebiPvtPara->setZ(vecZ); + // 水粘度 + bFetchedMiuw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Miuw", vecX, vecMiuw); + m_pebiPvtPara->setMiuw(vecMiuw); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - } + setSolverModelType( + bFetchedBw + && bFetchedCw + && bFetchedMiuw + ? SMT_Water_VariablePvt + : SMT_Water_ConstPvt); + break; + case WFT_Oil_Water: { + setSolverModelType(SMT_Oil_Water_TwoPhase); - if(bReadWaterPvt) { - // 溶解气水比 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Rsw", vecX, vecRsw); - m_pebiPvtPara->setRsw(vecRsw); + // 油体积系数 + pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Bo", vecX, vecBo); + m_pebiPvtPara->setBo(vecBo); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 水体积系数 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Bw", vecX, vecBw); - m_pebiPvtPara->setBw(vecBw); + // 油粘度 + pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Miuo", vecX, vecMiuo); + m_pebiPvtPara->setMiuo(vecMiuo); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 水压缩系数 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Cw", vecX, vecCw); - m_pebiPvtPara->setCw(vecCw); + // 水体积系数 + pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Bw", vecX, vecBw); + m_pebiPvtPara->setBw(vecBw); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); // 水粘度 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Miuw", vecX, vecMiuw); + pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Miuw", vecX, vecMiuw); m_pebiPvtPara->setMiuw(vecMiuw); setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - // 水密度 - pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Rhow", vecX, vecRouw); - m_pebiPvtPara->setRouw(vecRouw); - setPebiPressureIfEmpty(m_pebiPvtPara, vecX); - } - - if(eType == WFT_Oil_Water) { // Diffusion相关数据来自Diffusion页面,只在油水两相时读取 // DSO_KK:相渗结果,主要用于So/Kro/Sw/Krw VVecDouble vvecDiffusionKK; if(pContextProvider->getDiffusionRstOf(pSubWndFitting, DSO_KK, vvecDiffusionKK)) { applyDiffusionKkToPebiPvt(m_pebiPvtPara, vvecDiffusionKK); } + break; + } + default: + break; } } //// 吸附气量,王老师界面没有,油相暂时不需要 @@ -2386,6 +2359,16 @@ void nmDataAnalyzeManager::setGridType(NM_Grid_Type newGridType) m_eGridType = newGridType; } +NM_SOLVER_MODEL_TYPE nmDataAnalyzeManager::getSolverModelType() const +{ + return m_eSolverModelType; +} + +void nmDataAnalyzeManager::setSolverModelType(NM_SOLVER_MODEL_TYPE newSolverModelType) +{ + m_eSolverModelType = newSolverModelType; +} + // 获取Pebi网格求解数据接口 // 获取压力历史数据 QVector> nmDataAnalyzeManager::getPebiSolverHistoryDataByName(const QString & wellName) diff --git a/Src/nmNum/nmData/nmDataReservoir.cpp b/Src/nmNum/nmData/nmDataReservoir.cpp index f6028bf..4432c88 100644 --- a/Src/nmNum/nmData/nmDataReservoir.cpp +++ b/Src/nmNum/nmData/nmDataReservoir.cpp @@ -5,7 +5,7 @@ nmDataReservoir::nmDataReservoir() { m_initialPressure = nmDataAttribute("Initial Pressure",40.0, "MPa", UNIT_TYPE_PRESSURE, QStringList(), QStringList() << "psia" << "Pa" << "kPa" << "atm" << "bara" << "kg/cm^2" << "m" << "psig" << "bar" << "MPa" << "kPag"); m_reservoirType = nmDataAttribute("Reservoir type", "Homogeneous", "", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Homogeneous" << "Dual porosity pseudo steady state", QStringList()); m_Bo = nmDataAttribute("Bo", 1.2, ""); - m_permeability = nmDataAttribute("Permeability", 0.025, "Darcy", UNIT_TYPE_PERMEABILITY, QStringList(), QStringList() << "md" << "Darcy" << "m^2" << "cm^2" << "um^2"); + m_permeability = nmDataAttribute("Permeability", 0.001, "Darcy", UNIT_TYPE_PERMEABILITY, QStringList(), QStringList() << "md" << "Darcy" << "m^2" << "cm^2" << "um^2"); m_thickness = nmDataAttribute("Thickness", 10.0, "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km"); m_porosity = nmDataAttribute("Porosity", 0.1, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList()); m_Ct = nmDataAttribute("Ct", 0.001, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());