|
|
|
@ -75,6 +75,8 @@ static const double kSurrogateHMin = 2.0; // 代理模型训练
|
|
|
|
static const double kSurrogateHMax = 50.0; // 代理模型训练域:储层厚度上界。
|
|
|
|
static const double kSurrogateHMax = 50.0; // 代理模型训练域:储层厚度上界。
|
|
|
|
static const double kSurrogateCfFixed = 4.315e-4; // 当前代理模型按近似固定 Cf 训练。
|
|
|
|
static const double kSurrogateCfFixed = 4.315e-4; // 当前代理模型按近似固定 Cf 训练。
|
|
|
|
static const double kSurrogateCfRelTol = 0.25; // Cf 允许相对偏差,超过则不使用代理筛选。
|
|
|
|
static const double kSurrogateCfRelTol = 0.25; // Cf 允许相对偏差,超过则不使用代理筛选。
|
|
|
|
|
|
|
|
static const double kSurrogateCfMin = 1.0e-6; // 变化 PVT 模型的 Cf 训练域下界。
|
|
|
|
|
|
|
|
static const double kSurrogateCfMax = 5.0e-3; // 变化 PVT 模型的 Cf 训练域上界。
|
|
|
|
static const int kSurrogateMinProdSections = 3; // 代理训练流量制度:生产段数量下界。
|
|
|
|
static const int kSurrogateMinProdSections = 3; // 代理训练流量制度:生产段数量下界。
|
|
|
|
static const int kSurrogateMaxProdSections = 5; // 代理训练流量制度:生产段数量上界。
|
|
|
|
static const int kSurrogateMaxProdSections = 5; // 代理训练流量制度:生产段数量上界。
|
|
|
|
static const double kSurrogateProdTimeMin = 24.0; // 代理训练流量制度:生产总时长下界。
|
|
|
|
static const double kSurrogateProdTimeMin = 24.0; // 代理训练流量制度:生产总时长下界。
|
|
|
|
@ -1224,7 +1226,7 @@ QString nmCalculationAutoFitPSO::getSurrogateTag() const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 当前 C++ 绑定的代理模型实验标识,对应 ML 侧训练输出目录/checkpoint 命名。
|
|
|
|
// 当前 C++ 绑定的代理模型实验标识,对应 ML 侧训练输出目录/checkpoint 命名。
|
|
|
|
// 如果以后换模型,需要同步更新这里和 ML 脚本可识别的 tag。
|
|
|
|
// 如果以后换模型,需要同步更新这里和 ML 脚本可识别的 tag。
|
|
|
|
return "family_random_v2_q_50k_noslope";
|
|
|
|
return "T1_T4_merged_40000";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString nmCalculationAutoFitPSO::getSurrogateStage() const
|
|
|
|
QString nmCalculationAutoFitPSO::getSurrogateStage() const
|
|
|
|
@ -1277,7 +1279,7 @@ bool nmCalculationAutoFitPSO::writeSurrogateCandidateCsv(const QString& candidat
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// 文件位置通常是 ML/nmWTAI-ML/data/temp/pso_screen_candidates_<run_id>_gen<N>.csv。
|
|
|
|
// 文件位置通常是 ML/nmWTAI-ML/data/temp/pso_screen_candidates_<run_id>_gen<N>.csv。
|
|
|
|
// 字段顺序必须与 ML 脚本 score_pso_candidates*.py 保持一致:
|
|
|
|
// 字段顺序必须与 ML 脚本 score_pso_candidates*.py 保持一致:
|
|
|
|
// particle_id,k,skin,wellboreC,phi,h,Cf
|
|
|
|
// particle_id,k,skin,wellboreC,phi,h,Cf,solverType
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// 这里写的是“完整参数体系”中的关键字段,不是粒子内部紧凑向量。
|
|
|
|
// 这里写的是“完整参数体系”中的关键字段,不是粒子内部紧凑向量。
|
|
|
|
// 例如用户没有勾选 Cf 时,Cf 会从当前 DataManager 取值写入 CSV。
|
|
|
|
// 例如用户没有勾选 Cf 时,Cf 会从当前 DataManager 取值写入 CSV。
|
|
|
|
@ -1289,8 +1291,16 @@ bool nmCalculationAutoFitPSO::writeSurrogateCandidateCsv(const QString& candidat
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QTextStream out(&file);
|
|
|
|
QTextStream out(&file);
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!dataManager) {
|
|
|
|
|
|
|
|
DEBUG_OUT("Failed to write surrogate candidates: data manager is unavailable");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int solverType = static_cast<int>(dataManager->getSolverModelType());
|
|
|
|
// 代理模型只需要这些输入字段;其它参数当前不在训练输入集中。
|
|
|
|
// 代理模型只需要这些输入字段;其它参数当前不在训练输入集中。
|
|
|
|
out << "particle_id,k,skin,wellboreC,phi,h,Cf\n";
|
|
|
|
out << "particle_id,k,skin,wellboreC,phi,h,Cf,solverType\n";
|
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < m_swarm.size(); ++i) {
|
|
|
|
for(int i = 0; i < m_swarm.size(); ++i) {
|
|
|
|
QVector<double> params = buildTraceParameterVector(m_swarm[i].position);
|
|
|
|
QVector<double> params = buildTraceParameterVector(m_swarm[i].position);
|
|
|
|
@ -1301,7 +1311,8 @@ bool nmCalculationAutoFitPSO::writeSurrogateCandidateCsv(const QString& candidat
|
|
|
|
<< traceParamAt(params, 2)
|
|
|
|
<< traceParamAt(params, 2)
|
|
|
|
<< traceParamAt(params, 3)
|
|
|
|
<< traceParamAt(params, 3)
|
|
|
|
<< traceParamAt(params, 5)
|
|
|
|
<< traceParamAt(params, 5)
|
|
|
|
<< traceParamAt(params, 7);
|
|
|
|
<< traceParamAt(params, 7)
|
|
|
|
|
|
|
|
<< QString::number(solverType);
|
|
|
|
out << cols.join(",") << "\n";
|
|
|
|
out << cols.join(",") << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -1851,6 +1862,22 @@ bool nmCalculationAutoFitPSO::isSurrogateRunContextSupported(QString* reason) co
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NM_SOLVER_MODEL_TYPE solverModelType = dataManager->getSolverModelType();
|
|
|
|
|
|
|
|
bool isVariablePvt = solverModelType == SMT_Oil_VariablePvt ||
|
|
|
|
|
|
|
|
solverModelType == SMT_Water_VariablePvt;
|
|
|
|
|
|
|
|
bool isSupportedSolverType = solverModelType == SMT_Oil_ConstPvt ||
|
|
|
|
|
|
|
|
solverModelType == SMT_Oil_VariablePvt ||
|
|
|
|
|
|
|
|
solverModelType == SMT_Water_ConstPvt ||
|
|
|
|
|
|
|
|
solverModelType == SMT_Water_VariablePvt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!isSupportedSolverType) {
|
|
|
|
|
|
|
|
if(reason) {
|
|
|
|
|
|
|
|
*reason = QString("solverType=%1 is outside the T1-T4 surrogate model")
|
|
|
|
|
|
|
|
.arg(static_cast<int>(solverModelType));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 网格类型 gate:当前代理模型只按 PEBI 网格样本训练。
|
|
|
|
// 网格类型 gate:当前代理模型只按 PEBI 网格样本训练。
|
|
|
|
if(dataManager->getGridType() != NM_Grid_PEBI) {
|
|
|
|
if(dataManager->getGridType() != NM_Grid_PEBI) {
|
|
|
|
if(reason) *reason = "surrogate model is trained only for PEBI grid cases";
|
|
|
|
if(reason) *reason = "surrogate model is trained only for PEBI grid cases";
|
|
|
|
@ -1898,11 +1925,15 @@ bool nmCalculationAutoFitPSO::isSurrogateRunContextSupported(QString* reason) co
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 参数 gate:代理输入目前只覆盖 k/skin/wellboreC/phi/h,Cf 作为固定背景参数传入。
|
|
|
|
// 参数 gate:变化 PVT 的 T2/T4 允许 Cf 参与拟合;常数 PVT 的 T1/T3 仍固定 Cf。
|
|
|
|
// 用户勾选其它参数时,代理无法可靠反映这些参数变化,直接禁用代理筛选。
|
|
|
|
// 用户勾选其它参数时,代理无法可靠反映这些参数变化,直接禁用代理筛选。
|
|
|
|
QVector<int> allowedParamIndices;
|
|
|
|
QVector<int> allowedParamIndices;
|
|
|
|
allowedParamIndices << 0 << 1 << 2 << 3 << 5;
|
|
|
|
allowedParamIndices << 0 << 1 << 2 << 3 << 5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(isVariablePvt) {
|
|
|
|
|
|
|
|
allowedParamIndices << 7;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < m_enabledParamIndices.size(); ++i) {
|
|
|
|
for(int i = 0; i < m_enabledParamIndices.size(); ++i) {
|
|
|
|
if(!allowedParamIndices.contains(m_enabledParamIndices[i])) {
|
|
|
|
if(!allowedParamIndices.contains(m_enabledParamIndices[i])) {
|
|
|
|
if(reason) {
|
|
|
|
if(reason) {
|
|
|
|
@ -1919,10 +1950,12 @@ bool nmCalculationAutoFitPSO::isSurrogateRunContextSupported(QString* reason) co
|
|
|
|
nmDataReservoir reservoirData = dataManager->getReservoirDataCopy();
|
|
|
|
nmDataReservoir reservoirData = dataManager->getReservoirDataCopy();
|
|
|
|
double cf = reservoirData.getCf().getValue().toDouble();
|
|
|
|
double cf = reservoirData.getCf().getValue().toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
// Cf gate:当前模型按近似固定 Cf 训练,允许小范围相对偏差。
|
|
|
|
bool cfSupported = isVariablePvt
|
|
|
|
if(!isNearRelative(cf, kSurrogateCfFixed, kSurrogateCfRelTol)) {
|
|
|
|
? isInClosedRange(cf, kSurrogateCfMin, kSurrogateCfMax)
|
|
|
|
|
|
|
|
: isNearRelative(cf, kSurrogateCfFixed, kSurrogateCfRelTol);
|
|
|
|
|
|
|
|
if(!cfSupported) {
|
|
|
|
if(reason) {
|
|
|
|
if(reason) {
|
|
|
|
*reason = QString("Cf=%1 is outside surrogate fixed-Cf domain").arg(cf, 0, 'g', 10);
|
|
|
|
*reason = QString("Cf=%1 is outside surrogate domain").arg(cf, 0, 'g', 10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
@ -2075,7 +2108,16 @@ bool nmCalculationAutoFitPSO::isSurrogateCandidateInDomain(const QVector<double>
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!isNearRelative(cf, kSurrogateCfFixed, kSurrogateCfRelTol)) {
|
|
|
|
nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
|
|
|
NM_SOLVER_MODEL_TYPE solverModelType = dataManager
|
|
|
|
|
|
|
|
? dataManager->getSolverModelType()
|
|
|
|
|
|
|
|
: SMT_Oil_ConstPvt;
|
|
|
|
|
|
|
|
bool isVariablePvt = solverModelType == SMT_Oil_VariablePvt ||
|
|
|
|
|
|
|
|
solverModelType == SMT_Water_VariablePvt;
|
|
|
|
|
|
|
|
bool cfSupported = isVariablePvt
|
|
|
|
|
|
|
|
? isInClosedRange(cf, kSurrogateCfMin, kSurrogateCfMax)
|
|
|
|
|
|
|
|
: isNearRelative(cf, kSurrogateCfFixed, kSurrogateCfRelTol);
|
|
|
|
|
|
|
|
if(!cfSupported) {
|
|
|
|
if(reason) *reason = QString("Cf=%1").arg(cf, 0, 'g', 10);
|
|
|
|
if(reason) *reason = QString("Cf=%1").arg(cf, 0, 'g', 10);
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|