分相态导出数据

feature/Model-20260625
lvjunjie 2 weeks ago
parent c64dc6ce88
commit 8c90dffadd

@ -28,6 +28,43 @@ static std::string getExeDir()
return path;
}
static std::string getParentDir(const std::string& path)
{
size_t pos = path.find_last_of("\\/");
return (pos == std::string::npos ? std::string(".") : path.substr(0, pos));
}
static std::string getFileStem(const std::string& path)
{
size_t slash = path.find_last_of("\\/");
size_t begin = (slash == std::string::npos ? 0 : slash + 1);
size_t dot = path.find_last_of('.');
if (dot == std::string::npos || dot < begin) {
dot = path.size();
}
return path.substr(begin, dot - begin);
}
static std::string joinPath(const std::string& dir, const std::string& filename)
{
if (dir.empty() || dir == ".") {
return filename;
}
char last = dir[dir.size() - 1];
return dir + (last == '\\' || last == '/' ? "" : "\\") + filename;
}
static std::string deriveSceneSiblingPath(const std::string& scenePath, const std::string& prefix)
{
std::string stem = getFileStem(scenePath);
std::string suffix;
if (stem.size() > 6 && stem.compare(0, 6, "scene_") == 0) {
suffix = stem.substr(6);
}
std::string filename = prefix + (suffix.empty() ? "" : "_" + suffix) + ".bin";
return joinPath(getParentDir(scenePath), filename);
}
// 从 scene 重建 GRID 输入(与之前一致)
static HX_NWTM_GRID_INPUT rebuildGridInput(const PebiScene& scene)
{
@ -133,9 +170,13 @@ static void printInputSummary(const PebiScene& scene)
<< std::endl;
}
int main()
int main(int argc, char* argv[])
{
std::cout << "=== PEBI Scene Processor (Dataset First) ===" << std::endl;
if (argc > 4) {
std::cerr << "Usage: training.exe [scene.bin] [dataset.bin] [grid_cache.bin]" << std::endl;
return 1;
}
// 按需开关:发布版保持 true因为 dataset 是后续批量采样的核心)
const bool ENABLE_DATASET_FIRST = true;
@ -153,9 +194,13 @@ int main()
//std::string datasetPath = dataDir + "\\dataset.bin";
//std::string gridCachePath= dataDir + "\\grid_cache.bin";
std::string dataDir = exeDir + "\\..\\..\\nmWTAI-ML\\data\\temp";
std::string scenePath = dataDir + "\\scene.bin";
std::string datasetPath = dataDir + "\\dataset.bin";
std::string gridCachePath= dataDir + "\\grid_cache.bin";
std::string scenePath = (argc >= 2 ? argv[1] : dataDir + "\\scene.bin");
std::string datasetPath = (argc >= 3 ? argv[2] : deriveSceneSiblingPath(scenePath, "dataset"));
std::string gridCachePath = (argc >= 4 ? argv[3] : deriveSceneSiblingPath(scenePath, "grid_cache"));
std::cout << "Scene: " << scenePath << std::endl;
std::cout << "Dataset: " << datasetPath << std::endl;
std::cout << "Grid cache: " << gridCachePath << std::endl;
// 1) 加载 DLL
HMODULE hx = LoadLibraryW(L"HX_NWTM.dll");
@ -181,7 +226,7 @@ int main()
}
std::cout << "License OK: " << lic << std::endl;
// 3) dataset 优先尝试(但如果 scene.bin 存在,会做 sceneKey 串场景校验)
// 3) dataset 优先尝试(但如果对应 scene 存在,会做 sceneKey 串场景校验)
PebiScene scene;
HX_NWTM_GRID_OUTPUT2 gridOutput2;
bool gotFromDataset = false;
@ -197,11 +242,11 @@ int main()
bool headerOK = DatasetIO::readDatasetSceneKey(datasetPath, dsKey, dsCells, dsWells, dsSolver);
// 如果 scene.bin 存在我们就顺便做一次“串场景保护”sceneKey 不匹配就不用 dataset
// 如果对应 scene 存在我们就顺便做一次“串场景保护”sceneKey 不匹配就不用 dataset
bool sceneKeyMatch = true;
if (headerOK && DatasetIO::fileExists(scenePath)) {
std::cout << "\n加载 scene.bin仅用于串场景校验..." << std::endl;
std::cout << "\n加载 scene(仅用于串场景校验): " << scenePath << std::endl;
if (SceneIO::loadScene(scenePath, scene)) {
HX_NWTM_GRID_INPUT gi = rebuildGridInput(scene);
unsigned long long expected = DatasetIO::computeSceneKey64(gi);
@ -210,7 +255,7 @@ int main()
std::cout << "dataset sceneKey 不匹配(串场景保护触发),忽略 dataset准备重建..." << std::endl;
}
} else {
std::cout << "scene.bin 加载失败,跳过串场景校验,直接尝试 dataset 自检..." << std::endl;
std::cout << "scene 加载失败,跳过串场景校验,直接尝试 dataset 自检..." << std::endl;
sceneKeyMatch = true;
}
}
@ -233,17 +278,17 @@ int main()
}
}
// 4) 如果没有拿到 dataset就走 scene.bin + grid_cache.bin(带串场景保护)
// 4) 如果没有拿到 dataset就走 scene + grid_cache带串场景保护
if (!gotFromDataset) {
std::cout << "\n加载 scene.bin..." << std::endl;
std::cout << "\n加载 scene: " << scenePath << std::endl;
if (!SceneIO::loadScene(scenePath, scene)) {
std::cerr << "scene.bin 读取失败: " << scenePath << std::endl;
std::cerr << "scene 读取失败: " << scenePath << std::endl;
FreeLibrary(hx);
return 4;
}
// 输入摘要:帮助你定位 “为什么 steps 变了”
std::cout << "scene.bin 读取成功Wells=" << (unsigned int)scene.wellName.size()
std::cout << "scene 读取成功Wells=" << (unsigned int)scene.wellName.size()
<< ", PVT点=" << (unsigned int)scene.PVT.p.size()
<< ", Solver=" << scene.solverType << std::endl;
printInputSummary(scene);

@ -30,6 +30,114 @@
#include <vtkType.h>
#include <vtkUnsignedCharArray.h>
namespace {
const int CONST_PVT_POINT_COUNT = 200;
std::vector<double> buildConstantPvtVector(double value)
{
return std::vector<double>(CONST_PVT_POINT_COUNT, value);
}
std::vector<double> buildConstantPvtPressure()
{
std::vector<double> pressure(CONST_PVT_POINT_COUNT, 0.0);
for(int i = 0; i < CONST_PVT_POINT_COUNT; ++i) {
pressure[i] = i + 1.0;
}
return pressure;
}
QString solverModelFileTag(NM_SOLVER_MODEL_TYPE modelType)
{
switch(modelType) {
case SMT_Oil_ConstPvt:
return "T1_oil_const_pvt";
case SMT_Oil_VariablePvt:
return "T2_oil_variable_pvt";
case SMT_Water_ConstPvt:
return "T3_water_const_pvt";
case SMT_Water_VariablePvt:
return "T4_water_variable_pvt";
case SMT_Gas_VariablePvt:
return "T5_gas_variable_pvt";
case SMT_Oil_Water_TwoPhase:
return "T8_oil_water_two_phase";
default:
return QString("T%1_unsupported").arg(static_cast<int>(modelType));
}
}
void fillScenePvtByModel(nmDataBinaryTools::NM_PEBI_SCENE& scene,
NM_SOLVER_MODEL_TYPE modelType,
nmDataPvtParaForPebi* pvt,
nmDataReservoir* reservoir)
{
switch(modelType) {
case SMT_Oil_ConstPvt:
scene.PVT.p = buildConstantPvtPressure();
if(reservoir != nullptr) {
scene.PVT.Bo = buildConstantPvtVector(reservoir->getBo().getValue().toDouble());
scene.PVT.miuo = buildConstantPvtVector(reservoir->getMiuo().getValue().toDouble());
}
break;
case SMT_Oil_VariablePvt:
if(pvt != nullptr) {
scene.PVT.p = pvt->getPressure().toStdVector();
scene.PVT.Bo = pvt->getBo().toStdVector();
scene.PVT.Co = pvt->getCo().toStdVector();
scene.PVT.miuo = pvt->getMiuo().toStdVector();
}
break;
case SMT_Water_ConstPvt:
scene.PVT.p = buildConstantPvtPressure();
if(reservoir != nullptr) {
scene.PVT.Bw = buildConstantPvtVector(reservoir->getBw().getValue().toDouble());
scene.PVT.miuw = buildConstantPvtVector(reservoir->getMiuw().getValue().toDouble());
}
break;
case SMT_Water_VariablePvt:
if(pvt != nullptr) {
scene.PVT.p = pvt->getPressure().toStdVector();
scene.PVT.Bw = pvt->getBw().toStdVector();
scene.PVT.Cw = pvt->getCw().toStdVector();
scene.PVT.miuw = pvt->getMiuw().toStdVector();
}
break;
case SMT_Gas_VariablePvt:
case SMT_Gas_PseudoPressure:
if(pvt != nullptr) {
scene.PVT.p = pvt->getPressure().toStdVector();
scene.PVT.Bg = pvt->getBg().toStdVector();
scene.PVT.Cg = pvt->getCg().toStdVector();
scene.PVT.miug = pvt->getMiug().toStdVector();
}
break;
case SMT_Oil_Water_TwoPhase:
if(pvt != nullptr) {
scene.PVT.p = pvt->getPressure().toStdVector();
scene.PVT.Bo = pvt->getBo().toStdVector();
scene.PVT.miuo = pvt->getMiuo().toStdVector();
scene.PVT.Bw = pvt->getBw().toStdVector();
scene.PVT.miuw = pvt->getMiuw().toStdVector();
scene.PVT.So = pvt->getSo().toStdVector();
scene.PVT.Kro = pvt->getKro().toStdVector();
scene.PVT.Krw = pvt->getKrw().toStdVector();
}
break;
default:
break;
}
}
}
#ifdef Q_OS_WIN
#include <windows.h>
#define DEBUG_OUT(msg) OutputDebugStringA(QString("[Mesh] %1\n").arg(msg).toLocal8Bit().data())
@ -814,18 +922,10 @@ bool nmCalculationPebiGrid::generateOutputPara()
// ===== 3. 求解器参数 =====
// 3.1 求解器类型
// 3.1 求解器类型:与真实求解器使用同一个模型类型,不再根据相态推断。
nmDataReservoir* pReservoirData = dm->getReservoirData();
if(pReservoirData) {
if(pReservoirData->getPhaseType() == PHASE_Oil) {
scene.solverType = 2; // 油单相变化PVT
} else if(pReservoirData->getPhaseType() == PHASE_Gas) {
scene.solverType = 5; // 气单相变化PVT
} else {
scene.solverType = 1; // 默认油单相
}
}
NM_SOLVER_MODEL_TYPE solverModelType = dm->getSolverModelType();
scene.solverType = static_cast<int>(solverModelType);
// 3.2 Rate流量数据
scene.Rate.t.resize(order.size());
@ -925,42 +1025,9 @@ bool nmCalculationPebiGrid::generateOutputPara()
}
}
// 3.5 PVT数据
// 3.5 PVT数据常数PVT和变化PVT采用与真实求解器相同的填充方式。
nmDataPvtParaForPebi* pvt = dm->getPebiPvtPara();
if(pvt) {
scene.PVT.p = pvt->getPressure().toStdVector();
scene.PVT.Rso = pvt->getRso().toStdVector();
scene.PVT.pb = pvt->getPb().getValue().toDouble();
scene.PVT.Bo = pvt->getBo().toStdVector();
scene.PVT.Co = pvt->getCo().toStdVector();
scene.PVT.miuo = pvt->getMiuo().toStdVector();
scene.PVT.rouo = pvt->getRouo().toStdVector();
scene.PVT.Rv = pvt->getRv().toStdVector();
scene.PVT.Bg = pvt->getBg().toStdVector();
scene.PVT.Cg = pvt->getCg().toStdVector();
scene.PVT.miug = pvt->getMiug().toStdVector();
scene.PVT.roug = pvt->getRoug().toStdVector();
scene.PVT.Z = pvt->getZ().toStdVector();
scene.PVT.Rsw = pvt->getRsw().toStdVector();
scene.PVT.Bw = pvt->getBw().toStdVector();
scene.PVT.Cw = pvt->getCw().toStdVector();
scene.PVT.miuw = pvt->getMiuw().toStdVector();
scene.PVT.rouw = pvt->getRouw().toStdVector();
scene.PVT.V = pvt->getV().toStdVector();
scene.PVT.k_kinitial = pvt->getKKinitial().toStdVector();
scene.PVT.Cf_Cfinitial = pvt->getCfCfinitial().toStdVector();
scene.PVT.So = pvt->getSo().toStdVector();
scene.PVT.Kro = pvt->getKro().toStdVector();
scene.PVT.Sg = pvt->getSg().toStdVector();
scene.PVT.Krg = pvt->getKrg().toStdVector();
scene.PVT.Sw = pvt->getSw().toStdVector();
scene.PVT.Krw = pvt->getKrw().toStdVector();
}
fillScenePvtByModel(scene, solverModelType, pvt, pReservoirData);
// 3.6 Base储层参数
if(pReservoirData) {
@ -996,16 +1063,27 @@ bool nmCalculationPebiGrid::generateOutputPara()
dataDir.mkpath("."); // 确保 Data 目录存在
}
QString outPath = dataDir.filePath("scene.bin");
bool ok = nmDataBinaryTools::savePebiSceneBin(outPath, scene);
QString typedFileName = QString("scene_%1.bin").arg(solverModelFileTag(solverModelType));
QString typedOutPath = dataDir.filePath(typedFileName);
bool ok = nmDataBinaryTools::savePebiSceneBin(typedOutPath, scene);
if(!ok) {
zxLogInstance::getInstance()->writeLogF("savePebiSceneBin failed: " + nmDataBinaryTools::getLastError());
FreeLibrary(dll);
return false;
} else {
zxLogInstance::getInstance()->writeLogF("scene.bin exported: " + outPath);
}
// 保留固定文件名作为当前场景入口兼容现有Training和Python数据生成流程。
QString latestOutPath = dataDir.filePath("scene.bin");
ok = nmDataBinaryTools::savePebiSceneBin(latestOutPath, scene);
if(!ok) {
zxLogInstance::getInstance()->writeLogF("savePebiSceneBin failed: " + nmDataBinaryTools::getLastError());
FreeLibrary(dll);
return false;
}
zxLogInstance::getInstance()->writeLogF("scene exported: " + typedOutPath);
zxLogInstance::getInstance()->writeLogF("latest scene exported: " + latestOutPath);
}
// ===== 导出所有井loglog + rate + pressure 到 temp 目录 =====

Loading…
Cancel
Save