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

853 lines
33 KiB
C++

#include "nmReservoirParameterCatalog.h"
#include "nmReservoirPropertiesDataSource.h"
#include "nmAttrRegistry.h"
#include "nmDataAttribute.h"
#include "nmDataPerforation.h"
#include <QCoreApplication>
namespace
{
/*
* Qt 4.8lupdateeditorText()
*
*/
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", "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", "Vertical fractured well"),
QT_TRANSLATE_NOOP("nmWxReservoirPropertiesEditor", "Horizontal fractured 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"));
}
nmReservoirParameterGroupInfo oStorage =
parameterGroup("Storage and fracture", 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("Vertical fractured 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("Horizontal fractured 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;
}