|
|
|
|
|
#ifndef NMDATABINARYTOOLS_H
|
|
|
|
|
|
#define NMDATABINARYTOOLS_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <QString>
|
|
|
|
|
|
#include <QDataStream>
|
|
|
|
|
|
#include <QFile>
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
#include <QtGlobal>
|
|
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmData_global.h"
|
|
|
|
|
|
|
|
|
|
|
|
class NM_DATA_EXPORT nmDataBinaryTools : public QObject
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
nmDataBinaryTools();
|
|
|
|
|
|
~nmDataBinaryTools();
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 文件操作 =====
|
|
|
|
|
|
static bool openFileForWrite(const QString& filename, QDataStream*& stream, QFile*& file);
|
|
|
|
|
|
static bool openFileForRead(const QString& filename, QDataStream*& stream, QFile*& file);
|
|
|
|
|
|
static void closeFile(QDataStream*& stream, QFile*& file);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 基础数据类型写入 =====
|
|
|
|
|
|
static bool writeInt(QDataStream& stream, int value);
|
|
|
|
|
|
static bool writeDouble(QDataStream& stream, double value);
|
|
|
|
|
|
static bool writeString(QDataStream& stream, const QString& value);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 向量写入 =====
|
|
|
|
|
|
static bool writeVector1D(QDataStream& stream, const std::vector<double>& vec);
|
|
|
|
|
|
static bool writeVector2D(QDataStream& stream, const std::vector<std::vector<double>>& vec);
|
|
|
|
|
|
static bool writeVector3D(QDataStream& stream, const std::vector<std::vector<std::vector<double>>>& vec);
|
|
|
|
|
|
|
|
|
|
|
|
static bool writeVector1DInt(QDataStream& stream, const std::vector<int>& vec);
|
|
|
|
|
|
static bool writeVector2DInt(QDataStream& stream, const std::vector<std::vector<int>>& vec);
|
|
|
|
|
|
|
|
|
|
|
|
static bool writeVector2DChunked(QDataStream& stream,
|
|
|
|
|
|
const std::vector<std::vector<double>>& vec,
|
|
|
|
|
|
int chunkSize = 10000);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 基础数据类型读取 =====
|
|
|
|
|
|
static bool readInt(QDataStream& stream, int& value);
|
|
|
|
|
|
static bool readDouble(QDataStream& stream, double& value);
|
|
|
|
|
|
static bool readString(QDataStream& stream, QString& value);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 向量读取 =====
|
|
|
|
|
|
static bool readVector1D(QDataStream& stream, std::vector<double>& vec);
|
|
|
|
|
|
static bool readVector2D(QDataStream& stream, std::vector<std::vector<double>>& vec);
|
|
|
|
|
|
static bool readVector3D(QDataStream& stream, std::vector<std::vector<std::vector<double>>>& vec);
|
|
|
|
|
|
|
|
|
|
|
|
static bool readVector1DInt(QDataStream& stream, std::vector<int>& vec);
|
|
|
|
|
|
static bool readVector2DInt(QDataStream& stream, std::vector<std::vector<int>>& vec);
|
|
|
|
|
|
|
|
|
|
|
|
static bool readVector2DChunked(QDataStream& stream,
|
|
|
|
|
|
std::vector<std::vector<double>>& vec,
|
|
|
|
|
|
int chunkSize = 10000);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 安全检查和工具方法 =====
|
|
|
|
|
|
static bool writeSafeVectorSize(QDataStream& stream, size_t size);
|
|
|
|
|
|
static bool readSafeVectorSize(QDataStream& stream, size_t& size);
|
|
|
|
|
|
static bool checkStreamStatus(QDataStream& stream);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 错误处理 =====
|
|
|
|
|
|
static QString getLastError();
|
|
|
|
|
|
static void setLastError(const QString& error);
|
|
|
|
|
|
|
|
|
|
|
|
// 场景结构体定义
|
|
|
|
|
|
struct NM_DATA_EXPORT NM_PEBI_SCENE {
|
|
|
|
|
|
int version;
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 网格输入数据 =====
|
|
|
|
|
|
int D;
|
|
|
|
|
|
double GridControl;
|
|
|
|
|
|
std::vector<std::vector<double>> Boundary;
|
|
|
|
|
|
std::vector<std::vector<double>> VerticalWell;
|
|
|
|
|
|
std::vector<std::vector<double>> HorizontalWell;
|
|
|
|
|
|
std::vector<std::vector<double>> FractureVerticalWell;
|
|
|
|
|
|
std::vector<std::vector<std::vector<double>>> MultistageFracturedHorizontalWell;
|
|
|
|
|
|
std::vector<std::vector<double>> InclinedWell;
|
|
|
|
|
|
std::vector<std::vector<double>> Fault;
|
|
|
|
|
|
|
|
|
|
|
|
// 井顺序信息
|
|
|
|
|
|
std::vector<int> wellType;
|
|
|
|
|
|
std::vector<QString> wellName;
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 求解器参数(新增)=====
|
|
|
|
|
|
int solverType; // 1:油单相常数PVT, 2:油单相变化PVT, 5:气单相变化PVT...
|
|
|
|
|
|
|
|
|
|
|
|
// Rate流量数据
|
|
|
|
|
|
struct {
|
|
|
|
|
|
std::vector<std::vector<double>> t; // 时间
|
|
|
|
|
|
std::vector<std::vector<double>> qo; // 油流量
|
|
|
|
|
|
std::vector<std::vector<double>> qg; // 气流量
|
|
|
|
|
|
std::vector<std::vector<double>> qw; // 水流量
|
|
|
|
|
|
} Rate;
|
|
|
|
|
|
|
|
|
|
|
|
// CS井筒参数
|
|
|
|
|
|
struct {
|
|
|
|
|
|
std::vector<double> C; // 井筒储集系数
|
|
|
|
|
|
std::vector<double> S; // 表皮系数
|
|
|
|
|
|
} CS;
|
|
|
|
|
|
|
|
|
|
|
|
// 流动段索引
|
|
|
|
|
|
std::vector<int> wellFlowSectionIndex;
|
|
|
|
|
|
|
|
|
|
|
|
// PVT流体性质数据
|
|
|
|
|
|
struct {
|
|
|
|
|
|
std::vector<double> p; // 压力
|
|
|
|
|
|
double pb; // 饱和压力
|
|
|
|
|
|
std::vector<double> Rso; // 溶解气油比
|
|
|
|
|
|
std::vector<double> Bo; // 油体积系数
|
|
|
|
|
|
std::vector<double> Co; // 油压缩系数
|
|
|
|
|
|
std::vector<double> miuo; // 油粘度
|
|
|
|
|
|
std::vector<double> rouo; // 油密度
|
|
|
|
|
|
std::vector<double> Rv; // 凝析油气比
|
|
|
|
|
|
std::vector<double> Bg; // 气体积系数
|
|
|
|
|
|
std::vector<double> Cg; // 气压缩系数
|
|
|
|
|
|
std::vector<double> miug; // 气粘度
|
|
|
|
|
|
std::vector<double> roug; // 气密度
|
|
|
|
|
|
std::vector<double> Z; // 气偏差因子
|
|
|
|
|
|
std::vector<double> Rsw; // 溶解气水比
|
|
|
|
|
|
std::vector<double> Bw; // 水体积系数
|
|
|
|
|
|
std::vector<double> Cw; // 水压缩系数
|
|
|
|
|
|
std::vector<double> miuw; // 水粘度
|
|
|
|
|
|
std::vector<double> rouw; // 水密度
|
|
|
|
|
|
std::vector<double> V; // 吸附气量
|
|
|
|
|
|
std::vector<double> k_kinitial; // 渗透率比
|
|
|
|
|
|
std::vector<double> Cf_Cfinitial; // 岩石压缩系数比
|
|
|
|
|
|
std::vector<double> So; // 油饱和度
|
|
|
|
|
|
std::vector<double> Kro; // 油相对渗透率
|
|
|
|
|
|
std::vector<double> Sg; // 气饱和度
|
|
|
|
|
|
std::vector<double> Krg; // 气相对渗透率
|
|
|
|
|
|
std::vector<double> Sw; // 水饱和度
|
|
|
|
|
|
std::vector<double> Krw; // 水相对渗透率
|
|
|
|
|
|
} PVT;
|
|
|
|
|
|
|
|
|
|
|
|
// Base储层参数
|
|
|
|
|
|
struct {
|
|
|
|
|
|
double Pi; // 初始压力
|
|
|
|
|
|
double Cti; // 综合压缩系数
|
|
|
|
|
|
double Cf; // 岩石压缩系数
|
|
|
|
|
|
double Soi; // 初始含油饱和度
|
|
|
|
|
|
double Sgi; // 初始含气饱和度
|
|
|
|
|
|
double Swi; // 初始含水饱和度
|
|
|
|
|
|
double d; // 时间增长指数
|
|
|
|
|
|
double dt_Min; // 最小时间间隔
|
|
|
|
|
|
double dt_Max; // 最大时间间隔
|
|
|
|
|
|
// 注意:k, phi, h是每个网格单元一个值,数量太大不保存基准值
|
|
|
|
|
|
// Python采样时根据 Base.k_ref 给所有单元赋相同值
|
|
|
|
|
|
double k_ref; // 渗透率参考值(用于采样)
|
|
|
|
|
|
double phi_ref; // 孔隙度参考值(用于采样)
|
|
|
|
|
|
double h_ref; // 厚度参考值(用于采样)
|
|
|
|
|
|
} Base;
|
|
|
|
|
|
|
|
|
|
|
|
NM_PEBI_SCENE() {
|
|
|
|
|
|
version = 1;
|
|
|
|
|
|
D = 2;
|
|
|
|
|
|
GridControl = 150.0;
|
|
|
|
|
|
solverType = 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化PVT默认值(避免未初始化)
|
|
|
|
|
|
PVT.pb = 40.0;
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化Base默认值
|
|
|
|
|
|
Base.Pi = 40.0;
|
|
|
|
|
|
Base.Cti = 0.001;
|
|
|
|
|
|
Base.Cf = 0.0001;
|
|
|
|
|
|
Base.Soi = 0.8;
|
|
|
|
|
|
Base.Sgi = 0.0;
|
|
|
|
|
|
Base.Swi = 0.2;
|
|
|
|
|
|
Base.d = 1.05;
|
|
|
|
|
|
Base.dt_Min = 0.0025;
|
|
|
|
|
|
Base.dt_Max = 12.5;
|
|
|
|
|
|
Base.k_ref = 1.0;
|
|
|
|
|
|
Base.phi_ref = 0.2;
|
|
|
|
|
|
Base.h_ref = 10.0;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static bool savePebiSceneBin(const QString& filename, const NM_PEBI_SCENE& scene);
|
|
|
|
|
|
static bool loadPebiSceneBin(const QString& filename, NM_PEBI_SCENE& scene);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
static QString s_lastError;
|
|
|
|
|
|
|
|
|
|
|
|
static const size_t MAX_SAFE_SIZE = 100000000; // 1e8
|
|
|
|
|
|
static const int DEFAULT_CHUNK_SIZE = 50000;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif // NMDATABINARYTOOLS_H
|