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/Src/nmNum/nmData/nmDataBinaryTools.cpp

541 lines
18 KiB
C++

#include "nmDataBinaryTools.h"
// 静态成员初始化
QString nmDataBinaryTools::s_lastError = "";
// scene magic: 'NMSC'
static const quint32 NM_SCENE_MAGIC = 0x4E4D5343;
nmDataBinaryTools::nmDataBinaryTools()
{
}
nmDataBinaryTools::~nmDataBinaryTools()
{
}
// ===== 文件操作 =====
bool nmDataBinaryTools::openFileForWrite(const QString& filename, QDataStream*& stream, QFile*& file)
{
file = new QFile(filename);
if(!file->open(QIODevice::WriteOnly)) {
setLastError(QString("Cannot open file for writing: %1").arg(filename));
delete file;
file = NULL;
return false;
}
stream = new QDataStream(file);
stream->setByteOrder(QDataStream::LittleEndian);
stream->setVersion(QDataStream::Qt_4_8);
return true;
}
bool nmDataBinaryTools::openFileForRead(const QString& filename, QDataStream*& stream, QFile*& file)
{
file = new QFile(filename);
if(!file->open(QIODevice::ReadOnly)) {
setLastError(QString("Cannot open file for reading: %1").arg(filename));
delete file;
file = NULL;
return false;
}
stream = new QDataStream(file);
stream->setByteOrder(QDataStream::LittleEndian);
stream->setVersion(QDataStream::Qt_4_8);
return true;
}
void nmDataBinaryTools::closeFile(QDataStream*& stream, QFile*& file)
{
if(stream) {
delete stream;
stream = NULL;
}
if(file) {
file->close();
delete file;
file = NULL;
}
}
// ===== 基础数据类型写入 =====
bool nmDataBinaryTools::writeInt(QDataStream& stream, int value)
{
stream << static_cast<qint32>(value);
return checkStreamStatus(stream);
}
bool nmDataBinaryTools::writeDouble(QDataStream& stream, double value)
{
stream << value;
return checkStreamStatus(stream);
}
bool nmDataBinaryTools::writeString(QDataStream& stream, const QString& value)
{
stream << value;
return checkStreamStatus(stream);
}
// ===== 向量写入 =====
bool nmDataBinaryTools::writeVector1D(QDataStream& stream, const std::vector<double>& vec)
{
if(!writeSafeVectorSize(stream, vec.size())) return false;
for(size_t i = 0; i < vec.size(); ++i) {
if(!writeDouble(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::writeVector2D(QDataStream& stream, const std::vector<std::vector<double>>& vec)
{
if(!writeSafeVectorSize(stream, vec.size())) return false;
for(size_t i = 0; i < vec.size(); ++i) {
if(!writeVector1D(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::writeVector3D(QDataStream& stream, const std::vector<std::vector<std::vector<double>>>& vec)
{
if(!writeSafeVectorSize(stream, vec.size())) return false;
for(size_t i = 0; i < vec.size(); ++i) {
if(!writeVector2D(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::writeVector1DInt(QDataStream& stream, const std::vector<int>& vec)
{
if(!writeSafeVectorSize(stream, vec.size())) return false;
for(size_t i = 0; i < vec.size(); ++i) {
if(!writeInt(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::writeVector2DInt(QDataStream& stream, const std::vector<std::vector<int>>& vec)
{
if(!writeSafeVectorSize(stream, vec.size())) return false;
for(size_t i = 0; i < vec.size(); ++i) {
if(!writeVector1DInt(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::writeVector2DChunked(QDataStream& stream,
const std::vector<std::vector<double>>& vec,
int chunkSize)
{
qDebug() << "Writing large 2D vector with chunking. Size:" << (quint64)vec.size();
if(!writeSafeVectorSize(stream, vec.size())) return false;
for(size_t i = 0; i < vec.size(); i += (size_t)chunkSize) {
size_t endIdx = qMin(i + (size_t)chunkSize, vec.size());
for(size_t j = i; j < endIdx; ++j) {
if(!writeVector1D(stream, vec[j])) return false;
}
if(chunkSize > 0 && (i % (size_t)(chunkSize * 10) == 0)) {
qDebug() << "Chunked write progress:" << (quint64)i << "/" << (quint64)vec.size();
}
}
qDebug() << "Chunked write completed";
return true;
}
// ===== 基础数据类型读取 =====
bool nmDataBinaryTools::readInt(QDataStream& stream, int& value)
{
qint32 qvalue;
stream >> qvalue;
value = static_cast<int>(qvalue);
return checkStreamStatus(stream);
}
bool nmDataBinaryTools::readDouble(QDataStream& stream, double& value)
{
stream >> value;
return checkStreamStatus(stream);
}
bool nmDataBinaryTools::readString(QDataStream& stream, QString& value)
{
stream >> value;
return checkStreamStatus(stream);
}
// ===== 向量读取 =====
bool nmDataBinaryTools::readVector1D(QDataStream& stream, std::vector<double>& vec)
{
size_t size;
if(!readSafeVectorSize(stream, size)) return false;
vec.resize(size);
for(size_t i = 0; i < vec.size(); ++i) {
if(!readDouble(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::readVector2D(QDataStream& stream, std::vector<std::vector<double>>& vec)
{
size_t size;
if(!readSafeVectorSize(stream, size)) return false;
vec.resize(size);
for(size_t i = 0; i < vec.size(); ++i) {
if(!readVector1D(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::readVector3D(QDataStream& stream, std::vector<std::vector<std::vector<double>>>& vec)
{
size_t size;
if(!readSafeVectorSize(stream, size)) return false;
vec.resize(size);
for(size_t i = 0; i < vec.size(); ++i) {
if(!readVector2D(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::readVector1DInt(QDataStream& stream, std::vector<int>& vec)
{
size_t size;
if(!readSafeVectorSize(stream, size)) return false;
vec.resize(size);
for(size_t i = 0; i < vec.size(); ++i) {
if(!readInt(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::readVector2DInt(QDataStream& stream, std::vector<std::vector<int>>& vec)
{
size_t size;
if(!readSafeVectorSize(stream, size)) return false;
vec.resize(size);
for(size_t i = 0; i < vec.size(); ++i) {
if(!readVector1DInt(stream, vec[i])) return false;
}
return true;
}
bool nmDataBinaryTools::readVector2DChunked(QDataStream& stream,
std::vector<std::vector<double>>& vec,
int chunkSize)
{
size_t size;
if(!readSafeVectorSize(stream, size)) return false;
qDebug() << "Reading chunked 2D vector with" << (quint64)size << "elements";
vec.resize(size);
for(size_t i = 0; i < vec.size(); i += (size_t)chunkSize) {
size_t endIdx = qMin(i + (size_t)chunkSize, vec.size());
for(size_t j = i; j < endIdx; ++j) {
if(!readVector1D(stream, vec[j])) return false;
}
if(chunkSize > 0 && (i % (size_t)(chunkSize * 10) == 0)) {
qDebug() << "Chunked read progress:" << (quint64)i << "/" << (quint64)vec.size();
}
}
qDebug() << "Chunked read completed";
return true;
}
// ===== 安全检查和工具方法 =====
bool nmDataBinaryTools::writeSafeVectorSize(QDataStream& stream, size_t size)
{
if(size > MAX_SAFE_SIZE) {
setLastError(QString("Vector size too large: %1 (max: %2)")
.arg((quint64)size).arg((quint64)MAX_SAFE_SIZE));
return false;
}
stream << static_cast<quint32>(size);
return checkStreamStatus(stream);
}
bool nmDataBinaryTools::readSafeVectorSize(QDataStream& stream, size_t& size)
{
quint32 qsize = 0;
stream >> qsize;
if(!checkStreamStatus(stream)) {
setLastError("Failed to read vector size from stream");
return false;
}
if(qsize > MAX_SAFE_SIZE) {
setLastError(QString("Vector size too large: %1 (max: %2)")
.arg(qsize).arg((quint64)MAX_SAFE_SIZE));
return false;
}
size = static_cast<size_t>(qsize);
return true;
}
bool nmDataBinaryTools::checkStreamStatus(QDataStream& stream)
{
if(stream.status() != QDataStream::Ok) {
switch(stream.status()) {
case QDataStream::ReadPastEnd:
setLastError("Stream read past end");
break;
case QDataStream::ReadCorruptData:
setLastError("Stream read corrupt data");
break;
default:
setLastError("Stream error");
break;
}
return false;
}
return true;
}
// ===== 错误处理 =====
QString nmDataBinaryTools::getLastError()
{
return s_lastError;
}
void nmDataBinaryTools::setLastError(const QString& error)
{
s_lastError = error;
qDebug() << "Binary tools error:" << error;
}
bool nmDataBinaryTools::savePebiSceneBin(const QString& filename, const NM_PEBI_SCENE& s)
{
QDataStream* ds = NULL;
QFile* file = NULL;
if(!openFileForWrite(filename, ds, file)) return false;
// Magic + Version
(*ds) << static_cast<quint32>(0x4E4D5343); // 'NMSC'
if(!writeInt(*ds, s.version)) { closeFile(ds,file); return false; }
// ===== 网格基础数据 =====
if(!writeInt(*ds, s.D)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.GridControl)) { closeFile(ds,file); return false; }
// 几何数据
if(!writeVector2D(*ds, s.Boundary)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.VerticalWell)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.HorizontalWell)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.FractureVerticalWell)) { closeFile(ds,file); return false; }
if(!writeVector3D(*ds, s.MultistageFracturedHorizontalWell)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.InclinedWell)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.Fault)) { closeFile(ds,file); return false; }
// 井顺序
if(!writeSafeVectorSize(*ds, s.wellType.size())) { closeFile(ds,file); return false; }
for(size_t i=0; i<s.wellType.size(); ++i){
if(!writeInt(*ds, s.wellType[i])) { closeFile(ds,file); return false; }
}
if(!writeSafeVectorSize(*ds, s.wellName.size())) { closeFile(ds,file); return false; }
for(size_t i=0; i<s.wellName.size(); ++i){
if(!writeString(*ds, s.wellName[i])) { closeFile(ds,file); return false; }
}
// ===== 求解器参数 =====
if(!writeInt(*ds, s.solverType)) { closeFile(ds,file); return false; }
// Rate数据
if(!writeVector2D(*ds, s.Rate.t)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.Rate.qo)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.Rate.qg)) { closeFile(ds,file); return false; }
if(!writeVector2D(*ds, s.Rate.qw)) { closeFile(ds,file); return false; }
// CS数据
if(!writeVector1D(*ds, s.CS.C)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.CS.S)) { closeFile(ds,file); return false; }
// 流动段索引
if(!writeVector1DInt(*ds, s.wellFlowSectionIndex)) { closeFile(ds,file); return false; }
// PVT数据
if(!writeVector1D(*ds, s.PVT.p)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.PVT.pb)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Rso)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Bo)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Co)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.miuo)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.rouo)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Rv)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Bg)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Cg)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.miug)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.roug)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Z)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Rsw)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Bw)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Cw)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.miuw)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.rouw)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.V)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.k_kinitial)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Cf_Cfinitial)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.So)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Kro)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Sg)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Krg)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Sw)) { closeFile(ds,file); return false; }
if(!writeVector1D(*ds, s.PVT.Krw)) { closeFile(ds,file); return false; }
// Base数据
if(!writeDouble(*ds, s.Base.Pi)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.Cti)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.Cf)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.Soi)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.Sgi)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.Swi)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.d)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.dt_Min)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.dt_Max)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.k_ref)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.phi_ref)) { closeFile(ds,file); return false; }
if(!writeDouble(*ds, s.Base.h_ref)) { closeFile(ds,file); return false; }
closeFile(ds, file);
return true;
}
bool nmDataBinaryTools::loadPebiSceneBin(const QString& filename, NM_PEBI_SCENE& s)
{
QDataStream* ds = NULL;
QFile* file = NULL;
if(!openFileForRead(filename, ds, file)) return false;
// Magic + Version
quint32 magic = 0;
(*ds) >> magic;
if(!checkStreamStatus(*ds) || magic != 0x4E4D5343) {
setLastError("Scene magic mismatch or corrupt file.");
closeFile(ds,file);
return false;
}
if(!readInt(*ds, s.version)) { closeFile(ds,file); return false; }
// ===== 网格基础数据 =====
if(!readInt(*ds, s.D)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.GridControl)) { closeFile(ds,file); return false; }
// 几何数据
if(!readVector2D(*ds, s.Boundary)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.VerticalWell)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.HorizontalWell)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.FractureVerticalWell)) { closeFile(ds,file); return false; }
if(!readVector3D(*ds, s.MultistageFracturedHorizontalWell)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.InclinedWell)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.Fault)) { closeFile(ds,file); return false; }
// 井顺序
size_t nType = 0;
if(!readSafeVectorSize(*ds, nType)) { closeFile(ds,file); return false; }
s.wellType.resize(nType);
for(size_t i=0; i<nType; ++i){
if(!readInt(*ds, s.wellType[i])) { closeFile(ds,file); return false; }
}
size_t nName = 0;
if(!readSafeVectorSize(*ds, nName)) { closeFile(ds,file); return false; }
s.wellName.resize(nName);
for(size_t i=0; i<nName; ++i){
if(!readString(*ds, s.wellName[i])) { closeFile(ds,file); return false; }
}
// ===== 求解器参数 =====
if(!readInt(*ds, s.solverType)) { closeFile(ds,file); return false; }
// Rate数据
if(!readVector2D(*ds, s.Rate.t)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.Rate.qo)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.Rate.qg)) { closeFile(ds,file); return false; }
if(!readVector2D(*ds, s.Rate.qw)) { closeFile(ds,file); return false; }
// CS数据
if(!readVector1D(*ds, s.CS.C)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.CS.S)) { closeFile(ds,file); return false; }
// 流量段索引
if(!readVector1DInt(*ds, s.wellFlowSectionIndex)) { closeFile(ds,file); return false; }
// PVT数据
if(!readVector1D(*ds, s.PVT.p)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.PVT.pb)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Rso)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Bo)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Co)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.miuo)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.rouo)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Rv)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Bg)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Cg)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.miug)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.roug)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Z)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Rsw)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Bw)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Cw)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.miuw)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.rouw)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.V)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.k_kinitial)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Cf_Cfinitial)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.So)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Kro)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Sg)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Krg)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Sw)) { closeFile(ds,file); return false; }
if(!readVector1D(*ds, s.PVT.Krw)) { closeFile(ds,file); return false; }
// Base数据
if(!readDouble(*ds, s.Base.Pi)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.Cti)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.Cf)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.Soi)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.Sgi)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.Swi)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.d)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.dt_Min)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.dt_Max)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.k_ref)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.phi_ref)) { closeFile(ds,file); return false; }
if(!readDouble(*ds, s.Base.h_ref)) { closeFile(ds,file); return false; }
closeFile(ds, file);
return true;
}