|
|
|
|
@ -2,6 +2,7 @@
|
|
|
|
|
|
|
|
|
|
#include "nmAttrRegistry.h"
|
|
|
|
|
#include "nmDataAttribute.h"
|
|
|
|
|
#include "rapidjson/document.h"
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
@ -12,12 +13,37 @@ bool sameValue(const QVariant& oLeft, const QVariant& oRight)
|
|
|
|
|
return oLeft == oRight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 比较两口井的网格相关参数。 */
|
|
|
|
|
bool sameWellGeometry(nmDataWellBase& oLeft, nmDataWellBase& oRight)
|
|
|
|
|
template<typename T>
|
|
|
|
|
bool sameDataObject(const T& oLeft, const T& oRight)
|
|
|
|
|
{
|
|
|
|
|
rapidjson::Document oLeftDocument;
|
|
|
|
|
rapidjson::Document oRightDocument;
|
|
|
|
|
rapidjson::Value oLeftValue = oLeft.ToJsonValue(
|
|
|
|
|
oLeftDocument.GetAllocator());
|
|
|
|
|
rapidjson::Value oRightValue = oRight.ToJsonValue(
|
|
|
|
|
oRightDocument.GetAllocator());
|
|
|
|
|
return oLeftValue == oRightValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
bool sameDataVector(const QVector<T>& vecLeft, const QVector<T>& vecRight)
|
|
|
|
|
{
|
|
|
|
|
if(vecLeft.size() != vecRight.size()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for(int nIndex = 0; nIndex < vecLeft.size(); ++nIndex) {
|
|
|
|
|
if(!sameDataObject(vecLeft[nIndex], vecRight[nIndex])) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @brief 比较两口井的平面位置。 */
|
|
|
|
|
bool sameWellPosition(nmDataWellBase& oLeft, nmDataWellBase& oRight)
|
|
|
|
|
{
|
|
|
|
|
return sameValue(oLeft.getX().getValue(), oRight.getX().getValue()) &&
|
|
|
|
|
sameValue(oLeft.getY().getValue(), oRight.getY().getValue()) &&
|
|
|
|
|
sameValue(oLeft.getRadius().getValue(), oRight.getRadius().getValue());
|
|
|
|
|
sameValue(oLeft.getY().getValue(), oRight.getY().getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
@ -86,6 +112,10 @@ bool nmReservoirPropertiesSession::setValue(const QString& sParameterId,
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (sameValue(value(sParameterId), oValue))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
m_pAttrRegistry->setValue(sParameterId, oValue);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@ -117,9 +147,17 @@ bool nmReservoirPropertiesSession::setEnumCode(const QString& sParameterId,
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return nmReservoirParameterCatalog::setEnumCode(m_oWorkingSnapshot,
|
|
|
|
|
sParameterId,
|
|
|
|
|
sCode);
|
|
|
|
|
if (enumCode(sParameterId) == sCode)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (!nmReservoirParameterCatalog::setEnumCode(m_oWorkingSnapshot,
|
|
|
|
|
sParameterId,
|
|
|
|
|
sCode))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmReservoirPropertiesSession::commit(QString& sError)
|
|
|
|
|
@ -130,12 +168,20 @@ bool nmReservoirPropertiesSession::commit(QString& sError)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第一步:在提交前计算几何变更,供数据源决定是否重建网格和刷新画布。
|
|
|
|
|
bool bGeometryChanged = isGeometryChanged();
|
|
|
|
|
// 第一步:几何变化优先级最高;其他正式输入只推进结果版本。
|
|
|
|
|
NM_PEBI_INPUT_CHANGE eInputChange = NM_PEBI_INPUT_UNCHANGED;
|
|
|
|
|
if (isGeometryChanged())
|
|
|
|
|
{
|
|
|
|
|
eInputChange = NM_PEBI_GRID_INPUT_CHANGED;
|
|
|
|
|
}
|
|
|
|
|
else if (isInputChanged())
|
|
|
|
|
{
|
|
|
|
|
eInputChange = NM_PEBI_RESULT_INPUT_CHANGED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第二步:将完整工作副本一次性交给数据源;失败时继续保留当前编辑内容。
|
|
|
|
|
if (!m_pDataSource->commitSnapshot(m_oWorkingSnapshot,
|
|
|
|
|
bGeometryChanged,
|
|
|
|
|
eInputChange,
|
|
|
|
|
sError))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
@ -153,6 +199,29 @@ nmReservoirPropertiesSession::workingSnapshot() const
|
|
|
|
|
return m_oWorkingSnapshot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmReservoirPropertiesSession::isInputChanged() const
|
|
|
|
|
{
|
|
|
|
|
// 完整结构化比较覆盖数值、枚举和批量导入,不依赖具体界面入口。
|
|
|
|
|
return m_oOriginalSnapshot.m_nSolverModelType !=
|
|
|
|
|
m_oWorkingSnapshot.m_nSolverModelType ||
|
|
|
|
|
!sameDataObject(m_oOriginalSnapshot.m_oReservoir,
|
|
|
|
|
m_oWorkingSnapshot.m_oReservoir) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecVerticalWells,
|
|
|
|
|
m_oWorkingSnapshot.m_vecVerticalWells) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecVerticalFracturedWells,
|
|
|
|
|
m_oWorkingSnapshot.m_vecVerticalFracturedWells) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecHorizontalFracturedWells,
|
|
|
|
|
m_oWorkingSnapshot.m_vecHorizontalFracturedWells) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecRegionMarks,
|
|
|
|
|
m_oWorkingSnapshot.m_vecRegionMarks) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecFaults,
|
|
|
|
|
m_oWorkingSnapshot.m_vecFaults) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecFractures,
|
|
|
|
|
m_oWorkingSnapshot.m_vecFractures) ||
|
|
|
|
|
!sameDataVector(m_oOriginalSnapshot.m_vecRegions,
|
|
|
|
|
m_oWorkingSnapshot.m_vecRegions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmReservoirPropertiesSession::isGeometryChanged() const
|
|
|
|
|
{
|
|
|
|
|
// 第一步:对象数量变化视为几何变化,虽然当前对话框本身不提供增删操作。
|
|
|
|
|
@ -173,7 +242,9 @@ bool nmReservoirPropertiesSession::isGeometryChanged() const
|
|
|
|
|
const_cast<nmDataVerticalWell&>(m_oOriginalSnapshot.m_vecVerticalWells[nIndex]);
|
|
|
|
|
nmDataVerticalWell& oWorking =
|
|
|
|
|
const_cast<nmDataVerticalWell&>(m_oWorkingSnapshot.m_vecVerticalWells[nIndex]);
|
|
|
|
|
if (!sameWellGeometry(oOriginal, oWorking))
|
|
|
|
|
if (!sameWellPosition(oOriginal, oWorking) ||
|
|
|
|
|
!sameValue(oOriginal.getRadius().getValue(),
|
|
|
|
|
oWorking.getRadius().getValue()))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@ -184,11 +255,15 @@ bool nmReservoirPropertiesSession::isGeometryChanged() const
|
|
|
|
|
m_oOriginalSnapshot.m_vecVerticalFracturedWells[nIndex]);
|
|
|
|
|
nmDataVerticalFracturedWell& oWorking = const_cast<nmDataVerticalFracturedWell&>(
|
|
|
|
|
m_oWorkingSnapshot.m_vecVerticalFracturedWells[nIndex]);
|
|
|
|
|
if (!sameWellGeometry(oOriginal, oWorking) ||
|
|
|
|
|
if (!sameWellPosition(oOriginal, oWorking) ||
|
|
|
|
|
!sameValue(oOriginal.getFractureHalfLength().getValue(),
|
|
|
|
|
oWorking.getFractureHalfLength().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getFractureAngle().getValue(),
|
|
|
|
|
oWorking.getFractureAngle().getValue()))
|
|
|
|
|
oWorking.getFractureAngle().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getWidth().getValue(),
|
|
|
|
|
oWorking.getWidth().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getDfc().getValue(),
|
|
|
|
|
oWorking.getDfc().getValue()))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@ -201,7 +276,7 @@ bool nmReservoirPropertiesSession::isGeometryChanged() const
|
|
|
|
|
nmDataHorizontalFracturedWell& oWorking =
|
|
|
|
|
const_cast<nmDataHorizontalFracturedWell&>(
|
|
|
|
|
m_oWorkingSnapshot.m_vecHorizontalFracturedWells[nIndex]);
|
|
|
|
|
if (!sameWellGeometry(oOriginal, oWorking) ||
|
|
|
|
|
if (!sameWellPosition(oOriginal, oWorking) ||
|
|
|
|
|
!sameValue(oOriginal.getWellLength().getValue(), oWorking.getWellLength().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getDrainAngle().getValue(), oWorking.getDrainAngle().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getNumberOfFractures().getValue(),
|
|
|
|
|
@ -209,7 +284,11 @@ bool nmReservoirPropertiesSession::isGeometryChanged() const
|
|
|
|
|
!sameValue(oOriginal.getFractureHalfLength().getValue(),
|
|
|
|
|
oWorking.getFractureHalfLength().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getFractureAngle().getValue(),
|
|
|
|
|
oWorking.getFractureAngle().getValue()))
|
|
|
|
|
oWorking.getFractureAngle().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getWidth().getValue(),
|
|
|
|
|
oWorking.getWidth().getValue()) ||
|
|
|
|
|
!sameValue(oOriginal.getDfc().getValue(),
|
|
|
|
|
oWorking.getDfc().getValue()))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|