#include "nmSubWndDataAnalyzeController.h" #include "iSubWndFitting.h" #include "iAnalRun.h" #include "nmDataAnalyzeContext.h" #include "ZxBaseUtil.h" #include "ZxDataWell.h" #include "ZxRstWnd.h" #include "ZxSegmentInfo.h" #include namespace { // 将数据层保存的窗口指针还原为窗口层接口指针 iSubWndFitting* toFitting(void* pFitting) { return static_cast(pFitting); } typedef bool (*CalPseudoPressure)(double, double&, int); CalPseudoPressure getPseudoPressureConverter() { static HMODULE module = LoadLibraryW(L"mAlgPseudo.dll"); static CalPseudoPressure converter = module ? reinterpret_cast(GetProcAddress( module, "?calPS@iAlgPseuCaller@@SA_NNAANH@Z")) : nullptr; return converter; } // nmSubWnd模块加载时注册上下文提供者,避免在nmSubWndUtils中增加初始化代码 struct nmSubWndDataAnalyzeControllerRegistrar { nmSubWndDataAnalyzeControllerRegistrar() { nmDataAnalyzeContext::setProvider(nmSubWndDataAnalyzeController::instance()); } }; nmSubWndDataAnalyzeControllerRegistrar s_registrar; } // 获取窗口层上下文控制器单例 nmSubWndDataAnalyzeController* nmSubWndDataAnalyzeController::instance() { static nmSubWndDataAnalyzeController s_controller; return &s_controller; } // 获取界面当前选择的流动段索引 bool nmSubWndDataAnalyzeController::getCurrentSegmentIndex(void* pFitting, int& nIndexF) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } ZxSegmentInfo* pSegInfo = pSubWndFitting->getSegmentInfo(); if(pSegInfo == nullptr) { return false; } nIndexF = pSegInfo->m_nIndexF; return true; } // 获取基础数据中的PVT相态类型 bool nmSubWndDataAnalyzeController::getBasicPft(void* pFitting, PvtFluidType& eType) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } eType = pSubWndFitting->getBasicPft(); return true; } // 按参数名获取PVT基础参数值 bool nmSubWndDataAnalyzeController::getPvtParaValues(void* pFitting, const QStringList& listParas, QMap& mapValues) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } return pSubWndFitting->getPvtParaValues(listParas, mapValues); } // 获取基础数据分层数据 bool nmSubWndDataAnalyzeController::getBasicDataLayers(void* pFitting, VVecVariant& vvecLayerData) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } return pSubWndFitting->getBasicDataLayers(vvecLayerData); } // 获取指定相态和参数名对应的PVT曲线结果 bool nmSubWndDataAnalyzeController::getPvtRstOf(void* pFitting, PvtFluidType eType, const QString& sPara, VecDouble& vecX, VecDouble& vecY) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } return pSubWndFitting->getPvtRstOf(eType, sPara, vecX, vecY); } // 获取Diffusion页面中某个参数的具体数值 bool nmSubWndDataAnalyzeController::getDiffusionParaOf(void* pFitting, DiffusionSubOption dso, const QString& sPara, double& d) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } return pSubWndFitting->getDiffusionParaOf(dso, sPara, d); } // 获取Diffusion页面中指定子项的计算结果 bool nmSubWndDataAnalyzeController::getDiffusionRstOf(void* pFitting, DiffusionSubOption dso, VVecDouble& vvec) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } return pSubWndFitting->getDiffusionRstOf(dso, vvec); } bool nmSubWndDataAnalyzeController::getPseuRstOf(void* pFitting, VVecDouble& vvec) { // 先按当前井和相态配置拟压力算法,确保转换规则与自动拟合界面一致。 iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } iAnalRun* pAnalRun = pSubWndFitting->getAnalRun(); if(pAnalRun == nullptr || !pAnalRun->configPsAbouts(true, pSubWndFitting->getModelOption(), false, pSubWndFitting->getAllWxPtr())) { return false; } VVecDouble source; if(!pSubWndFitting->getPseuRstOf(source) || source.size() < 2 || source[0].size() < 2) { return false; } double minPressure = source[0][0]; double maxPressure = source[0][0]; for(int i = 1; i < source[0].size(); ++i) { minPressure = qMin(minPressure, source[0][i]); maxPressure = qMax(maxPressure, source[0][i]); } if(minPressure >= maxPressure) { return false; } // 在原始压力范围内建立稠密转换表,Runner 后续通过线性插值转换每个求解压力点。 const int sampleCount = 4096; CalPseudoPressure converter = getPseudoPressureConverter(); if(converter == nullptr) { return false; } VecDouble pressureTable; VecDouble pseudoPressureTable; pressureTable.reserve(sampleCount); pseudoPressureTable.reserve(sampleCount); for(int i = 0; i < sampleCount; ++i) { const double ratio = static_cast(i) / (sampleCount - 1); const double pressure = minPressure + ratio * (maxPressure - minPressure); double pseudoPressure = 0.0; if(!converter(pressure, pseudoPressure, -1)) { return false; } pressureTable.append(pressure); pseudoPressureTable.append(pseudoPressure); } vvec.clear(); vvec.append(pressureTable); vvec.append(pseudoPressureTable); return true; } // 组装当前井和当前结果窗口对应的数值结果保存目录 bool nmSubWndDataAnalyzeController::getSaveResultDir(void* pFitting, const QString& sRstCode, QString& sDir) { iSubWndFitting* pSubWndFitting = toFitting(pFitting); if(pSubWndFitting == nullptr) { return false; } ZxRstWnd* pRstWnd = pSubWndFitting->getRstUtilWnd(); if(pRstWnd == nullptr) { return false; } ZxDataWell* pDataWell = pSubWndFitting->getDataWell(); if(pDataWell == nullptr) { return false; } sDir = ZxBaseUtil::getWellDirOf(pDataWell->getName(), "Nm"); sDir += sRstCode + "/" + pRstWnd->getCode(); return true; }