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/Src/nmNum/nmSubWxs/nmReservoirParameterCatalog...

856 lines
33 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.

#include "nmReservoirParameterCatalog.h"
#include "nmReservoirPropertiesDataSource.h"
#include "nmAttrRegistry.h"
#include "nmDataAttribute.h"
#include "nmDataPerforation.h"
#include <QCoreApplication>
namespace
{
/*
* Qt 4.8的lupdate无法跟踪editorText()的间接参数,以下标记只用于
* 收集中英文资源;运行时仍由同一翻译上下文返回文字。
*/
static const char* const s_pCatalogTranslationMarkers[] =
{
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Reservoir type"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Homogeneous"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Dual porosity pseudo steady state"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Fault flow model"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Region flow model"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Leaky"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Composite limit"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Fracture flow model"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Finite conductivity"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Infinite conductivity"),
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", "Fluid parameters"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Compression and saturation"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Reservoir parameters"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Vertical well"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Fractured vertical well"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Multistage fractured horizontal well"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Dual-medium parameters"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Geometry"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Flow properties"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Conductivity properties"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Region properties")
};
/** @brief 返回当前语言下的界面文字。 */
QString editorText(const char* pText)
{
Q_UNUSED(s_pCatalogTranslationMarkers);
return QCoreApplication::translate("nmWxReservoirPropertiesEditor", pText);
}
/** @brief 创建一个稳定枚举选项。 */
nmReservoirEnumOption enumOption(const QString& sCode, const char* pText)
{
nmReservoirEnumOption oOption;
oOption.m_sCode = sCode;
oOption.m_sText = editorText(pText);
return oOption;
}
/** @brief 创建一个数值字段描述。 */
nmReservoirParameterFieldInfo numericField(
const QString& sParameterId,
const QString& sBaseParameterId,
nmReservoirParameterEditorType eEditorType)
{
nmReservoirParameterFieldInfo oField;
oField.m_sParameterId = sParameterId;
oField.m_sBaseParameterId = sBaseParameterId;
oField.m_eEditorType = eEditorType;
oField.m_bUnitEnabled = true;
return oField;
}
/** @brief 创建一个浮点数字段描述。 */
nmReservoirParameterFieldInfo numericField(
const QString& sParameterId,
const QString& sBaseParameterId)
{
return numericField(sParameterId, sBaseParameterId,
NM_RESERVOIR_EDITOR_NUMBER);
}
/** @brief 创建一个明确不显示单位的浮点数字段。 */
nmReservoirParameterFieldInfo unitlessNumericField(
const QString& sParameterId,
const QString& sBaseParameterId)
{
nmReservoirParameterFieldInfo oField =
numericField(sParameterId, sBaseParameterId);
oField.m_bUnitEnabled = false;
return oField;
}
/** @brief 创建储层类型字段。 */
nmReservoirParameterFieldInfo reservoirModelField(
const QString& sParameterId)
{
nmReservoirParameterFieldInfo oField;
oField.m_sParameterId = sParameterId;
oField.m_sLabel = editorText("Reservoir type");
oField.m_eEditorType = NM_RESERVOIR_EDITOR_ENUM;
oField.m_bUnitEnabled = false;
oField.m_listOptions.append(enumOption("homogeneous", "Homogeneous"));
oField.m_listOptions.append(enumOption(
"dual_porosity_pss", "Dual porosity pseudo steady state"));
return oField;
}
/** @brief 创建断层或复合区流动模型字段。 */
nmReservoirParameterFieldInfo leakageModelField(
const QString& sParameterId,
const char* pLabel)
{
nmReservoirParameterFieldInfo oField;
oField.m_sParameterId = sParameterId;
oField.m_sLabel = editorText(pLabel);
oField.m_eEditorType = NM_RESERVOIR_EDITOR_ENUM;
oField.m_bUnitEnabled = false;
oField.m_listOptions.append(enumOption("leaky", "Leaky"));
oField.m_listOptions.append(enumOption(
"composite_limit", "Composite limit"));
return oField;
}
/** @brief 创建裂缝导流模型字段。 */
nmReservoirParameterFieldInfo fractureModelField(
const QString& sParameterId)
{
nmReservoirParameterFieldInfo oField;
oField.m_sParameterId = sParameterId;
oField.m_sLabel = editorText("Fracture flow model");
oField.m_eEditorType = NM_RESERVOIR_EDITOR_ENUM;
oField.m_bUnitEnabled = false;
oField.m_listOptions.append(enumOption(
"finite_conductivity", "Finite conductivity"));
oField.m_listOptions.append(enumOption(
"infinite_conductivity", "Infinite conductivity"));
return oField;
}
/** @brief 创建页面上的一个参数分组。 */
nmReservoirParameterGroupInfo parameterGroup(
const char* pTitle,
int nRow,
int nColumn,
int nColumnSpan)
{
nmReservoirParameterGroupInfo oGroup;
oGroup.m_sTitle = editorText(pTitle);
oGroup.m_nRow = nRow;
oGroup.m_nColumn = nColumn;
oGroup.m_nRowSpan = 1;
oGroup.m_nColumnSpan = nColumnSpan;
oGroup.m_bValueRightAligned = false;
return oGroup;
}
/** @brief 为参数ID添加对象编码前缀。 */
QString prefixed(const QString& sObjectCode, const char* pParameterId)
{
return sObjectCode + "_" + QString::fromLatin1(pParameterId);
}
/** @brief 生成无井编码时的会话编码。 */
QString wellCode(const nmDataWellBase& oWell,
const QString& sFallbackPrefix,
int nIndex)
{
QString sCode = oWell.getWellCode();
if (sCode.isEmpty())
{
sCode = QString("%1%2").arg(sFallbackPrefix)
.arg(nIndex + 1, 4, 10, QChar('0'));
}
return sCode;
}
/** @brief 创建井对象的分组描述。 */
void createWellGroups(nmReservoirPropertyObjectInfo& oInfo,
NM_WELL_MODEL eWellType,
bool bHasPerforation)
{
nmReservoirParameterGroupInfo oPosition =
parameterGroup("Position and wellbore", 0, 0, 1);
oPosition.m_listFields
<< numericField(prefixed(oInfo.m_sObjectCode, "W_X"), "W_X")
<< numericField(prefixed(oInfo.m_sObjectCode, "W_Y"), "W_Y")
<< numericField(prefixed(oInfo.m_sObjectCode, "W_Rw"), "W_Rw");
if (bHasPerforation)
{
oPosition.m_listFields.append(numericField(
prefixed(oInfo.m_sObjectCode, "W_Skin"), "W_Skin"));
}
const char* pStorageGroupTitle = eWellType == Vertical_Well
? "Wellbore storage" : "Wellbore storage and fracture";
nmReservoirParameterGroupInfo oStorage =
parameterGroup(pStorageGroupTitle, 0, 1, 1);
oStorage.m_listFields.append(numericField(
prefixed(oInfo.m_sObjectCode, "W_C"), "W_C"));
if (eWellType == Vertical_Fractured_Well)
{
oStorage.m_listFields
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_FractureHalfLength"),
"W_FractureHalfLength")
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_FractureAngle"),
"W_FractureAngle")
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_Dfc"), "W_Dfc");
}
else if (eWellType == Horizontal_Fractured_Well)
{
oStorage.m_listFields
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_WellLength"),
"W_WellLength")
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_DrainAngle"),
"W_DrainAngle")
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_NumberOfFractures"),
"W_NumberOfFractures",
NM_RESERVOIR_EDITOR_INTEGER)
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_FractureHalfLength"),
"W_FractureHalfLength")
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_FractureAngle"),
"W_FractureAngle")
<< numericField(prefixed(oInfo.m_sObjectCode,
"W_Dfc"), "W_Dfc");
}
oInfo.m_listGroups << oPosition << oStorage;
}
/** @brief 注册一口井的全部可编辑数值属性。 */
void registerWell(nmAttrRegistry* pRegistry,
nmDataWellBase& oWell,
const QString& sCode)
{
pRegistry->regAttr(prefixed(sCode, "W_X"), &oWell.getX());
pRegistry->regAttr(prefixed(sCode, "W_Y"), &oWell.getY());
pRegistry->regAttr(prefixed(sCode, "W_Rw"), &oWell.getRadius());
pRegistry->regAttr(prefixed(sCode, "W_C"), &oWell.getWellboreStorage());
if (oWell.getPerforationCount() > 0 &&
oWell.getPerforation(0) != nullptr)
{
pRegistry->regAttr(prefixed(sCode, "W_Skin"),
&oWell.getPerforation(0)->getSkin());
}
}
/** @brief 判断对象描述中是否包含指定枚举字段。 */
bool containsEnumField(const nmReservoirPropertyObjectInfo& oInfo,
const QString& sParameterId)
{
for (int nGroupIndex = 0;
nGroupIndex < oInfo.m_listGroups.size();
++nGroupIndex)
{
const nmReservoirParameterGroupInfo& oGroup =
oInfo.m_listGroups[nGroupIndex];
for (int nFieldIndex = 0;
nFieldIndex < oGroup.m_listFields.size();
++nFieldIndex)
{
const nmReservoirParameterFieldInfo& oField =
oGroup.m_listFields[nFieldIndex];
if (oField.m_eEditorType == NM_RESERVOIR_EDITOR_ENUM &&
oField.m_sParameterId == sParameterId)
{
return true;
}
}
}
return false;
}
}
void nmReservoirParameterCatalog::registerSnapshot(
nmAttrRegistry* pRegistry,
nmReservoirPropertiesSnapshot& oSnapshot)
{
if (pRegistry == nullptr)
{
return;
}
// 第一步:重新建立编辑会话独占的注册表,杜绝与实时数据交叉连接。
pRegistry->clear();
pRegistry->regAttr("h", &oSnapshot.m_oReservoir.getThickness());
pRegistry->regAttr("Pi", &oSnapshot.m_oReservoir.getInitialPressure());
pRegistry->regAttr("K", &oSnapshot.m_oReservoir.getPermeability());
pRegistry->regAttr("phi", &oSnapshot.m_oReservoir.getPorosity());
pRegistry->regAttr("Cti", &oSnapshot.m_oReservoir.getCt());
pRegistry->regAttr("Cf", &oSnapshot.m_oReservoir.getCf());
pRegistry->regAttr("Soi", &oSnapshot.m_oReservoir.getSoi());
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());
// 第二步:注册求解器支持的三类井及其压裂参数。
for (int nIndex = 0;
nIndex < oSnapshot.m_vecVerticalWells.size();
++nIndex)
{
nmDataVerticalWell& oWell = oSnapshot.m_vecVerticalWells[nIndex];
registerWell(pRegistry, oWell, wellCode(oWell, "VWELL", nIndex));
}
for (int nIndex = 0;
nIndex < oSnapshot.m_vecVerticalFracturedWells.size();
++nIndex)
{
nmDataVerticalFracturedWell& oWell =
oSnapshot.m_vecVerticalFracturedWells[nIndex];
QString sCode = wellCode(oWell, "VFWELL", nIndex);
registerWell(pRegistry, oWell, sCode);
pRegistry->regAttr(prefixed(sCode, "W_FractureHalfLength"),
&oWell.getFractureHalfLength());
pRegistry->regAttr(prefixed(sCode, "W_FractureAngle"),
&oWell.getFractureAngle());
pRegistry->regAttr(prefixed(sCode, "W_Dfc"), &oWell.getDfc());
}
for (int nIndex = 0;
nIndex < oSnapshot.m_vecHorizontalFracturedWells.size();
++nIndex)
{
nmDataHorizontalFracturedWell& oWell =
oSnapshot.m_vecHorizontalFracturedWells[nIndex];
QString sCode = wellCode(oWell, "HFWELL", nIndex);
registerWell(pRegistry, oWell, sCode);
pRegistry->regAttr(prefixed(sCode, "W_WellLength"),
&oWell.getWellLength());
pRegistry->regAttr(prefixed(sCode, "W_DrainAngle"),
&oWell.getDrainAngle());
pRegistry->regAttr(prefixed(sCode, "W_NumberOfFractures"),
&oWell.getNumberOfFractures());
pRegistry->regAttr(prefixed(sCode, "W_FractureHalfLength"),
&oWell.getFractureHalfLength());
pRegistry->regAttr(prefixed(sCode, "W_FractureAngle"),
&oWell.getFractureAngle());
pRegistry->regAttr(prefixed(sCode, "W_Dfc"), &oWell.getDfc());
}
// 第三步:注册区域标记和复合区数值参数。
for (int nIndex = 0;
nIndex < oSnapshot.m_vecRegionMarks.size();
++nIndex)
{
QString sCode = QString("RMARK%1")
.arg(nIndex + 1, 4, 10, QChar('0'));
nmDataRegionMark& oMark = oSnapshot.m_vecRegionMarks[nIndex];
pRegistry->regAttr(prefixed(sCode, "RM_ComW"), &oMark.getComW());
pRegistry->regAttr(prefixed(sCode, "RM_ComKr"), &oMark.getComKr());
pRegistry->regAttr(prefixed(sCode, "RM_NetToGross"),
&oMark.getNetToGross());
}
for (int nIndex = 0;
nIndex < oSnapshot.m_vecRegions.size();
++nIndex)
{
QString sCode = QString("REGION%1")
.arg(nIndex + 1, 4, 10, QChar('0'));
pRegistry->regAttr(prefixed(sCode, "R_Leakage"),
&oSnapshot.m_vecRegions[nIndex]
.getRegionLeakage());
}
// 第四步注册断层和普通裂缝DFN由专用功能维护。
for (int nIndex = 0;
nIndex < oSnapshot.m_vecFaults.size();
++nIndex)
{
QString sCode = QString("FAULT%1")
.arg(nIndex + 1, 4, 10, QChar('0'));
nmDataFault& oFault = oSnapshot.m_vecFaults[nIndex];
pRegistry->regAttr(prefixed(sCode, "FT_X0"), &oFault.getStartX());
pRegistry->regAttr(prefixed(sCode, "FT_Y0"), &oFault.getStartY());
pRegistry->regAttr(prefixed(sCode, "FT_X1"), &oFault.getEndX());
pRegistry->regAttr(prefixed(sCode, "FT_Y1"), &oFault.getEndY());
pRegistry->regAttr(prefixed(sCode, "FT_Leakage"),
&oFault.getFaultLeakage());
}
int nVisibleFracture = 0;
for (int nIndex = 0;
nIndex < oSnapshot.m_vecFractures.size();
++nIndex)
{
nmDataFracture& oFracture = oSnapshot.m_vecFractures[nIndex];
if (oFracture.getFractureType().getValue().toString() == "DFN")
{
continue;
}
QString sCode = QString("FRAC%1")
.arg(++nVisibleFracture, 4, 10, QChar('0'));
pRegistry->regAttr(prefixed(sCode, "F_X0"),
&oFracture.getStartX());
pRegistry->regAttr(prefixed(sCode, "F_Y0"),
&oFracture.getStartY());
pRegistry->regAttr(prefixed(sCode, "F_X1"),
&oFracture.getEndX());
pRegistry->regAttr(prefixed(sCode, "F_Y1"),
&oFracture.getEndY());
pRegistry->regAttr(prefixed(sCode, "F_FC"),
&oFracture.getFractureDfc());
pRegistry->regAttr(prefixed(sCode, "F_DW"),
&oFracture.getFractureDw());
}
}
QList<nmReservoirPropertyObjectInfo>
nmReservoirParameterCatalog::createObjectInfos(
nmReservoirPropertiesCategory eCategory,
nmReservoirPropertiesSnapshot& oSnapshot)
{
QList<nmReservoirPropertyObjectInfo> listInfos;
if (eCategory == NM_RESERVOIR_PAGE_RESERVOIR)
{
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType = NM_RESERVOIR_OBJECT_RESERVOIR;
oInfo.m_nSourceIndex = 0;
oInfo.m_sObjectCode = "RESERVOIR";
oInfo.m_sDisplayName = editorText("Reservoir parameters");
nmReservoirParameterGroupInfo oBasic =
parameterGroup("Basic properties", 0, 0, 1);
oBasic.m_nRowSpan = 2;
oBasic.m_bValueRightAligned = true;
oBasic.m_listFields
<< numericField("Pi", "Pi")
<< numericField("K", "K")
<< numericField("h", "h")
<< 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");
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;
listInfos.append(oInfo);
return listInfos;
}
if (eCategory == NM_RESERVOIR_PAGE_WELL)
{
for (int nIndex = 0;
nIndex < oSnapshot.m_vecVerticalWells.size();
++nIndex)
{
nmDataVerticalWell& oWell =
oSnapshot.m_vecVerticalWells[nIndex];
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType = NM_RESERVOIR_OBJECT_VERTICAL_WELL;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = wellCode(oWell, "VWELL", nIndex);
oInfo.m_sDisplayName = oWell.getWellName() + " - " +
editorText("Vertical well");
createWellGroups(oInfo, Vertical_Well,
oWell.getPerforationCount() > 0);
listInfos.append(oInfo);
}
for (int nIndex = 0;
nIndex < oSnapshot.m_vecVerticalFracturedWells.size();
++nIndex)
{
nmDataVerticalFracturedWell& oWell =
oSnapshot.m_vecVerticalFracturedWells[nIndex];
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType =
NM_RESERVOIR_OBJECT_VERTICAL_FRAC_WELL;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = wellCode(oWell, "VFWELL", nIndex);
oInfo.m_sDisplayName = oWell.getWellName() + " - " +
editorText("Fractured vertical well");
createWellGroups(oInfo, Vertical_Fractured_Well,
oWell.getPerforationCount() > 0);
listInfos.append(oInfo);
}
for (int nIndex = 0;
nIndex < oSnapshot.m_vecHorizontalFracturedWells.size();
++nIndex)
{
nmDataHorizontalFracturedWell& oWell =
oSnapshot.m_vecHorizontalFracturedWells[nIndex];
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType =
NM_RESERVOIR_OBJECT_HORIZONTAL_FRAC_WELL;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = wellCode(oWell, "HFWELL", nIndex);
oInfo.m_sDisplayName = oWell.getWellName() + " - " +
editorText("Multistage fractured horizontal well");
createWellGroups(oInfo, Horizontal_Fractured_Well,
oWell.getPerforationCount() > 0);
listInfos.append(oInfo);
}
return listInfos;
}
if (eCategory == NM_RESERVOIR_PAGE_REGION_MARK)
{
for (int nIndex = 0;
nIndex < oSnapshot.m_vecRegionMarks.size();
++nIndex)
{
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType = NM_RESERVOIR_OBJECT_REGION_MARK;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = QString("RMARK%1")
.arg(nIndex + 1, 4, 10, QChar('0'));
oInfo.m_sDisplayName =
oSnapshot.m_vecRegionMarks[nIndex].getRegionMarkName();
nmReservoirParameterGroupInfo oDual =
parameterGroup("Dual-medium parameters", 0, 0, 2);
oDual.m_listFields
<< reservoirModelField(prefixed(
oInfo.m_sObjectCode, "RM_ReservoirType"))
<< numericField(prefixed(
oInfo.m_sObjectCode, "RM_ComW"), "RM_ComW")
<< numericField(prefixed(
oInfo.m_sObjectCode, "RM_ComKr"), "RM_ComKr")
<< numericField(prefixed(
oInfo.m_sObjectCode, "RM_NetToGross"),
"RM_NetToGross");
oInfo.m_listGroups.append(oDual);
listInfos.append(oInfo);
}
return listInfos;
}
if (eCategory == NM_RESERVOIR_PAGE_FAULT)
{
for (int nIndex = 0;
nIndex < oSnapshot.m_vecFaults.size();
++nIndex)
{
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType = NM_RESERVOIR_OBJECT_FAULT;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = QString("FAULT%1")
.arg(nIndex + 1, 4, 10, QChar('0'));
oInfo.m_sDisplayName =
oSnapshot.m_vecFaults[nIndex].getFaultName();
nmReservoirParameterGroupInfo oGeometry =
parameterGroup("Geometry", 0, 0, 1);
oGeometry.m_listFields
<< numericField(prefixed(
oInfo.m_sObjectCode, "FT_X0"), "FT_X0")
<< numericField(prefixed(
oInfo.m_sObjectCode, "FT_Y0"), "FT_Y0")
<< numericField(prefixed(
oInfo.m_sObjectCode, "FT_X1"), "FT_X1")
<< numericField(prefixed(
oInfo.m_sObjectCode, "FT_Y1"), "FT_Y1");
nmReservoirParameterGroupInfo oFlow =
parameterGroup("Flow properties", 0, 1, 1);
oFlow.m_listFields
<< leakageModelField(prefixed(
oInfo.m_sObjectCode, "FT_FlowModel"),
"Fault flow model")
<< numericField(prefixed(
oInfo.m_sObjectCode, "FT_Leakage"),
"FT_Leakage");
oInfo.m_listGroups << oGeometry << oFlow;
listInfos.append(oInfo);
}
return listInfos;
}
if (eCategory == NM_RESERVOIR_PAGE_FRACTURE)
{
int nVisibleFracture = 0;
for (int nIndex = 0;
nIndex < oSnapshot.m_vecFractures.size();
++nIndex)
{
nmDataFracture& oFracture =
oSnapshot.m_vecFractures[nIndex];
if (oFracture.getFractureType().getValue().toString() ==
"DFN")
{
continue;
}
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType = NM_RESERVOIR_OBJECT_FRACTURE;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = QString("FRAC%1")
.arg(++nVisibleFracture, 4, 10, QChar('0'));
oInfo.m_sDisplayName = oFracture.getFractureName();
nmReservoirParameterGroupInfo oGeometry =
parameterGroup("Geometry", 0, 0, 1);
oGeometry.m_listFields
<< numericField(prefixed(
oInfo.m_sObjectCode, "F_X0"), "F_X0")
<< numericField(prefixed(
oInfo.m_sObjectCode, "F_Y0"), "F_Y0")
<< numericField(prefixed(
oInfo.m_sObjectCode, "F_X1"), "F_X1")
<< numericField(prefixed(
oInfo.m_sObjectCode, "F_Y1"), "F_Y1");
nmReservoirParameterGroupInfo oFlow =
parameterGroup("Conductivity properties", 0, 1, 1);
oFlow.m_listFields
<< fractureModelField(prefixed(
oInfo.m_sObjectCode, "F_FlowModel"))
<< numericField(prefixed(
oInfo.m_sObjectCode, "F_FC"), "F_FC")
<< numericField(prefixed(
oInfo.m_sObjectCode, "F_DW"), "F_DW");
oInfo.m_listGroups << oGeometry << oFlow;
listInfos.append(oInfo);
}
return listInfos;
}
if (eCategory == NM_RESERVOIR_PAGE_COMPOSITE_REGION)
{
for (int nIndex = 0;
nIndex < oSnapshot.m_vecRegions.size();
++nIndex)
{
nmReservoirPropertyObjectInfo oInfo;
oInfo.m_eCategory = eCategory;
oInfo.m_eObjectType = NM_RESERVOIR_OBJECT_REGION;
oInfo.m_nSourceIndex = nIndex;
oInfo.m_sObjectCode = QString("REGION%1")
.arg(nIndex + 1, 4, 10, QChar('0'));
oInfo.m_sDisplayName =
oSnapshot.m_vecRegions[nIndex].getRegoinName();
nmReservoirParameterGroupInfo oRegion =
parameterGroup("Region properties", 0, 0, 2);
oRegion.m_listFields
<< leakageModelField(prefixed(
oInfo.m_sObjectCode, "R_FlowModel"),
"Region flow model")
<< numericField(prefixed(
oInfo.m_sObjectCode, "R_Leakage"),
"R_Leakage");
oInfo.m_listGroups.append(oRegion);
listInfos.append(oInfo);
}
}
return listInfos;
}
QString nmReservoirParameterCatalog::enumCodeFromStoredValue(
const QString& sParameterId,
const QString& sStoredValue)
{
QString sValue = sStoredValue.trimmed().toLower();
if (sParameterId.endsWith("ReservoirType"))
{
return sValue.contains("dual")
? "dual_porosity_pss" : "homogeneous";
}
if (sParameterId.endsWith("F_FlowModel"))
{
return sValue.contains("infinite")
? "infinite_conductivity" : "finite_conductivity";
}
if (sParameterId.endsWith("FlowModel"))
{
return sValue.contains("leaky") ? "leaky" : "composite_limit";
}
return QString();
}
QString nmReservoirParameterCatalog::storedValueFromEnumCode(
const QString& sParameterId,
const QString& sCode)
{
if (sParameterId.endsWith("ReservoirType"))
{
return sCode == "dual_porosity_pss"
? "Dual porosity pseudo steady state" : "Homogeneous";
}
if (sParameterId.endsWith("F_FlowModel"))
{
return sCode == "infinite_conductivity"
? "Infinite Conductivity" : "Finite Conductivity";
}
if (sParameterId.endsWith("FlowModel"))
{
return sCode == "leaky" ? "Leaky" : "Composite limit";
}
return QString();
}
QString nmReservoirParameterCatalog::enumCode(
const nmReservoirPropertiesSnapshot& oSnapshot,
const QString& sParameterId)
{
if (sParameterId == "ReservoirType")
{
nmDataReservoir& oReservoir =
const_cast<nmDataReservoir&>(oSnapshot.m_oReservoir);
return enumCodeFromStoredValue(
sParameterId,
oReservoir.getReservoirType().getValue().toString());
}
QList<nmReservoirPropertyObjectInfo> listAll;
nmReservoirPropertiesSnapshot& oWritable =
const_cast<nmReservoirPropertiesSnapshot&>(oSnapshot);
listAll << createObjectInfos(NM_RESERVOIR_PAGE_FAULT,
oWritable)
<< createObjectInfos(NM_RESERVOIR_PAGE_FRACTURE,
oWritable)
<< createObjectInfos(NM_RESERVOIR_PAGE_COMPOSITE_REGION,
oWritable)
<< createObjectInfos(NM_RESERVOIR_PAGE_REGION_MARK,
oWritable);
for (int nInfoIndex = 0;
nInfoIndex < listAll.size();
++nInfoIndex)
{
const nmReservoirPropertyObjectInfo& oInfo =
listAll[nInfoIndex];
if (!containsEnumField(oInfo, sParameterId))
{
continue;
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_REGION_MARK)
{
nmDataRegionMark& oMark =
oWritable.m_vecRegionMarks[oInfo.m_nSourceIndex];
return enumCodeFromStoredValue(
sParameterId,
oMark.getReservoirType().getValue().toString());
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_FAULT)
{
nmDataFault& oFault =
oWritable.m_vecFaults[oInfo.m_nSourceIndex];
return enumCodeFromStoredValue(
sParameterId,
oFault.getFaultFlowModel().getValue().toString());
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_FRACTURE)
{
nmDataFracture& oFracture =
oWritable.m_vecFractures[oInfo.m_nSourceIndex];
return enumCodeFromStoredValue(
sParameterId,
oFracture.getFractureFlowModel()
.getValue().toString());
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_REGION)
{
nmDataRegion& oRegion =
oWritable.m_vecRegions[oInfo.m_nSourceIndex];
return enumCodeFromStoredValue(
sParameterId,
oRegion.getRegionFlowModel().getValue().toString());
}
}
return QString();
}
bool nmReservoirParameterCatalog::setEnumCode(
nmReservoirPropertiesSnapshot& oSnapshot,
const QString& sParameterId,
const QString& sCode)
{
QString sStoredValue =
storedValueFromEnumCode(sParameterId, sCode);
if (sStoredValue.isEmpty())
{
return false;
}
if (sParameterId == "ReservoirType")
{
oSnapshot.m_oReservoir.getReservoirType()
.setValue(sStoredValue);
return true;
}
QList<nmReservoirPropertyObjectInfo> listAll;
listAll << createObjectInfos(NM_RESERVOIR_PAGE_FAULT,
oSnapshot)
<< createObjectInfos(NM_RESERVOIR_PAGE_FRACTURE,
oSnapshot)
<< createObjectInfos(NM_RESERVOIR_PAGE_COMPOSITE_REGION,
oSnapshot)
<< createObjectInfos(NM_RESERVOIR_PAGE_REGION_MARK,
oSnapshot);
for (int nInfoIndex = 0;
nInfoIndex < listAll.size();
++nInfoIndex)
{
const nmReservoirPropertyObjectInfo& oInfo =
listAll[nInfoIndex];
if (!containsEnumField(oInfo, sParameterId))
{
continue;
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_REGION_MARK)
{
oSnapshot.m_vecRegionMarks[oInfo.m_nSourceIndex]
.getReservoirType().setValue(sStoredValue);
return true;
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_FAULT)
{
oSnapshot.m_vecFaults[oInfo.m_nSourceIndex]
.getFaultFlowModel().setValue(sStoredValue);
return true;
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_FRACTURE)
{
oSnapshot.m_vecFractures[oInfo.m_nSourceIndex]
.getFractureFlowModel().setValue(sStoredValue);
return true;
}
if (oInfo.m_eObjectType == NM_RESERVOIR_OBJECT_REGION)
{
oSnapshot.m_vecRegions[oInfo.m_nSourceIndex]
.getRegionFlowModel().setValue(sStoredValue);
return true;
}
}
return false;
}