#include "nmPebiResultSnapshot.h" #include #include #include #include // VTK 结构和压力操作仅供渲染适配器调用,普通结果读取接口不暴露可写对象。 nmPebiResultSolverSlot::nmPebiResultSolverSlot() : m_nSolverIndex(-1), m_eEntryKind(NM_SolverEntry_Well), m_eWellType(Unknow_Well) { } nmPebiResultWellSnapshot::nmPebiResultWellSnapshot() : m_eWellType(Unknow_Well), m_eWellMode(NM_CaseWell_Observation), m_bHasPerforation(false), m_bHasSkin(false), m_bHasDfc(false), m_dRadius(0.0), m_dWellboreStorage(0.0), m_dSkin(0.0), m_dDfc(0.0) { } nmPebiResultReservoirParameters::nmPebiResultReservoirParameters() : m_dInitialPressure(0.0), m_dPermeability(0.0), m_dThickness(0.0), m_dPorosity(0.0), m_dTotalCompressibility(0.0), m_dRockCompressibility(0.0), m_dOilSaturation(0.0), m_dGasSaturation(0.0), m_dWaterSaturation(0.0) { } nmPebiResultPvtParameters::nmPebiResultPvtParameters() : m_bHasBubblePoint(false), m_dBubblePoint(0.0), m_dConstantBo(0.0), m_dConstantMiuo(0.0), m_dConstantBg(0.0), m_dConstantMiug(0.0), m_dConstantBw(0.0), m_dConstantMiuw(0.0) { } nmPebiResultSolverSettings::nmPebiResultSolverSettings() : m_nSolverModelType(0), m_nPebiSolverType(0), m_nOmpThreads(0), m_nIluReuseSteps(0), m_dGridControl(0.0), m_bHasTimeStepSettings(false), m_dTimeGrowthExponent(0.0), m_dMinDeltaT(0.0), m_dMaxDeltaT(0.0) { } nmPebiResultSnapshot::PressureFrame::PressureFrame() : m_dTime(0.0) { } nmPebiResultSnapshot::nmPebiResultSnapshot() : m_sSnapshotId(QUuid::createUuid().toString() .remove('{').remove('}')), m_nGridInputRevision(0), m_nResultInputRevision(0), m_bComplete(false), m_dScalarMin(0.0), m_dScalarMax(0.0) { } nmPebiResultSnapshot::~nmPebiResultSnapshot() { } QString nmPebiResultSnapshot::getSnapshotId() const { return m_sSnapshotId; } quint64 nmPebiResultSnapshot::getGridInputRevision() const { return m_nGridInputRevision; } quint64 nmPebiResultSnapshot::getResultInputRevision() const { return m_nResultInputRevision; } bool nmPebiResultSnapshot::isComplete() const { return m_bComplete; } int nmPebiResultSnapshot::getSolverSlotCount() const { return m_vecSolverSlots.size(); } const nmPebiResultSolverSlot* nmPebiResultSnapshot::getSolverSlotAt( int nIndex) const { if(nIndex < 0 || nIndex >= m_vecSolverSlots.size()) { return NULL; } return &m_vecSolverSlots[nIndex]; } int nmPebiResultSnapshot::getWellCount() const { return m_vecWells.size(); } const nmPebiResultWellSnapshot* nmPebiResultSnapshot::getWellAt( int nIndex) const { if(nIndex < 0 || nIndex >= m_vecWells.size()) { return NULL; } return &m_vecWells[nIndex]; } const nmPebiResultWellSnapshot* nmPebiResultSnapshot::findWell( const QString& sWellInstanceId) const { for(int nIndex = 0; nIndex < m_vecWells.size(); ++nIndex) { if(m_vecWells[nIndex].m_sWellInstanceId == sWellInstanceId) { return &m_vecWells[nIndex]; } } return NULL; } const QStringList& nmPebiResultSnapshot::getDisplayWellInstanceIds() const { return m_listDisplayWellInstanceIds; } bool nmPebiResultSnapshot::isDisplayWell( const QString& sWellInstanceId) const { return m_listDisplayWellInstanceIds.contains(sWellInstanceId); } vtkIdType nmPebiResultSnapshot::getResultCellCount() const { return m_pResultGrid != NULL ? m_pResultGrid->GetNumberOfCells() : 0; } int nmPebiResultSnapshot::getPressureFrameCount() const { return m_vecPressureFrames.size(); } double nmPebiResultSnapshot::getPressureTimeAt(int nIndex) const { if(nIndex < 0 || nIndex >= m_vecPressureFrames.size()) { return 0.0; } return m_vecPressureFrames[nIndex].m_dTime; } bool nmPebiResultSnapshot::getScalarRange(double aRange[2]) const { if(aRange == NULL || !m_bComplete) { return false; } aRange[0] = m_dScalarMin; aRange[1] = m_dScalarMax; return true; } const nmPebiResultReservoirParameters& nmPebiResultSnapshot::getReservoirParameters() const { return m_oReservoirParameters; } const nmPebiResultPvtParameters& nmPebiResultSnapshot::getPvtParameters() const { return m_oPvtParameters; } const nmPebiResultSolverSettings& nmPebiResultSnapshot::getSolverSettings() const { return m_oSolverSettings; } bool nmPebiResultSnapshot::copyResultGridStructure( vtkUnstructuredGrid* pTargetGrid) const { if(!m_bComplete || m_pResultGrid == NULL || pTargetGrid == NULL) { return false; } // CopyStructure 在当前 VTK 7.1 中共享点和单元拓扑,不复制大网格。 // 随后清空目标 CellData,确保压力只能通过受控接口按帧挂载。 pTargetGrid->Initialize(); pTargetGrid->CopyStructure(m_pResultGrid); pTargetGrid->GetCellData()->Initialize(); return pTargetGrid->GetNumberOfCells() == m_pResultGrid->GetNumberOfCells(); } bool nmPebiResultSnapshot::bindPressureFrame( int nIndex, vtkUnstructuredGrid* pTargetGrid) const { if(!m_bComplete || pTargetGrid == NULL || nIndex < 0 || nIndex >= m_vecPressureFrames.size() || pTargetGrid->GetNumberOfCells() != getResultCellCount()) { return false; } vtkDoubleArray* pPressure = m_vecPressureFrames[nIndex].m_pPressure.GetPointer(); if(pPressure == NULL || pPressure->GetNumberOfTuples() != getResultCellCount()) { return false; } // SetScalars 会增加 VTK 引用计数,压力的规范所有权仍属于快照。 // 渲染网格销毁或切换快照时应及时解除这个临时引用。 pTargetGrid->GetCellData()->SetScalars(pPressure); pTargetGrid->Modified(); return pTargetGrid->GetCellData()->GetScalars() == pPressure; } bool nmPebiResultSnapshot::copyPressureFrame( int nIndex, vtkDoubleArray* pTargetPressure) const { if(!m_bComplete || pTargetPressure == NULL || nIndex < 0 || nIndex >= m_vecPressureFrames.size()) { return false; } vtkDoubleArray* pSourcePressure = m_vecPressureFrames[nIndex].m_pPressure.GetPointer(); if(pSourcePressure == NULL) { return false; } // 回退路径只复制当前帧,调用方应在动画期间复用同一个缓冲数组。 pTargetPressure->DeepCopy(pSourcePressure); pTargetPressure->SetName("p"); return pTargetPressure->GetNumberOfComponents() == 1 && pTargetPressure->GetNumberOfTuples() == getResultCellCount(); }