2017-11-29 06:41:13 -06:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright (C) 2017 Statoil ASA
|
2019-09-06 03:40:57 -05:00
|
|
|
//
|
2017-11-29 06:41:13 -06:00
|
|
|
// 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.
|
2019-09-06 03:40:57 -05:00
|
|
|
//
|
2017-11-29 06:41:13 -06:00
|
|
|
// 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.
|
2019-09-06 03:40:57 -05:00
|
|
|
//
|
|
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
2017-11-29 06:41:13 -06:00
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "RiuRelativePermeabilityPlotUpdater.h"
|
2018-11-30 05:53:46 -06:00
|
|
|
#include "Riu3dSelectionManager.h"
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "RiuRelativePermeabilityPlotPanel.h"
|
2017-11-29 06:41:13 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "RigActiveCellInfo.h"
|
|
|
|
#include "RigCaseCellResultsData.h"
|
2017-11-29 06:41:13 -06:00
|
|
|
#include "RigEclipseCaseData.h"
|
|
|
|
#include "RigGridBase.h"
|
|
|
|
#include "RigResultAccessor.h"
|
|
|
|
#include "RigResultAccessorFactory.h"
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "Rim2dIntersectionView.h"
|
2018-01-09 03:11:28 -06:00
|
|
|
#include "Rim3dView.h"
|
2017-11-29 06:41:13 -06:00
|
|
|
#include "RimEclipseResultCase.h"
|
2019-09-06 03:40:57 -05:00
|
|
|
#include "RimEclipseView.h"
|
2019-11-26 04:35:21 -06:00
|
|
|
#include "RimExtrudedCurveIntersection.h"
|
2017-11-29 06:41:13 -06:00
|
|
|
|
|
|
|
//#include "cvfTrace.h"
|
|
|
|
|
2017-11-30 01:49:21 -06:00
|
|
|
#include <cmath>
|
2017-11-29 06:41:13 -06:00
|
|
|
|
|
|
|
//==================================================================================================
|
|
|
|
///
|
|
|
|
/// \class RiuRelativePermeabilityPlotUpdater
|
|
|
|
///
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-29 06:41:13 -06:00
|
|
|
///
|
|
|
|
//==================================================================================================
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-29 06:41:13 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
RiuRelativePermeabilityPlotUpdater::RiuRelativePermeabilityPlotUpdater( RiuRelativePermeabilityPlotPanel* targetPlotPanel )
|
|
|
|
: m_targetPlotPanel( targetPlotPanel )
|
|
|
|
, m_sourceEclipseViewOfLastPlot( nullptr )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-29 06:41:13 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuRelativePermeabilityPlotUpdater::updateOnSelectionChanged( const RiuSelectionItem* selectionItem )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( !m_targetPlotPanel )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-18 11:56:43 -06:00
|
|
|
m_sourceEclipseViewOfLastPlot = nullptr;
|
2019-09-06 03:40:57 -05:00
|
|
|
bool mustClearPlot = true;
|
2017-11-29 06:41:13 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
RiuEclipseSelectionItem* eclipseSelectionItem = dynamic_cast<RiuEclipseSelectionItem*>(
|
|
|
|
const_cast<RiuSelectionItem*>( selectionItem ) );
|
2018-02-18 11:56:43 -06:00
|
|
|
RimEclipseView* eclipseView = eclipseSelectionItem ? eclipseSelectionItem->m_view.p() : nullptr;
|
2018-02-06 07:39:38 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( !eclipseSelectionItem && !eclipseView )
|
2018-02-06 07:39:38 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
const Riu2dIntersectionSelectionItem* intersectionSelItem = dynamic_cast<const Riu2dIntersectionSelectionItem*>(
|
|
|
|
selectionItem );
|
|
|
|
if ( intersectionSelItem && intersectionSelItem->eclipseSelectionItem() )
|
2018-02-06 07:39:38 -06:00
|
|
|
{
|
|
|
|
eclipseSelectionItem = intersectionSelItem->eclipseSelectionItem();
|
2019-09-06 03:40:57 -05:00
|
|
|
eclipseView = eclipseSelectionItem->m_view;
|
2018-02-06 07:39:38 -06:00
|
|
|
}
|
|
|
|
}
|
2017-11-29 06:41:13 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( m_targetPlotPanel->isVisible() && eclipseSelectionItem && eclipseView )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
const size_t gridIndex = eclipseSelectionItem->m_gridIndex;
|
2017-11-29 06:41:13 -06:00
|
|
|
const size_t gridLocalCellIndex = eclipseSelectionItem->m_gridLocalCellIndex;
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( queryDataAndUpdatePlot( *eclipseView, gridIndex, gridLocalCellIndex, m_targetPlotPanel ) )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
mustClearPlot = false;
|
2017-11-29 06:41:13 -06:00
|
|
|
m_sourceEclipseViewOfLastPlot = eclipseView;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( mustClearPlot )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
m_targetPlotPanel->clearPlot();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-29 06:41:13 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiuRelativePermeabilityPlotUpdater::updateOnTimeStepChanged( Rim3dView* changedView )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( !m_targetPlotPanel || !m_targetPlotPanel->isVisible() )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
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
|
2019-09-06 03:40:57 -05:00
|
|
|
const RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( changedView );
|
|
|
|
if ( !eclipseView || eclipseView != m_sourceEclipseViewOfLastPlot )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch the current global selection and only continue if the selection's view matches the view with time step change
|
2019-09-06 03:40:57 -05:00
|
|
|
const RiuEclipseSelectionItem* eclipseSelectionItem = dynamic_cast<const RiuEclipseSelectionItem*>(
|
|
|
|
Riu3dSelectionManager::instance()->selectedItem() );
|
|
|
|
if ( eclipseSelectionItem && eclipseSelectionItem->m_view == eclipseView )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
const size_t gridIndex = eclipseSelectionItem->m_gridIndex;
|
2017-11-29 06:41:13 -06:00
|
|
|
const size_t gridLocalCellIndex = eclipseSelectionItem->m_gridLocalCellIndex;
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( !queryDataAndUpdatePlot( *eclipseView, gridIndex, gridLocalCellIndex, m_targetPlotPanel ) )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
m_targetPlotPanel->clearPlot();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-29 06:41:13 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
bool RiuRelativePermeabilityPlotUpdater::queryDataAndUpdatePlot( const RimEclipseView& eclipseView,
|
|
|
|
size_t gridIndex,
|
|
|
|
size_t gridLocalCellIndex,
|
|
|
|
RiuRelativePermeabilityPlotPanel* plotPanel )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
CVF_ASSERT( plotPanel );
|
2017-11-29 06:41:13 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
RimEclipseResultCase* eclipseResultCase = dynamic_cast<RimEclipseResultCase*>( eclipseView.eclipseCase() );
|
|
|
|
RigEclipseCaseData* eclipseCaseData = eclipseResultCase ? eclipseResultCase->eclipseCaseData() : nullptr;
|
|
|
|
if ( eclipseResultCase && eclipseCaseData && eclipseResultCase->flowDiagSolverInterface() )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
size_t activeCellIndex = CellLookupHelper::mapToActiveCellIndex( eclipseCaseData, gridIndex, gridLocalCellIndex );
|
|
|
|
if ( activeCellIndex != cvf::UNDEFINED_SIZE_T )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
// cvf::Trace::show("Updating RelPerm plot for active cell index: %d", static_cast<int>(activeCellIndex));
|
2017-11-29 06:41:13 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
std::vector<RigFlowDiagSolverInterface::RelPermCurve> relPermCurveArr =
|
|
|
|
eclipseResultCase->flowDiagSolverInterface()->calculateRelPermCurves( activeCellIndex );
|
2017-11-30 04:27:38 -06:00
|
|
|
|
|
|
|
// Make sure we load the results that we'll query below
|
2019-09-06 03:40:57 -05:00
|
|
|
RigCaseCellResultsData* cellResultsData = eclipseCaseData->results( RiaDefines::MATRIX_MODEL );
|
|
|
|
cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::DYNAMIC_NATIVE, "SWAT" ) );
|
|
|
|
cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::DYNAMIC_NATIVE, "SGAS" ) );
|
|
|
|
cellResultsData->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::STATIC_NATIVE, "SATNUM" ) );
|
2017-11-29 06:41:13 -06:00
|
|
|
|
|
|
|
// Fetch SWAT and SGAS cell values for the selected cell
|
2019-09-06 03:40:57 -05:00
|
|
|
const size_t timeStepIndex = static_cast<size_t>( eclipseView.currentTimeStep() );
|
|
|
|
cvf::ref<RigResultAccessor> swatAccessor =
|
|
|
|
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
|
|
|
|
gridIndex,
|
|
|
|
RiaDefines::MATRIX_MODEL,
|
|
|
|
timeStepIndex,
|
|
|
|
RigEclipseResultAddress( RiaDefines::DYNAMIC_NATIVE,
|
|
|
|
"SWAT" ) );
|
|
|
|
cvf::ref<RigResultAccessor> sgasAccessor =
|
|
|
|
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
|
|
|
|
gridIndex,
|
|
|
|
RiaDefines::MATRIX_MODEL,
|
|
|
|
timeStepIndex,
|
|
|
|
RigEclipseResultAddress( RiaDefines::DYNAMIC_NATIVE,
|
|
|
|
"SGAS" ) );
|
|
|
|
cvf::ref<RigResultAccessor> satnumAccessor =
|
|
|
|
RigResultAccessorFactory::createFromResultAddress( eclipseCaseData,
|
|
|
|
gridIndex,
|
|
|
|
RiaDefines::MATRIX_MODEL,
|
|
|
|
timeStepIndex,
|
|
|
|
RigEclipseResultAddress( RiaDefines::STATIC_NATIVE,
|
|
|
|
"SATNUM" ) );
|
|
|
|
const double cellSWAT = swatAccessor.notNull() ? swatAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL;
|
|
|
|
const double cellSGAS = sgasAccessor.notNull() ? sgasAccessor->cellScalar( gridLocalCellIndex ) : HUGE_VAL;
|
|
|
|
const double cellSATNUM = satnumAccessor.notNull() ? satnumAccessor->cellScalar( gridLocalCellIndex )
|
|
|
|
: HUGE_VAL;
|
|
|
|
// cvf::Trace::show("cellSWAT = %f cellSGAS = %f cellSATNUM = %f", cellSWAT, cellSGAS, cellSATNUM);
|
|
|
|
|
|
|
|
QString cellRefText = constructCellReferenceText( eclipseCaseData, gridIndex, gridLocalCellIndex, cellSATNUM );
|
|
|
|
QString caseName = eclipseResultCase->caseUserDescription;
|
|
|
|
|
|
|
|
plotPanel->setPlotData( eclipseCaseData->unitsType(), relPermCurveArr, cellSWAT, cellSGAS, caseName, cellRefText );
|
2017-11-29 06:41:13 -06:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-30 04:27:38 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-30 04:27:38 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
QString RiuRelativePermeabilityPlotUpdater::constructCellReferenceText( const RigEclipseCaseData* eclipseCaseData,
|
|
|
|
size_t gridIndex,
|
|
|
|
size_t gridLocalCellIndex,
|
|
|
|
double satnum )
|
2017-11-30 04:27:38 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
const size_t gridCount = eclipseCaseData ? eclipseCaseData->gridCount() : 0;
|
|
|
|
const RigGridBase* grid = gridIndex < gridCount ? eclipseCaseData->grid( gridIndex ) : nullptr;
|
|
|
|
if ( grid && gridLocalCellIndex < grid->cellCount() )
|
2017-11-30 04:27:38 -06:00
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
size_t j = 0;
|
|
|
|
size_t k = 0;
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( grid->ijkFromCellIndex( gridLocalCellIndex, &i, &j, &k ) )
|
2017-11-30 04:27:38 -06:00
|
|
|
{
|
|
|
|
// Adjust to 1-based Eclipse indexing
|
|
|
|
i++;
|
|
|
|
j++;
|
|
|
|
k++;
|
|
|
|
|
2017-12-18 04:27:56 -06:00
|
|
|
QString retText;
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( gridIndex == 0 )
|
2017-12-18 04:27:56 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
retText = QString( "Cell: [%1, %2, %3]" ).arg( i ).arg( j ).arg( k );
|
2017-12-18 04:27:56 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
retText = QString( "LGR %1, Cell: [%2, %3, %4]" ).arg( gridIndex ).arg( i ).arg( j ).arg( k );
|
2017-12-18 04:27:56 -06:00
|
|
|
}
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( satnum != HUGE_VAL )
|
2017-11-30 04:27:38 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
retText += QString( " (SATNUM=%1)" ).arg( satnum );
|
2017-11-30 04:27:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return retText;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
2017-11-29 06:41:13 -06:00
|
|
|
//==================================================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//==================================================================================================
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
///
|
2017-11-29 06:41:13 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
size_t CellLookupHelper::mapToActiveCellIndex( const RigEclipseCaseData* eclipseCaseData,
|
|
|
|
size_t gridIndex,
|
|
|
|
size_t gridLocalCellIndex )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
const size_t gridCount = eclipseCaseData ? eclipseCaseData->gridCount() : 0;
|
|
|
|
const RigGridBase* grid = gridIndex < gridCount ? eclipseCaseData->grid( gridIndex ) : nullptr;
|
|
|
|
if ( grid && gridLocalCellIndex < grid->cellCount() )
|
2017-11-29 06:41:13 -06:00
|
|
|
{
|
|
|
|
// Note!!
|
|
|
|
// Which type of porosity model to choose? Currently hard-code to MATRIX_MODEL
|
2019-09-06 03:40:57 -05:00
|
|
|
const RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo( RiaDefines::MATRIX_MODEL );
|
|
|
|
CVF_ASSERT( activeCellInfo );
|
2017-11-29 06:41:13 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
const size_t reservoirCellIndex = grid->reservoirCellIndex( gridLocalCellIndex );
|
|
|
|
const size_t activeCellIndex = activeCellInfo->cellResultIndex( reservoirCellIndex );
|
2017-11-29 06:41:13 -06:00
|
|
|
return activeCellIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cvf::UNDEFINED_SIZE_T;
|
|
|
|
}
|