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/ML/Training/Training/DatasetIO.cpp

827 lines
28 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.

#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;
}