|
|
|
|
@ -2,6 +2,7 @@
|
|
|
|
|
|
|
|
|
|
#include "nmReservoirPropertiesDataSource.h"
|
|
|
|
|
#include "nmAttrRegistry.h"
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
#include "nmDataAttribute.h"
|
|
|
|
|
#include "nmDataPerforation.h"
|
|
|
|
|
|
|
|
|
|
@ -31,9 +32,12 @@ static const char* const s_pCatalogTranslationMarkers[] =
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Position and wellbore"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Wellbore storage"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Wellbore storage and fracture"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Basic properties"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Basic and medium properties"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Fluid parameters"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Compression and saturation"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Oil phase parameters"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Water phase parameters"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Compressibility"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Compressibility and saturation"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Reservoir parameters"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Vertical well"),
|
|
|
|
|
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Fractured vertical well"),
|
|
|
|
|
@ -162,6 +166,141 @@ nmReservoirParameterGroupInfo parameterGroup(
|
|
|
|
|
return oGroup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 返回当前求解器模型对应的流体参数分组标题。 */
|
|
|
|
|
const char* solverPvtGroupTitle(
|
|
|
|
|
int nSolverModelType,
|
|
|
|
|
NM_PHASE_TYPE ePhaseType)
|
|
|
|
|
{
|
|
|
|
|
switch (nSolverModelType)
|
|
|
|
|
{
|
|
|
|
|
case SMT_Oil_ConstPvt:
|
|
|
|
|
return "Oil phase parameters";
|
|
|
|
|
case SMT_Water_ConstPvt:
|
|
|
|
|
return "Water phase parameters";
|
|
|
|
|
default:
|
|
|
|
|
if (nSolverModelType == 0 && ePhaseType == PHASE_Oil)
|
|
|
|
|
{
|
|
|
|
|
return "Oil phase parameters";
|
|
|
|
|
}
|
|
|
|
|
if (nSolverModelType == 0 && ePhaseType == PHASE_Water)
|
|
|
|
|
{
|
|
|
|
|
return "Water phase parameters";
|
|
|
|
|
}
|
|
|
|
|
return "Fluid parameters";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 按求解器模型向流体分组添加实际使用的PVT单值参数。 */
|
|
|
|
|
void appendSolverPvtFields(
|
|
|
|
|
nmReservoirParameterGroupInfo& oGroup,
|
|
|
|
|
int nSolverModelType,
|
|
|
|
|
NM_PHASE_TYPE ePhaseType)
|
|
|
|
|
{
|
|
|
|
|
switch (nSolverModelType)
|
|
|
|
|
{
|
|
|
|
|
case SMT_Oil_ConstPvt:
|
|
|
|
|
oGroup.m_listFields
|
|
|
|
|
<< numericField("Miuo", "Miuo")
|
|
|
|
|
<< unitlessNumericField("Bo", "Bo");
|
|
|
|
|
break;
|
|
|
|
|
case SMT_Water_ConstPvt:
|
|
|
|
|
oGroup.m_listFields
|
|
|
|
|
<< numericField("Miuw", "Miuw")
|
|
|
|
|
<< unitlessNumericField("Bw", "Bw");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// 自定义数据源未提供模型类型时,按单相相态保留兼容入口。
|
|
|
|
|
if (nSolverModelType == 0 &&
|
|
|
|
|
(ePhaseType == PHASE_Oil ||
|
|
|
|
|
ePhaseType == PHASE_UNKNOWN))
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields
|
|
|
|
|
<< numericField("Miuo", "Miuo")
|
|
|
|
|
<< unitlessNumericField("Bo", "Bo");
|
|
|
|
|
}
|
|
|
|
|
else if (nSolverModelType == 0 &&
|
|
|
|
|
ePhaseType == PHASE_Water)
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields
|
|
|
|
|
<< numericField("Miuw", "Miuw")
|
|
|
|
|
<< unitlessNumericField("Bw", "Bw");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 判断当前模型是否需要编辑初始含水饱和度。 */
|
|
|
|
|
bool solverUsesInitialWaterSaturation(
|
|
|
|
|
int nSolverModelType,
|
|
|
|
|
NM_PHASE_TYPE ePhaseType)
|
|
|
|
|
{
|
|
|
|
|
return nSolverModelType == SMT_Oil_Water_TwoPhase ||
|
|
|
|
|
(nSolverModelType == 0 &&
|
|
|
|
|
ePhaseType == PHASE_Oil_Water);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 判断当前模型是否需要编辑初始含油饱和度。 */
|
|
|
|
|
bool solverUsesInitialOilSaturation(
|
|
|
|
|
int nSolverModelType,
|
|
|
|
|
NM_PHASE_TYPE ePhaseType)
|
|
|
|
|
{
|
|
|
|
|
return nSolverModelType == SMT_Oil_Water_TwoPhase ||
|
|
|
|
|
(nSolverModelType == 0 &&
|
|
|
|
|
ePhaseType == PHASE_Oil_Water);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 判断当前模型是否需要编辑初始含气饱和度。 */
|
|
|
|
|
bool solverUsesInitialGasSaturation(
|
|
|
|
|
int nSolverModelType,
|
|
|
|
|
NM_PHASE_TYPE ePhaseType)
|
|
|
|
|
{
|
|
|
|
|
return nSolverModelType == SMT_Gas_VariablePvt ||
|
|
|
|
|
nSolverModelType == SMT_Gas_PseudoPressure ||
|
|
|
|
|
(nSolverModelType == 0 &&
|
|
|
|
|
ePhaseType == PHASE_Gas);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 按求解器模型添加实际使用的压缩系数和饱和度参数。 */
|
|
|
|
|
void appendSolverCompressionFields(
|
|
|
|
|
nmReservoirParameterGroupInfo& oGroup,
|
|
|
|
|
int nSolverModelType,
|
|
|
|
|
NM_PHASE_TYPE ePhaseType)
|
|
|
|
|
{
|
|
|
|
|
switch (nSolverModelType)
|
|
|
|
|
{
|
|
|
|
|
case SMT_Oil_ConstPvt:
|
|
|
|
|
case SMT_Water_ConstPvt:
|
|
|
|
|
oGroup.m_listFields.append(numericField("Cti", "Cti"));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (nSolverModelType == 0 &&
|
|
|
|
|
(ePhaseType == PHASE_Oil ||
|
|
|
|
|
ePhaseType == PHASE_Water ||
|
|
|
|
|
ePhaseType == PHASE_UNKNOWN))
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields.append(numericField("Cti", "Cti"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields.append(numericField("Cf", "Cf"));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (solverUsesInitialOilSaturation(nSolverModelType, ePhaseType))
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields.append(numericField("Soi", "Soi"));
|
|
|
|
|
}
|
|
|
|
|
if (solverUsesInitialWaterSaturation(nSolverModelType, ePhaseType))
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields.append(numericField("Swi", "Swi"));
|
|
|
|
|
}
|
|
|
|
|
if (solverUsesInitialGasSaturation(nSolverModelType, ePhaseType))
|
|
|
|
|
{
|
|
|
|
|
oGroup.m_listFields.append(numericField("Sgi", "Sgi"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 为参数ID添加对象编码前缀。 */
|
|
|
|
|
QString prefixed(const QString& sObjectCode, const char* pParameterId)
|
|
|
|
|
{
|
|
|
|
|
@ -306,10 +445,12 @@ void nmReservoirParameterCatalog::registerSnapshot(
|
|
|
|
|
pRegistry->regAttr("Cti", &oSnapshot.m_oReservoir.getCt());
|
|
|
|
|
pRegistry->regAttr("Cf", &oSnapshot.m_oReservoir.getCf());
|
|
|
|
|
pRegistry->regAttr("Soi", &oSnapshot.m_oReservoir.getSoi());
|
|
|
|
|
pRegistry->regAttr("Sgi", &oSnapshot.m_oReservoir.getSgi());
|
|
|
|
|
pRegistry->regAttr("Swi", &oSnapshot.m_oReservoir.getSwi());
|
|
|
|
|
pRegistry->regAttr("Bo", &oSnapshot.m_oReservoir.getBo());
|
|
|
|
|
pRegistry->regAttr("Miuo", &oSnapshot.m_oReservoir.getMiuo());
|
|
|
|
|
pRegistry->regAttr("KxKy", &oSnapshot.m_oReservoir.getKxKy());
|
|
|
|
|
pRegistry->regAttr("Bw", &oSnapshot.m_oReservoir.getBw());
|
|
|
|
|
pRegistry->regAttr("Miuw", &oSnapshot.m_oReservoir.getMiuw());
|
|
|
|
|
|
|
|
|
|
// 第二步:注册求解器支持的三类井及其压裂参数。
|
|
|
|
|
for (int nIndex = 0;
|
|
|
|
|
@ -437,8 +578,11 @@ nmReservoirParameterCatalog::createObjectInfos(
|
|
|
|
|
oInfo.m_sObjectCode = "RESERVOIR";
|
|
|
|
|
oInfo.m_sDisplayName = editorText("Reservoir parameters");
|
|
|
|
|
|
|
|
|
|
NM_PHASE_TYPE ePhaseType =
|
|
|
|
|
oSnapshot.m_oReservoir.getPhaseType();
|
|
|
|
|
|
|
|
|
|
nmReservoirParameterGroupInfo oBasic =
|
|
|
|
|
parameterGroup("Basic properties", 0, 0, 1);
|
|
|
|
|
parameterGroup("Basic and medium properties", 0, 0, 1);
|
|
|
|
|
oBasic.m_nRowSpan = 2;
|
|
|
|
|
oBasic.m_bValueRightAligned = true;
|
|
|
|
|
oBasic.m_listFields
|
|
|
|
|
@ -448,21 +592,37 @@ nmReservoirParameterCatalog::createObjectInfos(
|
|
|
|
|
<< numericField("phi", "phi");
|
|
|
|
|
|
|
|
|
|
nmReservoirParameterGroupInfo oFluid =
|
|
|
|
|
parameterGroup("Fluid parameters", 0, 1, 1);
|
|
|
|
|
oFluid.m_listFields
|
|
|
|
|
<< reservoirModelField("ReservoirType")
|
|
|
|
|
<< numericField("Miuo", "Miuo")
|
|
|
|
|
<< unitlessNumericField("Bo", "Bo")
|
|
|
|
|
<< numericField("KxKy", "KxKy");
|
|
|
|
|
parameterGroup(solverPvtGroupTitle(
|
|
|
|
|
oSnapshot.m_nSolverModelType,
|
|
|
|
|
ePhaseType),
|
|
|
|
|
0, 1, 1);
|
|
|
|
|
appendSolverPvtFields(oFluid,
|
|
|
|
|
oSnapshot.m_nSolverModelType,
|
|
|
|
|
ePhaseType);
|
|
|
|
|
|
|
|
|
|
bool bUsesSaturation = solverUsesInitialWaterSaturation(
|
|
|
|
|
oSnapshot.m_nSolverModelType, ePhaseType) ||
|
|
|
|
|
solverUsesInitialGasSaturation(
|
|
|
|
|
oSnapshot.m_nSolverModelType, ePhaseType);
|
|
|
|
|
nmReservoirParameterGroupInfo oCompression =
|
|
|
|
|
parameterGroup("Compression and saturation", 1, 1, 1);
|
|
|
|
|
oCompression.m_listFields
|
|
|
|
|
<< numericField("Cti", "Cti")
|
|
|
|
|
<< numericField("Cf", "Cf")
|
|
|
|
|
<< numericField("Soi", "Soi")
|
|
|
|
|
<< numericField("Swi", "Swi");
|
|
|
|
|
oInfo.m_listGroups << oBasic << oFluid << oCompression;
|
|
|
|
|
parameterGroup(bUsesSaturation
|
|
|
|
|
? "Compressibility and saturation"
|
|
|
|
|
: "Compressibility",
|
|
|
|
|
oFluid.m_listFields.isEmpty() ? 0 : 1,
|
|
|
|
|
1, 1);
|
|
|
|
|
if (oFluid.m_listFields.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
oCompression.m_nRowSpan = 2;
|
|
|
|
|
}
|
|
|
|
|
appendSolverCompressionFields(oCompression,
|
|
|
|
|
oSnapshot.m_nSolverModelType,
|
|
|
|
|
ePhaseType);
|
|
|
|
|
oInfo.m_listGroups.append(oBasic);
|
|
|
|
|
if (!oFluid.m_listFields.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
oInfo.m_listGroups.append(oFluid);
|
|
|
|
|
}
|
|
|
|
|
oInfo.m_listGroups.append(oCompression);
|
|
|
|
|
listInfos.append(oInfo);
|
|
|
|
|
return listInfos;
|
|
|
|
|
}
|
|
|
|
|
|