|
|
#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
|