refactor: 重构PVT初始化逻辑,按相态获取参数并简化代码结构

1. nmDataReservoir新增Gas/Water独立字段(Bg/Miug/Bw/Miuw),消除复用Bo/Miuo的语义混淆
2. nmDataReservoir成员变量按相态分组排列(油/气/水),构造/拷贝/序列化/getter-setter顺序同步
3. 重构initPvtParaFromSubFit:提取tryFetchPhasePvtCurves辅助函数,234行→~80行
4. 重构createReservoir:拆分为readPvtSingleValues/populateReservoirByPhase/createDefaultLayer,206行→~50行
5. solver task新增fillPvtInputByModel,ConstPvt从reservoir单值扩展为200元素数组
6. Ct/Cf统一获取,不再按ConstPvt/VariablePvt互斥
7. 移除油水两相多余的PVT.Sw传递,与PEBI示例对齐
feature/UI-20260528
lh 2 days ago
parent 4e574b76d6
commit e81c9e0b41

@ -43,16 +43,10 @@ public:
virtual QIcon getIcon(bool expanded) const;
public:
// 属性的 set 和 get 方法
// 基础属性
void setInitialPressure(const nmDataAttribute& attr);
nmDataAttribute& getInitialPressure();
void setReservoirType(const nmDataAttribute& attr);
nmDataAttribute& getReservoirType();
void setBo(const nmDataAttribute& attr);
nmDataAttribute& getBo();
void setPermeability(const nmDataAttribute& attr);
nmDataAttribute& getPermeability();
@ -62,27 +56,45 @@ public:
void setPorosity(const nmDataAttribute& attr);
nmDataAttribute& getPorosity();
void setCt(const nmDataAttribute& attr);
nmDataAttribute& getCt();
void setKxKy(const nmDataAttribute& attr);
nmDataAttribute& getKxKy();
void setCf(const nmDataAttribute& attr);
nmDataAttribute& getCf();
// 油相PVT单值参数
void setBo(const nmDataAttribute& attr);
nmDataAttribute& getBo();
void setMiuo(const nmDataAttribute& attr);
nmDataAttribute& getMiuo();
void setTempGasRe(double temp);
double getTempGasRe() const;
// 气相PVT单值参数
void setBg(const nmDataAttribute& attr);
nmDataAttribute& getBg();
void setPhaseType(NM_PHASE_TYPE phaseType);
NM_PHASE_TYPE getPhaseType() const;
void setMiug(const nmDataAttribute& attr);
nmDataAttribute& getMiug();
// 水相PVT单值参数
void setBw(const nmDataAttribute& attr);
nmDataAttribute& getBw();
void setMiuw(const nmDataAttribute& attr);
nmDataAttribute& getMiuw();
// 压缩系数
void setCt(const nmDataAttribute& attr);
nmDataAttribute& getCt();
void setCf(const nmDataAttribute& attr);
nmDataAttribute& getCf();
// 储层类型与传导率
void setReservoirType(const nmDataAttribute& attr);
nmDataAttribute& getReservoirType();
void setTransmissibility(const nmDataAttribute& attr);
nmDataAttribute& getTransmissibility();
// 初始饱和度
void setSoi(const nmDataAttribute& attr);
nmDataAttribute& getSoi();
@ -92,28 +104,48 @@ public:
void setSwi(const nmDataAttribute& attr);
nmDataAttribute& getSwi();
// 气藏温度与相态
void setTempGasRe(double temp);
double getTempGasRe() const;
void setPhaseType(NM_PHASE_TYPE phaseType);
NM_PHASE_TYPE getPhaseType() const;
void resetToDefaults(); // 重置所有参数为构造函数默认值
protected:
nmDataAttribute m_initialPressure; // 初始地层压力
nmDataAttribute m_permeability; // 渗透率
nmDataAttribute m_thickness; // 储层厚度
nmDataAttribute m_Miuo; // 流体粘度 (pvt参数中有)
nmDataAttribute m_Bo; // 体积系数 (pvt参数中有)
nmDataAttribute m_porosity; // 孔隙度
nmDataAttribute m_Ct; // 综合压缩系数
nmDataAttribute m_kxKy; // 各项性系数 (求解器中没有用到)
// 油相PVT单值
nmDataAttribute m_Bo; // 油体积系数
nmDataAttribute m_Miuo; // 油相粘度
// 气相PVT单值
nmDataAttribute m_Bg; // 气体积系数
nmDataAttribute m_Miug; // 气相粘度
// 水相PVT单值
nmDataAttribute m_Bw; // 水体积系数
nmDataAttribute m_Miuw; // 水相粘度
// 压缩系数
nmDataAttribute m_Ct; // 综合压缩系数
nmDataAttribute m_Cf; // 岩石压缩系数
nmDataAttribute m_reservoirType; // 储层类型 (求解器中没有用到)
nmDataAttribute m_transmissibility; // 传导率 (求解器中没有用到)
// 初始饱和度
nmDataAttribute m_Soi; // 初始含油饱和度
nmDataAttribute m_Sgi; // 初始含气饱和度
nmDataAttribute m_Swi; // 初始含水饱和度
double m_dTempGasRe; //气藏温度 (求解器中没有用到)
NM_PHASE_TYPE m_ePhaseType; //多相流类型
double m_dTempGasRe; // 气藏温度 (求解器中没有用到)
NM_PHASE_TYPE m_ePhaseType; // 多相流类型
static nmDataReservoir* s_instance;
};

@ -77,6 +77,97 @@ bool isValidSemiLogPoint(const Point& pt)
&& isReasonableLogLogValue(pt.pointData[0]);
}
/// @brief 将常数PVT单值扩展为200元素数组PEBI求解器要求数组输入
/// @param dValue 常数PVT值
/// @param nSize 数组大小默认200
/// @return 包含nSize个dValue元素的dVec1数组
dVec1 expandConstPvt(double dValue, int nSize = 200)
{
return dVec1(nSize, dValue);
}
/// @brief 根据求解器模型类型填充PVT输入数据
/// 常数PVT模型从 reservoir 读单值并扩展为200元素数组
/// 变化PVT模型从 pebiPvtPara 读曲线数组
/// @param input PEBI求解器输入结构
/// @param eModelType 求解器模型类型
/// @param pPvt PEBI PVT参数对象变化PVT时提供曲线数组
/// @param pRes 油藏数据对象常数PVT时提供单值
void fillPvtInputByModel(HX_NWTM_MODEL_INPUT& input,
NM_SOLVER_MODEL_TYPE eModelType,
nmDataPvtParaForPebi* pPvt,
nmDataReservoir* pRes)
{
// 压力横坐标始终从 pebiPvtPara 读取
if(pPvt != nullptr) {
assignPvtVectorIfNotEmpty(input.PVT.p, pPvt->getPressure());
}
switch(eModelType) {
case SMT_Oil_ConstPvt:
// 油相常数PVT单值扩展为200元素数组
if(pRes != nullptr) {
input.PVT.Bo = expandConstPvt(pRes->getBo().getValue().toDouble());
input.PVT.miuo = expandConstPvt(pRes->getMiuo().getValue().toDouble());
}
break;
case SMT_Oil_VariablePvt:
// 油相变化PVT从 pebiPvtPara 读曲线数组
if(pPvt != nullptr) {
assignPvtVectorIfNotEmpty(input.PVT.Bo, pPvt->getBo());
assignPvtVectorIfNotEmpty(input.PVT.Co, pPvt->getCo());
assignPvtVectorIfNotEmpty(input.PVT.miuo, pPvt->getMiuo());
}
break;
case SMT_Water_ConstPvt:
// 水相常数PVT单值扩展为200元素数组
if(pRes != nullptr) {
input.PVT.Bw = expandConstPvt(pRes->getBw().getValue().toDouble());
input.PVT.miuw = expandConstPvt(pRes->getMiuw().getValue().toDouble());
}
break;
case SMT_Water_VariablePvt:
// 水相变化PVT从 pebiPvtPara 读曲线数组
if(pPvt != nullptr) {
assignPvtVectorIfNotEmpty(input.PVT.Bw, pPvt->getBw());
assignPvtVectorIfNotEmpty(input.PVT.Cw, pPvt->getCw());
assignPvtVectorIfNotEmpty(input.PVT.miuw, pPvt->getMiuw());
}
break;
case SMT_Gas_VariablePvt:
case SMT_Gas_PseudoPressure:
// 气相变化PVT/拟压力:从 pebiPvtPara 读曲线数组
if(pPvt != nullptr) {
assignPvtVectorIfNotEmpty(input.PVT.Bg, pPvt->getBg());
assignPvtVectorIfNotEmpty(input.PVT.Cg, pPvt->getCg());
assignPvtVectorIfNotEmpty(input.PVT.miug, pPvt->getMiug());
}
break;
case SMT_Oil_Water_TwoPhase:
// 油水两相:从 pebiPvtPara 读油+水曲线数组 + 相渗数据
if(pPvt != nullptr) {
assignPvtVectorIfNotEmpty(input.PVT.Bo, pPvt->getBo());
assignPvtVectorIfNotEmpty(input.PVT.miuo, pPvt->getMiuo());
assignPvtVectorIfNotEmpty(input.PVT.Bw, pPvt->getBw());
assignPvtVectorIfNotEmpty(input.PVT.miuw, pPvt->getMiuw());
// 相渗与饱和度数据PEBI油水两相不需要PVT.Sw数组初始含水饱和度通过Base.Swi传递
assignPvtVectorIfNotEmpty(input.PVT.So, pPvt->getSo());
assignPvtVectorIfNotEmpty(input.PVT.Kro, pPvt->getKro());
assignPvtVectorIfNotEmpty(input.PVT.Krw, pPvt->getKrw());
}
break;
default:
break;
}
}
}
@ -110,7 +201,6 @@ bool nmCalculationDllPebiSolverTask::execute()
bool nmCalculationDllPebiSolverTask::execPebiMode()
{
//emit sigResSolverProgressUpdated(1);
nmDataAnalyzeManager* pDataInstance = nmDataAnalyzeManager::getCurrentInstance();
nmCalculationPebiGrid* pGridInstance = nmCalculationPebiGrid::getInstance();
if(pDataInstance == nullptr || pGridInstance == nullptr) {
@ -156,8 +246,6 @@ bool nmCalculationDllPebiSolverTask::execPebiMode()
p0.Rate.qw.resize(vecWellsOrder.size());
p0.Rate.qg.resize(vecWellsOrder.size());
//emit sigResSolverProgressUpdated(2);
// 遍历井数据
for(int i = 0; i < vecWellsOrder.size(); ++i) {
NM_WELL_MODEL wellType = vecWellsOrder[i].first; // 获取井的类型
@ -342,56 +430,10 @@ bool nmCalculationDllPebiSolverTask::execPebiMode()
}
}
//emit sigResSolverProgressUpdated(3);
// PVT数据
// PVT数据根据求解器模型类型填充PVT输入数据
nmDataPvtParaForPebi* pebiPvtPara = pDataInstance->getPebiPvtPara();
fillPvtInputByModel(p0, static_cast<NM_SOLVER_MODEL_TYPE>(p0.T), pebiPvtPara, pReservoirData);
if(pebiPvtPara != nullptr) {
// p0构造时已有默认PVT数据这里只用读到的参数覆盖
// 压力与饱和压力
assignPvtVectorIfNotEmpty(p0.PVT.p, pebiPvtPara->getPressure());
if(pebiPvtPara->getPb().getValue().isValid()) {
p0.PVT.pb = pebiPvtPara->getPb().getValue().toDouble();
}
// 读取PVT数据 - 油相参数
assignPvtVectorIfNotEmpty(p0.PVT.Rso, pebiPvtPara->getRso());
assignPvtVectorIfNotEmpty(p0.PVT.Bo, pebiPvtPara->getBo());
assignPvtVectorIfNotEmpty(p0.PVT.Co, pebiPvtPara->getCo());
assignPvtVectorIfNotEmpty(p0.PVT.miuo, pebiPvtPara->getMiuo());
assignPvtVectorIfNotEmpty(p0.PVT.rouo, pebiPvtPara->getRouo());
// 读取PVT数据 - 气相参数
assignPvtVectorIfNotEmpty(p0.PVT.Rv, pebiPvtPara->getRv());
assignPvtVectorIfNotEmpty(p0.PVT.Bg, pebiPvtPara->getBg());
assignPvtVectorIfNotEmpty(p0.PVT.Cg, pebiPvtPara->getCg());
assignPvtVectorIfNotEmpty(p0.PVT.miug, pebiPvtPara->getMiug());
assignPvtVectorIfNotEmpty(p0.PVT.roug, pebiPvtPara->getRoug());
assignPvtVectorIfNotEmpty(p0.PVT.Z, pebiPvtPara->getZ());
// 读取PVT数据 - 水相参数
assignPvtVectorIfNotEmpty(p0.PVT.Rsw, pebiPvtPara->getRsw());
assignPvtVectorIfNotEmpty(p0.PVT.Bw, pebiPvtPara->getBw());
assignPvtVectorIfNotEmpty(p0.PVT.Cw, pebiPvtPara->getCw());
assignPvtVectorIfNotEmpty(p0.PVT.miuw, pebiPvtPara->getMiuw());
assignPvtVectorIfNotEmpty(p0.PVT.rouw, pebiPvtPara->getRouw());
// 读取PVT数据 - 其他参数
assignPvtVectorIfNotEmpty(p0.PVT.V, pebiPvtPara->getV());
assignPvtVectorIfNotEmpty(p0.PVT.k_kinitial, pebiPvtPara->getKKinitial());
assignPvtVectorIfNotEmpty(p0.PVT.Cf_Cfinitial, pebiPvtPara->getCfCfinitial());
// 读取PVT数据 - 饱和度与相对渗透率
assignPvtVectorIfNotEmpty(p0.PVT.So, pebiPvtPara->getSo());
assignPvtVectorIfNotEmpty(p0.PVT.Kro, pebiPvtPara->getKro());
assignPvtVectorIfNotEmpty(p0.PVT.Sg, pebiPvtPara->getSg());
assignPvtVectorIfNotEmpty(p0.PVT.Krg, pebiPvtPara->getKrg());
assignPvtVectorIfNotEmpty(p0.PVT.Sw, pebiPvtPara->getSw());
assignPvtVectorIfNotEmpty(p0.PVT.Krw, pebiPvtPara->getKrw());
}
//emit sigResSolverProgressUpdated(4);
// 基础数据(储层参数?)
if(pReservoirData != nullptr) {
@ -416,21 +458,6 @@ bool nmCalculationDllPebiSolverTask::execPebiMode()
p0.Base.dt_Max = pTimeStepSetting->getMaxDeltaTAttribute().getValue().toDouble();
}
//emit sigResSolverProgressUpdated(5);
// 模拟进度条更新
// 在调用 HX_NWTM_MODEL 前启动一个线程或 QFutureWatcher 模拟进度
//QFuture<void> future = QtConcurrent::run([this]() {
// for(int i = 6; i <= 95; ++i) {
// QThread::msleep(500); // 模拟耗时
// if (!isRunning()){
// return;
// }
// emit sigResSolverProgressUpdated(i);
// }
//});
try {
nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getCurrentInstance();
QString licensePath = pDataManager->getLicensePath();
@ -474,8 +501,6 @@ bool nmCalculationDllPebiSolverTask::execPebiMode()
return false;
}
// 求解完成后停止定时器并直接设置进度到%
//emit sigResSolverProgressUpdated(97);
// 保存计算结果
bool success = this->savePebiModeResult(p1);

@ -192,7 +192,6 @@ void applyDiffusionKkToPebiPvt(nmDataPvtParaForPebi* pPvtPara, const VVecDouble&
extractDiffusionColumn(vvecKK, 2, vecKr2);
// 油水第一列为SwSo按1-Sw生成后续列为Kro/Krw
pPvtPara->setSw(vecS);
// PEBI默认相渗以So为横坐标Diffusion表按Sw递增保存这里整体转为So递增方向
pPvtPara->setSo(reversedVector(complementSaturation(vecS)));
if(!vecKr1.isEmpty()) {
@ -203,6 +202,169 @@ void applyDiffusionKkToPebiPvt(nmDataPvtParaForPebi* pPvtPara, const VVecDouble&
}
}
/// @brief 尝试获取某相态的3条PVT曲线B/C/Miu全部成功则写入pebiPvtPara
/// @param pCtx 上下文提供者用于读取PVT结果页
/// @param pSubWnd 当前流动段分析窗口
/// @param pftContext getPvtRstOf需要的相态参数
/// @param sBName 体积系数参数名("Bo"/"Bg"/"Bw"
/// @param sCName 压缩系数参数名("Co"/"Cg"/"Cw"
/// @param sMiuName 粘度参数名("Miuo"/"Miug"/"Miuw"
/// @param pPvt 输出的PEBI PVT参数对象
/// @param vecPressure 压力横坐标(首次成功时写入,后续复用)
/// @return 三条曲线全部获取成功返回true否则返回false且不写入pPvt
bool tryFetchPhasePvtCurves(
nmDataAnalyzeContextProvider* pCtx,
iSubWndFitting* pSubWnd,
PvtFluidType pftContext,
const QString& sBName,
const QString& sCName,
const QString& sMiuName,
nmDataPvtParaForPebi* pPvt,
QVector<double>& vecPressure)
{
// 分别获取体积系数、压缩系数、粘度三条曲线
QVector<double> vecB, vecC, vecMiu, vecX;
bool bB = pCtx->getPvtRstOf(pSubWnd, pftContext, sBName, vecX, vecB);
bool bC = pCtx->getPvtRstOf(pSubWnd, pftContext, sCName, vecX, vecC);
bool bMiu = pCtx->getPvtRstOf(pSubWnd, pftContext, sMiuName, vecX, vecMiu);
// 任一曲线缺失则视为该相态PVT数据不完整不写入
if(!(bB && bC && bMiu)) {
return false;
}
// 首次成功时保存压力横坐标
if(vecPressure.isEmpty() && !vecX.isEmpty()) {
vecPressure = vecX;
}
// 按相态名称写入对应的setter油气水各自独立字段
if(sBName == "Bo") pPvt->setBo(vecB);
else if(sBName == "Bg") pPvt->setBg(vecB);
else if(sBName == "Bw") pPvt->setBw(vecB);
if(sCName == "Co") pPvt->setCo(vecC);
else if(sCName == "Cg") pPvt->setCg(vecC);
else if(sCName == "Cw") pPvt->setCw(vecC);
if(sMiuName == "Miuo") pPvt->setMiuo(vecMiu);
else if(sMiuName == "Miug") pPvt->setMiug(vecMiu);
else if(sMiuName == "Miuw") pPvt->setMiuw(vecMiu);
return true;
}
/// @brief 设置油藏属性的简化辅助,消除 tempAttr=getX(); tempAttr.setValue(); setX(tempAttr) 三行重复模式
/// @param attr 油藏属性引用
/// @param dValue 属性值
void setReservoirAttr(nmDataAttribute& attr, double dValue)
{
attr.setValue(dValue);
}
/// @brief 设置油藏属性的简化辅助QString版本
void setReservoirAttr(nmDataAttribute& attr, const QString& sValue)
{
attr.setValue(sValue);
}
/// @brief 从界面读取PVT单值参数
/// @param pCtx 上下文提供者
/// @param pSubWnd 当前流动段分析窗口
/// @param eType 相态类型
/// @return 参数名到值的映射
QMap<QString, double> readPvtSingleValues(
nmDataAnalyzeContextProvider* pCtx,
iSubWndFitting* pSubWnd,
PvtFluidType eType)
{
// 按相态构建需要读取的参数列表
QStringList listParas;
switch(eType) {
case WFT_Oil: listParas << "Bo" << "Miuo"; break;
case WFT_Gas: listParas << "Bg" << "Miug"; break;
case WFT_Water: listParas << "Bw" << "Miuw"; break;
case WFT_Oil_Water: listParas << "Bo" << "Miuo" << "Bw" << "Miuw"; break;
default: break;
}
// 综合压缩系数Ct不区分模式统一读取
listParas << "Ct";
// 调用接口读取参数值
QMap<QString, double> mapPvtValues;
if(!listParas.isEmpty()) {
pCtx->getPvtParaValues(pSubWnd, listParas, mapPvtValues);
}
return mapPvtValues;
}
/// @brief 按相态填充油藏PVT字段和压缩系数
/// @param pRes 油藏数据对象
/// @param eType 相态类型
/// @param mapPvtValues 从界面读取的PVT单值参数
/// @param dCf 岩石压缩系数(来自分层数据)
void populateReservoirByPhase(
nmDataReservoir* pRes,
PvtFluidType eType,
const QMap<QString, double>& mapPvtValues,
double dCf)
{
// 按相态设置多相流类型和对应的B/Miu字段
switch(eType) {
case WFT_Oil:
pRes->setPhaseType(PHASE_Oil);
setReservoirAttr(pRes->getBo(), mapPvtValues.value("Bo", 1.5));
setReservoirAttr(pRes->getMiuo(), mapPvtValues.value("Miuo", 1.0));
break;
case WFT_Gas:
pRes->setPhaseType(PHASE_Gas);
setReservoirAttr(pRes->getBg(), mapPvtValues.value("Bg", 1.0));
setReservoirAttr(pRes->getMiug(), mapPvtValues.value("Miug", 1.0));
break;
case WFT_Water:
pRes->setPhaseType(PHASE_Water);
setReservoirAttr(pRes->getBw(), mapPvtValues.value("Bw", 1.0));
setReservoirAttr(pRes->getMiuw(), mapPvtValues.value("Miuw", 1.0));
break;
case WFT_Oil_Water:
pRes->setPhaseType(PHASE_Oil_Water);
setReservoirAttr(pRes->getBo(), mapPvtValues.value("Bo", 1.5));
setReservoirAttr(pRes->getMiuo(), mapPvtValues.value("Miuo", 1.0));
setReservoirAttr(pRes->getBw(), mapPvtValues.value("Bw", 1.0));
setReservoirAttr(pRes->getMiuw(), mapPvtValues.value("Miuw", 1.0));
break;
default:
pRes->setPhaseType(PHASE_UNKNOWN);
break;
}
// 压缩系数Ct来自PVT参数界面Cf来自分层数据不区分模式统一设置
setReservoirAttr(pRes->getCt(), mapPvtValues.value("Ct", 0.1));
setReservoirAttr(pRes->getCf(), dCf);
}
/// @brief 创建默认分层
/// @param dThickness 储层厚度
/// @param vecLayers 分层数据列表(输出)
void createDefaultLayer(double dThickness, QVector<nmDataLayer*>& vecLayers)
{
// 清空现有分层数据
qDeleteAll(vecLayers);
vecLayers.clear();
// 创建一个默认分层
nmDataLayer* pDefaultLayer = new nmDataLayer();
pDefaultLayer->setTop(6000.0); // 默认顶深
pDefaultLayer->setThickness(dThickness); // 使用从界面获取的厚度值
pDefaultLayer->setBottom(6000.0 + dThickness); // 计算底深
pDefaultLayer->setIsChecked(false); // 默认未选中
pDefaultLayer->setColor(QColor(0, 255, 0)); // 设置默认颜色(绿色)
// 将默认分层添加到分层列表
vecLayers.append(pDefaultLayer);
}
}
ZX_DEFINE_DYNAMIC(DataAnalyzeManager, nmDataAnalyzeManager)
@ -1090,211 +1252,54 @@ void nmDataAnalyzeManager::appendNmWellData(nmDataWellBase* pWellData)
m_vWellData.append(pWellData);
}
/// @brief 创建油藏数据对象从界面读取PVT单值和分层数据构建reservoir对象
void nmDataAnalyzeManager::createReservoir()
{
// 根据当前Fitting窗口来获取对应的井相关数据
// 1. 获取上下文
iSubWndFitting* pSubWndFitting = nmDataAnalyzeManager::getCurrentFitting();
nmDataAnalyzeContextProvider* pContextProvider = nmDataAnalyzeContext::provider();
nmDataAnalyzeContextProvider* pCtx = nmDataAnalyzeContext::provider();
Q_ASSERT(nullptr != pSubWndFitting);
Q_ASSERT(nullptr != pContextProvider);
Q_ASSERT(nullptr != pCtx);
// 定义获取的分层数据
VVecVariant vvecLayerData;
// 定义返回结果的 QMap
QMap<QString, double> mapParaValues;
// 相态类型
PvtFluidType eType = WFT_Null;
pCtx->getBasicPft(pSubWndFitting, eType);
// initPvtParaFromSubFit先根据PVT数据确定求解器类型这里按PEBI算例选择需要覆盖的Base字段
NM_SOLVER_MODEL_TYPE eSolverModelType = getSolverModelType();
bool bNeedCti = false;
bool bNeedCf = false;
switch(eSolverModelType) {
case SMT_Oil_ConstPvt:
case SMT_Water_ConstPvt:
bNeedCti = true;
break;
case SMT_Oil_VariablePvt:
case SMT_Water_VariablePvt:
case SMT_Gas_VariablePvt:
case SMT_Oil_Water_TwoPhase:
bNeedCf = true;
break;
default:
break;
}
if(nullptr != pSubWndFitting && nullptr != pContextProvider) {
// 读取界面选择的PVT相态类型
pContextProvider->getBasicPft(pSubWndFitting, eType);
//QString sMainPft =pSubWndFitting->getBasicMainPft();
//QString sPftDesc = pSubWndFitting->getBasicPftDesc();
// 只读取当前相态存在的PVT页避免PVT工具输出PhaseGas/PhaseWater缺失日志
QStringList listParas;
// 储层基础数据这里只需要体积系数和粘度;不属于当前相态的参数继续走默认值
switch(eType) {
case WFT_Oil:
listParas << "Bo" << "Miuo";
break;
case WFT_Gas:
listParas << "Bg" << "Miug";
break;
case WFT_Water:
listParas << "Bw" << "Miuw";
break;
case WFT_Oil_Water:
listParas << "Bo" << "Miuo" << "Bw" << "Miuw";
break;
default:
break;
}
//油、水单相常数pvt需要Ct
if(bNeedCti) {
listParas << "Ct";
}
if(!listParas.isEmpty()) {
pContextProvider->getPvtParaValues(pSubWndFitting, listParas, mapParaValues);
}
// 读取分层数据
pContextProvider->getBasicDataLayers(pSubWndFitting, vvecLayerData);
}
// 2. 读取PVT单值参数
QMap<QString, double> mapPvtValues = readPvtSingleValues(pCtx, pSubWndFitting, eType);
// 获取油体积系数和油相粘度
double dBo = mapParaValues.value("Bo", 1.5); // 如果键不存在,返回默认值 1.5
double dMiuo = mapParaValues.value("Miuo", 1); // 如果键不存在,返回默认值 1
// 获取气体积系数和气相粘度
double dBg = mapParaValues.value("Bg", 1); // 如果键不存在,返回默认值 1.5
double dMiug = mapParaValues.value("Miug", 1); // 如果键不存在,返回默认值 1
// 获取水体积系数和水相粘度
double dBw = mapParaValues.value("Bw", 1);
double dMiuw = mapParaValues.value("Miuw", 1);
// 获取综合压缩系数
double dCt = mapParaValues.value("Ct", 0.1);
// 获取初始油、气、水饱和度---------王老师那的是临时数据,没法获取
//double dSo = mapParaValues.value("Ko", 1);
//double dSg = mapParaValues.value("Sg", 0);
//double dSw = mapParaValues.value("Sw", 0);
// 3. 读取分层数据,提取储层基础参数
VVecVariant vvecLayerData;
pCtx->getBasicDataLayers(pSubWndFitting, vvecLayerData);
// 检查 vvecLayerData 是否有效,有效重新赋值,无效设置默认值
double dThickness = 10;
double dPorosity = 0.5;
double dCf = 1.00; // 岩石压缩系数
double dCf = 1.0;
double dInitialPre = 30.0;
if(!vvecLayerData.isEmpty() && vvecLayerData[0].size() >= 5) {
dThickness = vvecLayerData[0][1].toDouble();
dPorosity = vvecLayerData[0][2].toDouble();
dCf = vvecLayerData[0][3].toDouble();
dInitialPre = vvecLayerData[0][4].toDouble();
dThickness = vvecLayerData[0][1].toDouble();
dPorosity = vvecLayerData[0][2].toDouble();
dCf = vvecLayerData[0][3].toDouble();
dInitialPre = vvecLayerData[0][4].toDouble();
}
// 判断是否已有油藏参数数据
// 4. 构建油藏对象
if(m_reservoirData != nullptr) {
delete m_reservoirData;
m_reservoirData = nullptr;
}
m_reservoirData = new nmDataReservoir;
nmDataAttribute tempAttr;
// 将界面相态转换为内部储层相态后续再映射为求解器T
if(eType == WFT_Oil) {
m_reservoirData->setPhaseType(PHASE_Oil);
tempAttr = m_reservoirData->getBo();// 油体积系数
tempAttr.setValue(dBo);
m_reservoirData->setBo(tempAttr);
tempAttr = m_reservoirData->getMiuo();// 油相黏度
tempAttr.setValue(dMiuo);
m_reservoirData->setMiuo(tempAttr);
} else if(eType == WFT_Gas) {
m_reservoirData->setPhaseType(PHASE_Gas);
// TODO:这里先使用用一个变量,后续根据需求再进行分类
tempAttr = m_reservoirData->getBo();// 气体积系数
tempAttr.setValue(dBg);
m_reservoirData->setBo(tempAttr);
tempAttr = m_reservoirData->getMiuo();// 气相黏度
tempAttr.setValue(dMiug);
m_reservoirData->setMiuo(tempAttr);
} else if(eType == WFT_Water) {
m_reservoirData->setPhaseType(PHASE_Water);
tempAttr = m_reservoirData->getBo();// 水体积系数
tempAttr.setValue(dBw);
m_reservoirData->setBo(tempAttr);
tempAttr = m_reservoirData->getMiuo();// 水相黏度
tempAttr.setValue(dMiuw);
m_reservoirData->setMiuo(tempAttr);
} else if(eType == WFT_Oil_Water) {
m_reservoirData->setPhaseType(PHASE_Oil_Water);
tempAttr = m_reservoirData->getBo();// 油体积系数
tempAttr.setValue(dBo);
m_reservoirData->setBo(tempAttr);
tempAttr = m_reservoirData->getMiuo();// 油相黏度
tempAttr.setValue(dMiuo);
m_reservoirData->setMiuo(tempAttr);
} else {
m_reservoirData->setPhaseType(PHASE_UNKNOWN);
}
tempAttr = m_reservoirData->getInitialPressure();//初始压力
tempAttr.setValue(dInitialPre);
m_reservoirData->setInitialPressure(tempAttr);
tempAttr = m_reservoirData->getReservoirType();
tempAttr.setValue("Homogeneous");
m_reservoirData->setReservoirType(tempAttr);
tempAttr = m_reservoirData->getThickness();// 储层厚度
tempAttr.setValue(dThickness);
m_reservoirData->setThickness(tempAttr);
tempAttr = m_reservoirData->getCt(); // 综合压缩系数
if(bNeedCti) {
tempAttr.setValue(dCt);
}
m_reservoirData->setCt(tempAttr);
tempAttr = m_reservoirData->getPorosity();// 孔隙度
tempAttr.setValue(dPorosity);
m_reservoirData->setPorosity(tempAttr);
tempAttr = m_reservoirData->getCf();// 岩石压缩系数
// 变化PVT、气单相和油水两相需要Cf值来自基础分层数据
if(bNeedCf) {
tempAttr.setValue(dCf);
}
m_reservoirData->setCf(tempAttr);
// 清空现有分层数据
qDeleteAll(m_vecLayers);
m_vecLayers.clear();
// 创建一个默认分层
nmDataLayer* defaultLayer = new nmDataLayer();
// 按相态填充PVT字段和压缩系数
populateReservoirByPhase(m_reservoirData, eType, mapPvtValues, dCf);
// 设置默认分层参数
defaultLayer->setTop(6000.0); // 默认顶深
defaultLayer->setThickness(dThickness); // 使用从框架获取的厚度值
defaultLayer->setBottom(6000.0 + dThickness); // 计算底深
defaultLayer->setIsChecked(false); // 默认未选中
defaultLayer->setColor(QColor(0, 255, 0)); // 设置默认颜色(绿色)
// 设置基础属性
setReservoirAttr(m_reservoirData->getInitialPressure(), dInitialPre);
setReservoirAttr(m_reservoirData->getReservoirType(), QString("Homogeneous"));
setReservoirAttr(m_reservoirData->getThickness(), dThickness);
setReservoirAttr(m_reservoirData->getPorosity(), dPorosity);
// 将默认分层添加到分层列表
m_vecLayers.append(defaultLayer);
// 5. 创建默认分层
createDefaultLayer(dThickness, m_vecLayers);
}
nmDataAxis* nmDataAnalyzeManager::getAxisData() const
@ -1628,239 +1633,90 @@ void nmDataAnalyzeManager::updateAutomaticFittingData(const nmDataAutomaticFitti
*m_pAutomaticFittingData = newData; // 调用赋值运算符
}
/// @brief 从PVT结果页读取曲线数组确定求解器模型类型
/// 按相态获取PVT数组参数获取不到则回退到常数PVT模型Gas除外弹警告
void nmDataAnalyzeManager::initPvtParaFromSubFit()
{
// 根据当前Fitting窗口来获取对应的井相关数据
// 1. 获取上下文
iSubWndFitting* pSubWndFitting = nmDataAnalyzeManager::getCurrentFitting();
nmDataAnalyzeContextProvider* pContextProvider = nmDataAnalyzeContext::provider();
nmDataAnalyzeContextProvider* pCtx = nmDataAnalyzeContext::provider();
Q_ASSERT(nullptr != pSubWndFitting);
Q_ASSERT(nullptr != pContextProvider);
Q_ASSERT(nullptr != pCtx);
if(nullptr != pSubWndFitting && nullptr != pContextProvider) {
PvtFluidType eType = WFT_Null;
pContextProvider->getBasicPft(pSubWndFitting, eType);
//QVector<double> vecPressure; // 压力, MPa
QVector<double> vecBo; // 油体积系数, m^3/m^3
QVector<double> vecCo; // 油压缩系数, 1/MPa
QVector<double> vecMiuo; // 油粘度, mPa·s
QVector<double> vecBg; // 气体积系数, m^3/m^3
QVector<double> vecCg; // 气压缩系数, 1/MPa
QVector<double> vecMiug; // 气粘度, mPa·s
QVector<double> vecBw; // 水体积系数, m^3/m^3
QVector<double> vecCw; // 水压缩系数, 1/MPa
QVector<double> vecMiuw; // 水粘度, mPa·s
VecDouble vecX;
// 判断是否已有PebiPvt参数数据
if(m_pebiPvtPara != nullptr) {
delete m_pebiPvtPara;
m_pebiPvtPara = nullptr;
}
if(nullptr == pSubWndFitting || nullptr == pCtx) {
return;
}
m_pebiPvtPara = new nmDataPvtParaForPebi;
setSolverModelType(SMT_Oil_ConstPvt);
bool bFetchedBo = false;
bool bFetchedCo = false;
bool bFetchedMiuo = false;
bool bFetchedBg = false;
bool bFetchedCg = false;
bool bFetchedMiug = false;
bool bFetchedBw = false;
bool bFetchedCw = false;
bool bFetchedMiuw = false;
// PVT结果曲线直接按当前相态分支读取任一必要曲线缺失则保留PEBI默认数据
switch(eType) {
case WFT_Oil:
// 单油相需要体积系数、压缩系数和粘度全部可获取
bFetchedBo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Bo", vecX, vecBo);
bFetchedCo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Co", vecX, vecCo);
bFetchedMiuo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil, "Miuo", vecX, vecMiuo);
if(!(bFetchedBo && bFetchedCo && bFetchedMiuo)) {
return;
}
PvtFluidType eType = WFT_Null;
pCtx->getBasicPft(pSubWndFitting, eType);
// 油体积系数
m_pebiPvtPara->setBo(vecBo);
// 2. 清理旧的PVT参数对象新建空对象
if(m_pebiPvtPara != nullptr) {
delete m_pebiPvtPara;
m_pebiPvtPara = nullptr;
}
m_pebiPvtPara = new nmDataPvtParaForPebi;
// 油压缩系数
m_pebiPvtPara->setCo(vecCo);
// 压力横坐标,首次成功读取时赋值
QVector<double> vecPressure;
// 油粘度
m_pebiPvtPara->setMiuo(vecMiuo);
setPebiPressureIfEmpty(m_pebiPvtPara, vecX);
// 3. 按相态分支获取PVT曲线并确定求解器类型
switch(eType) {
case WFT_Oil:
// 油相获取到变量PVT曲线则升级模型否则保持常数PVT
if(tryFetchPhasePvtCurves(pCtx, pSubWndFitting, WFT_Oil,
"Bo", "Co", "Miuo", m_pebiPvtPara, vecPressure)) {
setSolverModelType(SMT_Oil_VariablePvt);
break;
case WFT_Gas:
setSolverModelType(SMT_Gas_VariablePvt);
// 气相缺少任一PVT曲线时提醒用户补齐参数勾选
bFetchedBg = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Bg", vecX, vecBg);
bFetchedCg = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Cg", vecX, vecCg);
bFetchedMiug = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Gas, "Miug", vecX, vecMiug);
if(!(bFetchedBg && bFetchedCg && bFetchedMiug)) {
QMessageBox::warning(nullptr, tr("Warning"), tr("Please select all gas PVT parameters."));
return;
}
// 气体积系数
m_pebiPvtPara->setBg(vecBg);
// 气压缩系数
m_pebiPvtPara->setCg(vecCg);
// 气粘度
m_pebiPvtPara->setMiug(vecMiug);
setPebiPressureIfEmpty(m_pebiPvtPara, vecX);
break;
case WFT_Water:
// 单水相需要体积系数、压缩系数和粘度全部可获取
bFetchedBw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Bw", vecX, vecBw);
bFetchedCw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Cw", vecX, vecCw);
bFetchedMiuw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Water, "Miuw", vecX, vecMiuw);
if(!(bFetchedBw && bFetchedCw && bFetchedMiuw)) {
setSolverModelType(SMT_Water_ConstPvt);
return;
}
// 水体积系数
m_pebiPvtPara->setBw(vecBw);
// 水压缩系数
m_pebiPvtPara->setCw(vecCw);
} else {
setSolverModelType(SMT_Oil_ConstPvt);
}
break;
// 水粘度
m_pebiPvtPara->setMiuw(vecMiuw);
setPebiPressureIfEmpty(m_pebiPvtPara, vecX);
case WFT_Water:
// 水相获取到变量PVT曲线则升级模型否则保持常数PVT
if(tryFetchPhasePvtCurves(pCtx, pSubWndFitting, WFT_Water,
"Bw", "Cw", "Miuw", m_pebiPvtPara, vecPressure)) {
setSolverModelType(SMT_Water_VariablePvt);
break;
case WFT_Oil_Water: {
setSolverModelType(SMT_Oil_Water_TwoPhase);
// 油水两相需要油、水两相体积系数和粘度全部可获取
bFetchedBo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Bo", vecX, vecBo);
bFetchedMiuo = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Miuo", vecX, vecMiuo);
bFetchedBw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Bw", vecX, vecBw);
bFetchedMiuw = pContextProvider->getPvtRstOf(pSubWndFitting, WellFluidType::WFT_Oil_Water, "Miuw", vecX, vecMiuw);
if(!(bFetchedBo && bFetchedMiuo && bFetchedBw && bFetchedMiuw)) {
return;
}
// 油体积系数
m_pebiPvtPara->setBo(vecBo);
// 油粘度
m_pebiPvtPara->setMiuo(vecMiuo);
// 水体积系数
m_pebiPvtPara->setBw(vecBw);
} else {
setSolverModelType(SMT_Water_ConstPvt);
}
break;
// 水粘度
m_pebiPvtPara->setMiuw(vecMiuw);
setPebiPressureIfEmpty(m_pebiPvtPara, vecX);
case WFT_Gas:
// 气相必须获取到全部PVT曲线否则弹警告并返回
setSolverModelType(SMT_Gas_VariablePvt);
if(!tryFetchPhasePvtCurves(pCtx, pSubWndFitting, WFT_Gas,
"Bg", "Cg", "Miug", m_pebiPvtPara, vecPressure)) {
QMessageBox::warning(nullptr, tr("Warning"), tr("Please select all gas PVT parameters."));
return;
}
break;
// Diffusion相关数据来自Diffusion页面只在油水两相时读取
// DSO_KK相渗结果主要用于So/Kro/Sw/Krw
VVecDouble vvecDiffusionKK;
if(pContextProvider->getDiffusionRstOf(pSubWndFitting, DSO_KK, vvecDiffusionKK)) {
applyDiffusionKkToPebiPvt(m_pebiPvtPara, vvecDiffusionKK);
}
break;
case WFT_Oil_Water: {
// 油水两相油、水PVT曲线必须全部获取否则返回
setSolverModelType(SMT_Oil_Water_TwoPhase);
bool bOilOk = tryFetchPhasePvtCurves(pCtx, pSubWndFitting, WFT_Oil_Water,
"Bo", "Co", "Miuo", m_pebiPvtPara, vecPressure);
bool bWaterOk = tryFetchPhasePvtCurves(pCtx, pSubWndFitting, WFT_Oil_Water,
"Bw", "Cw", "Miuw", m_pebiPvtPara, vecPressure);
if(!(bOilOk && bWaterOk)) {
return;
}
default:
break;
// Diffusion相渗数据来自Diffusion页面
VVecDouble vvecDiffusionKK;
if(pCtx->getDiffusionRstOf(pSubWndFitting, DSO_KK, vvecDiffusionKK)) {
applyDiffusionKkToPebiPvt(m_pebiPvtPara, vvecDiffusionKK);
}
break;
}
//// 吸附气量,王老师界面没有,油相暂时不需要
//m_pebiPvtPara->setV(vecV);
//
//// 渗透率比,王老师界面没有,油相暂时不需要
//m_pebiPvtPara->setKKinitial(vecKKinitial);
//// 岩石压缩系数比,王老师界面没有,油相暂时不需要
//m_pebiPvtPara->setCfCfinitial(vecCfCfinitial);
//// 相渗,单相暂时用不到
////QVector< QVector<double> > vvec;
////pSubWndFitting->getDiffusionRstOf(DiffusionSubOption::DSO_KK, vvec);
////QVector<double> vecSw;
////QVector<double> vecKro;
////QVector<double> vecKrw;
//// 遍历 vvec 中的每个子向量
////foreach (const QVector<double>& innerVec , vvec) {
//// // 确保每个子向量确实有3个元素
//// if (innerVec.size() >= 3) {
//// vecSw.append(innerVec[0]); // 第一个元素是 Sw
//// vecKro.append(innerVec[1]); // 第二个元素是 Kro
//// vecKrw.append(innerVec[2]); // 第三个元素是 Krw
//// }
////}
//// 油饱和度
//m_pebiPvtPara->setSo(vecSo);
//// 油相对渗透率
//m_pebiPvtPara->setKro(vecKro);
//// 气饱和度
//m_pebiPvtPara->setSg(vecSg);
//// 气相对渗透率
//m_pebiPvtPara->setKrg(vecKrg);
//// 水饱和度
//m_pebiPvtPara->setSw(vecSw);
//// 水相对渗透率
//m_pebiPvtPara->setKrw(vecKrw);
// 调用 getPvtParaValues 函数获取参数值
//pSubWndFitting->getPvtParaValues(listPvtParas, mapPebiPvtPara);
//m_pebiPvtPara->setZ(mapPebiPvtPara.contains("Zg") ?
// QVector<double>(200, mapPebiPvtPara["Zg"]) :
//QVector<double>(200, 1));
// 下面参数单项流不需要
//m_pebiPvtPara->setRv(mapPebiPvtPara.contains("Rv") ?
// QVector<double>(200, mapPebiPvtPara["Rv"]) :
//QVector<double>(200, 0));
//m_pebiPvtPara->setV(mapPebiPvtPara.contains("V") ?
// QVector<double>(200, mapPebiPvtPara["V"]) :
//QVector<double>(200, 0));
//m_pebiPvtPara->setKKinitial(mapPebiPvtPara.contains("k_kinitial") ?
// QVector<double>(200, mapPebiPvtPara["k_kinitial"]) :
//QVector<double>(200, 1));
//m_pebiPvtPara->setCfCfinitial(mapPebiPvtPara.contains("Cf_Cfinitial") ?
// QVector<double>(200, mapPebiPvtPara["Cf_Cfinitial"]) :
//QVector<double>(200, 1));
//// 饱和度与相对渗透率大小为100
//m_pebiPvtPara->setSo(mapPebiPvtPara.contains("So") ?
//QVector<double>(100, mapPebiPvtPara["So"]) :
//QVector<double>(100, 0));
//m_pebiPvtPara->setKro(mapPebiPvtPara.contains("Kro") ?
// QVector<double>(100, mapPebiPvtPara["Kro"]) :
//QVector<double>(100, 0));
//m_pebiPvtPara->setSg(mapPebiPvtPara.contains("Sg") ?
// QVector<double>(100, mapPebiPvtPara["Sg"]) :
//QVector<double>(100, 0));
//m_pebiPvtPara->setKrg(mapPebiPvtPara.contains("Krg") ?
// QVector<double>(100, mapPebiPvtPara["Krg"]) :
//QVector<double>(100, 0));
//m_pebiPvtPara->setSw(mapPebiPvtPara.contains("Sw") ?
// QVector<double>(100, mapPebiPvtPara["Sw"]) :
//QVector<double>(100, 0));
//m_pebiPvtPara->setKrw(mapPebiPvtPara.contains("Krw") ?
// QVector<double>(100, mapPebiPvtPara["Krw"]) :
//QVector<double>(100, 0));
default:
break;
}
// 4. 统一设置压力横坐标
setPebiPressureIfEmpty(m_pebiPvtPara, vecPressure);
}
nmDataRegionMark *nmDataAnalyzeManager::createRegionMark()

@ -2,17 +2,33 @@
#include "ZxSerializer.h"
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.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());
m_kxKy = nmDataAttribute("Kx/Ky", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_Cf = nmDataAttribute("Cf", 0.0001, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 油相PVT单值
m_Bo = nmDataAttribute("Bo", 1.2, "");
m_Miuo = nmDataAttribute("Miuo", 0.5, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 气相PVT单值
m_Bg = nmDataAttribute("Bg", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_Miug = nmDataAttribute("Miug", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 水相PVT单值
m_Bw = nmDataAttribute("Bw", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_Miuw = nmDataAttribute("Miuw", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 压缩系数
m_Ct = nmDataAttribute("Ct", 0.001, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_Cf = nmDataAttribute("Cf", 0.0001, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 储层类型与传导率
m_reservoirType = nmDataAttribute("Reservoir type", "Homogeneous", "", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Homogeneous" << "Dual porosity pseudo steady state", QStringList());
m_transmissibility = nmDataAttribute("Transmissibility", 1000.0, "md.m", UNIT_TYPE_CONDUCTIVITY, QStringList(), QStringList()<< "md.ft" << "md.m" << "m^3");
// 初始饱和度
m_Soi = nmDataAttribute("Soi", 0.8, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_Sgi = nmDataAttribute("Sgi", 0.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
@ -20,7 +36,6 @@ nmDataReservoir::nmDataReservoir() {
m_dTempGasRe = 100;
m_ePhaseType = PHASE_Oil;
m_transmissibility = nmDataAttribute("Transmissibility", 1000.0, "md.m", UNIT_TYPE_CONDUCTIVITY, QStringList(), QStringList()<< "md.ft" << "md.m" << "m^3");
}
void nmDataReservoir::resetToDefaults()
@ -42,20 +57,34 @@ nmDataReservoir& nmDataReservoir::operator=(const nmDataReservoir& other) {
// 复制所有成员变量
m_initialPressure = other.m_initialPressure;
m_reservoirType = other.m_reservoirType;
m_Bo = other.m_Bo;
m_permeability = other.m_permeability;
m_thickness = other.m_thickness;
m_porosity = other.m_porosity;
m_Ct = other.m_Ct;
m_kxKy = other.m_kxKy;
m_Cf = other.m_Cf;
// 油相PVT单值
m_Bo = other.m_Bo;
m_Miuo = other.m_Miuo;
// 气相PVT单值
m_Bg = other.m_Bg;
m_Miug = other.m_Miug;
// 水相PVT单值
m_Bw = other.m_Bw;
m_Miuw = other.m_Miuw;
// 压缩系数
m_Ct = other.m_Ct;
m_Cf = other.m_Cf;
m_reservoirType = other.m_reservoirType;
m_transmissibility = other.m_transmissibility;
m_Soi = other.m_Soi;
m_Sgi = other.m_Sgi;
m_Swi = other.m_Swi;
m_dTempGasRe = other.m_dTempGasRe;
m_transmissibility = other.m_transmissibility;
m_ePhaseType = other.m_ePhaseType;
}
return *this;
@ -73,19 +102,34 @@ rapidjson::Value nmDataReservoir::ToJsonValue(rapidjson::Document::AllocatorType
// 序列化 nmDataAttribute 类型的成员
// 调用 nmDataAttribute 自身的 ToJsonValue 方法进行递归序列化
reservoirObject.AddMember("InitialPressure", m_initialPressure.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("ReservoirType", m_reservoirType.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Bo", m_Bo.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Permeability", m_permeability.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Thickness", m_thickness.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Porosity", m_porosity.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Ct", m_Ct.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Kx/Ky", m_kxKy.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Cf", m_Cf.ToJsonValue(allocator), allocator);
// 油相PVT单值
reservoirObject.AddMember("Bo", m_Bo.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Miuo", m_Miuo.ToJsonValue(allocator), allocator);
// 气相PVT单值
reservoirObject.AddMember("Bg", m_Bg.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Miug", m_Miug.ToJsonValue(allocator), allocator);
// 水相PVT单值
reservoirObject.AddMember("Bw", m_Bw.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Miuw", m_Miuw.ToJsonValue(allocator), allocator);
// 压缩系数
reservoirObject.AddMember("Ct", m_Ct.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Cf", m_Cf.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("ReservoirType", m_reservoirType.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Transmissibility", m_transmissibility.ToJsonValue(allocator), allocator);
// 初始饱和度
reservoirObject.AddMember("Soi", m_Soi.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Sgi", m_Sgi.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Swi", m_Swi.ToJsonValue(allocator), allocator);
reservoirObject.AddMember("Transmissibility", m_transmissibility.ToJsonValue(allocator), allocator);
return reservoirObject; // 返回序列化后的 RapidJSON Value
}
@ -98,12 +142,6 @@ void nmDataReservoir::FromJsonValue(const rapidjson::Value& jsonValue)
if (jsonValue.HasMember("InitialPressure") && jsonValue["InitialPressure"].IsObject()) {
m_initialPressure.FromJsonValue(jsonValue["InitialPressure"]);
}
if (jsonValue.HasMember("ReservoirType") && jsonValue["ReservoirType"].IsObject()) {
m_reservoirType.FromJsonValue(jsonValue["ReservoirType"]);
}
if (jsonValue.HasMember("Bo") && jsonValue["Bo"].IsObject()) {
m_Bo.FromJsonValue(jsonValue["Bo"]);
}
if (jsonValue.HasMember("Permeability") && jsonValue["Permeability"].IsObject()) {
m_permeability.FromJsonValue(jsonValue["Permeability"]);
}
@ -113,18 +151,50 @@ void nmDataReservoir::FromJsonValue(const rapidjson::Value& jsonValue)
if (jsonValue.HasMember("Porosity") && jsonValue["Porosity"].IsObject()) {
m_porosity.FromJsonValue(jsonValue["Porosity"]);
}
if (jsonValue.HasMember("Ct") && jsonValue["Ct"].IsObject()) {
m_Ct.FromJsonValue(jsonValue["Ct"]);
}
if (jsonValue.HasMember("Kx/Ky") && jsonValue["Kx/Ky"].IsObject()) {
m_kxKy.FromJsonValue(jsonValue["Kx/Ky"]);
}
if (jsonValue.HasMember("Cf") && jsonValue["Cf"].IsObject()) {
m_Cf.FromJsonValue(jsonValue["Cf"]);
// 油相PVT单值
if (jsonValue.HasMember("Bo") && jsonValue["Bo"].IsObject()) {
m_Bo.FromJsonValue(jsonValue["Bo"]);
}
if (jsonValue.HasMember("Miuo") && jsonValue["Miuo"].IsObject()) {
m_Miuo.FromJsonValue(jsonValue["Miuo"]);
}
// 气相PVT单值
if (jsonValue.HasMember("Bg") && jsonValue["Bg"].IsObject()) {
m_Bg.FromJsonValue(jsonValue["Bg"]);
}
if (jsonValue.HasMember("Miug") && jsonValue["Miug"].IsObject()) {
m_Miug.FromJsonValue(jsonValue["Miug"]);
}
// 水相PVT单值
if (jsonValue.HasMember("Bw") && jsonValue["Bw"].IsObject()) {
m_Bw.FromJsonValue(jsonValue["Bw"]);
}
if (jsonValue.HasMember("Miuw") && jsonValue["Miuw"].IsObject()) {
m_Miuw.FromJsonValue(jsonValue["Miuw"]);
}
// 压缩系数
if (jsonValue.HasMember("Ct") && jsonValue["Ct"].IsObject()) {
m_Ct.FromJsonValue(jsonValue["Ct"]);
}
if (jsonValue.HasMember("Cf") && jsonValue["Cf"].IsObject()) {
m_Cf.FromJsonValue(jsonValue["Cf"]);
}
if (jsonValue.HasMember("ReservoirType") && jsonValue["ReservoirType"].IsObject()) {
m_reservoirType.FromJsonValue(jsonValue["ReservoirType"]);
}
if (jsonValue.HasMember("Transmissibility") && jsonValue["Transmissibility"].IsObject()) {
m_transmissibility.FromJsonValue(jsonValue["Transmissibility"]);
}
// 初始饱和度
if (jsonValue.HasMember("Soi") && jsonValue["Soi"].IsObject()) {
m_Soi.FromJsonValue(jsonValue["Soi"]);
}
@ -134,9 +204,6 @@ void nmDataReservoir::FromJsonValue(const rapidjson::Value& jsonValue)
if (jsonValue.HasMember("Swi") && jsonValue["Swi"].IsObject()) {
m_Swi.FromJsonValue(jsonValue["Swi"]);
}
if (jsonValue.HasMember("Transmissibility") && jsonValue["Transmissibility"].IsObject()) {
m_transmissibility.FromJsonValue(jsonValue["Transmissibility"]);
}
}
@ -217,7 +284,9 @@ QIcon nmDataReservoir::getIcon(bool expanded) const {
return zxLoadIcon("Reservoir");
}
// Getters and Setters
// ===== Getters and Setters =====
// 基础属性
void nmDataReservoir::setInitialPressure(const nmDataAttribute& attr) {
m_initialPressure = attr;
}
@ -226,22 +295,6 @@ nmDataAttribute& nmDataReservoir::getInitialPressure() {
return m_initialPressure;
}
void nmDataReservoir::setReservoirType(const nmDataAttribute& attr) {
m_reservoirType = attr;
}
nmDataAttribute& nmDataReservoir::getReservoirType() {
return m_reservoirType;
}
void nmDataReservoir::setBo(const nmDataAttribute& attr) {
m_Bo = attr;
}
nmDataAttribute& nmDataReservoir::getBo() {
return m_Bo;
}
void nmDataReservoir::setPermeability(const nmDataAttribute& attr) {
m_permeability = attr;
}
@ -266,14 +319,6 @@ nmDataAttribute& nmDataReservoir::getPorosity() {
return m_porosity;
}
void nmDataReservoir::setCt(const nmDataAttribute& attr) {
m_Ct = attr;
}
nmDataAttribute& nmDataReservoir::getCt() {
return m_Ct;
}
void nmDataReservoir::setKxKy(const nmDataAttribute& attr) {
m_kxKy = attr;
}
@ -282,12 +327,13 @@ nmDataAttribute& nmDataReservoir::getKxKy() {
return m_kxKy;
}
void nmDataReservoir::setCf(const nmDataAttribute& attr) {
m_Cf = attr;
// 油相PVT单值参数
void nmDataReservoir::setBo(const nmDataAttribute& attr) {
m_Bo = attr;
}
nmDataAttribute& nmDataReservoir::getCf() {
return m_Cf;
nmDataAttribute& nmDataReservoir::getBo() {
return m_Bo;
}
void nmDataReservoir::setMiuo(const nmDataAttribute& attr) {
@ -298,22 +344,64 @@ nmDataAttribute& nmDataReservoir::getMiuo() {
return m_Miuo;
}
// 气藏温度的 getter 和 setter
void nmDataReservoir::setTempGasRe(double temp) {
m_dTempGasRe = temp;
// 气相PVT单值参数
void nmDataReservoir::setBg(const nmDataAttribute& attr) {
m_Bg = attr;
}
double nmDataReservoir::getTempGasRe() const {
return m_dTempGasRe;
nmDataAttribute& nmDataReservoir::getBg() {
return m_Bg;
}
// 多相流类型的 getter 和 setter
void nmDataReservoir::setPhaseType(NM_PHASE_TYPE phaseType) {
m_ePhaseType = phaseType;
void nmDataReservoir::setMiug(const nmDataAttribute& attr) {
m_Miug = attr;
}
NM_PHASE_TYPE nmDataReservoir::getPhaseType() const {
return m_ePhaseType;
nmDataAttribute& nmDataReservoir::getMiug() {
return m_Miug;
}
// 水相PVT单值参数
void nmDataReservoir::setBw(const nmDataAttribute& attr) {
m_Bw = attr;
}
nmDataAttribute& nmDataReservoir::getBw() {
return m_Bw;
}
void nmDataReservoir::setMiuw(const nmDataAttribute& attr) {
m_Miuw = attr;
}
nmDataAttribute& nmDataReservoir::getMiuw() {
return m_Miuw;
}
// 压缩系数
void nmDataReservoir::setCt(const nmDataAttribute& attr) {
m_Ct = attr;
}
nmDataAttribute& nmDataReservoir::getCt() {
return m_Ct;
}
void nmDataReservoir::setCf(const nmDataAttribute& attr) {
m_Cf = attr;
}
nmDataAttribute& nmDataReservoir::getCf() {
return m_Cf;
}
// 储层类型与传导率
void nmDataReservoir::setReservoirType(const nmDataAttribute& attr) {
m_reservoirType = attr;
}
nmDataAttribute& nmDataReservoir::getReservoirType() {
return m_reservoirType;
}
void nmDataReservoir::setTransmissibility(const nmDataAttribute &attr) {
@ -324,6 +412,7 @@ nmDataAttribute& nmDataReservoir::getTransmissibility() {
return m_transmissibility;
}
// 初始饱和度
void nmDataReservoir::setSoi(const nmDataAttribute &attr) {
m_Soi = attr;
}
@ -347,3 +436,21 @@ void nmDataReservoir::setSwi(const nmDataAttribute &attr) {
nmDataAttribute& nmDataReservoir::getSwi() {
return m_Swi;
}
// 气藏温度
void nmDataReservoir::setTempGasRe(double temp) {
m_dTempGasRe = temp;
}
double nmDataReservoir::getTempGasRe() const {
return m_dTempGasRe;
}
// 多相流类型
void nmDataReservoir::setPhaseType(NM_PHASE_TYPE phaseType) {
m_ePhaseType = phaseType;
}
NM_PHASE_TYPE nmDataReservoir::getPhaseType() const {
return m_ePhaseType;
}

Loading…
Cancel
Save