|
|
|
@ -1,4 +1,4 @@
|
|
|
|
#ifndef NMCALCULATIONAUTOFIT_H
|
|
|
|
#ifndef NMCALCULATIONAUTOFIT_H
|
|
|
|
#define NMCALCULATIONAUTOFIT_H
|
|
|
|
#define NMCALCULATIONAUTOFIT_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QObject>
|
|
|
|
@ -20,6 +20,12 @@ class QTimer;
|
|
|
|
class QProcess;
|
|
|
|
class QProcess;
|
|
|
|
|
|
|
|
|
|
|
|
// PSO粒子结构
|
|
|
|
// PSO粒子结构
|
|
|
|
|
|
|
|
// 这里的 position / velocity / bestPosition 只保存“用户勾选参与拟合的参数”,
|
|
|
|
|
|
|
|
// 不是完整的 11 个储层/井筒参数。完整参数向量会在写 trace 或调用代理模型时
|
|
|
|
|
|
|
|
// 通过 buildTraceParameterVector() 重新组装。
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// surrogate* 和 screeningDecision 是 PSO 加速筛选的辅助字段。代理模型只决定
|
|
|
|
|
|
|
|
// “这一代哪些粒子需要继续跑真实求解器”,不会直接更新 pbest / gbest。
|
|
|
|
struct AutoFitParticle {
|
|
|
|
struct AutoFitParticle {
|
|
|
|
QVector<QVector<double> > currentLogLogData;
|
|
|
|
QVector<QVector<double> > currentLogLogData;
|
|
|
|
QVector<QVector<double> > bestLogLogData;
|
|
|
|
QVector<QVector<double> > bestLogLogData;
|
|
|
|
@ -50,7 +56,8 @@ struct AutoFitParticle {
|
|
|
|
{}
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 判断类型枚举
|
|
|
|
// PSO停止原因。主循环每一代结束时会根据目标误差、收敛历史、粒子群多样性、
|
|
|
|
|
|
|
|
// 连续失败次数等状态给出一个停止判断。
|
|
|
|
enum StopReasonPSO {
|
|
|
|
enum StopReasonPSO {
|
|
|
|
PSO_CONTINUE_OPTIMIZATION = 0, // 继续优化
|
|
|
|
PSO_CONTINUE_OPTIMIZATION = 0, // 继续优化
|
|
|
|
PSO_TARGET_ACHIEVED = 1, // 达到目标精度
|
|
|
|
PSO_TARGET_ACHIEVED = 1, // 达到目标精度
|
|
|
|
@ -72,6 +79,11 @@ public:
|
|
|
|
~nmCalculationAutoFitPSO();
|
|
|
|
~nmCalculationAutoFitPSO();
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 核心接口:完全数据驱动 =====
|
|
|
|
// ===== 核心接口:完全数据驱动 =====
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// 这个类不直接读取自动拟合对话框控件。界面层 nmWxAutomaticFitting 会先把
|
|
|
|
|
|
|
|
// 用户选择的参数范围、迭代次数、误差容限、PSO acceleration 开关等保存到
|
|
|
|
|
|
|
|
// nmDataAnalyzeManager / nmDataAutomaticFitting,然后本类在 startAutoFitting()
|
|
|
|
|
|
|
|
// 内部统一读取。
|
|
|
|
void setTargetLogLogData(const QVector<QVector<double> >& targetData);
|
|
|
|
void setTargetLogLogData(const QVector<QVector<double> >& targetData);
|
|
|
|
bool startAutoFitting();
|
|
|
|
bool startAutoFitting();
|
|
|
|
void stopFitting();
|
|
|
|
void stopFitting();
|
|
|
|
@ -119,6 +131,13 @@ private:
|
|
|
|
void loadParameterBounds();
|
|
|
|
void loadParameterBounds();
|
|
|
|
|
|
|
|
|
|
|
|
// ===== PSO核心算法 =====
|
|
|
|
// ===== PSO核心算法 =====
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// 主流程:
|
|
|
|
|
|
|
|
// 1. extractUserInitialValues(): 从当前项目数据中取用户已有初始解;
|
|
|
|
|
|
|
|
// 2. initializeSwarm(): 根据初始解和上下界生成粒子群;
|
|
|
|
|
|
|
|
// 3. updateParticle(): 对单个粒子跑真实求解器并计算误差;
|
|
|
|
|
|
|
|
// 4. updateGlobalBest(): 只用真实求解器误差更新全局最优;
|
|
|
|
|
|
|
|
// 5. updateVelocityAndPosition(): 按 PSO 公式推进下一代粒子。
|
|
|
|
void extractUserInitialValues();
|
|
|
|
void extractUserInitialValues();
|
|
|
|
void initializeSwarm();
|
|
|
|
void initializeSwarm();
|
|
|
|
void updateVelocityAndPosition();
|
|
|
|
void updateVelocityAndPosition();
|
|
|
|
@ -127,6 +146,11 @@ private:
|
|
|
|
void updateParticle(int particleIndex);
|
|
|
|
void updateParticle(int particleIndex);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 参数应用方法 =====
|
|
|
|
// ===== 参数应用方法 =====
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// 每次评价粒子前,都会把该粒子的参数临时写入 DataManager:
|
|
|
|
|
|
|
|
// - 储层参数写入 nmDataReservoir;
|
|
|
|
|
|
|
|
// - 井参数(skin / wellbore storage)写入目标井。
|
|
|
|
|
|
|
|
// 求解器随后基于 DataManager 的当前状态计算模拟曲线。
|
|
|
|
void applyParametersToDataManager(const QVector<double>& parameters);
|
|
|
|
void applyParametersToDataManager(const QVector<double>& parameters);
|
|
|
|
void updateReservoirParameters(const QVector<double>& parameters);
|
|
|
|
void updateReservoirParameters(const QVector<double>& parameters);
|
|
|
|
void updateWellParameters(const QVector<double>& parameters);
|
|
|
|
void updateWellParameters(const QVector<double>& parameters);
|
|
|
|
@ -171,6 +195,10 @@ private:
|
|
|
|
void logDebugInfo(const QString& message) const;
|
|
|
|
void logDebugInfo(const QString& message) const;
|
|
|
|
|
|
|
|
|
|
|
|
// ===== Baseline trace =====
|
|
|
|
// ===== Baseline trace =====
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// trace:记录每一代、每个粒子的参数、真实求解器误差、
|
|
|
|
|
|
|
|
// 代理模型误差、筛选决策、pbest 和 gbest。代理筛选质量、某个粒子为什么
|
|
|
|
|
|
|
|
// 没有跑真实求解器,都应该优先看 trace。
|
|
|
|
void initializeTraceFile();
|
|
|
|
void initializeTraceFile();
|
|
|
|
void closeTraceFile();
|
|
|
|
void closeTraceFile();
|
|
|
|
void writeTraceHeader();
|
|
|
|
void writeTraceHeader();
|
|
|
|
@ -193,6 +221,15 @@ private:
|
|
|
|
void emitRunSummary(bool success, StopReasonPSO finalReason);
|
|
|
|
void emitRunSummary(bool success, StopReasonPSO finalReason);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== Surrogate screening prototype =====
|
|
|
|
// ===== Surrogate screening prototype =====
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// PSO acceleration 的核心逻辑。开启后,buildSurrogateEvaluationMask() 会:
|
|
|
|
|
|
|
|
// 1. 判断当前工况是否在代理模型训练域内;
|
|
|
|
|
|
|
|
// 2. 将当代粒子候选写成 CSV;
|
|
|
|
|
|
|
|
// 3. 调用 Python 代理模型输出 surrogate_objective;
|
|
|
|
|
|
|
|
// 4. 选择 top-k、随机审计、fallback 和最小真实求解比例对应的粒子;
|
|
|
|
|
|
|
|
// 5. 返回 bool mask,true 表示该粒子继续跑真实求解器。
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// 代理模型只筛选候选,不直接决定最终最优参数。
|
|
|
|
bool isSurrogateScreeningEnabled() const;
|
|
|
|
bool isSurrogateScreeningEnabled() const;
|
|
|
|
QString getMlRootPath() const;
|
|
|
|
QString getMlRootPath() const;
|
|
|
|
QString getPythonExecutablePath() const;
|
|
|
|
QString getPythonExecutablePath() const;
|
|
|
|
@ -228,57 +265,64 @@ private:
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
// ===== 运行状态 =====
|
|
|
|
// ===== 运行状态 =====
|
|
|
|
bool m_isRunning;
|
|
|
|
bool m_isRunning; // 当前是否有一次自动拟合正在运行。
|
|
|
|
bool m_shouldStop;
|
|
|
|
bool m_shouldStop; // 用户停止标志;主循环和求解器等待循环会定期检查它。
|
|
|
|
bool m_isPaused;
|
|
|
|
bool m_isPaused; // 预留暂停标志;主循环中有暂停等待逻辑。
|
|
|
|
int m_currentIteration;
|
|
|
|
int m_currentIteration; // 当前 PSO 迭代序号,从 0 开始。
|
|
|
|
QString m_lastError;
|
|
|
|
QString m_lastError; // 最近一次失败原因,供 UI 展示或日志排查。
|
|
|
|
|
|
|
|
|
|
|
|
// ===== PSO数据 =====
|
|
|
|
// ===== PSO数据 =====
|
|
|
|
QVector<double> m_initialValues; // 用户设置的初始值
|
|
|
|
QVector<double> m_initialValues; // 当前模型中提取的用户初始值,顺序与 m_enabledParamIndices 一致。
|
|
|
|
QVector<AutoFitParticle> m_swarm;
|
|
|
|
QVector<AutoFitParticle> m_swarm; // 粒子群,每个粒子只保存启用参数维度。
|
|
|
|
QVector<double> m_globalBestPosition;
|
|
|
|
QVector<double> m_globalBestPosition; // 全局最优参数,仍是启用参数向量。
|
|
|
|
double m_globalBestFitness;
|
|
|
|
double m_globalBestFitness; // 全局最优真实误差,越小越好。
|
|
|
|
double m_previousBestFitness;
|
|
|
|
double m_previousBestFitness; // 上一轮全局最优误差,用于自适应参数更新。
|
|
|
|
QVector<QVector<double> > m_lastEvaluatedLogLogData;
|
|
|
|
QVector<QVector<double> > m_lastEvaluatedLogLogData; // 最近一次真实求解得到的 result log-log 曲线。
|
|
|
|
QVector<QVector<double> > m_globalBestLogLogData;
|
|
|
|
QVector<QVector<double> > m_globalBestLogLogData; // 当前全局最优对应的 result log-log 曲线。
|
|
|
|
QVector<QVector<double> > m_userInitialLogLogData;
|
|
|
|
QVector<QVector<double> > m_userInitialLogLogData; // 用户初始解对应的 result log-log 曲线,用于精英保护。
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 优化配置 =====
|
|
|
|
// ===== 优化配置 =====
|
|
|
|
QVector<bool> m_parameterSelected;
|
|
|
|
//
|
|
|
|
QVector<double> m_parameterLower;
|
|
|
|
// 参数索引约定:
|
|
|
|
QVector<double> m_parameterUpper;
|
|
|
|
// 0 k 渗透率;1 skin 表皮系数;2 wellboreC 井筒储集;
|
|
|
|
QVector<int> m_enabledParamIndices;
|
|
|
|
// 3 phi 孔隙度;4 initialPressure 初始压力;5 h 储层厚度;
|
|
|
|
QVector<QVector<double> > m_targetLogLogData;
|
|
|
|
// 6 Ct 综合压缩系数;7 Cf 岩石压缩系数;
|
|
|
|
QString m_targetWellName;
|
|
|
|
// 8 Soi 初始含油饱和度;9 Swi 初始含水饱和度;10 Sgi 初始含气饱和度。
|
|
|
|
|
|
|
|
// m_enabledParamIndices 保存被用户勾选的参数索引,粒子的 position 维度与它一致。
|
|
|
|
|
|
|
|
QVector<bool> m_parameterSelected; // 完整 11 个参数是否被用户勾选参与拟合。
|
|
|
|
|
|
|
|
QVector<double> m_parameterLower; // 完整 11 个参数的搜索下界。
|
|
|
|
|
|
|
|
QVector<double> m_parameterUpper; // 完整 11 个参数的搜索上界。
|
|
|
|
|
|
|
|
QVector<int> m_enabledParamIndices; // 被勾选参数在完整 11 维体系中的索引。
|
|
|
|
|
|
|
|
QVector<QVector<double> > m_targetLogLogData; // 目标井 history log-log 曲线:time/pressure/derivative。
|
|
|
|
|
|
|
|
QString m_targetWellName; // 目标井名称;读写井参数和读取模拟曲线都依赖它。
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 算法配置 =====
|
|
|
|
// ===== 算法配置 =====
|
|
|
|
int m_swarmSize;
|
|
|
|
int m_swarmSize; // 粒子数量,当前默认 20。
|
|
|
|
int m_maxIterations;
|
|
|
|
int m_maxIterations; // 最大迭代次数,来自自动拟合配置。
|
|
|
|
double m_targetError;
|
|
|
|
double m_targetError; // 目标误差,小于该值视为达到拟合目标。
|
|
|
|
double m_inertiaWeight;
|
|
|
|
double m_inertiaWeight; // 惯性权重,控制粒子保留上一轮速度的程度。
|
|
|
|
double m_cognitiveParam;
|
|
|
|
double m_cognitiveParam; // 个体学习因子,控制粒子靠近自身 pbest 的程度。
|
|
|
|
double m_socialParam;
|
|
|
|
double m_socialParam; // 群体学习因子,控制粒子靠近全局 gbest 的程度。
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 统计信息 =====
|
|
|
|
// ===== 统计信息 =====
|
|
|
|
int m_totalEvaluations;
|
|
|
|
int m_totalEvaluations; // 已调用真实求解器评价的粒子总数。
|
|
|
|
int m_successfulEvaluations;
|
|
|
|
int m_successfulEvaluations; // 真实求解器成功且误差有效的评价次数。
|
|
|
|
QVector<double> m_convergenceHistory;
|
|
|
|
QVector<double> m_convergenceHistory; // 每代全局最优误差历史,用于收敛判断。
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 常量 =====
|
|
|
|
// ===== 常量 =====
|
|
|
|
static const double MIN_FITNESS_IMPROVEMENT;
|
|
|
|
static const double MIN_FITNESS_IMPROVEMENT; // 判断误差是否有有效改善的最小阈值。
|
|
|
|
static const double VELOCITY_LIMIT_FACTOR;
|
|
|
|
static const double VELOCITY_LIMIT_FACTOR; // 粒子速度上限占参数搜索区间的比例。
|
|
|
|
static const int CONVERGENCE_CHECK_INTERVAL;
|
|
|
|
static const int CONVERGENCE_CHECK_INTERVAL; // 收敛检查的基础间隔。
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 资源管理 =====
|
|
|
|
// ===== 资源管理 =====
|
|
|
|
volatile int m_evaluationInProgress; // 并发控制
|
|
|
|
volatile int m_evaluationInProgress; // 并发控制
|
|
|
|
int m_consecutiveFailures; // 连续失败计数
|
|
|
|
int m_consecutiveFailures; // 连续失败计数
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 精英保护 =====
|
|
|
|
// ===== 精英保护 =====
|
|
|
|
QVector<double> m_userInitialSolution; // 用户初始解
|
|
|
|
QVector<double> m_userInitialSolution; // 用户初始解参数,若最终改进不足会恢复它。
|
|
|
|
double m_userInitialFitness; // 用户初始解的适应度
|
|
|
|
double m_userInitialFitness; // 用户初始解真实误差。
|
|
|
|
double m_improvementThreshold; // 改进阈值
|
|
|
|
double m_improvementThreshold; // 最终结果相对初始解至少需要达到的改进阈值。
|
|
|
|
bool m_hasValidUserSolution; // 是否有有效的用户解
|
|
|
|
bool m_hasValidUserSolution; // 初始解是否成功跑过真实求解器。
|
|
|
|
|
|
|
|
|
|
|
|
int m_consecutiveFailedIterations; // 连续失败迭代次数
|
|
|
|
int m_consecutiveFailedIterations; // 连续失败迭代次数
|
|
|
|
int m_maxConsecutiveFailures; // 最大允许连续失败次数
|
|
|
|
int m_maxConsecutiveFailures; // 最大允许连续失败次数
|
|
|
|
@ -299,45 +343,47 @@ private:
|
|
|
|
double m_nearTargetFactor; // 接近目标的倍数因子
|
|
|
|
double m_nearTargetFactor; // 接近目标的倍数因子
|
|
|
|
double m_farTargetFactor; // 远离目标的倍数因子
|
|
|
|
double m_farTargetFactor; // 远离目标的倍数因子
|
|
|
|
|
|
|
|
|
|
|
|
// DLL求解器需要的临时目录
|
|
|
|
// DLL求解器需要的临时目录。每个对象单独创建,析构或停止时递归清理。
|
|
|
|
QString m_tempDirectory;
|
|
|
|
QString m_tempDirectory;
|
|
|
|
|
|
|
|
|
|
|
|
// Baseline trace output. It is kept separate from legacy UI counters.
|
|
|
|
// ===== Trace 和代理筛选统计 =====
|
|
|
|
bool m_traceEnabled;
|
|
|
|
//
|
|
|
|
QString m_traceRunId;
|
|
|
|
// 这些字段只描述代理筛选和运行复盘,不参与 PSO 数学更新。
|
|
|
|
QString m_traceFilePath;
|
|
|
|
bool m_traceEnabled; // 是否写出 trace CSV/meta 文件。
|
|
|
|
QString m_traceMetaFilePath;
|
|
|
|
QString m_traceRunId; // 本次运行 ID,作为 trace/candidate/score 文件名的一部分。
|
|
|
|
QFile m_traceFile;
|
|
|
|
QString m_traceFilePath; // pso_baseline_trace_<run_id>.csv 完整路径。
|
|
|
|
bool m_surrogateScreeningEnabled;
|
|
|
|
QString m_traceMetaFilePath; // pso_baseline_trace_<run_id>.meta.json 完整路径。
|
|
|
|
unsigned int m_psoRandomSeed;
|
|
|
|
QFile m_traceFile; // trace CSV 文件句柄。
|
|
|
|
QString m_surrogateRunContextSummary;
|
|
|
|
bool m_surrogateScreeningEnabled; // 用户配置中的 PSO acceleration 开关。
|
|
|
|
int m_surrogateWarmupIterationCount;
|
|
|
|
unsigned int m_psoRandomSeed; // PSO 随机种子,也用于可复现 random audit。
|
|
|
|
int m_surrogatePeriodicAuditIterationCount;
|
|
|
|
QString m_surrogateRunContextSummary; // 本次运行代理工况 gate 的摘要。
|
|
|
|
int m_surrogateContextBlockedIterationCount;
|
|
|
|
int m_surrogateWarmupIterationCount; // warmup 全量真实评价代数。
|
|
|
|
int m_surrogateActiveIterationCount;
|
|
|
|
int m_surrogatePeriodicAuditIterationCount; // 周期性全量审计代数。
|
|
|
|
int m_surrogateSelectedParticleCount;
|
|
|
|
int m_surrogateContextBlockedIterationCount; // 因工况不支持而全量真实评价的代数。
|
|
|
|
int m_surrogateScreenedParticleCount;
|
|
|
|
int m_surrogateActiveIterationCount; // 代理筛选真正参与的代数。
|
|
|
|
int m_surrogateTopKParticleCount;
|
|
|
|
int m_surrogateSelectedParticleCount; // 被选中跑真实求解器的粒子累计数。
|
|
|
|
int m_surrogateAuditParticleCount;
|
|
|
|
int m_surrogateScreenedParticleCount; // 被代理筛掉的粒子累计数。
|
|
|
|
int m_surrogateFallbackParticleCount;
|
|
|
|
int m_surrogateTopKParticleCount; // 因 surrogate top-k 被选中的粒子累计数。
|
|
|
|
int m_surrogateDomainParticleCount;
|
|
|
|
int m_surrogateAuditParticleCount; // 因 random audit 被选中的粒子累计数。
|
|
|
|
int m_surrogateMinFloorParticleCount;
|
|
|
|
int m_surrogateFallbackParticleCount; // 因 fallback gate 被选中的粒子累计数。
|
|
|
|
QProcess* m_surrogateScoringProcess;
|
|
|
|
int m_surrogateDomainParticleCount; // 因训练域 gate 被选中的粒子累计数。
|
|
|
|
QString m_surrogateScoringServerKey;
|
|
|
|
int m_surrogateMinFloorParticleCount; // 因最低真实求解比例被补选中的粒子累计数。
|
|
|
|
|
|
|
|
QProcess* m_surrogateScoringProcess; // 常驻 Python 代理评分 server 进程。
|
|
|
|
|
|
|
|
QString m_surrogateScoringServerKey; // 标识当前 server 对应的 python/script/meta/tag/stage。
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
// 模拟拟合相关成员
|
|
|
|
// 模拟拟合相关成员
|
|
|
|
bool m_simulationMode;
|
|
|
|
bool m_simulationMode; // 是否启用仿真模式;仿真模式不调用真实求解器。
|
|
|
|
QTimer* m_simulationTimer;
|
|
|
|
QTimer* m_simulationTimer; // 仿真日志定时器,用于分步模拟长任务。
|
|
|
|
int m_simulationIteration;
|
|
|
|
int m_simulationIteration; // 仿真当前迭代。
|
|
|
|
int m_simulationMaxIterations;
|
|
|
|
int m_simulationMaxIterations; // 仿真最大迭代。
|
|
|
|
QVector<double> m_simulationTargetParams;
|
|
|
|
QVector<double> m_simulationTargetParams; // 仿真最终目标参数。
|
|
|
|
QVector<double> m_simulationStartParams;
|
|
|
|
QVector<double> m_simulationStartParams; // 仿真起始参数。
|
|
|
|
double m_simulationTargetError;
|
|
|
|
double m_simulationTargetError; // 仿真最终目标误差。
|
|
|
|
double m_simulationStartError;
|
|
|
|
double m_simulationStartError; // 仿真起始误差。
|
|
|
|
double m_simulationCurrentError;
|
|
|
|
double m_simulationCurrentError; // 仿真当前误差。
|
|
|
|
int m_simulationLogInterval;
|
|
|
|
int m_simulationLogInterval; // 仿真日志输出间隔,单位秒。
|
|
|
|
QTime m_simulationStartTime;
|
|
|
|
QTime m_simulationStartTime; // 仿真开始时间,用于演示节奏统计。
|
|
|
|
|
|
|
|
|
|
|
|
// 用于逐粒子输出的状态
|
|
|
|
// 用于逐粒子输出的状态
|
|
|
|
int m_simulationCurrentParticle; // 当前正在处理的粒子索引
|
|
|
|
int m_simulationCurrentParticle; // 当前正在处理的粒子索引
|
|
|
|
|