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

214 lines
11 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 NMDATANUMERICALANALYSISCASE_H
#define NMDATANUMERICALANALYSISCASE_H
#include "nmData_global.h"
#include "nmDefines.h"
#include <QString>
#include <QStringList>
#include <QVector>
/**
* @brief 井在当前数值分析方案中的计算角色。
*
* PEBI 求解器本身不区分“测试井”和“干扰井”,但构造产量输入和
* 后处理曲线时必须明确井是否提供源汇项。因此这里把角色定义在
* 数值分析方案中,而不是写入井的永久属性。
*/
enum NM_CASE_WELL_MODE
{
NM_CaseWell_RateControlled = 1, ///< 有生产或注入制度,参与改变压力场。
NM_CaseWell_Observation = 2 ///< 无产量制度,只接收并保存井底压力。
};
/**
* @brief 当前分析方案中的一口真实井。
*/
struct NM_DATA_EXPORT nmCalculationWellRef
{
/** @brief 构造空井引用,默认角色为无源汇项观察井。 */
nmCalculationWellRef();
/** @brief 使用稳定井编码和本次分析角色构造井引用。 */
nmCalculationWellRef(const QString& sWellCode, NM_CASE_WELL_MODE eMode);
QString m_sWellCode; ///< 项目内唯一井编码,所有持久化关联均使用该字段。
NM_CASE_WELL_MODE m_eMode; ///< 当前方案中的计算角色。
};
/**
* @brief 求解器数组中的条目类型。
*
* 手工裂缝在旧流程中使用“未知井 + 空井名”占位。显式区分条目类型后,
* 可以继续保持 DLL 数组下标对齐,同时不再伪装成一口井。
*/
enum NM_SOLVER_ENTRY_KIND
{
NM_SolverEntry_Well = 1, ///< 真实井,占用一组 Rate/CS/pw 数组槽位。
NM_SolverEntry_ManualFracture = 2 ///< Map 手工裂缝,仅用于保持 DLL 下标对齐。
};
/**
* @brief PEBI 网格输出确定的求解器井顺序。
*/
struct NM_DATA_EXPORT nmSolverWellRef
{
/** @brief 构造尚未分配求解器下标的真实井条目。 */
nmSolverWellRef();
/** @brief 构造网格输出中的求解器槽位描述。 */
nmSolverWellRef(int nSolverIndex,
NM_WELL_MODEL eWellType,
const QString& sWellCode,
NM_SOLVER_ENTRY_KIND eEntryKind = NM_SolverEntry_Well);
int m_nSolverIndex; ///< 对应 Rate[i] 和 pw[i] 的固定下标。
NM_WELL_MODEL m_eWellType; ///< 真实井的几何模型类型。
QString m_sWellCode; ///< 真实井编码;手工裂缝条目为空。
NM_SOLVER_ENTRY_KIND m_eEntryKind; ///< 真实井或手工裂缝占位。
};
/**
* @brief 一次数值分析从选井到结果展示所需的独立状态。
*
* 该类不拥有井对象也不保存井名称。Map 负责“项目中有什么”,本类保存
* 主井和手工包含的有产量井;数据管理层再自动加入 Map 中的无产量观察井。
*/
class NM_DATA_EXPORT nmDataNumericalAnalysisCase
{
public:
/** @brief 建立空分析方案,并初始化网格与结果版本号。 */
nmDataNumericalAnalysisCase();
/** @brief 返回主分析井的项目唯一 WellCode。 */
QString getPrimaryWellCode() const;
/** @brief 设置主分析井;同时移除包含列表中的同井项并使网格失效。 */
void setPrimaryWellCode(const QString& sWellCode);
/** @brief 返回主分析井在本次方案中的主动井或观察井角色。 */
NM_CASE_WELL_MODE getPrimaryWellMode() const;
/** @brief 设置主井角色;角色只影响源汇输入,因此仅使结果失效。 */
void setPrimaryWellMode(NM_CASE_WELL_MODE eMode);
/** @brief 返回是否启用手工选择的其他有产量井。 */
bool getIncludeOtherWells() const;
/** @brief 启停其他有产量井Map 无产量井不受该开关影响。 */
void setIncludeOtherWells(bool bInclude);
/** @brief 返回当前方案的 PEBI 网格疏密控制值。 */
double getPebiGridControl() const;
/** @brief 设置正数网格控制值;实际变化时使网格和结果失效。 */
void setPebiGridControl(double dGridControl);
/** @brief 返回已保存的其他有产量井选择,关闭总开关时选择仍保留。 */
QVector<nmCalculationWellRef> getIncludedWells() const;
/** @brief 保存其他有产量井,并按 WellCode 去空、去主井和去重。 */
void setIncludedWells(const QVector<nmCalculationWellRef>& vecWells);
/** @brief 判断 WellCode 是否存在于已保存的包含井列表。 */
bool isIncludedWell(const QString& sWellCode) const;
/** @brief 查询主井或显式包含井的方案角色,未配置井返回观察井角色。 */
NM_CASE_WELL_MODE getWellMode(const QString& sWellCode) const;
/** @brief 返回方案显式选择的井Map 观察井由数据管理层自动补充。 */
QVector<nmCalculationWellRef> getEffectiveWells() const;
/** @brief 返回界面当前查看结果的井编码。 */
QString getCurrentResultWellCode() const;
/** @brief 切换结果查看井;不改变主井、网格或已计算结果。 */
void setCurrentResultWellCode(const QString& sWellCode);
/** @brief 返回网格生成后确定的 DLL 井槽位顺序。 */
QVector<nmSolverWellRef> getSolverWellOrder() const;
/** @brief 清空求解器顺序,并将已建网格和结果标记为无效。 */
void clearSolverWellOrder();
/** @brief 在末尾追加槽位,并自动写入连续求解器下标。 */
void appendSolverWell(const nmSolverWellRef& oWellRef);
/** @brief 在指定下标插入槽位,并重新编号后续全部条目。 */
void insertSolverWell(int nIndex, const nmSolverWellRef& oWellRef);
/** @brief 删除指定槽位并重新编号;下标非法时返回 false。 */
bool removeSolverWell(int nIndex);
/** @brief 整体替换求解器顺序,并按容器顺序重新编号。 */
void setSolverWellOrder(const QVector<nmSolverWellRef>& vecOrder);
/** @brief 返回最后一次成功求解所使用的 DLL 井槽位顺序。 */
QVector<nmSolverWellRef> getResultSolverWellOrder() const;
/** @brief 返回最后一次成功求解时冻结的结果下拉框井编码。 */
QStringList getResultSelectableWellCodes() const;
/** @brief 从成果文件恢复结果存在状态、当前性和独立井顺序。 */
void restoreResultState(const QVector<nmSolverWellRef>& vecOrder,
bool bAvailable,
bool bCurrent);
/** @brief 从成果文件同时恢复冻结的结果下拉框井编码。 */
void restoreResultState(const QVector<nmSolverWellRef>& vecOrder,
const QStringList& listSelectableWellCodes,
bool bAvailable,
bool bCurrent);
/** @brief 选井或几何输入改变后,使当前网格和结果失效。 */
void invalidateGrid();
/** @brief 产量、PVT 等只影响求解的输入改变后,仅使结果失效。 */
void invalidateResults();
/** @brief 网格成功生成后记录当前输入版本。 */
void markGridBuilt();
/** @brief 仅当网格生成期间几何输入未变化时提交网格。 */
bool markGridBuiltIfCurrent(quint64 nGridInputRevision);
/** @brief 丢弃旧结果,但不改变输入版本号。 */
void discardResults();
/** @brief 求解成功并完成结果映射后记录结果有效。 */
void markResultsAvailable();
/** @brief 仅当任务启动后的网格和求解输入均未变化时提交结果。 */
bool markResultsAvailableIfCurrent(quint64 nGridInputRevision,
quint64 nResultInputRevision);
/** @brief 当前网格版本与几何输入一致且井顺序非空时返回 true。 */
bool isGridValid() const;
/** @brief 内存中存在一套可保存和查看的完整求解结果时返回 true。 */
bool hasResults() const;
/** @brief 已有结果仍对应当前输入时返回 true。 */
bool areResultsCurrent() const;
/** @brief 当前结果已提交且所依赖网格仍有效时返回 true。 */
bool areResultsValid() const;
/** @brief 返回最新几何/选井输入版本,供后台任务启动时捕获。 */
quint64 getGridInputRevision() const;
/** @brief 返回当前缓存网格对应的输入版本0 表示没有有效网格。 */
quint64 getBuiltGridRevision() const;
/** @brief 返回最新产量/PVT等求解输入版本供后台任务启动时捕获。 */
quint64 getResultInputRevision() const;
/**
* @brief 从 v3 成果恢复三个输入版本号。
* @note 当前网格版本只能为 0 或等于网格输入版本。
*/
bool restoreInputRevisions(quint64 nGridInputRevision,
quint64 nBuiltGridRevision,
quint64 nResultInputRevision);
/** @brief 清空方案状态,用于重新加载项目。 */
void clear();
private:
/** @brief 规范化有产量包含井,移除空编码、主井和重复项。 */
void normalizeIncludedWells();
/** @brief 保证当前结果井属于最后结果顺序,否则回退到第一口真实井。 */
void normalizeCurrentResultWellCode();
/** @brief 按本次主井和已启用主动井冻结结果下拉框井编码。 */
void freezeResultSelectableWellCodes();
private:
QString m_sPrimaryWellCode; ///< 主分析井的项目唯一 WellCode。
NM_CASE_WELL_MODE m_ePrimaryWellMode; ///< 主井在本次方案中的源汇角色。
bool m_bIncludeOtherWells; ///< 是否启用手工选择的有产量干扰井。
double m_dPebiGridControl; ///< 当前方案使用的 PEBI 网格疏密参数。
QVector<nmCalculationWellRef> m_vecIncludedWells; ///< 已选择的其他有产量井,不含自动观察井。
QString m_sCurrentResultWellCode; ///< 当前结果查看井,仅属于展示状态。
QVector<nmSolverWellRef> m_vecSolverWellOrder; ///< 网格确定的 DLL 数组下标映射。
QVector<nmSolverWellRef> m_vecResultSolverWellOrder; ///< 最后结果使用的独立槽位映射。
QStringList m_listResultSelectableWellCodes; ///< 最后结果允许在下拉框中显示的井编码。
quint64 m_nGridInputRevision; ///< 几何、选井等网格输入的最新版本。
quint64 m_nBuiltGridRevision; ///< 当前缓存网格对应版本0 表示无有效网格。
quint64 m_nResultInputRevision; ///< 产量、角色、PVT 等求解输入版本。
bool m_bResultsAvailable; ///< 是否存在一套可保存和查看的结果载荷。
bool m_bResultsValid; ///< 已有结果是否仍对应当前输入和网格。
};
#endif // NMDATANUMERICALANALYSISCASE_H