2016-12-14 02:50:30 -06:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016- 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
# include "RimFlowDiagSolution.h"
2017-01-09 12:04:45 -06:00
2017-02-10 11:53:14 -06:00
# include "RiaApplication.h"
2017-02-10 01:39:25 -06:00
# include "RiaColorTables.h"
2016-12-14 02:50:30 -06:00
2017-01-09 12:14:07 -06:00
# include "RigActiveCellInfo.h"
2016-12-20 04:41:05 -06:00
# include "RigCaseCellResultsData.h"
2017-01-10 02:51:39 -06:00
# include "RigEclipseCaseData.h"
2017-01-09 12:04:45 -06:00
# include "RigFlowDiagResults.h"
# include "RigMainGrid.h"
2017-01-09 12:51:15 -06:00
# include "RigSingleWellResultsData.h"
2017-02-10 01:39:25 -06:00
# include "RimEclipseResultCase.h"
2017-02-24 04:07:15 -06:00
# include "RimEclipseView.h"
2017-02-10 11:53:14 -06:00
# include "RimEclipseWell.h"
2017-02-02 02:56:39 -06:00
# include "RimEclipseWellCollection.h"
2016-12-16 07:17:56 -06:00
2016-12-14 02:50:30 -06:00
CAF_PDM_SOURCE_INIT ( RimFlowDiagSolution , " FlowDiagSolution " ) ;
2017-03-16 11:46:45 -05:00
# define CROSS_FLOW_ENDING "-XF"
2017-03-06 09:33:29 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool hasCrossFlowEnding ( const QString & tracerName )
{
2017-03-16 11:46:45 -05:00
return tracerName . endsWith ( CROSS_FLOW_ENDING ) ;
2017-03-06 09:33:29 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString removeCrossFlowEnding ( const QString & tracerName )
{
2017-03-16 11:46:45 -05:00
if ( tracerName . endsWith ( CROSS_FLOW_ENDING ) )
2017-03-06 09:33:29 -06:00
{
return tracerName . left ( tracerName . size ( ) - 3 ) ;
}
else
{
return tracerName ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString addCrossFlowEnding ( const QString & wellName )
{
2017-03-16 11:46:45 -05:00
return wellName + CROSS_FLOW_ENDING ;
2017-03-06 09:33:29 -06:00
}
2016-12-14 02:50:30 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFlowDiagSolution : : RimFlowDiagSolution ( void )
{
CAF_PDM_InitObject ( " Flow Diagnostics Solution " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_userDescription , " UserDescription " , QString ( " All Wells " ) , " Description " , " " , " " , " " ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFlowDiagSolution : : ~ RimFlowDiagSolution ( void )
{
}
2017-03-09 03:03:52 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFlowDiagSolution : : userDescription ( ) const
{
return m_userDescription ( ) ;
}
2016-12-16 07:17:56 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagResults * RimFlowDiagSolution : : flowDiagResults ( )
{
2016-12-17 03:46:57 -06:00
if ( m_flowDiagResults . isNull ( ) )
{
size_t timeStepCount ;
{
RimEclipseResultCase * eclCase ;
this - > firstAncestorOrThisOfType ( eclCase ) ;
2017-03-15 03:10:16 -05:00
CVF_ASSERT ( eclCase & & eclCase - > eclipseCaseData ( ) ) ;
2016-12-17 03:46:57 -06:00
2017-03-15 03:10:16 -05:00
timeStepCount = eclCase - > eclipseCaseData ( ) - > results ( RifReaderInterface : : MATRIX_RESULTS ) - > maxTimeStepCount ( ) ;
2016-12-17 03:46:57 -06:00
}
m_flowDiagResults = new RigFlowDiagResults ( this , timeStepCount ) ;
}
2016-12-16 07:17:56 -06:00
return m_flowDiagResults . p ( ) ;
}
2016-12-14 02:50:30 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
std : : vector < QString > RimFlowDiagSolution : : tracerNames ( ) const
2016-12-14 02:50:30 -06:00
{
RimEclipseResultCase * eclCase ;
this - > firstAncestorOrThisOfType ( eclCase ) ;
2017-01-03 02:27:25 -06:00
std : : vector < QString > tracerNameSet ;
2016-12-14 02:50:30 -06:00
if ( eclCase )
{
2017-03-15 03:10:16 -05:00
const cvf : : Collection < RigSingleWellResultsData > & wellResults = eclCase - > eclipseCaseData ( ) - > wellResults ( ) ;
2016-12-14 02:50:30 -06:00
for ( size_t wIdx = 0 ; wIdx < wellResults . size ( ) ; + + wIdx )
{
2017-01-03 02:27:25 -06:00
tracerNameSet . push_back ( wellResults [ wIdx ] - > m_wellName ) ;
2017-03-06 09:33:29 -06:00
tracerNameSet . push_back ( addCrossFlowEnding ( wellResults [ wIdx ] - > m_wellName ) ) ;
2016-12-14 02:50:30 -06:00
}
}
return tracerNameSet ;
}
2016-12-20 04:41:05 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
std : : map < std : : string , std : : vector < int > > RimFlowDiagSolution : : allInjectorTracerActiveCellIndices ( size_t timeStepIndex ) const
2016-12-20 04:41:05 -06:00
{
return allTracerActiveCellIndices ( timeStepIndex , true ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
std : : map < std : : string , std : : vector < int > > RimFlowDiagSolution : : allProducerTracerActiveCellIndices ( size_t timeStepIndex ) const
2016-12-20 04:41:05 -06:00
{
return allTracerActiveCellIndices ( timeStepIndex , false ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
std : : map < std : : string , std : : vector < int > > RimFlowDiagSolution : : allTracerActiveCellIndices ( size_t timeStepIndex , bool useInjectors ) const
2016-12-20 04:41:05 -06:00
{
RimEclipseResultCase * eclCase ;
this - > firstAncestorOrThisOfType ( eclCase ) ;
std : : map < std : : string , std : : vector < int > > tracersWithCells ;
if ( eclCase )
{
2017-03-15 03:10:16 -05:00
const cvf : : Collection < RigSingleWellResultsData > & wellResults = eclCase - > eclipseCaseData ( ) - > wellResults ( ) ;
RigMainGrid * mainGrid = eclCase - > eclipseCaseData ( ) - > mainGrid ( ) ;
RigActiveCellInfo * activeCellInfo = eclCase - > eclipseCaseData ( ) - > activeCellInfo ( RifReaderInterface : : MATRIX_RESULTS ) ; //Todo: Must come from the results definition
2016-12-20 04:41:05 -06:00
for ( size_t wIdx = 0 ; wIdx < wellResults . size ( ) ; + + wIdx )
{
if ( ! wellResults [ wIdx ] - > hasWellResult ( timeStepIndex ) ) continue ;
2017-03-07 05:19:19 -06:00
const RigWellResultFrame & wellResFrame = wellResults [ wIdx ] - > wellResultFrame ( timeStepIndex ) ;
bool isInjectorWell = ( wellResFrame . m_productionType ! = RigWellResultFrame : : PRODUCER
& & wellResFrame . m_productionType ! = RigWellResultFrame : : UNDEFINED_PRODUCTION_TYPE ) ;
2016-12-20 04:41:05 -06:00
2017-03-06 09:33:29 -06:00
std : : string wellname = wellResults [ wIdx ] - > m_wellName . toStdString ( ) ;
std : : string wellNameXf = addCrossFlowEnding ( wellResults [ wIdx ] - > m_wellName ) . toStdString ( ) ;
2016-12-20 04:41:05 -06:00
2017-03-06 09:33:29 -06:00
std : : vector < int > & tracerCells = tracersWithCells [ wellname ] ;
std : : vector < int > & tracerCellsCrossFlow = tracersWithCells [ wellNameXf ] ;
2016-12-20 04:41:05 -06:00
2017-03-06 09:33:29 -06:00
for ( const RigWellResultBranch & wBr : wellResFrame . m_wellResultBranches )
{
for ( const RigWellResultPoint & wrp : wBr . m_branchResultPoints )
2016-12-20 04:41:05 -06:00
{
2017-03-06 09:33:29 -06:00
if ( wrp . isValid ( ) & & wrp . m_isOpen
& & ( ( useInjectors & & wrp . flowRate ( ) < 0.0 ) | | ( ! useInjectors & & wrp . flowRate ( ) > 0.0 ) ) )
2016-12-20 04:41:05 -06:00
{
2017-03-06 09:33:29 -06:00
RigGridBase * grid = mainGrid - > gridByIndex ( wrp . m_gridIndex ) ;
size_t reservoirCellIndex = grid - > reservoirCellIndex ( wrp . m_gridCellIndex ) ;
int cellActiveIndex = static_cast < int > ( activeCellInfo - > cellResultIndex ( reservoirCellIndex ) ) ;
2016-12-20 04:41:05 -06:00
2017-03-06 09:33:29 -06:00
if ( useInjectors = = isInjectorWell )
{
2016-12-20 04:41:05 -06:00
tracerCells . push_back ( cellActiveIndex ) ;
}
2017-03-06 09:33:29 -06:00
else
{
tracerCellsCrossFlow . push_back ( cellActiveIndex ) ;
}
2016-12-20 04:41:05 -06:00
}
}
}
}
}
return tracersWithCells ;
}
2016-12-14 02:50:30 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
RimFlowDiagSolution : : TracerStatusType RimFlowDiagSolution : : tracerStatusOverall ( const QString & tracerName ) const
2016-12-14 02:50:30 -06:00
{
RimEclipseResultCase * eclCase ;
2017-03-06 09:33:29 -06:00
this - > firstAncestorOrThisOfTypeAsserted ( eclCase ) ;
2016-12-14 02:50:30 -06:00
TracerStatusType tracerStatus = UNDEFINED ;
2017-03-06 09:33:29 -06:00
2017-03-15 03:10:16 -05:00
const cvf : : Collection < RigSingleWellResultsData > & wellResults = eclCase - > eclipseCaseData ( ) - > wellResults ( ) ;
2017-03-06 09:33:29 -06:00
for ( size_t wIdx = 0 ; wIdx < wellResults . size ( ) ; + + wIdx )
2016-12-14 02:50:30 -06:00
{
2017-03-06 09:33:29 -06:00
QString wellName = removeCrossFlowEnding ( tracerName ) ;
2016-12-14 02:50:30 -06:00
2017-03-06 09:33:29 -06:00
if ( wellResults [ wIdx ] - > m_wellName ! = wellName ) continue ;
tracerStatus = CLOSED ;
for ( const RigWellResultFrame & wellResFrame : wellResults [ wIdx ] - > m_wellCellsTimeSteps )
2016-12-14 02:50:30 -06:00
{
2017-03-07 05:19:19 -06:00
if ( wellResFrame . m_productionType = = RigWellResultFrame : : GAS_INJECTOR
| | wellResFrame . m_productionType = = RigWellResultFrame : : OIL_INJECTOR
| | wellResFrame . m_productionType = = RigWellResultFrame : : WATER_INJECTOR )
2016-12-14 02:50:30 -06:00
{
2017-03-07 05:19:19 -06:00
if ( tracerStatus = = PRODUCER ) tracerStatus = VARYING ;
else tracerStatus = INJECTOR ;
}
else if ( wellResFrame . m_productionType = = RigWellResultFrame : : PRODUCER )
{
if ( tracerStatus = = INJECTOR ) tracerStatus = VARYING ;
else tracerStatus = PRODUCER ;
2016-12-14 02:50:30 -06:00
}
2017-03-06 09:33:29 -06:00
if ( tracerStatus = = VARYING ) break ;
2016-12-14 02:50:30 -06:00
}
2017-03-06 09:33:29 -06:00
break ;
}
if ( hasCrossFlowEnding ( tracerName ) )
{
if ( tracerStatus = = PRODUCER ) tracerStatus = INJECTOR ;
else if ( tracerStatus = = INJECTOR ) tracerStatus = PRODUCER ;
2016-12-14 02:50:30 -06:00
}
return tracerStatus ;
}
2016-12-21 10:14:13 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
RimFlowDiagSolution : : TracerStatusType RimFlowDiagSolution : : tracerStatusInTimeStep ( const QString & tracerName , size_t timeStepIndex ) const
2016-12-21 10:14:13 -06:00
{
RimEclipseResultCase * eclCase ;
2017-03-06 09:33:29 -06:00
this - > firstAncestorOrThisOfTypeAsserted ( eclCase ) ;
2016-12-21 10:14:13 -06:00
2017-03-15 03:10:16 -05:00
const cvf : : Collection < RigSingleWellResultsData > & wellResults = eclCase - > eclipseCaseData ( ) - > wellResults ( ) ;
2017-03-06 09:33:29 -06:00
for ( size_t wIdx = 0 ; wIdx < wellResults . size ( ) ; + + wIdx )
2016-12-21 10:14:13 -06:00
{
2017-03-06 09:33:29 -06:00
QString wellName = removeCrossFlowEnding ( tracerName ) ;
2016-12-21 10:14:13 -06:00
2017-03-06 09:33:29 -06:00
if ( wellResults [ wIdx ] - > m_wellName ! = wellName ) continue ;
2017-03-07 05:19:19 -06:00
if ( ! wellResults [ wIdx ] - > hasWellResult ( timeStepIndex ) ) return CLOSED ;
2017-03-06 09:33:29 -06:00
2017-03-07 05:19:19 -06:00
const RigWellResultFrame & wellResFrame = wellResults [ wIdx ] - > wellResultFrame ( timeStepIndex ) ;
2017-03-06 09:33:29 -06:00
2017-03-07 05:19:19 -06:00
if ( wellResFrame . m_productionType = = RigWellResultFrame : : GAS_INJECTOR
| | wellResFrame . m_productionType = = RigWellResultFrame : : OIL_INJECTOR
| | wellResFrame . m_productionType = = RigWellResultFrame : : WATER_INJECTOR )
2016-12-21 10:14:13 -06:00
{
2017-03-07 05:19:19 -06:00
if ( hasCrossFlowEnding ( tracerName ) ) return PRODUCER ;
2017-03-06 09:33:29 -06:00
2017-03-07 05:19:19 -06:00
return INJECTOR ;
}
else if ( wellResFrame . m_productionType = = RigWellResultFrame : : PRODUCER
| | wellResFrame . m_productionType = = RigWellResultFrame : : UNDEFINED_PRODUCTION_TYPE )
{
if ( hasCrossFlowEnding ( tracerName ) ) return INJECTOR ;
2017-01-11 05:34:48 -06:00
2017-03-07 05:19:19 -06:00
return PRODUCER ;
}
else
{
CVF_ASSERT ( false ) ;
2016-12-21 10:14:13 -06:00
}
}
CVF_ASSERT ( false ) ;
return UNDEFINED ;
}
2017-02-02 02:56:39 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-09 03:03:52 -06:00
cvf : : Color3f RimFlowDiagSolution : : tracerColor ( const QString & tracerName ) const
2017-02-02 02:56:39 -06:00
{
RimEclipseResultCase * eclCase ;
this - > firstAncestorOrThisOfType ( eclCase ) ;
2017-03-06 09:33:29 -06:00
QString wellName = removeCrossFlowEnding ( tracerName ) ;
2017-02-02 02:56:39 -06:00
if ( eclCase )
{
2017-02-10 11:53:14 -06:00
RimEclipseView * activeView = dynamic_cast < RimEclipseView * > ( RiaApplication : : instance ( ) - > activeReservoirView ( ) ) ;
2017-02-10 01:39:25 -06:00
2017-02-10 11:53:14 -06:00
if ( activeView )
2017-02-02 02:56:39 -06:00
{
2017-03-06 09:33:29 -06:00
RimEclipseWell * well = activeView - > wellCollection - > findWell ( wellName ) ;
2017-02-10 11:53:14 -06:00
if ( well )
{
return well - > wellPipeColor ( ) ;
}
}
else
{
// If we do not find a well color, use index in well result data to be able to get variation of tracer colors
// This can be the case if we do not have any views at all
2017-03-15 03:10:16 -05:00
const cvf : : Collection < RigSingleWellResultsData > & wellResults = eclCase - > eclipseCaseData ( ) - > wellResults ( ) ;
2017-02-10 11:53:14 -06:00
for ( size_t wIdx = 0 ; wIdx < wellResults . size ( ) ; + + wIdx )
2017-02-02 02:56:39 -06:00
{
2017-03-06 09:33:29 -06:00
if ( wellResults [ wIdx ] - > m_wellName = = wellName )
2017-02-10 11:53:14 -06:00
{
return RiaColorTables : : wellsPaletteColors ( ) . cycledColor3f ( wIdx ) ;
}
2017-02-02 02:56:39 -06:00
}
}
}
2017-03-06 09:33:29 -06:00
if ( wellName = = RIG_FLOW_TOTAL_NAME ) return cvf : : Color3f : : LIGHT_GRAY ;
if ( wellName = = RIG_RESERVOIR_TRACER_NAME ) return cvf : : Color3f : : LIGHT_GRAY ;
if ( wellName = = RIG_TINY_TRACER_GROUP_NAME ) return cvf : : Color3f : : DARK_GRAY ;
2017-02-17 04:18:58 -06:00
return cvf : : Color3f : : LIGHT_GRAY ;
2017-02-02 02:56:39 -06:00
}
2016-12-14 02:50:30 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf : : PdmFieldHandle * RimFlowDiagSolution : : userDescriptionField ( )
{
return & m_userDescription ;
}