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/nmCalculationPebiGrid.h

241 lines
12 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef NMCALCULATIONPEBIGRID_H
#define NMCALCULATIONPEBIGRID_H
#include "nmCalculation_global.h"
#include <QVector>
#include <QPointF>
#include <QString>
#include <QSet>
#include <QAtomicInt>
#include "pch.h"
#include "nmDataBinaryTools.h"
#include "nmDataNumericalAnalysisCase.h"
#include <vtkUnstructuredGrid.h>
#include <vtkSmartPointer.h>
class nmDataAnalyzeManager;
class nmDataWellBase;
/**
* @brief 一口求解井在输入捕获时形成的值快照。
*
* 井对象只允许在 DataManager 所属线程读取;后台准备场景和后处理曲线时只使用
* 这里的值,避免多井循环反复扫描 DataManager 或跨线程访问井对象。
*/
struct nmPebiWellInputSnapshot
{
nmPebiWellInputSnapshot()
: m_eWellCategory(NM_WellCategory_Unknown),
m_eFlowSchedulePhase(PHASE_UNKNOWN),
m_nFlowSectionIndex(1),
m_dRadius(0.0),
m_dWellboreStorage(0.0),
m_dSkin(0.0),
m_dDfc(0.0),
m_bUseOilRate(false),
m_bUseGasRate(false),
m_bUseWaterRate(false),
m_bRateControlled(false),
m_bRealWell(false),
m_bHasPerforation(false),
m_bHasDfc(false),
m_bDisplayResultWell(false)
{
}
QString m_sWellCode; ///< 项目内稳定井编码。
QString m_sWellName; ///< 捕获时井名称。
QString m_sWellInstanceId; ///< 完整场结果使用的稳定井 UUID。
QString m_sGaugeInputSha1; ///< 与井角色无关的规范化 Gauge 输入签名。
QVector<double> m_vecFlowDurations; ///< 去除框架占位行后的公共流动段时长。
QVector<double> m_vecOilRates; ///< 与公共流动段逐项对应的油相流量。
QVector<double> m_vecGasRates; ///< 与公共流动段逐项对应的气相流量。
QVector<double> m_vecWaterRates; ///< 与公共流动段逐项对应的水相流量。
NM_WELL_CATEGORY m_eWellCategory; ///< 求解时冻结的油井、气井或水井井别。
NM_PHASE_TYPE m_eFlowSchedulePhase; ///< 旧单相后处理使用的当前制度参考相。
/** @brief 求解时冻结的历史压力曲线。 */
QVector<QVector<double> > m_vecHistoryPressure;
/** @brief 求解时冻结的历史双对数曲线。 */
QVector<QVector<double> > m_vecHistoryLogLog;
/** @brief 求解时冻结的历史半对数曲线。 */
QVector<QVector<double> > m_vecHistorySemiLog;
QPointF m_oLocation; ///< 求解时井平面位置。
int m_nFlowSectionIndex; ///< 当前流动段一基索引。
double m_dRadius; ///< 求解时井筒半径。
double m_dWellboreStorage; ///< 求解时井筒储集系数。
double m_dSkin; ///< 求解时表皮系数。
double m_dDfc; ///< 求解时裂缝导流能力。
bool m_bUseOilRate; ///< 求解时是否启用油相流量。
bool m_bUseGasRate; ///< 求解时是否启用气相流量。
bool m_bUseWaterRate; ///< 求解时是否启用水相流量。
bool m_bRateControlled; ///< 是否提供源汇项。
bool m_bRealWell; ///< 是否为真实井而非手工裂缝槽位。
bool m_bHasPerforation; ///< 求解时是否存在射孔。
bool m_bHasDfc; ///< 当前井型是否具有 Dfc 参数。
bool m_bDisplayResultWell; ///< 是否进入结果井下拉框。
};
/**
* @brief 一次 PEBI 网格任务使用的不可变输入快照。
*
* 该结构只保存值类型,不持有 DataManager、QObject 或井对象指针。主线程在
* 启动任务前完整填充,后台线程随后只读取本结构,从而避免与 Map 编辑并发访问。
*/
struct nmPebiGridInputSnapshot
{
/** @brief 创建空快照m_bValid 为 false不能直接提交给网格 DLL。 */
nmPebiGridInputSnapshot()
: m_nGridInputRevision(0),
m_bCaptured(false),
m_bRequireSolverInput(false),
m_bValid(false)
{
}
HX_NWTM_GRID_INPUT m_oGridInput; ///< 边界、井、断层和裂缝等 DLL 输入。
nmDataBinaryTools::NM_PEBI_SCENE m_oScene; ///< 与本次网格输入一致的 ML 场景数据。
QVector<nmSolverWellRef> m_vecSolverWellOrder; ///< DLL 数组槽位对应的稳定井编码顺序。
QVector<nmPebiWellInputSnapshot> m_vecWellInputs; ///< 与 DLL 井槽位严格对齐的值快照。
QString m_sLicensePath; ///< 网格 DLL 授权文件路径副本。
quint64 m_nGridInputRevision; ///< 捕获时的几何输入版本。
bool m_bCaptured; ///< DataManager 值是否已在所属线程完整捕获。
bool m_bRequireSolverInput; ///< 是否还需组装产量、PVT 等求解输入。
bool m_bValid; ///< 后台场景准备是否完成,可否提交给网格 DLL。
};
/**
* @brief 后台 PEBI 计算产生、尚未写回分析成果的局部结果。
*/
struct nmPebiGridResult
{
/** @brief 创建空结果;只有 m_bSucceeded 为 true 时才允许提交。 */
nmPebiGridResult()
: m_pUnstructuredGrid(nullptr),
m_nPebiCount(-1),
m_bSucceeded(false)
{
}
HX_NWTM_GRID_OUTPUT1 m_oGridOutput1; ///< 网格 DLL 主输出。
HX_NWTM_GRID_OUTPUT2 m_oGridOutput2; ///< 网格 DLL 辅助输出。
vtkSmartPointer<vtkUnstructuredGrid> m_pUnstructuredGrid; ///< 局部构造的 VTK 网格。
int m_nPebiCount; ///< DLL 返回的 PEBI 单元数量。
bool m_bSucceeded; ///< DLL 和 VTK 转换是否全部成功。
};
class NMCALCULATION_EXPORT nmCalculationPebiGrid
{
public:
/** @brief 返回进程内唯一的 PEBI 网格服务实例。 */
static nmCalculationPebiGrid* getInstance();
nmCalculationPebiGrid();
~nmCalculationPebiGrid();
/** @brief 在调用线程从 DataManager 复制一份完整且不含对象指针的输入快照。 */
bool captureInputSnapshot(nmDataAnalyzeManager* pDataManager,
nmPebiGridInputSnapshot& oSnapshot,
bool bDeferPreparation = false,
bool bRequireSolverInput = true);
/** @brief 初始化手工求解的分批网格快照,只在 DataManager 所属线程调用。 */
bool beginManualInputSnapshot(nmDataAnalyzeManager* pDataManager,
nmPebiGridInputSnapshot& oSnapshot);
/** @brief 把一口有效井的几何和值追加到手工求解快照。 */
bool appendManualWellInputSnapshot(nmDataWellBase* pWellData,
int nWellMode,
nmPebiGridInputSnapshot& oSnapshot);
/** @brief 捕获非井输入并完成手工值快照;后台准备前 m_bValid 保持 false。 */
bool finishManualInputSnapshot(nmDataAnalyzeManager* pDataManager,
const QSet<QString>& setEffectiveWellCodes,
nmPebiGridInputSnapshot& oSnapshot);
/** @brief 只使用已捕获的值在后台组装场景;取消时保持 m_bValid 为 false。 */
bool prepareInputSnapshot(nmPebiGridInputSnapshot& oSnapshot,
const QAtomicInt* pCancelRequested = NULL);
/** @brief 仅使用值快照调用网格 DLL并把输出保存在局部结果中。 */
bool calculateSnapshot(const nmPebiGridInputSnapshot& oSnapshot,
nmPebiGridResult& oResult,
bool bCreateUnstructuredGrid = true,
const QAtomicInt* pCancelRequested = NULL);
/** @brief 在主线程校验输入版本,并一次性提交井顺序、网格和单例缓存。 */
bool commitSnapshotResult(nmDataAnalyzeManager* pDataManager,
const nmPebiGridInputSnapshot& oSnapshot,
const nmPebiGridResult& oResult);
/** @brief 设置 PEBI 网格控制值,并同步到指定分析方案。 */
void setGridControl(double dGridControl,
nmDataAnalyzeManager* pDataManager = nullptr);
/** @brief 仅在缓存属于指定管理器时清理;空参数强制清理当前缓存。 */
void clearGridData(const nmDataAnalyzeManager* pDataManager = nullptr);
private:
/** @brief 从绑定数据管理器构造边界输入。 */
bool meshGenPebiBoundary(nmDataAnalyzeManager* pDataManager,
HX_NWTM_GRID_INPUT& inputObj);
/** @brief 按有效计算井集合构造井几何并记录 DLL 井顺序。 */
bool meshGenPebiWells(nmDataAnalyzeManager* pDataManager,
HX_NWTM_GRID_INPUT& inputObj,
QVector<nmSolverWellRef>& vecSolverWellOrder,
const QSet<QString>& setEffectiveWellCodes);
/** @brief 从 Map 构造断层输入。 */
bool meshGenPebiFault(nmDataAnalyzeManager* pDataManager,
HX_NWTM_GRID_INPUT& inputObj);
/** @brief 从 Map 构造手工裂缝输入和求解器占位条目。 */
bool meshGenPebiCrack(nmDataAnalyzeManager* pDataManager,
HX_NWTM_GRID_INPUT& inputObj,
QVector<nmSolverWellRef>& vecSolverWellOrder);
/** @brief 从已捕获值构造与网格输入一致的 ML 场景,不访问 DataManager。 */
bool buildPebiScene(nmPebiGridInputSnapshot& oSnapshot,
const QAtomicInt* pCancelRequested);
/** @brief 更新单例中的 DLL 输入输出缓存,不改变网格有效版本。 */
void commitOutputCache(nmDataAnalyzeManager* pDataManager,
const nmPebiGridInputSnapshot& oSnapshot,
const nmPebiGridResult& oResult);
// 生成vtk数据
void genPebiVTK(const HX_NWTM_GRID_OUTPUT1& P1, QString vtkDir);
// 根据网格输出结构体创建 vtkUnstructuredGrid 对象
vtkSmartPointer<vtkUnstructuredGrid> createPebiUnstructuredGrid(
const HX_NWTM_GRID_OUTPUT1& P1,
const QAtomicInt* pCancelRequested = NULL);
// 日志输出
void logCurrentState();
void logInputParameters(const HX_NWTM_GRID_INPUT& input);
public:
/** @brief 非阻塞复制当前有效网格DLL忙碌或缓存不匹配时返回 false。 */
bool copyCurrentGridFor(const nmDataAnalyzeManager* pDataManager,
quint64 nGridInputRevision,
HX_NWTM_GRID_OUTPUT1& oGridOutput1,
HX_NWTM_GRID_OUTPUT2& oGridOutput2,
int& nPebiCount,
const QAtomicInt* pCancelRequested = NULL) const;
/** @brief 主线程快速判断缓存归属和版本,不复制大型 DLL 输出。 */
bool isCurrentGridAvailableFor(const nmDataAnalyzeManager* pDataManager,
quint64 nGridInputRevision) const;
public:
/** @brief 在线程锁保护下返回最近一次网格输出 p1 的副本。 */
HX_NWTM_GRID_OUTPUT1 getGridOutput1();
/** @brief 在线程锁保护下返回最近一次网格输出 p2 的副本。 */
HX_NWTM_GRID_OUTPUT2 getGridOutput2();
/** @brief 返回最近一次网格划分生成的 PEBI 单元数量。 */
int getPebiCount() const;
private:
static nmCalculationPebiGrid* m_instance; ///< 进程内共享的 PEBI 网格服务实例。
HX_NWTM_GRID_INPUT p0; ///< 最近一次提交给网格 DLL 的输入快照。
HX_NWTM_GRID_OUTPUT1 p1; ///< 最近一次网格 DLL 主输出。
HX_NWTM_GRID_OUTPUT2 p2; ///< 最近一次网格 DLL 辅助输出。
double m_dGridControl; ///< 对应 HX_NWTM_GRID_INPUT::GridControl。
int m_nPebiCount; ///< 最近一次成功网格的单元数量,未生成时为 -1。
quint64 m_nCachedGridInputRevision; ///< 单例 DLL 输出对应的网格输入版本。
/** @brief 当前单例缓存所属的数据管理器,不拥有对象。 */
nmDataAnalyzeManager* m_pDataManager;
};
#endif // NMCALCULATIONPEBIGRID_H