|
|
#include "DatasetIO.h"
|
|
|
|
|
|
// ---------------- public ----------------
|
|
|
|
|
|
bool DatasetIO::fileExists(const std::string& filename)
|
|
|
{
|
|
|
std::ifstream fs(filename.c_str(), std::ios::binary);
|
|
|
return fs.good();
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::saveDataset(const std::string& filename,
|
|
|
const PebiScene& scene,
|
|
|
const HX_NWTM_GRID_INPUT& gridInput,
|
|
|
const HX_NWTM_GRID_OUTPUT2& grid)
|
|
|
{
|
|
|
std::ofstream fs(filename.c_str(), std::ios::binary);
|
|
|
if (!fs) {
|
|
|
std::cerr << "DatasetIO::saveDataset: 无法打开文件: " << filename << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
DatasetHeader hdr;
|
|
|
hdr.magic = (unsigned int)MAGIC;
|
|
|
hdr.version = (unsigned int)VERSION;
|
|
|
hdr.reserved = 0;
|
|
|
hdr.sceneKey = computeSceneKey64(gridInput);
|
|
|
hdr.nCells = (unsigned int)grid.Trinodexy.size();
|
|
|
|
|
|
// 井数:优先用 Rate.t.size(),没有就用 wellName.size()
|
|
|
unsigned int wells = 0;
|
|
|
if (!scene.Rate.t.empty()) wells = (unsigned int)scene.Rate.t.size();
|
|
|
else wells = (unsigned int)scene.wellName.size();
|
|
|
|
|
|
hdr.nWells = wells;
|
|
|
hdr.solverType = scene.solverType;
|
|
|
|
|
|
if (!writeHeader(fs, hdr)) {
|
|
|
std::cerr << "DatasetIO::saveDataset: 写 header 失败\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 写 scene(为了 dataset 自包含)
|
|
|
if (!writeScene(fs, scene)) {
|
|
|
std::cerr << "DatasetIO::saveDataset: 写 scene 失败\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 写 gridOutput2
|
|
|
if (!writeGridOutput2(fs, grid)) {
|
|
|
std::cerr << "DatasetIO::saveDataset: 写 gridOutput2 失败\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return fs.good();
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readDatasetSceneKey(const std::string& filename,
|
|
|
unsigned long long& outSceneKey,
|
|
|
unsigned int& outCells,
|
|
|
unsigned int& outWells,
|
|
|
int& outSolverType)
|
|
|
{
|
|
|
std::ifstream fs(filename.c_str(), std::ios::binary);
|
|
|
if (!fs) return false;
|
|
|
|
|
|
DatasetHeader hdr;
|
|
|
if (!readHeader(fs, hdr)) return false;
|
|
|
if (hdr.magic != (unsigned int)MAGIC) return false;
|
|
|
if (hdr.version != (unsigned int)VERSION) return false;
|
|
|
|
|
|
outSceneKey = hdr.sceneKey;
|
|
|
outCells = hdr.nCells;
|
|
|
outWells = hdr.nWells;
|
|
|
outSolverType = hdr.solverType;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::loadDataset(const std::string& filename,
|
|
|
PebiScene& outScene,
|
|
|
HX_NWTM_GRID_OUTPUT2& outGrid,
|
|
|
bool strictVerify)
|
|
|
{
|
|
|
std::ifstream fs(filename.c_str(), std::ios::binary);
|
|
|
if (!fs) {
|
|
|
std::cerr << "DatasetIO::loadDataset: 无法打开文件: " << filename << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
DatasetHeader hdr;
|
|
|
if (!readHeader(fs, hdr)) {
|
|
|
std::cerr << "DatasetIO::loadDataset: 读 header 失败\n";
|
|
|
return false;
|
|
|
}
|
|
|
if (hdr.magic != (unsigned int)MAGIC) {
|
|
|
std::cerr << "DatasetIO::loadDataset: magic 不匹配\n";
|
|
|
return false;
|
|
|
}
|
|
|
if (hdr.version != (unsigned int)VERSION) {
|
|
|
std::cerr << "DatasetIO::loadDataset: version 不匹配\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (!readScene(fs, outScene)) {
|
|
|
std::cerr << "DatasetIO::loadDataset: 读 scene 失败\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (!readGridOutput2(fs, outGrid)) {
|
|
|
std::cerr << "DatasetIO::loadDataset: 读 gridOutput2 失败\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 快速检查 cell 数
|
|
|
if (hdr.nCells != (unsigned int)outGrid.Trinodexy.size()) {
|
|
|
std::cerr << "DatasetIO::loadDataset: nCells 不匹配,dataset 可能损坏\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 严格校验:用 scene 重建 gridInput 再算一次 sceneKey,对比 header,防止写错/损坏
|
|
|
if (strictVerify) {
|
|
|
HX_NWTM_GRID_INPUT in = buildGridInputFromScene(outScene);
|
|
|
unsigned long long key = computeSceneKey64(in);
|
|
|
if (key != hdr.sceneKey) {
|
|
|
std::cerr << "DatasetIO::loadDataset: sceneKey 校验失败(dataset 内容与 header 不一致)\n";
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return fs.good();
|
|
|
}
|
|
|
|
|
|
// ---------------- header io ----------------
|
|
|
|
|
|
bool DatasetIO::writeHeader(std::ofstream& fs, const DatasetHeader& hdr)
|
|
|
{
|
|
|
if (!writeUInt(fs, hdr.magic)) return false;
|
|
|
if (!writeUInt(fs, hdr.version)) return false;
|
|
|
if (!writeUInt(fs, hdr.reserved)) return false;
|
|
|
if (!writeULL(fs, hdr.sceneKey)) return false;
|
|
|
if (!writeUInt(fs, hdr.nCells)) return false;
|
|
|
if (!writeUInt(fs, hdr.nWells)) return false;
|
|
|
if (!writeInt(fs, hdr.solverType)) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readHeader(std::ifstream& fs, DatasetHeader& hdr)
|
|
|
{
|
|
|
if (!readUInt(fs, hdr.magic)) return false;
|
|
|
if (!readUInt(fs, hdr.version)) return false;
|
|
|
if (!readUInt(fs, hdr.reserved)) return false;
|
|
|
if (!readULL(fs, hdr.sceneKey)) return false;
|
|
|
if (!readUInt(fs, hdr.nCells)) return false;
|
|
|
if (!readUInt(fs, hdr.nWells)) return false;
|
|
|
if (!readInt(fs, hdr.solverType)) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// ---------------- scene -> gridInput ----------------
|
|
|
|
|
|
HX_NWTM_GRID_INPUT DatasetIO::buildGridInputFromScene(const PebiScene& scene)
|
|
|
{
|
|
|
HX_NWTM_GRID_INPUT input;
|
|
|
input.D = scene.D;
|
|
|
input.GridControl = scene.GridControl;
|
|
|
input.Boundary = scene.Boundary;
|
|
|
input.VerticalWell = scene.VerticalWell;
|
|
|
input.HorizontalWell = scene.HorizontalWell;
|
|
|
input.FractureVerticalWell = scene.FractureVerticalWell;
|
|
|
input.MultistageFracturedHorizontalWell = scene.MultistageFracturedHorizontalWell;
|
|
|
input.InclinedWell = scene.InclinedWell;
|
|
|
input.Fault = scene.Fault;
|
|
|
return input;
|
|
|
}
|
|
|
|
|
|
// ---------------- primitive io ----------------
|
|
|
|
|
|
bool DatasetIO::writeUInt(std::ofstream& fs, unsigned int v) { fs.write((const char*)&v, sizeof(v)); return fs.good(); }
|
|
|
bool DatasetIO::writeULL(std::ofstream& fs, unsigned long long v) { fs.write((const char*)&v, sizeof(v)); return fs.good(); }
|
|
|
bool DatasetIO::writeInt(std::ofstream& fs, int v) { fs.write((const char*)&v, sizeof(v)); return fs.good(); }
|
|
|
bool DatasetIO::writeDouble(std::ofstream& fs, double v) { fs.write((const char*)&v, sizeof(v)); return fs.good(); }
|
|
|
|
|
|
bool DatasetIO::readUInt(std::ifstream& fs, unsigned int& v) { fs.read((char*)&v, sizeof(v)); return fs.good(); }
|
|
|
bool DatasetIO::readULL(std::ifstream& fs, unsigned long long& v) { fs.read((char*)&v, sizeof(v)); return fs.good(); }
|
|
|
bool DatasetIO::readInt(std::ifstream& fs, int& v) { fs.read((char*)&v, sizeof(v)); return fs.good(); }
|
|
|
bool DatasetIO::readDouble(std::ifstream& fs, double& v) { fs.read((char*)&v, sizeof(v)); return fs.good(); }
|
|
|
|
|
|
bool DatasetIO::writeSafeSize(std::ofstream& fs, size_t sz)
|
|
|
{
|
|
|
unsigned int u = (unsigned int)sz;
|
|
|
return writeUInt(fs, u);
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readSafeSize(std::ifstream& fs, size_t& sz)
|
|
|
{
|
|
|
unsigned int u = 0;
|
|
|
if (!readUInt(fs, u)) return false;
|
|
|
|
|
|
// 防御:避免异常超大导致内存爆炸
|
|
|
const unsigned int MAX_SIZE = 100000000U;
|
|
|
if (u > MAX_SIZE) return false;
|
|
|
|
|
|
sz = (size_t)u;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// ---------------- string / std::vector IO ----------------
|
|
|
// 说明:dataset.bin 自己定义字符串格式:uint32 字节长度 + raw bytes(UTF-8/ASCII)
|
|
|
// 0xFFFFFFFF 表示 null 字符串
|
|
|
|
|
|
bool DatasetIO::writeString(std::ofstream& fs, const std::string& s)
|
|
|
{
|
|
|
unsigned int len = (unsigned int)s.size();
|
|
|
if (!writeUInt(fs, len)) return false;
|
|
|
if (len > 0) {
|
|
|
fs.write(s.data(), len);
|
|
|
if (!fs.good()) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readString(std::ifstream& fs, std::string& s)
|
|
|
{
|
|
|
unsigned int len = 0;
|
|
|
if (!readUInt(fs, len)) return false;
|
|
|
|
|
|
if (len == 0xFFFFFFFFU) { s.clear(); return true; }
|
|
|
|
|
|
// 防御
|
|
|
const unsigned int MAX_STR = 16 * 1024 * 1024U;
|
|
|
if (len > MAX_STR) return false;
|
|
|
|
|
|
s.assign(len, '\0');
|
|
|
if (len > 0) {
|
|
|
fs.read(&s[0], len);
|
|
|
if (!fs.good()) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeStdVecD(std::ofstream& fs, const std::vector<double>& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
if (!v.empty()) {
|
|
|
fs.write((const char*)&v[0], (std::streamsize)(v.size() * sizeof(double)));
|
|
|
if (!fs.good()) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readStdVecD(std::ifstream& fs, std::vector<double>& v)
|
|
|
{
|
|
|
size_t sz = 0;
|
|
|
if (!readSafeSize(fs, sz)) return false;
|
|
|
v.resize(sz);
|
|
|
if (sz > 0) {
|
|
|
fs.read((char*)&v[0], (std::streamsize)(sz * sizeof(double)));
|
|
|
if (!fs.good()) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeStdVecI(std::ofstream& fs, const std::vector<int>& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
if (!v.empty()) {
|
|
|
fs.write((const char*)&v[0], (std::streamsize)(v.size() * sizeof(int)));
|
|
|
if (!fs.good()) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readStdVecI(std::ifstream& fs, std::vector<int>& v)
|
|
|
{
|
|
|
size_t sz = 0;
|
|
|
if (!readSafeSize(fs, sz)) return false;
|
|
|
v.resize(sz);
|
|
|
if (sz > 0) {
|
|
|
fs.read((char*)&v[0], (std::streamsize)(sz * sizeof(int)));
|
|
|
if (!fs.good()) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeStdVec2D(std::ofstream& fs, const std::vector<std::vector<double> >& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) {
|
|
|
if (!writeStdVecD(fs, v[i])) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readStdVec2D(std::ifstream& fs, std::vector<std::vector<double> >& v)
|
|
|
{
|
|
|
size_t rows = 0;
|
|
|
if (!readSafeSize(fs, rows)) return false;
|
|
|
v.resize(rows);
|
|
|
for (size_t i = 0; i < rows; ++i) {
|
|
|
if (!readStdVecD(fs, v[i])) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeStdVec3D(std::ofstream& fs, const std::vector<std::vector<std::vector<double> > >& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) {
|
|
|
if (!writeStdVec2D(fs, v[i])) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readStdVec3D(std::ifstream& fs, std::vector<std::vector<std::vector<double> > >& v)
|
|
|
{
|
|
|
size_t depth = 0;
|
|
|
if (!readSafeSize(fs, depth)) return false;
|
|
|
v.resize(depth);
|
|
|
for (size_t i = 0; i < depth; ++i) {
|
|
|
if (!readStdVec2D(fs, v[i])) return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// ---------------- scene IO ----------------
|
|
|
|
|
|
bool DatasetIO::writeScene(std::ofstream& fs, const PebiScene& s)
|
|
|
{
|
|
|
// 基本版本
|
|
|
if (!writeInt(fs, s.version)) return false;
|
|
|
|
|
|
// 网格几何
|
|
|
if (!writeInt(fs, s.D)) return false;
|
|
|
if (!writeDouble(fs, s.GridControl)) return false;
|
|
|
if (!writeStdVec2D(fs, s.Boundary)) return false;
|
|
|
if (!writeStdVec2D(fs, s.VerticalWell)) return false;
|
|
|
if (!writeStdVec2D(fs, s.HorizontalWell)) return false;
|
|
|
if (!writeStdVec2D(fs, s.FractureVerticalWell)) return false;
|
|
|
if (!writeStdVec3D(fs, s.MultistageFracturedHorizontalWell)) return false;
|
|
|
if (!writeStdVec2D(fs, s.InclinedWell)) return false;
|
|
|
if (!writeStdVec2D(fs, s.Fault)) return false;
|
|
|
|
|
|
// 井顺序
|
|
|
if (!writeStdVecI(fs, s.wellType)) return false;
|
|
|
|
|
|
// 井名
|
|
|
if (!writeSafeSize(fs, s.wellName.size())) return false;
|
|
|
for (size_t i = 0; i < s.wellName.size(); ++i) {
|
|
|
if (!writeString(fs, s.wellName[i])) return false;
|
|
|
}
|
|
|
|
|
|
// 求解器
|
|
|
if (!writeInt(fs, s.solverType)) return false;
|
|
|
|
|
|
// Rate
|
|
|
// 注意:scene.Rate.t 是 vector<vector<double>>
|
|
|
// 为了兼容,这里存原始数据,不做转换
|
|
|
if (!writeStdVec2D(fs, s.Rate.t)) return false;
|
|
|
if (!writeStdVec2D(fs, s.Rate.qo)) return false;
|
|
|
if (!writeStdVec2D(fs, s.Rate.qg)) return false;
|
|
|
if (!writeStdVec2D(fs, s.Rate.qw)) return false;
|
|
|
|
|
|
// CS
|
|
|
if (!writeStdVecD(fs, s.CS.C)) return false;
|
|
|
if (!writeStdVecD(fs, s.CS.S)) return false;
|
|
|
|
|
|
// 流动段
|
|
|
if (!writeStdVecI(fs, s.wellFlowSectionIndex)) return false;
|
|
|
|
|
|
// PVT
|
|
|
if (!writeStdVecD(fs, s.PVT.p)) return false;
|
|
|
if (!writeDouble(fs, s.PVT.pb)) return false;
|
|
|
|
|
|
if (!writeStdVecD(fs, s.PVT.Rso)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Bo)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Co)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.miuo)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.rouo)) return false;
|
|
|
|
|
|
if (!writeStdVecD(fs, s.PVT.Rv)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Bg)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Cg)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.miug)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.roug)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Z)) return false;
|
|
|
|
|
|
if (!writeStdVecD(fs, s.PVT.Rsw)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Bw)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Cw)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.miuw)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.rouw)) return false;
|
|
|
|
|
|
if (!writeStdVecD(fs, s.PVT.V)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.k_kinitial)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Cf_Cfinitial)) return false;
|
|
|
|
|
|
if (!writeStdVecD(fs, s.PVT.So)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Kro)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Sg)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Krg)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Sw)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.Krw)) return false;
|
|
|
// 只有气单相变化 PVT 的数据集需要附带压力/拟压力转换表。
|
|
|
if (s.solverType == 5) {
|
|
|
if (!writeStdVecD(fs, s.PVT.pseudoPressureP)) return false;
|
|
|
if (!writeStdVecD(fs, s.PVT.pseudoPressurePs)) return false;
|
|
|
}
|
|
|
|
|
|
// Base
|
|
|
if (!writeDouble(fs, s.Base.Pi)) return false;
|
|
|
if (!writeDouble(fs, s.Base.Cti)) return false;
|
|
|
if (!writeDouble(fs, s.Base.Cf)) return false;
|
|
|
if (!writeDouble(fs, s.Base.Soi)) return false;
|
|
|
if (!writeDouble(fs, s.Base.Sgi)) return false;
|
|
|
if (!writeDouble(fs, s.Base.Swi)) return false;
|
|
|
|
|
|
if (!writeDouble(fs, s.Base.d)) return false;
|
|
|
if (!writeDouble(fs, s.Base.dt_Min)) return false;
|
|
|
if (!writeDouble(fs, s.Base.dt_Max)) return false;
|
|
|
|
|
|
if (!writeDouble(fs, s.Base.k_ref)) return false;
|
|
|
if (!writeDouble(fs, s.Base.phi_ref)) return false;
|
|
|
if (!writeDouble(fs, s.Base.h_ref)) return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readScene(std::ifstream& fs, PebiScene& s)
|
|
|
{
|
|
|
if (!readInt(fs, s.version)) return false;
|
|
|
|
|
|
// 网格几何
|
|
|
if (!readInt(fs, s.D)) return false;
|
|
|
if (!readDouble(fs, s.GridControl)) return false;
|
|
|
if (!readStdVec2D(fs, s.Boundary)) return false;
|
|
|
if (!readStdVec2D(fs, s.VerticalWell)) return false;
|
|
|
if (!readStdVec2D(fs, s.HorizontalWell)) return false;
|
|
|
if (!readStdVec2D(fs, s.FractureVerticalWell)) return false;
|
|
|
if (!readStdVec3D(fs, s.MultistageFracturedHorizontalWell)) return false;
|
|
|
if (!readStdVec2D(fs, s.InclinedWell)) return false;
|
|
|
if (!readStdVec2D(fs, s.Fault)) return false;
|
|
|
|
|
|
// 井顺序
|
|
|
if (!readStdVecI(fs, s.wellType)) return false;
|
|
|
|
|
|
// 井名
|
|
|
size_t nName = 0;
|
|
|
if (!readSafeSize(fs, nName)) return false;
|
|
|
s.wellName.resize(nName);
|
|
|
for (size_t i = 0; i < nName; ++i) {
|
|
|
if (!readString(fs, s.wellName[i])) return false;
|
|
|
}
|
|
|
|
|
|
// 求解器
|
|
|
if (!readInt(fs, s.solverType)) return false;
|
|
|
|
|
|
// Rate
|
|
|
if (!readStdVec2D(fs, s.Rate.t)) return false;
|
|
|
if (!readStdVec2D(fs, s.Rate.qo)) return false;
|
|
|
if (!readStdVec2D(fs, s.Rate.qg)) return false;
|
|
|
if (!readStdVec2D(fs, s.Rate.qw)) return false;
|
|
|
|
|
|
// CS
|
|
|
if (!readStdVecD(fs, s.CS.C)) return false;
|
|
|
if (!readStdVecD(fs, s.CS.S)) return false;
|
|
|
|
|
|
// 井流量段索引
|
|
|
if (!readStdVecI(fs, s.wellFlowSectionIndex)) return false;
|
|
|
|
|
|
// PVT
|
|
|
if (!readStdVecD(fs, s.PVT.p)) return false;
|
|
|
if (!readDouble(fs, s.PVT.pb)) return false;
|
|
|
|
|
|
if (!readStdVecD(fs, s.PVT.Rso)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Bo)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Co)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.miuo)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.rouo)) return false;
|
|
|
|
|
|
if (!readStdVecD(fs, s.PVT.Rv)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Bg)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Cg)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.miug)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.roug)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Z)) return false;
|
|
|
|
|
|
if (!readStdVecD(fs, s.PVT.Rsw)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Bw)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Cw)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.miuw)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.rouw)) return false;
|
|
|
|
|
|
if (!readStdVecD(fs, s.PVT.V)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.k_kinitial)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Cf_Cfinitial)) return false;
|
|
|
|
|
|
if (!readStdVecD(fs, s.PVT.So)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Kro)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Sg)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Krg)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Sw)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.Krw)) return false;
|
|
|
// 写入和读取必须使用相同条件,保证后续字段的二进制位置一致。
|
|
|
if (s.solverType == 5) {
|
|
|
if (!readStdVecD(fs, s.PVT.pseudoPressureP)) return false;
|
|
|
if (!readStdVecD(fs, s.PVT.pseudoPressurePs)) return false;
|
|
|
}
|
|
|
|
|
|
// Base
|
|
|
if (!readDouble(fs, s.Base.Pi)) return false;
|
|
|
if (!readDouble(fs, s.Base.Cti)) return false;
|
|
|
if (!readDouble(fs, s.Base.Cf)) return false;
|
|
|
if (!readDouble(fs, s.Base.Soi)) return false;
|
|
|
if (!readDouble(fs, s.Base.Sgi)) return false;
|
|
|
if (!readDouble(fs, s.Base.Swi)) return false;
|
|
|
|
|
|
if (!readDouble(fs, s.Base.d)) return false;
|
|
|
if (!readDouble(fs, s.Base.dt_Min)) return false;
|
|
|
if (!readDouble(fs, s.Base.dt_Max)) return false;
|
|
|
|
|
|
if (!readDouble(fs, s.Base.k_ref)) return false;
|
|
|
if (!readDouble(fs, s.Base.phi_ref)) return false;
|
|
|
if (!readDouble(fs, s.Base.h_ref)) return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// ---------------- gridOutput2 IO ----------------
|
|
|
|
|
|
bool DatasetIO::writeVec1D(std::ofstream& fs, const dVec1& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) if (!writeDouble(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeIVec1D(std::ofstream& fs, const iVec1& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) if (!writeInt(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeVec2D(std::ofstream& fs, const dVec2& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) if (!writeVec1D(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeIVec2D(std::ofstream& fs, const iVec2& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) if (!writeIVec1D(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeVec3D(std::ofstream& fs, const dVec3& v)
|
|
|
{
|
|
|
if (!writeSafeSize(fs, v.size())) return false;
|
|
|
for (size_t i = 0; i < v.size(); ++i) if (!writeVec2D(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readVec1D(std::ifstream& fs, dVec1& v)
|
|
|
{
|
|
|
size_t sz = 0;
|
|
|
if (!readSafeSize(fs, sz)) return false;
|
|
|
v.resize(sz);
|
|
|
for (size_t i = 0; i < sz; ++i) if (!readDouble(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readIVec1D(std::ifstream& fs, iVec1& v)
|
|
|
{
|
|
|
size_t sz = 0;
|
|
|
if (!readSafeSize(fs, sz)) return false;
|
|
|
v.resize(sz);
|
|
|
for (size_t i = 0; i < sz; ++i) if (!readInt(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readVec2D(std::ifstream& fs, dVec2& v)
|
|
|
{
|
|
|
size_t rows = 0;
|
|
|
if (!readSafeSize(fs, rows)) return false;
|
|
|
v.resize(rows);
|
|
|
for (size_t i = 0; i < rows; ++i) if (!readVec1D(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readIVec2D(std::ifstream& fs, iVec2& v)
|
|
|
{
|
|
|
size_t rows = 0;
|
|
|
if (!readSafeSize(fs, rows)) return false;
|
|
|
v.resize(rows);
|
|
|
for (size_t i = 0; i < rows; ++i) if (!readIVec1D(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readVec3D(std::ifstream& fs, dVec3& v)
|
|
|
{
|
|
|
size_t depth = 0;
|
|
|
if (!readSafeSize(fs, depth)) return false;
|
|
|
v.resize(depth);
|
|
|
for (size_t i = 0; i < depth; ++i) if (!readVec2D(fs, v[i])) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::writeGridOutput2(std::ofstream& fs, const HX_NWTM_GRID_OUTPUT2& g)
|
|
|
{
|
|
|
// top
|
|
|
if (!writeVec2D(fs, g.Trinodexy)) return false;
|
|
|
if (!writeVec1D(fs, g.Area)) return false;
|
|
|
if (!writeVec2D(fs, g.D)) return false;
|
|
|
|
|
|
// ZhiJingNeiBianJie
|
|
|
if (!writeInt(fs, g.ZhiJingNeiBianJie.n)) return false;
|
|
|
if (!writeVec2D(fs, g.ZhiJingNeiBianJie.XiLinw)) return false;
|
|
|
if (!writeVec2D(fs, g.ZhiJingNeiBianJie.lw)) return false;
|
|
|
if (!writeVec2D(fs, g.ZhiJingNeiBianJie.dw)) return false;
|
|
|
if (!writeVec1D(fs, g.ZhiJingNeiBianJie.rw)) return false;
|
|
|
if (!writeIVec2D(fs, g.ZhiJingNeiBianJie.inwell)) return false;
|
|
|
if (!writeVec1D(fs, g.ZhiJingNeiBianJie.dwell)) return false;
|
|
|
|
|
|
// LieFengJingNeiBianJie
|
|
|
if (!writeInt(fs, g.LieFengJingNeiBianJie.n)) return false;
|
|
|
if (!writeVec2D(fs, g.LieFengJingNeiBianJie.XiLinf)) return false;
|
|
|
if (!writeVec2D(fs, g.LieFengJingNeiBianJie.lf)) return false;
|
|
|
if (!writeVec2D(fs, g.LieFengJingNeiBianJie.df)) return false;
|
|
|
if (!writeVec1D(fs, g.LieFengJingNeiBianJie.xf)) return false;
|
|
|
if (!writeIVec2D(fs, g.LieFengJingNeiBianJie.infra)) return false;
|
|
|
if (!writeIVec1D(fs, g.LieFengJingNeiBianJie.nf)) return false;
|
|
|
if (!writeIVec1D(fs, g.LieFengJingNeiBianJie.jjf)) return false;
|
|
|
if (!writeIVec1D(fs, g.LieFengJingNeiBianJie.jjfl)) return false;
|
|
|
if (!writeVec1D(fs, g.LieFengJingNeiBianJie.lfcd)) return false;
|
|
|
if (!writeIVec2D(fs, g.LieFengJingNeiBianJie.infra1)) return false;
|
|
|
if (!writeVec2D(fs, g.LieFengJingNeiBianJie.lf1)) return false;
|
|
|
if (!writeVec2D(fs, g.LieFengJingNeiBianJie.df1)) return false;
|
|
|
|
|
|
// DuoJiYaLieShuiPingJingNeiBianJie
|
|
|
if (!writeInt(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.n)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.XiLinh)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.lh)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.dh)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.dsxf)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.inhor)) return false;
|
|
|
if (!writeIVec1D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.nhor)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.areah)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.inhor1)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.nh)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.jjh)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.hfcd)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.jjhl)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.jjh2)) return false;
|
|
|
if (!writeIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.inhor2)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.lh1)) return false;
|
|
|
if (!writeVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.dh1)) return false;
|
|
|
|
|
|
// WaiBianJie
|
|
|
if (!writeInt(fs, g.WaiBianJie.n)) return false;
|
|
|
if (!writeVec2D(fs, g.WaiBianJie.WaiBianh)) return false;
|
|
|
if (!writeVec2D(fs, g.WaiBianJie.WaiBianl)) return false;
|
|
|
if (!writeVec2D(fs, g.WaiBianJie.WaiBiand)) return false;
|
|
|
|
|
|
// NeiBuDuanCeng
|
|
|
if (!writeInt(fs, g.NeiBuDuanCeng.n)) return false;
|
|
|
if (!writeVec2D(fs, g.NeiBuDuanCeng.faultb1)) return false;
|
|
|
if (!writeVec2D(fs, g.NeiBuDuanCeng.faultb2)) return false;
|
|
|
if (!writeVec2D(fs, g.NeiBuDuanCeng.faultl1)) return false;
|
|
|
if (!writeVec2D(fs, g.NeiBuDuanCeng.faultd1)) return false;
|
|
|
|
|
|
// YuChuLiJuZhen
|
|
|
if (!writeIVec1D(fs, g.YuChuLiJuZhen.ia)) return false;
|
|
|
if (!writeIVec1D(fs, g.YuChuLiJuZhen.ja)) return false;
|
|
|
if (!writeIVec2D(fs, g.YuChuLiJuZhen.nzeros)) return false;
|
|
|
if (!writeInt(fs, g.YuChuLiJuZhen.numk)) return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool DatasetIO::readGridOutput2(std::ifstream& fs, HX_NWTM_GRID_OUTPUT2& g)
|
|
|
{
|
|
|
if (!readVec2D(fs, g.Trinodexy)) return false;
|
|
|
if (!readVec1D(fs, g.Area)) return false;
|
|
|
if (!readVec2D(fs, g.D)) return false;
|
|
|
|
|
|
if (!readInt(fs, g.ZhiJingNeiBianJie.n)) return false;
|
|
|
if (!readVec2D(fs, g.ZhiJingNeiBianJie.XiLinw)) return false;
|
|
|
if (!readVec2D(fs, g.ZhiJingNeiBianJie.lw)) return false;
|
|
|
if (!readVec2D(fs, g.ZhiJingNeiBianJie.dw)) return false;
|
|
|
if (!readVec1D(fs, g.ZhiJingNeiBianJie.rw)) return false;
|
|
|
if (!readIVec2D(fs, g.ZhiJingNeiBianJie.inwell)) return false;
|
|
|
if (!readVec1D(fs, g.ZhiJingNeiBianJie.dwell)) return false;
|
|
|
|
|
|
if (!readInt(fs, g.LieFengJingNeiBianJie.n)) return false;
|
|
|
if (!readVec2D(fs, g.LieFengJingNeiBianJie.XiLinf)) return false;
|
|
|
if (!readVec2D(fs, g.LieFengJingNeiBianJie.lf)) return false;
|
|
|
if (!readVec2D(fs, g.LieFengJingNeiBianJie.df)) return false;
|
|
|
if (!readVec1D(fs, g.LieFengJingNeiBianJie.xf)) return false;
|
|
|
if (!readIVec2D(fs, g.LieFengJingNeiBianJie.infra)) return false;
|
|
|
if (!readIVec1D(fs, g.LieFengJingNeiBianJie.nf)) return false;
|
|
|
if (!readIVec1D(fs, g.LieFengJingNeiBianJie.jjf)) return false;
|
|
|
if (!readIVec1D(fs, g.LieFengJingNeiBianJie.jjfl)) return false;
|
|
|
if (!readVec1D(fs, g.LieFengJingNeiBianJie.lfcd)) return false;
|
|
|
if (!readIVec2D(fs, g.LieFengJingNeiBianJie.infra1)) return false;
|
|
|
if (!readVec2D(fs, g.LieFengJingNeiBianJie.lf1)) return false;
|
|
|
if (!readVec2D(fs, g.LieFengJingNeiBianJie.df1)) return false;
|
|
|
|
|
|
if (!readInt(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.n)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.XiLinh)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.lh)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.dh)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.dsxf)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.inhor)) return false;
|
|
|
if (!readIVec1D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.nhor)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.areah)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.inhor1)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.nh)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.jjh)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.hfcd)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.jjhl)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.jjh2)) return false;
|
|
|
if (!readIVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.inhor2)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.lh1)) return false;
|
|
|
if (!readVec2D(fs, g.DuoJiYaLieShuiPingJingNeiBianJie.dh1)) return false;
|
|
|
|
|
|
if (!readInt(fs, g.WaiBianJie.n)) return false;
|
|
|
if (!readVec2D(fs, g.WaiBianJie.WaiBianh)) return false;
|
|
|
if (!readVec2D(fs, g.WaiBianJie.WaiBianl)) return false;
|
|
|
if (!readVec2D(fs, g.WaiBianJie.WaiBiand)) return false;
|
|
|
|
|
|
if (!readInt(fs, g.NeiBuDuanCeng.n)) return false;
|
|
|
if (!readVec2D(fs, g.NeiBuDuanCeng.faultb1)) return false;
|
|
|
if (!readVec2D(fs, g.NeiBuDuanCeng.faultb2)) return false;
|
|
|
if (!readVec2D(fs, g.NeiBuDuanCeng.faultl1)) return false;
|
|
|
if (!readVec2D(fs, g.NeiBuDuanCeng.faultd1)) return false;
|
|
|
|
|
|
if (!readIVec1D(fs, g.YuChuLiJuZhen.ia)) return false;
|
|
|
if (!readIVec1D(fs, g.YuChuLiJuZhen.ja)) return false;
|
|
|
if (!readIVec2D(fs, g.YuChuLiJuZhen.nzeros)) return false;
|
|
|
if (!readInt(fs, g.YuChuLiJuZhen.numk)) return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// ---------------- FNV-1a 64 hash ----------------
|
|
|
|
|
|
unsigned long long DatasetIO::fnv1a64_init()
|
|
|
{
|
|
|
return 14695981039346656037ULL;
|
|
|
}
|
|
|
|
|
|
void DatasetIO::fnv1a64_update(unsigned long long& h, const void* data, size_t len)
|
|
|
{
|
|
|
const unsigned char* p = (const unsigned char*)data;
|
|
|
const unsigned long long prime = 1099511628211ULL;
|
|
|
for (size_t i = 0; i < len; ++i) {
|
|
|
h ^= (unsigned long long)p[i];
|
|
|
h *= prime;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void DatasetIO::hashInt(unsigned long long& h, int v) { fnv1a64_update(h, &v, sizeof(int)); }
|
|
|
void DatasetIO::hashUInt(unsigned long long& h, unsigned int v) { fnv1a64_update(h, &v, sizeof(unsigned int)); }
|
|
|
void DatasetIO::hashDouble(unsigned long long& h, double v) { fnv1a64_update(h, &v, sizeof(double)); }
|
|
|
|
|
|
void DatasetIO::hashVec1D(unsigned long long& h, const dVec1& v)
|
|
|
{
|
|
|
unsigned int sz = (unsigned int)v.size();
|
|
|
hashUInt(h, sz);
|
|
|
for (size_t i = 0; i < v.size(); ++i) hashDouble(h, v[i]);
|
|
|
}
|
|
|
|
|
|
void DatasetIO::hashIVec1D(unsigned long long& h, const iVec1& v)
|
|
|
{
|
|
|
unsigned int sz = (unsigned int)v.size();
|
|
|
hashUInt(h, sz);
|
|
|
for (size_t i = 0; i < v.size(); ++i) hashInt(h, v[i]);
|
|
|
}
|
|
|
|
|
|
void DatasetIO::hashVec2D(unsigned long long& h, const dVec2& v)
|
|
|
{
|
|
|
unsigned int rows = (unsigned int)v.size();
|
|
|
hashUInt(h, rows);
|
|
|
for (size_t i = 0; i < v.size(); ++i) {
|
|
|
unsigned int cols = (unsigned int)v[i].size();
|
|
|
hashUInt(h, cols);
|
|
|
for (size_t j = 0; j < v[i].size(); ++j) hashDouble(h, v[i][j]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void DatasetIO::hashIVec2D(unsigned long long& h, const iVec2& v)
|
|
|
{
|
|
|
unsigned int rows = (unsigned int)v.size();
|
|
|
hashUInt(h, rows);
|
|
|
for (size_t i = 0; i < v.size(); ++i) {
|
|
|
unsigned int cols = (unsigned int)v[i].size();
|
|
|
hashUInt(h, cols);
|
|
|
for (size_t j = 0; j < v[i].size(); ++j) hashInt(h, v[i][j]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void DatasetIO::hashVec3D(unsigned long long& h, const dVec3& v)
|
|
|
{
|
|
|
unsigned int depth = (unsigned int)v.size();
|
|
|
hashUInt(h, depth);
|
|
|
for (size_t i = 0; i < v.size(); ++i) {
|
|
|
hashVec2D(h, v[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
unsigned long long DatasetIO::computeSceneKey64(const HX_NWTM_GRID_INPUT& in)
|
|
|
{
|
|
|
unsigned long long h = fnv1a64_init();
|
|
|
hashInt(h, in.D);
|
|
|
hashDouble(h, in.GridControl);
|
|
|
|
|
|
hashVec2D(h, in.Boundary);
|
|
|
hashVec2D(h, in.VerticalWell);
|
|
|
hashVec2D(h, in.HorizontalWell);
|
|
|
hashVec2D(h, in.FractureVerticalWell);
|
|
|
hashVec3D(h, in.MultistageFracturedHorizontalWell);
|
|
|
hashVec2D(h, in.InclinedWell);
|
|
|
hashVec2D(h, in.Fault);
|
|
|
return h;
|
|
|
}
|