You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Include/nmNum/nmData/nmPebiResultSnapshot.h

374 lines
15 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef NMPEBIRESULTSNAPSHOT_H
#define NMPEBIRESULTSNAPSHOT_H
#include "nmData_global.h"
#include "nmDataNumericalAnalysisCase.h"
#include <QPointF>
#include <QSharedPointer>
#include <QString>
#include <QStringList>
#include <QVector>
#include <vtkSmartPointer.h>
#include <vtkType.h>
class vtkDoubleArray;
class vtkUnstructuredGrid;
class nmPebiResultSnapshotBuilder;
class nmPebiResultSnapshotRenderAdapter;
class nmPebiResultSnapshotSerializer;
/** @brief 一条求解器槽位在最后成功结果中的冻结描述。 */
struct NM_DATA_EXPORT nmPebiResultSolverSlot
{
/** @brief 初始化为未分配的真实井槽位。 */
nmPebiResultSolverSlot();
/** @brief 求解器中的连续槽位下标。 */
int m_nSolverIndex;
/** @brief 槽位是实际井还是手工裂缝。 */
NM_SOLVER_ENTRY_KIND m_eEntryKind;
/** @brief 实际井 UUID手工裂缝槽位必须为空。 */
QString m_sWellInstanceId;
/** @brief 求解时冻结的井编码。 */
QString m_sWellCode;
/** @brief 求解时冻结的井模型类型。 */
NM_WELL_MODEL m_eWellType;
/** @brief 求解时冻结的油井、气井或水井井别。 */
NM_WELL_CATEGORY m_eWellCategory;
};
/** @brief 一口结果井的历史曲线和计算曲线。 */
struct NM_DATA_EXPORT nmPebiResultWellCurves
{
// 二维容器沿用现有绘图数据约定:每个子数组是一条数据序列,
// 同一组曲线内各序列点数必须一致,快照不改变序列含义和单位。
/** @brief 求解时冻结的历史压力曲线数据序列组。 */
QVector<QVector<double> > m_vecHistoryPressure;
/** @brief 求解时冻结的历史双对数曲线数据序列组。 */
QVector<QVector<double> > m_vecHistoryLogLog;
/** @brief 求解时冻结的历史半对数曲线数据序列组。 */
QVector<QVector<double> > m_vecHistorySemiLog;
/** @brief 最后成功求解的压力曲线数据序列组。 */
QVector<QVector<double> > m_vecResultPressure;
/** @brief 最后成功求解的双对数曲线数据序列组。 */
QVector<QVector<double> > m_vecResultLogLog;
/** @brief 最后成功求解的半对数曲线数据序列组。 */
QVector<QVector<double> > m_vecResultSemiLog;
};
/** @brief 一口结果井在求解成功时冻结的完整值数据。 */
struct NM_DATA_EXPORT nmPebiResultWellSnapshot
{
/** @brief 初始化空的结果井元数据。 */
nmPebiResultWellSnapshot();
/** @brief 求解时井对象的稳定 UUID。 */
QString m_sWellInstanceId;
/** @brief 求解时冻结的井编码。 */
QString m_sWellCode;
/** @brief 求解时冻结的井名称。 */
QString m_sWellName;
/** @brief 求解时冻结的井模型类型。 */
NM_WELL_MODEL m_eWellType;
/** @brief 求解时冻结的油井、气井或水井井别。 */
NM_WELL_CATEGORY m_eWellCategory;
/** @brief 求解时冻结的井角色。 */
NM_CASE_WELL_MODE m_eWellMode;
/** @brief 求解时冻结的规范化 Gauge 输入签名。 */
QString m_sGaugeInputSha1;
/** @brief 求解时冻结的公共流动段时长,不包含框架占位行。 */
QVector<double> m_vecFlowDurations;
/** @brief 与公共流动段逐项对应的油相流量。 */
QVector<double> m_vecOilRates;
/** @brief 与公共流动段逐项对应的气相流量。 */
QVector<double> m_vecGasRates;
/** @brief 与公共流动段逐项对应的水相流量。 */
QVector<double> m_vecWaterRates;
/** @brief 历史流量图及旧单相后处理使用的制度参考相。 */
NM_PHASE_TYPE m_eFlowSchedulePhase;
/** @brief 求解时冻结的一基流动段索引。 */
int m_nFlowSectionIndex;
/** @brief 求解时是否启用油相流量。 */
bool m_bUseOilRate;
/** @brief 求解时是否启用气相流量。 */
bool m_bUseGasRate;
/** @brief 求解时是否启用水相流量。 */
bool m_bUseWaterRate;
/** @brief 求解时冻结的井平面位置。 */
QPointF m_oLocation;
/** @brief 求解时是否存在射孔数据。 */
bool m_bHasPerforation;
/** @brief 求解时是否启用表皮参数。 */
bool m_bHasSkin;
/** @brief 求解时是否启用裂缝导流能力参数。 */
bool m_bHasDfc;
/** @brief 求解时井筒半径。 */
double m_dRadius;
/** @brief 求解时井筒储集系数。 */
double m_dWellboreStorage;
/** @brief 求解时表皮系数。 */
double m_dSkin;
/** @brief 求解时裂缝导流能力。 */
double m_dDfc;
/** @brief 求解时冻结的历史曲线和计算曲线。 */
nmPebiResultWellCurves m_oCurves;
};
/** @brief 结果参数页使用的求解时储层参数。 */
struct NM_DATA_EXPORT nmPebiResultReservoirParameters
{
/** @brief 初始化空的储层参数。 */
nmPebiResultReservoirParameters();
/** @brief 初始地层压力 Pi。 */
double m_dInitialPressure;
/** @brief 储层渗透率 K。 */
double m_dPermeability;
/** @brief 储层有效厚度 h。 */
double m_dThickness;
/** @brief 储层孔隙度 phi。 */
double m_dPorosity;
/** @brief 总压缩系数 Cti。 */
double m_dTotalCompressibility;
/** @brief 岩石压缩系数 Cf。 */
double m_dRockCompressibility;
/** @brief 初始含油饱和度 Soi。 */
double m_dOilSaturation;
/** @brief 初始含气饱和度 Sgi。 */
double m_dGasSaturation;
/** @brief 初始含水饱和度 Swi。 */
double m_dWaterSaturation;
};
/** @brief 求解时使用的常量 PVT 和全部变化 PVT 数组。 */
struct NM_DATA_EXPORT nmPebiResultPvtParameters
{
/** @brief 初始化空的 PVT 参数。 */
nmPebiResultPvtParameters();
/** @brief 是否保存了有效泡点压力。 */
bool m_bHasBubblePoint;
/** @brief 求解时泡点压力。 */
double m_dBubblePoint;
/** @brief 求解时常量原油体积系数 Bo。 */
double m_dConstantBo;
/** @brief 求解时常量原油黏度 Miuo。 */
double m_dConstantMiuo;
/** @brief 求解时常量天然气体积系数 Bg。 */
double m_dConstantBg;
/** @brief 求解时常量天然气黏度 Miug。 */
double m_dConstantMiug;
/** @brief 求解时常量地层水体积系数 Bw。 */
double m_dConstantBw;
/** @brief 求解时常量地层水黏度 Miuw。 */
double m_dConstantMiuw;
/** @brief 变化 PVT 的压力采样数组。 */
QVector<double> m_vecPressure;
/** @brief 溶解气油比 Rso 数组。 */
QVector<double> m_vecRso;
/** @brief 原油体积系数 Bo 数组。 */
QVector<double> m_vecBo;
/** @brief 原油压缩系数 Co 数组。 */
QVector<double> m_vecCo;
/** @brief 原油黏度 Miuo 数组。 */
QVector<double> m_vecMiuo;
/** @brief 原油密度 Rouo 数组。 */
QVector<double> m_vecRouo;
/** @brief 挥发油气比 Rv 数组。 */
QVector<double> m_vecRv;
/** @brief 天然气体积系数 Bg 数组。 */
QVector<double> m_vecBg;
/** @brief 天然气压缩系数 Cg 数组。 */
QVector<double> m_vecCg;
/** @brief 天然气黏度 Miug 数组。 */
QVector<double> m_vecMiug;
/** @brief 天然气密度 Roug 数组。 */
QVector<double> m_vecRoug;
/** @brief 天然气偏差因子 Z 数组。 */
QVector<double> m_vecZ;
/** @brief 地层水溶解气比 Rsw 数组。 */
QVector<double> m_vecRsw;
/** @brief 地层水体积系数 Bw 数组。 */
QVector<double> m_vecBw;
/** @brief 地层水压缩系数 Cw 数组。 */
QVector<double> m_vecCw;
/** @brief 地层水黏度 Miuw 数组。 */
QVector<double> m_vecMiuw;
/** @brief 地层水密度 Rouw 数组。 */
QVector<double> m_vecRouw;
/** @brief PVT 原始 V 数组。 */
QVector<double> m_vecV;
/** @brief PVT 原始 KkInitial 数组。 */
QVector<double> m_vecKkInitial;
/** @brief PVT 原始 CfCfInitial 数组。 */
QVector<double> m_vecCfCfInitial;
/** @brief 油相饱和度 So 数组。 */
QVector<double> m_vecSo;
/** @brief 油相相对渗透率 Kro 数组。 */
QVector<double> m_vecKro;
/** @brief 气相饱和度 Sg 数组。 */
QVector<double> m_vecSg;
/** @brief 气相相对渗透率 Krg 数组。 */
QVector<double> m_vecKrg;
/** @brief 水相饱和度 Sw 数组。 */
QVector<double> m_vecSw;
/** @brief 水相相对渗透率 Krw 数组。 */
QVector<double> m_vecKrw;
};
/** @brief 结果页面和追溯所需的求解时设置。 */
struct NM_DATA_EXPORT nmPebiResultSolverSettings
{
/** @brief 初始化空的求解设置。 */
nmPebiResultSolverSettings();
/** @brief 求解时流体模型类型。 */
int m_nSolverModelType;
/** @brief 求解时 PEBI 线性求解器类型。 */
int m_nPebiSolverType;
/** @brief 求解时 OpenMP 线程数。 */
int m_nOmpThreads;
/** @brief 求解时 ILU 预条件复用步数。 */
int m_nIluReuseSteps;
/** @brief 求解时网格控制值。 */
double m_dGridControl;
/** @brief 是否保存了时间步控制设置。 */
bool m_bHasTimeStepSettings;
/** @brief 时间步增长指数。 */
double m_dTimeGrowthExponent;
/** @brief 最小时间步长。 */
double m_dMinDeltaT;
/** @brief 最大时间步长。 */
double m_dMaxDeltaT;
};
/**
* @brief 最后一次成功 PEBI 求解的完整只读结果。
*
* 普通调用方只能读取值类型,或要求快照把结构和压力绑定到调用方拥有的
* VTK 对象,不能取得快照内部 VTK 对象的可写指针。
*/
class NM_DATA_EXPORT nmPebiResultSnapshot
{
public:
/** @brief 释放快照独占的网格、压力帧和冻结结果数据。 */
~nmPebiResultSnapshot();
/** @brief 返回快照 UUID。 */
QString getSnapshotId() const;
/** @brief 返回求解候选使用的网格输入版本。 */
quint64 getGridInputRevision() const;
/** @brief 返回求解候选使用的求解输入版本。 */
quint64 getResultInputRevision() const;
/** @brief 返回快照是否已通过 Builder 的完整校验。 */
bool isComplete() const;
/** @brief 返回完整求解器槽位数量。 */
int getSolverSlotCount() const;
/** @brief 按槽位下标返回只读描述,越界时返回 NULL。 */
const nmPebiResultSolverSlot* getSolverSlotAt(int nIndex) const;
/** @brief 返回快照结果井数量。 */
int getWellCount() const;
/** @brief 按存储下标返回只读结果井,越界时返回 NULL。 */
const nmPebiResultWellSnapshot* getWellAt(int nIndex) const;
/** @brief 按井 UUID 查找只读结果井,不存在时返回 NULL。 */
const nmPebiResultWellSnapshot* findWell(
const QString& sWellInstanceId) const;
/** @brief 返回结果井下拉框使用的有序 UUID 列表。 */
const QStringList& getDisplayWellInstanceIds() const;
/** @brief 判断井 UUID 是否属于可显示结果井列表。 */
bool isDisplayWell(const QString& sWellInstanceId) const;
/** @brief 返回结果基础网格单元数。 */
vtkIdType getResultCellCount() const;
/** @brief 返回压力时间步数量。 */
int getPressureFrameCount() const;
/** @brief 返回指定压力帧的时间,越界时返回 0。 */
double getPressureTimeAt(int nIndex) const;
/** @brief 返回全部压力帧的全局标量范围。 */
bool getScalarRange(double aRange[2]) const;
/** @brief 返回求解时冻结的储层参数。 */
const nmPebiResultReservoirParameters& getReservoirParameters() const;
/** @brief 返回求解时冻结的完整 PVT 参数。 */
const nmPebiResultPvtParameters& getPvtParameters() const;
/** @brief 返回求解时冻结的求解设置。 */
const nmPebiResultSolverSettings& getSolverSettings() const;
private:
struct PressureFrame
{
/** @brief 初始化空压力帧。 */
PressureFrame();
/** @brief 该压力帧对应的求解时间。 */
double m_dTime;
/** @brief 快照规范持有的单分量单元压力数组。 */
vtkSmartPointer<vtkDoubleArray> m_pPressure;
};
/** @brief 仅允许 Builder 创建未完成候选。 */
nmPebiResultSnapshot();
/** @brief 禁止复制,避免无意深拷贝大网格和全部压力帧。 */
nmPebiResultSnapshot(const nmPebiResultSnapshot&);
/** @brief 禁止赋值,避免无意复制大结果载荷。 */
nmPebiResultSnapshot& operator=(const nmPebiResultSnapshot&);
/**
* @brief 只复制拓扑到适配器拥有的渲染网格,不复制快照的 CellData。
* @note VTK 7.1 的 CopyStructure 会共享点和单元拓扑,适配器不得修改它们。
*/
bool copyResultGridStructure(vtkUnstructuredGrid* pTargetGrid) const;
/**
* @brief 将快照压力帧临时共享绑定到适配器的独立渲染网格。
* @note 目标网格会临时持有同一 VTK 数组引用,下游流程不得改写数组。
*/
bool bindPressureFrame(int nIndex,
vtkUnstructuredGrid* pTargetGrid) const;
/** @brief 将一帧压力复制到适配器复用的缓冲数组。 */
bool copyPressureFrame(int nIndex,
vtkDoubleArray* pTargetPressure) const;
private:
// 网格与压力分开保存,避免基础网格通过 CellData 暴露可变压力数组。
/** @brief 快照 UUID。 */
QString m_sSnapshotId;
/** @brief 生成结果时使用的网格输入版本。 */
quint64 m_nGridInputRevision;
/** @brief 生成结果时使用的求解输入版本。 */
quint64 m_nResultInputRevision;
/** @brief 是否已由 Builder 完整校验并封闭。 */
bool m_bComplete;
/** @brief 不含压力 p 数组和活动标量的结果基础网格。 */
vtkSmartPointer<vtkUnstructuredGrid> m_pResultGrid;
/** @brief 按时间严格递增保存的全部压力帧。 */
QVector<PressureFrame> m_vecPressureFrames;
/** @brief 全部压力帧中的全局最小值。 */
double m_dScalarMin;
/** @brief 全部压力帧中的全局最大值。 */
double m_dScalarMax;
/** @brief 完整且连续的求解器槽位顺序。 */
QVector<nmPebiResultSolverSlot> m_vecSolverSlots;
/** @brief 求解时冻结的全部结果井。 */
QVector<nmPebiResultWellSnapshot> m_vecWells;
/** @brief 结果井下拉框使用的有序井 UUID 子集。 */
QStringList m_listDisplayWellInstanceIds;
/** @brief 求解时冻结的储层参数。 */
nmPebiResultReservoirParameters m_oReservoirParameters;
/** @brief 求解时冻结的完整 PVT 参数。 */
nmPebiResultPvtParameters m_oPvtParameters;
/** @brief 求解时冻结的求解设置。 */
nmPebiResultSolverSettings m_oSolverSettings;
// 只有 Builder 和快照序列化器可以在发布前填充私有数据。
friend class nmPebiResultSnapshotBuilder;
friend class nmPebiResultSnapshotRenderAdapter;
friend class nmPebiResultSnapshotSerializer;
};
#endif // NMPEBIRESULTSNAPSHOT_H