///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017 Statoil ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RiuPvtPlotUpdater.h" #include "RigEclipseCaseData.h" #include "RigResultAccessor.h" #include "RigResultAccessorFactory.h" #include "Rim3dView.h" #include "RimEclipseResultCase.h" #include "RimEclipseResultDefinition.h" #include "Riu3dSelectionManager.h" #include "RiuPvtPlotPanel.h" #include "RiuRelativePermeabilityPlotUpdater.h" #include //================================================================================================== /// /// \class RiuPvtPlotUpdater /// /// /// //================================================================================================== //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RiuPvtPlotUpdater::RiuPvtPlotUpdater( RiuPvtPlotPanel* targetPlotPanel ) : m_targetPlotPanel( targetPlotPanel ) , m_viewToFollowAnimationFrom( nullptr ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuPvtPlotUpdater::updateOnSelectionChanged( const RiuSelectionItem* selectionItem ) { if ( !m_targetPlotPanel ) { return; } Rim3dView* newFollowAnimView = nullptr; RiuEclipseSelectionItem* eclipseSelectionItem = nullptr; eclipseSelectionItem = RiuRelativePermeabilityPlotUpdater::extractEclipseSelectionItem( selectionItem, newFollowAnimView ); bool mustClearPlot = true; m_viewToFollowAnimationFrom = nullptr; if ( m_targetPlotPanel->isVisible() && eclipseSelectionItem && eclipseSelectionItem->m_resultDefinition ) { if ( queryDataAndUpdatePlot( eclipseSelectionItem->m_resultDefinition, eclipseSelectionItem->m_timestepIdx, eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex, m_targetPlotPanel ) ) { mustClearPlot = false; m_viewToFollowAnimationFrom = newFollowAnimView; } } if ( mustClearPlot ) { m_targetPlotPanel->clearPlot(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuPvtPlotUpdater::updateOnTimeStepChanged( Rim3dView* changedView ) { if ( !m_targetPlotPanel || !m_targetPlotPanel->isVisible() ) { return; } // Don't update the plot if the view that changed time step is different // from the view that was the source of the current plot if ( changedView != m_viewToFollowAnimationFrom ) { return; } // Fetch the current global selection and only continue if the selection's view matches the view with time step change const RiuSelectionItem* selectionItem = Riu3dSelectionManager::instance()->selectedItem(); Rim3dView* newFollowAnimView = nullptr; RiuEclipseSelectionItem* eclipseSelectionItem = nullptr; eclipseSelectionItem = RiuRelativePermeabilityPlotUpdater::extractEclipseSelectionItem( selectionItem, newFollowAnimView ); if ( eclipseSelectionItem && newFollowAnimView == changedView ) { if ( !queryDataAndUpdatePlot( eclipseSelectionItem->m_resultDefinition, newFollowAnimView->currentTimeStep(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex, m_targetPlotPanel ) ) { m_targetPlotPanel->clearPlot(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RiuPvtPlotUpdater::queryDataAndUpdatePlot( const RimEclipseResultDefinition* eclipseResDef, size_t timeStepIndex, size_t gridIndex, size_t gridLocalCellIndex, RiuPvtPlotPanel* plotPanel ) { CVF_ASSERT( plotPanel ); if ( !eclipseResDef ) return false; RimEclipseResultCase* eclipseResultCase = dynamic_cast( eclipseResDef->eclipseCase() ); RigEclipseCaseData* eclipseCaseData = eclipseResultCase ? eclipseResultCase->eclipseCaseData() : nullptr; RiaDefines::PorosityModelType porosityModel = eclipseResDef->porosityModel(); if ( eclipseResultCase && eclipseCaseData && eclipseResultCase->flowDiagSolverInterface() ) { // cvf::Trace::show("Update PVT plot for active cell index: %d", static_cast(activeCellIndex)); // The following calls will read results from file in preparation for the queries below RigCaseCellResultsData* cellResultsData = eclipseCaseData->results( porosityModel ); cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "RS" ) ); cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "RV" ) ); cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "PRESSURE" ) ); cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PVTNUM" ) ); cvf::ref rsAccessor = RigResultAccessorFactory::createFromResultAddress( eclipseCaseData, gridIndex, porosityModel, timeStepIndex, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "RS" ) ); cvf::ref rvAccessor = RigResultAccessorFactory::createFromResultAddress( eclipseCaseData, gridIndex, porosityModel, timeStepIndex, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "RV" ) ); cvf::ref pressureAccessor = RigResultAccessorFactory::createFromResultAddress( eclipseCaseData, gridIndex, porosityModel, timeStepIndex, RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "PRESSURE" ) ); cvf::ref pvtnumAccessor = RigResultAccessorFactory::createFromResultAddress( eclipseCaseData, gridIndex, porosityModel, timeStepIndex, RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PVTNUM" ) ); RiuPvtPlotPanel::CellValues cellValues; cellValues.rs = rsAccessor.notNull() ? rsAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL; cellValues.rv = rvAccessor.notNull() ? rvAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL; cellValues.pressure = pressureAccessor.notNull() ? pressureAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL; const double cellPvtNumDouble = pvtnumAccessor.notNull() ? pvtnumAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL; const int cellPvtNum = ( cellPvtNumDouble != HUGE_VAL ) ? static_cast( cellPvtNumDouble ) : std::numeric_limits::max(); std::vector fvfCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculatePvtCurves( RigFlowDiagSolverInterface::PVT_CT_FVF, cellPvtNum ); std::vector viscosityCurveArr = eclipseResultCase->flowDiagSolverInterface()->calculatePvtCurves( RigFlowDiagSolverInterface::PVT_CT_VISCOSITY, cellPvtNum ); RiuPvtPlotPanel::FvfDynProps fvfDynProps; eclipseResultCase->flowDiagSolverInterface()->calculatePvtDynamicPropertiesFvf( cellPvtNum, cellValues.pressure, cellValues.rs, cellValues.rv, &fvfDynProps.bo, &fvfDynProps.bg ); RiuPvtPlotPanel::ViscosityDynProps viscosityDynProps; eclipseResultCase->flowDiagSolverInterface()->calculatePvtDynamicPropertiesViscosity( cellPvtNum, cellValues.pressure, cellValues.rs, cellValues.rv, &viscosityDynProps.mu_o, &viscosityDynProps.mu_g ); QString cellRefText = RiuRelativePermeabilityPlotUpdater::constructCellReferenceText( eclipseCaseData, gridIndex, gridLocalCellIndex, "PVTNUM", cellPvtNumDouble ); plotPanel->setPlotData( eclipseCaseData->unitsType(), fvfCurveArr, viscosityCurveArr, fvfDynProps, viscosityDynProps, cellValues, cellRefText ); return true; } return false; }