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

350 lines
14 KiB
C

#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 一口结果井的历史曲线和计算曲线。 */
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_CASE_WELL_MODE m_eWellMode;
/** @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 和后续 v3 序列化器可以在发布前填充私有数据。
friend class nmPebiResultSnapshotBuilder;
friend class nmPebiResultSnapshotRenderAdapter;
friend class nmPebiResultSnapshotSerializer;
};
#endif // NMPEBIRESULTSNAPSHOT_H