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/nmData/nmDataAnalyzeManager.h

653 lines
24 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 NMDATAANALYZEMANAGER_H
#define NMDATAANALYZEMANAGER_H
#include <QObject>
#include "ZxDataObjectBin.h"
#include "nmData_global.h"
#include "nmDefines.h"
#include "nmDataVerticalWell.h"
#include "nmDataHorizontalWell.h"
#include "nmDataVerticalFracturedWell.h"
#include "nmDataHorizontalFracturedWell.h"
#include "nmGridDefine.h"
#include <QMap>
#include <QVector>
#include <QPointF>
#include <QPair>
#include <QString>
#include <QList>
#include <vtkUnstructuredGrid.h>
#include <vtkSmartPointer.h>
#include <vtkDoubleArray.h>
// 子类别显示信息结构
struct ChildCategoryDisplayInfo {
QString name; // 子项名称
bool isChecked; // 子项是否选中
bool isEnabled; // 子项是否启用 (取决于父项的选中状态)
};
// 类别显示信息结构
struct CategoryDisplayInfo {
bool isRootChecked; // 根节点是否选中
QVector<ChildCategoryDisplayInfo> childItems; // 子节点信息列表
};
// 整体
struct DisplaySetting {
QString key;
CategoryDisplayInfo value;
};
// 油藏地图显示信息结构体
struct BackgroundImageInfo {
bool bIsVisible; // 是否显示背景图片到地图
QString sFilePath; // 背景图片的文件路径
QImage objImage; // 具体的QImage对象
};
enum NM_SOLVER_MODEL_TYPE {
SMT_Oil_ConstPvt = 1,
SMT_Oil_VariablePvt = 2,
SMT_Water_ConstPvt = 3,
SMT_Water_VariablePvt = 4,
SMT_Gas_VariablePvt = 5,
SMT_Gas_PseudoPressure = 6,
SMT_Oil_Gas_TwoPhase = 7,
SMT_Oil_Water_TwoPhase = 8,
SMT_Gas_Water_TwoPhase = 9,
SMT_Oil_Gas_Water_ThreePhase = 10
};
class nmDataWellBase;
class ZxDataWell;
class nmDataReservoir;
class nmDataRegionMark;
class nmDataRegion;
class nmDataOutline;
class nmDataFracture;
class nmDataFault;
class nmDataAxis;
class nmGuiPlot;
class nmDataMeasuringScale;
class nmDataMeasure;
class nmDataPvtParaForPebi;
class nmDataMixedResults;
class nmDataLayer;
class nmDataGeoRef;
class nmDataAutomaticFitting;
class nmDataDiagnostic;
class nmDataForecast;
class ZxDataWell;
class iSubWndFitting;
class nmDataTimeStepSetting;
class nmDataSensitive;
class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin
{
ZX_DECLARE_DYNAMIC
Q_OBJECT
public:
nmDataAnalyzeManager();
// 释放当前流动段分析独占的数据对象
~nmDataAnalyzeManager();
// 分析窗口和数据管理器的映射关系
static QMap<iSubWndFitting*, nmDataAnalyzeManager*> s_mapDataAnalManager;
// 当前操作的分析窗体
static iSubWndFitting* s_pCurSubWndFitting;
// 根据流动段分析窗口的指针作为唯一标识
static nmDataAnalyzeManager* getInstanceByFitting(iSubWndFitting* pSubWndF);
// 流动段分析窗口销毁后,移除并释放对应的数据管理器
static void removeInstanceByFitting(iSubWndFitting* pSubWndF);
/**
* @brief 根据流动段分析窗口指针key查找对应的分析管理器实例value
* @param pSubWndF 流动段分析窗口指针作为key
* @return 返回对应的 nmDataAnalyzeManager 实例指针,如果未找到则返回 nullptr
*/
static nmDataAnalyzeManager* findManagerByFitting(iSubWndFitting* pSubWndF)
{
return s_mapDataAnalManager.value(pSubWndF, nullptr);
}
static iSubWndFitting* getCurrentFitting()
{
return s_pCurSubWndFitting;
}
static void setCurrentFitting(iSubWndFitting* pSubWndF)
{
s_pCurSubWndFitting = pSubWndF;
}
// 获取当前分析窗体下的指针
static nmDataAnalyzeManager* getCurrentInstance();
// 井的接口
// 添加井
nmDataWellBase* createWell(NM_WELL_MODEL eWellType);
nmDataWellBase* changeWellType(nmDataWellBase* pOldWellData, NM_WELL_MODEL eTargetWellType);
bool removeWell(nmDataWellBase* pWellData);
// 移除井图元以及数据
void removeWellDataAndPlot(nmDataWellBase* pWellData);
/**
* @brief 清空所有井数据
* @note 会删除所有井对象并清空数组
*/
void clearAllWellData();
// 获取井的数据
QVector<nmDataWellBase*> getWellDataList() const;
// 井副本数据
//QVector<nmDataWellBase> getWellDataListCopy() const;
// TODO:有问题,不会更新不同类型的井数据
//void updateWellData(const QVector<nmDataWellBase>& newData);
// 添加针对具体井类型的更新方法
void updateVerticalWells(const QVector<nmDataVerticalWell>& wells);
void updateVerticalFracturedWells(const QVector<nmDataVerticalFracturedWell>& wells);
void updateHorizontalFracturedWells(const QVector<nmDataHorizontalFracturedWell>& wells);
// 返回分类后的井数据
// 获取所有直井数据
QVector<nmDataVerticalWell*> getVerticalWellData() const;
// 获取所有垂直裂缝井数据
QVector<nmDataVerticalFracturedWell*> getVerticalFracturedWellData() const;
// 获取所有多段压裂水平井数据
QVector<nmDataHorizontalFracturedWell*> getHorizontalFracturedWellData() const;
// 通过井的名称查找井数据
//nmDataWellBase* findWellByName(const QString& wellName) const;
nmDataWellBase* findWellByName(QString wellName) const;
// 初始化测试井数据,即点击数值解的时候,将当前井添加到里面
void initCurWellData();
// 添加井数据,包括对应的流量数据和压力数据
void appendWellData(ZxDataWell* pWellData);
// 直接添加自定义的井数据
void appendNmWellData(nmDataWellBase* pWellData);
// 初始化油藏参数
void createReservoir();
// 获取油藏参数
nmDataReservoir* getReservoirData() const;
// 返回油藏副本数据
nmDataReservoir getReservoirDataCopy() const;
void updateReservoirData(const nmDataReservoir& newData);
// 初始化坐标轴参数
nmDataAxis* getAxisData() const;
void setAxisData(nmDataAxis* pAxisData);
// 从流动段分析窗口获取对应的PVT相关数据
void initPvtParaFromSubFit();
// 初始化区域标记参数
nmDataRegionMark* createRegionMark();
// 获取区域标记数据
QVector<nmDataRegionMark*> getRegionMarkDataList() const;
// 移除区域标记数据
bool removeRegionMarkData(nmDataRegionMark* pData);
// 返回区域标记副本数据
QVector<nmDataRegionMark> getRegionMarkDataListCopy() const;
void updateRegionMarkData(const QVector<nmDataRegionMark>& newData);
// 初始化边界数据
nmDataOutline* createOutline();
nmDataOutline* getOutlineData();
// 移除边界数据
bool removeOutlineData();
// 返回边界副本数据
nmDataOutline getOutlineDataCopy() const;
void updateOutlineData(const nmDataOutline& newData);
// 初始化复合区数据
nmDataRegion* createRegion();
// 获取复合区数据
QVector<nmDataRegion*> getRegionDataList() const;
// 移除复合区数据
bool removeRegionData(nmDataRegion* pData);
// 返回复合区副本数据
QVector<nmDataRegion> getRegionDataListCopy() const;
void updateRegionData(const QVector<nmDataRegion>& newData);
// 初始化裂缝数据
nmDataFracture* createFracture();
// 获取所有裂缝数据
QVector<nmDataFracture*> getFractureDataList() const;
// 获取DNF生成的裂缝数据
QVector<nmDataFracture*> getDFNFractureDataList() const;
// 移除裂缝数据
bool removeFractureData(nmDataFracture* pData);
// 返回裂缝副本数据
QVector<nmDataFracture> getFractureDataListCopy() const;
void updateFractureData(const QVector<nmDataFracture>& newData);
// 初始化断层数据
nmDataFault* createFault();
// 获取断层数据
QVector<nmDataFault*> getFaultDataList() const;
// 移除断层数据
bool removeFaultData(nmDataFault* pData);
// 返回断层数据副本
QVector<nmDataFault> getFaultDataListCopy() const;
// 更新断层数据
void updateFaultData(const QVector<nmDataFault>& newData);
// 绘图
nmGuiPlot* getPlot() const;
void setPlot(nmGuiPlot* plot);
// 更新井图元
void updateWellPlotByDataManager();
// 获取所有可连接的点(Value实际坐标)
QVector<QPointF> getValueAllConnectablePoints();
// 获取所有可连接的点(Pos屏幕坐标)
QVector<QPointF> getPosAllConnectablePoints();
// 根据传入的指针,去掉对应的点的坐标
QVector<QPointF> removePosByObject(QObject* obj);
// 比例尺数据对象相关
nmDataMeasuringScale* getMeasuringScaleData();
void setMeasuringScaleData(nmDataMeasuringScale *pMeasuringScaleData);
// 测量相关
nmDataMeasure* getMeasureData();
void setMeasureData(nmDataMeasure *pMeasureData);
bool removeMeasureData();
// 模型参考点相关
nmDataGeoRef* createGeoRefData();
nmDataGeoRef* getGeoRefData() const;
nmDataGeoRef getGeoRefDataCopy() const;
void updateGeoRefData(const nmDataGeoRef& newData);
// 预测相关
nmDataForecast* createForecastData();
nmDataForecast* getForecastData() const;
nmDataForecast getForecastDataCopy() const;
void updateForecastData(const nmDataForecast& newData);
// 敏感性分析相关
nmDataSensitive* createSensitiveData();
nmDataSensitive* getSensitiveData() const;
nmDataSensitive getSensitiveDataCopy() const;
void updateSensitiveData(const nmDataSensitive& newData);
// 自动拟合相关
nmDataAutomaticFitting* createAutomaticFittingData();
nmDataAutomaticFitting* getAutomaticFittingData() const;
nmDataAutomaticFitting getAutomaticFittingDataCopy() const;
void updateAutomaticFittingData(const nmDataAutomaticFitting& newData);
// 诊断参数相关
nmDataDiagnostic* getDiagnosticData() const;
// 应用诊断结果
void applyDiagnosticResults(nmDataDiagnostic* diagnostic, nmDataWellBase* wellData, nmDataReservoir* reservoirData);
// 重置功能相关方法
bool resetFromDiagnostic(); // 诊断重置业务逻辑
bool resetFromAnalytical(); // 分析重置业务逻辑
// 网格类型
NM_Grid_Type getGridType();
void setGridType(NM_Grid_Type newGridType);
// 求解模型类型
NM_SOLVER_MODEL_TYPE getSolverModelType() const;
void setSolverModelType(NM_SOLVER_MODEL_TYPE newSolverModelType);
// 获取Pebi网格求解数据接口
// 获取压力历史数据
QVector<QVector<double >> getPebiSolverHistoryDataByName(const QString& wellName);
// 获取压力对数信息
QVector<QVector<double >> getPebiSolverLogPreDataByName(const QString& wellName);
// 获取压力半对数数据
QVector<QVector<double >> getPebiSolverSemiLogPreDataByName(const QString& wellName);
// 获取PEBI求解器需要的pvt数据
nmDataPvtParaForPebi* getPebiPvtPara();
// 获取混合结果参数
nmDataMixedResults* getMixedResults();
// 创建混合结果参数对象
nmDataMixedResults* createMixedResult();
// 获取储层数据
nmDataLayer* getLayerData();
// 添加多储层数据
void setLayers(QVector<nmDataLayer*> vecLayers);
// 获取多储层数据
QVector<nmDataLayer*> getLayers();
// 获取储层边界数据
double getMinLayerTop();
double getMaxLayerBottom();
// 在末尾追加一个新的井信息
void appendCalculationWell(const QPair<NM_WELL_MODEL, QString>& well);
// 在指定位置插入一个新的井信息
void insertCalculationWell(int index, const QPair<NM_WELL_MODEL, QString>& well);
// 移除指定位置的井信息
bool removeCalculationWell(int index);
// 清空容器
void clearCalculationWells();
// 返回井信息的副本
QVector<QPair<NM_WELL_MODEL, QString>> getCalculationWells() const;
// 查询当前计算井中是否有某口井
bool isContainsWellName(const QString& wellName) const;
// 设置当前查看井
void setCurWellData(nmDataWellBase* wellData);
// 获取当前查看井
nmDataWellBase* getCurWellData();
void notifyDataChanged();
/**
* @brief 设置显示设置信息。
* @param displaySettings 包含所有类别显示状态的QVector。
*/
void setDisplaySettings(const QVector<DisplaySetting>& displaySettings);
/**
* @brief 获取当前显示设置信息。
* @return 包含所有类别显示状态的QVector。
*/
QVector<DisplaySetting> getDisplaySettings() const;
/**
* @brief 更新单个类别的显示设置。
* @param categoryName 类别名称。
* @param info 要更新的CategoryDisplayInfo。
* @return 如果找到并更新了指定类别返回true否则返回false
*/
bool updateCategoryDisplaySetting(const QString& categoryName, const CategoryDisplayInfo& info);
// 初始化默认显示设置
void initDefaultDisplaySettings();
// 用于查找类别
CategoryDisplayInfo* findCategoryDisplayInfo(const QString& categoryName);
/**
* @brief 向显示设置向量中添加一个子元素。
* @param displaySetting 要添加的DisplaySetting结构。
* @return 添加成功返回true否则返回false如已存在相同key
*/
bool appendDisplaySetting(const DisplaySetting& displaySetting);
/**
* @brief 从显示设置向量中删除指定key的子元素。
* @param categoryName 要删除的类别的key。
* @return 删除成功返回true否则返回false如未找到
*/
bool removeDisplaySetting(const QString& categoryName);
/**
* @brief 为指定的父类别添加子项
* @param parentCategory 父类别名称(如"Wells", "Faults"等)
* @param childNames 要添加的子项名称列表
* @param defaultChecked 子项的默认选中状态
* @return 添加成功返回true如果父类别不存在则返回false
*/
bool nmDataAnalyzeManager::addChildItemsToCategory(const QString& parentCategory,
const QStringList& childNames,
bool defaultChecked);
// 刷新当前显示的子节点
void nmDataAnalyzeManager::refreshChildItemsDisplay();
void addWellChildItemsToCategory(const QString& parentCategory);
void addFaultChildItemsToCategory(const QString& parentCategory);
void addFractureChildItemsToCategory(const QString& parentCategory);
void addRegionChildItemsToCategory(const QString& parentCategory);
void addRegionMarkChildItemsToCategory(const QString& parentCategory);
/**
* @brief 设置所有类别的根节点可见性
* @param isVisible true为全部可见false为全部不可见
*/
void setAllCategoriesRootVisibility(bool bIsVisible);
// 设置背景图片信息
void setBackgroundImageInfo(const BackgroundImageInfo& info);
// 获取背景图片信息
const BackgroundImageInfo& getBackgroundImageInfo() const;
// 统一的读写整个项目数据的方法
// @param filePath JSON文件的路径
// @return 读取成功返回 true否则返回 false
bool ReadProjectData(const QString& filePath);
// 统一的写整个项目数据的方法
// @param filePath JSON文件的路径
// @return 写入成功返回 true否则返回 false
bool WriteProjectData(const QString& filePath);
// 保存数值成果到本地
// @param sRstCode 当前成果ID
// @param pSubWndF 当前分析窗体
// @return 保存成功返回 true否则返回 false
bool saveNmResult(QString sRstCode, iSubWndFitting* pSubWndF);
// 加载本地成果到内存中
// @param sLoadAnalDir 加载的分析目录
// @return 保存成功返回 true否则返回 false
bool loadNmResult(QString sLoadAnalDir);
// 辅助函数:确保目录存在,如果不存在则创建
bool ensureDirectoryExists(const QString& dirPath);
/**
* @brief 判断指定目录是否存在。
* @param sDirPath 要检查的目录路径。
* @return 如果目录存在且可访问则返回true否则返回false。
*/
static bool isDirExist(const QString& sDirPath)
{
QFileInfo dirInfo(sDirPath);
bool bExists = dirInfo.exists() && dirInfo.isDir();
return bExists;
}
// 加载井数组里对应的压力、流量数据,这个是在井里没有这些数据的情况下调用
void loadWellPreAndFlow();
// 设置当前分析下的VTK网格对象
void setUnstructuredGrid(vtkSmartPointer<vtkUnstructuredGrid> grid);
// 获取当前分析下的VTK网格对象
vtkSmartPointer<vtkUnstructuredGrid> getUnstructuredGrid() const;
// 清理当前分析下的VTK网格对象
void clearUnstructuredGrid();
// 获取当前分析下的VTK网格对象的深拷贝对象一般复制给m_pResultBaseGrid使用深拷贝防止场图污染网格
vtkSmartPointer<vtkUnstructuredGrid> getUnstructuredGridCopy() const;
// 设置当前分析下的结果基础网格
void setResultBaseGrid(vtkSmartPointer<vtkUnstructuredGrid> grid);
// 获取当前分析下的结果基础网格
vtkSmartPointer<vtkUnstructuredGrid> getResultBaseGrid() const;
// 获取当前分析下的结果基础网格的深拷贝对象,一般作为场图渲染的基础网格
vtkSmartPointer<vtkUnstructuredGrid> getResultBaseGridCopy() const;
// 将非结构化网格数据写入文件
bool writeUnstructuredGridToFile(vtkSmartPointer<vtkUnstructuredGrid> grid, const QString& filePath);
// 从文件读取非结构化网格数据
bool readUnstructuredGridFromFile(vtkSmartPointer<vtkUnstructuredGrid>& grid, const QString& filePath);
// 添加时间步数据
void addTimeStep(double time, vtkSmartPointer<vtkDoubleArray> data);
// 获取时间步数据
vtkSmartPointer<vtkDoubleArray> getTimeStepData(double time) const;
// 获取时间步数据 QMap 的所有键(时间点)
QList<double> getTimeStepKeys();
// 判断当前是否存储了时间步数据
bool isTimeStepDataEmpty();
// 保存整个时间步数据QMap到单个二进制文件
bool writeTimeStepDataMapToBinaryFile(const QString& filePath);
// 从单个二进制文件加载整个时间步数据QMap
bool readTimeStepDataMapFromBinaryFile(const QString& filePath);
// 保存井的历史数据(所有井都要调用)
bool saveWellHistoryData(QString sDir, nmDataWellBase* pWellData);
// 加载井的历史数据(所有井都要调用)
bool loadWellHistoryData(QString sDir, nmDataWellBase* pWellData);
// 保存参与计算井的结果到本地,压力、双对数、半对数
bool saveWellCalRstData(QString sDir, nmDataWellBase* pWellData);
// 加载井的计算结果到内存
bool loadWellCalRstData(QString sDir, nmDataWellBase* pWellData);
// 获取 / 设置 压力标量值的范围
void getScalarRangeP(double range[2]) const;
void setScalarRangeP(double min, double max);
// 用于获取和设置井位置信息的接口
void addWellLocation(const QString& wellName, const QPointF& location);
QPointF getWellLocation(const QString& wellName) const;
bool removeWellLocation(const QString& wellName);
void clearWellLocations();
QMap<QString, QPointF> getAllWellLocations() const; // 获取所有井位置的副本
// 保存/加载当前场图中的井位置相关信息
bool saveWellLocations(const QString& filePath);
bool loadWellLocations(const QString& filePath);
// 创建时间步数据
//void createTimeStep();
nmDataTimeStepSetting* createTimeStep();
// 获取时间步数据
nmDataTimeStepSetting* getTimeStep();
void calculationLogData(
nmDataWellBase* pWellData,
QVector<QVector<double>>& vvecHistoryData,
QVector<QVector<double>>& vvecLogPreData,
QVector<QVector<double>>& vvecSemiLogPreData);
// 获取许可证路径
void setLicensePath(const QString& licensePath);
QString getLicensePath() const;
signals:
void dataChanged();
private:
// 存储井的数据
QVector<nmDataWellBase*> m_vWellData;
// 断层数据
QVector<nmDataFault*> m_vFaultData;
// 裂缝数据
QVector<nmDataFracture*> m_vFractureData;
// 复合区数据
QVector<nmDataRegion*> m_vRegionData;
// 区域标记数据
QVector<nmDataRegionMark*> m_vRegionMarkData;
// 边界数据
nmDataOutline* m_outlineData;
// 坐标轴范围数据
nmDataAxis* m_axisData;
// 自动拟合数据
nmDataAutomaticFitting* m_pAutomaticFittingData;
// 油藏数据
nmDataReservoir* m_reservoirData;
// 存储nmGuiPlot,绘图
nmGuiPlot* m_pNmGuiPlot;
// 比例尺信息
nmDataMeasuringScale* m_pMeasuringScaleData;
// 测量信息
nmDataMeasure* m_pMeasureData;
// 模型参考点信息
nmDataGeoRef* m_pGeoRefData;
// 预测信息
nmDataForecast* m_pForecastData;
// 敏感性信息
nmDataSensitive* m_pSensitiveData;
// 诊断参数
nmDataDiagnostic* m_pDiagnosticData;
// 网格类型
NM_Grid_Type m_eGridType;
// 求解模型类型
NM_SOLVER_MODEL_TYPE m_eSolverModelType;
// Pvt数据(Pebi)
nmDataPvtParaForPebi* m_pebiPvtPara;
// 混合结果参数
nmDataMixedResults* m_pMixedResults;
// 储层数据
nmDataLayer* m_pLayerData;
QVector<nmDataLayer*> m_vecLayers; // 通过储层对话框后初始化的数组,临时
// 孔射封堵
//nmDataPerforationClosing* m_pPerCloData;
// 存储PEBI求解井顺序
QVector<QPair<NM_WELL_MODEL, QString>> m_vecCalculationWells;
// 当前查看的是哪一口井的数据,也是哪一口测试井
nmDataWellBase* m_pCurDataWell;
// 显示设置信息
QVector<DisplaySetting> m_vecDisplaySettings;
// 背景图片信息
BackgroundImageInfo m_backgroundImageInfo;
// VTK非结构化网格对象用于展示网格划分窗体
vtkSmartPointer<vtkUnstructuredGrid> m_pVtkUnstructuredGrid;
// VTK非结构化网格对象用于结果场图里的基础网格
vtkSmartPointer<vtkUnstructuredGrid> m_pResultBaseGrid;
// 时间步压力数据
QMap<double, vtkSmartPointer<vtkDoubleArray>> m_mapTimeStepDataP;
// 压力值范围 [min, max]
double m_dScalarRangeP[2];
// 存储井名称及其二维位置坐标的映射,这里应该是参与计算求解的井
QMap<QString, QPointF> m_mapWellLocations;
// 时间步设置数据
nmDataTimeStepSetting* m_pTimeStep;
// 许可证路径
QString m_licensePath;
public:
// 数据是否是从本地加载进来的
bool m_bIsLoadData;
};
#endif // NMDATAANALYZEMANAGER_H