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/Include/nmNum/nmCalculation/nmCalculationDllPebiSolverT...

131 lines
6.5 KiB
C

#ifndef NMCALCULATIONDLLPEBISOLVERTASK_H
#define NMCALCULATIONDLLPEBISOLVERTASK_H
#include <QThread>
#include <QString>
#include <QVector>
#include <QMap>
#include <QPointF>
#include <iostream>
#include <vector>
#include <Windows.h>
#include <vtkSmartPointer.h>
#include "nmCalculationDefine.h"
#include "nmCalculation_global.h"
#include "pch.h"
class nmDataAnalyzeManager;
class vtkDoubleArray;
class vtkUnstructuredGrid;
struct nmPebiSolverInputSnapshot;
// 主窗口现在直接创建DLL求解线程任务因此类需要导出供nmSubWnd模块跨DLL使用。
class NMCALCULATION_EXPORT nmCalculationDllPebiSolverTask : public QThread {
Q_OBJECT
public:
/**
* @brief PEBI
* @param sPostprocessingDir
* @param pDataManager
* @param sAutoFitTargetWellName
* @param parent Qt
*/
nmCalculationDllPebiSolverTask(QString sPostprocessingDir,
nmDataAnalyzeManager* pDataManager = nullptr,
const QString& sAutoFitTargetWellName = QString(),
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 返回自动拟合目标井的原始压力结果副本。 */
QVector<QVector<double> > getAutoFitResultPressure() const;
/** @brief 返回自动拟合目标井的双对数结果副本。 */
QVector<QVector<double> > getAutoFitResultLogLog() const;
/** @brief 返回自动拟合目标井的半对数结果副本。 */
QVector<QVector<double> > getAutoFitResultSemiLog() const;
private:
/** @brief 执行当前唯一的 PEBI 求解模式。 */
bool execute();
/** @brief 成对释放构造时登记的 DataManager 后台使用权。 */
void releaseDataManagerUse();
/** @brief 在任务创建线程一次性捕获网格、井、储层和求解器设置。 */
bool captureInputSnapshot(const QString& sAutoFitTargetWellName);
/** @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<QVector<double> > m_vecPressure; ///< 时间和井底压力。
QVector<QVector<double> > m_vecLogLog; ///< 时间、压差及导数。
QVector<QVector<double> > m_vecSemiLog; ///< 时间和半对数压力。
QPointF m_oLocation; ///< 结果网格中的井坐标。
};
QString m_sPostprocessingDir; ///< 本次求解使用的后处理输出目录。
/** @brief 创建任务时捕获所属数据中心,工作线程不得读取全局当前窗口。 */
nmDataAnalyzeManager* m_pDataManager;
/** @brief 任务独占的完整值快照;析构时释放,后台禁止访问 DataManager。 */
nmPebiSolverInputSnapshot* m_pInputSnapshot;
bool m_bManagerUseActive; ///< 是否仍持有 DataManager 后台使用权。
bool m_bInputSnapshotValid; ///< 构造阶段是否已完成全部输入校验。
/** @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<QVector<double> > m_autoFitResultPressure; ///< 目标井原始压力结果。
QVector<QVector<double> > m_autoFitResultLogLog; ///< 目标井双对数结果。
QVector<QVector<double> > m_autoFitResultSemiLog; ///< 目标井半对数结果。
QVector<nmPebiWellResultSnapshot> m_vecPendingWellResults; ///< 完整求解的井结果快照。
QMap<double, vtkSmartPointer<vtkDoubleArray> > m_mapPendingTimeSteps; ///< 场压力时间步快照。
vtkSmartPointer<vtkUnstructuredGrid> 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