#ifndef NMCALCULATIONDLLPEBISOLVERTASK_H #define NMCALCULATIONDLLPEBISOLVERTASK_H #include #include #include #include #include #include #include #include #include #include "nmCalculationDefine.h" #include "nmCalculation_global.h" #include "pch.h" class nmDataAnalyzeManager; class vtkDoubleArray; class vtkUnstructuredGrid; // 主窗口现在直接创建DLL求解线程任务,因此类需要导出,供nmSubWnd模块跨DLL使用。 class NMCALCULATION_EXPORT nmCalculationDllPebiSolverTask : public QThread { Q_OBJECT public: /** * @brief 创建绑定到指定分析窗口的 PEBI 求解任务。 * @param sPostprocessingDir 后处理文件输出目录。 * @param pDataManager 任务所属数据管理器,不转移所有权。 * @param parent Qt 父对象。 */ nmCalculationDllPebiSolverTask(QString sPostprocessingDir, nmDataAnalyzeManager* pDataManager = nullptr, QObject *parent = nullptr); ~nmCalculationDllPebiSolverTask(); /** @brief QThread 入口,记录本次 execute() 的成功状态并发送完成信号。 */ void run(); // PSO 等待线程结束后通过该接口判断本次结果是否可以继续参与误差计算. // 返回 false 时调用方会丢弃本次结果, 防止复用上一粒子留下的旧曲线. bool wasSuccessful() const; /** @brief 获取本次DLL内部求解耗时,单位为毫秒。 */ int getSolveTimeMs() const; /** @brief 获取本次求解的PEBI网格数量。 */ int getPebiCount() const; /** * @brief 在主线程一次性提交已经完整校验的求解结果。 * @param pDataManager 启动任务时绑定的数据管理器,必须仍然存活且版本一致。 * @return 全部结果提交成功返回 true;自动拟合任务和过期任务返回 false。 */ bool commitResult(nmDataAnalyzeManager* pDataManager); /** * @brief 按显示井名设置自动拟合目标井,内部立即转换并保存 WellCode。 * @note 井名为空或查找失败时保持完整结果保存模式。 */ void setAutoFitTargetWell(const QString& wellName); /** @brief 返回自动拟合目标井的原始压力结果副本。 */ QVector > getAutoFitResultPressure() const; /** @brief 返回自动拟合目标井的双对数结果副本。 */ QVector > getAutoFitResultLogLog() const; /** @brief 返回自动拟合目标井的半对数结果副本。 */ QVector > getAutoFitResultSemiLog() const; private: /** @brief 执行当前唯一的 PEBI 求解模式。 */ bool execute(); /** @brief 成对释放构造时登记的 DataManager 后台使用权。 */ void releaseDataManagerUse(); /** @brief 构造 DLL 输入、执行求解并生成仍然有效的局部结果快照。 */ bool execPebiMode(); /** @brief 按求解器井顺序组装压力、曲线和场结果快照,不修改 DataManager。 */ bool buildPebiModeResult(HX_NWTM_MODEL_OUTPUT& p1, int nModelType, const HX_NWTM_GRID_OUTPUT1& oGridOutput); /** @brief 输出精简版 DLL 输入日志,用于定位求解异常。 */ void logHX_NWTM_MODEL_INPUT_Simplified(const HX_NWTM_MODEL_INPUT& p0); /** @brief 将完整 DLL 输入保存到文本文件,成功时返回 true。 */ bool saveHX_NWTM_MODEL_INPUT_ToTxt(const HX_NWTM_MODEL_INPUT& p0, const QString& filePath); private: /** @brief 一口真实井在本次求解中完整生成的待提交结果。 */ struct nmPebiWellResultSnapshot { QString m_sWellCode; ///< 稳定井编码。 QVector > m_vecPressure; ///< 时间和井底压力。 QVector > m_vecLogLog; ///< 时间、压差及导数。 QVector > m_vecSemiLog; ///< 时间和半对数压力。 QPointF m_oLocation; ///< 结果网格中的井坐标。 }; QString m_sPostprocessingDir; ///< 本次求解使用的后处理输出目录。 /** @brief 创建任务时捕获所属数据中心,工作线程不得读取全局当前窗口。 */ nmDataAnalyzeManager* m_pDataManager; bool m_bManagerUseActive; ///< 是否仍持有 DataManager 后台使用权。 /** @brief 创建任务时捕获网格输入版本,防止回填过期网格上的结果。 */ quint64 m_nGridInputRevision; /** @brief 创建任务时捕获求解输入版本,防止角色或参数变化后回填旧结果。 */ quint64 m_nResultInputRevision; bool m_lastRunSucceeded; ///< run() 保存的执行状态,供等待线程安全读取。 /** @brief 本次DLL内部求解耗时,单位为毫秒。 */ int m_nSolveTimeMs; /** @brief 本次求解的PEBI网格数量。 */ int m_nPebiCount; QString m_sAutoFitTargetWellCode; ///< 自动拟合目标井 WellCode;空值表示保存完整结果。 QVector > m_autoFitResultPressure; ///< 目标井原始压力结果。 QVector > m_autoFitResultLogLog; ///< 目标井双对数结果。 QVector > m_autoFitResultSemiLog; ///< 目标井半对数结果。 QVector m_vecPendingWellResults; ///< 完整求解的井结果快照。 QMap > m_mapPendingTimeSteps; ///< 场压力时间步快照。 vtkSmartPointer m_pPendingResultGrid; ///< 本次结果绑定的基础网格副本。 double m_dPendingScalarMin; ///< 全部场压力的最小值。 double m_dPendingScalarMax; ///< 全部场压力的最大值。 bool m_bPendingFullResultReady; ///< 是否已有可由主线程一次提交的完整结果。 private slots: //void slotTaskUpdateProgress(); signals: void sig_calculateDone(bool isSuccessed); //void sigTaskProgressUpdated(int progress); //void sigResSolverProgressUpdated(int progress); }; #endif // NMCALCULATIONDLLPEBISOLVERTASK_H