|
|
#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 <Windows.h>
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
// 将数据层保存的窗口指针还原为窗口层接口指针
|
|
|
iSubWndFitting* toFitting(void* pFitting)
|
|
|
{
|
|
|
return static_cast<iSubWndFitting*>(pFitting);
|
|
|
}
|
|
|
|
|
|
typedef bool (*CalPseudoPressure)(double, double&, int);
|
|
|
|
|
|
CalPseudoPressure getPseudoPressureConverter()
|
|
|
{
|
|
|
static HMODULE module = LoadLibraryW(L"mAlgPseudo.dll");
|
|
|
static CalPseudoPressure converter = module
|
|
|
? reinterpret_cast<CalPseudoPressure>(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<QString, double>& 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<double>(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;
|
|
|
}
|