2017-03-24 15:10:39 +01:00
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimFlowCharacteristicsPlot.h"
#include "RigFlowDiagResults.h"
2017-08-24 09:27:08 +02:00
#include "RigEclipseCaseData.h"
#include "RigActiveCellInfo.h"
2017-03-24 15:10:39 +01:00
2017-03-28 09:47:06 +02:00
#include "RimEclipseResultCase.h"
#include "RimFlowDiagSolution.h"
2017-03-24 15:10:39 +01:00
#include "RimProject.h"
2017-08-17 11:24:51 +02:00
#include "RimEclipseCellColors.h"
#include "RimEclipseView.h"
2017-08-17 13:49:51 +02:00
#include "RimEclipsePropertyFilter.h"
#include "RimEclipsePropertyFilterCollection.h"
2017-10-15 21:20:03 +02:00
#include "RimFaultInViewCollection.h"
2017-08-17 11:24:51 +02:00
#include "RicEclipsePropertyFilterFeatureImpl.h"
2017-08-17 13:49:51 +02:00
#include "RicSelectOrCreateViewFeatureImpl.h"
2017-03-24 15:10:39 +01:00
2017-03-28 09:47:06 +02:00
#include "RiuFlowCharacteristicsPlot.h"
2017-08-17 11:24:51 +02:00
#include "RiuMainWindow.h"
2017-03-28 09:47:06 +02:00
2017-05-11 21:44:44 +02:00
#include "cafPdmUiCheckBoxEditor.h"
2017-08-17 11:24:51 +02:00
#include "cafPdmUiListEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafUtils.h"
2017-05-11 21:44:44 +02:00
2017-08-11 10:24:35 +02:00
#include <QDateTime>
2017-03-28 09:47:06 +02:00
#include <cmath> // Needed for HUGE_VAL on Linux
2017-03-24 15:10:39 +01:00
2017-03-29 09:28:14 +02:00
namespace caf
{
2017-08-17 11:24:51 +02:00
template <>
void AppEnum < RimFlowCharacteristicsPlot :: TimeSelectionType >:: setUp ()
{
2017-08-21 11:37:45 +02:00
addItem ( RimFlowCharacteristicsPlot :: ALL_AVAILABLE , "ALL_AVAILABLE" , "All With Calculated Flow Diagnostics" );
2017-08-21 11:25:40 +02:00
addItem ( RimFlowCharacteristicsPlot :: SELECTED , "SELECTED" , "Selected" );
setDefault ( RimFlowCharacteristicsPlot :: SELECTED );
2017-08-17 11:24:51 +02:00
}
2017-03-29 09:28:14 +02:00
}
2017-03-24 15:10:39 +01:00
CAF_PDM_SOURCE_INIT ( RimFlowCharacteristicsPlot , "FlowCharacteristicsPlot" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFlowCharacteristicsPlot :: RimFlowCharacteristicsPlot ()
{
2017-09-07 10:39:59 +02:00
CAF_PDM_InitObject ( "Flow Characteristics" , ":/FlowCharPlot16x16.png" , "" , "" );
2017-03-24 15:10:39 +01:00
CAF_PDM_InitFieldNoDefault ( & m_case , "FlowCase" , "Case" , "" , "" , "" );
CAF_PDM_InitFieldNoDefault ( & m_flowDiagSolution , "FlowDiagSolution" , "Flow Diag Solution" , "" , "" , "" );
2017-04-06 10:59:52 +02:00
m_flowDiagSolution . uiCapability () -> setUiHidden ( true );
2017-03-29 09:28:14 +02:00
CAF_PDM_InitFieldNoDefault ( & m_timeStepSelectionType , "TimeSelectionType" , "Time Steps" , "" , "" , "" );
CAF_PDM_InitFieldNoDefault ( & m_selectedTimeSteps , "SelectedTimeSteps" , "" , "" , "" , "" );
2017-08-21 13:09:06 +02:00
m_selectedTimeSteps . uiCapability () -> setUiHidden ( true );
CAF_PDM_InitFieldNoDefault ( & m_selectedTimeStepsUi , "SelectedTimeStepsUi" , "" , "" , "" , "" );
2017-08-17 11:24:51 +02:00
CAF_PDM_InitFieldNoDefault ( & m_applyTimeSteps , "ApplyTimeSteps" , "" , "" , "" , "" );
2017-11-16 12:43:05 +01:00
caf :: PdmUiPushButtonEditor :: configureEditorForField ( & m_applyTimeSteps );
2017-08-09 14:10:39 +02:00
CAF_PDM_InitField ( & m_maxPvFraction , "CellPVThreshold" , 0.1 , "Aquifer Cell Threshold" , "" , "Exclude Aquifer Effects by adding a Cell Pore Volume Threshold as Fraction of Total Pore Volume." , "" );
2017-03-24 15:10:39 +01:00
2017-08-17 11:24:51 +02:00
2017-05-11 21:44:44 +02:00
CAF_PDM_InitField ( & m_showLegend , "ShowLegend" , true , "Legend" , "" , "" , "" );
2017-08-17 11:24:51 +02:00
// Region group
2017-08-21 11:39:11 +02:00
CAF_PDM_InitFieldNoDefault ( & m_cellFilter , "CellFilter" , "Cell Filter" , "" , "" , "" );
2017-08-24 09:27:08 +02:00
CAF_PDM_InitFieldNoDefault ( & m_cellFilterView , "CellFilterView" , "View" , "" , "" , "" );
2017-08-22 14:02:26 +02:00
CAF_PDM_InitField ( & m_tracerFilter , "TracerFilter" , QString (), "Tracer Filter" , "" , "" , "" );
2017-08-17 11:24:51 +02:00
CAF_PDM_InitFieldNoDefault ( & m_selectedTracerNames , "SelectedTracerNames" , " " , "" , "" , "" );
m_selectedTracerNames . uiCapability () -> setUiEditorTypeName ( caf :: PdmUiListEditor :: uiEditorTypeName ());
CAF_PDM_InitFieldNoDefault ( & m_showRegion , "ShowRegion" , "" , "" , "" , "" );
2017-11-16 12:43:05 +01:00
caf :: PdmUiPushButtonEditor :: configureEditorForField ( & m_showRegion );
2017-08-29 16:21:19 +02:00
CAF_PDM_InitField ( & m_minCommunication , "MinCommunication" , 0.0 , "Min Communication" , "" , "" , "" );
CAF_PDM_InitField ( & m_maxTof , "MaxTof" , 146000 , "Max Time of Flight [days]" , "" , "" , "" );
2017-08-17 11:24:51 +02:00
2017-03-24 15:10:39 +01:00
this -> m_showWindow = false ;
setAsPlotMdiWindow ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFlowCharacteristicsPlot ::~ RimFlowCharacteristicsPlot ()
{
removeMdiWindowFromMdiArea ();
deleteViewWidget ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: setFromFlowSolution ( RimFlowDiagSolution * flowSolution )
{
if ( ! flowSolution )
{
m_case = nullptr ;
2017-08-24 09:27:08 +02:00
m_cellFilterView = nullptr ;
2017-03-24 15:10:39 +01:00
}
else
{
RimEclipseResultCase * eclCase ;
flowSolution -> firstAncestorOrThisOfType ( eclCase );
m_case = eclCase ;
2017-08-24 09:27:08 +02:00
if ( ! eclCase -> reservoirViews . empty ())
{
m_cellFilterView = eclCase -> reservoirViews ()[ 0 ];
}
2017-03-24 15:10:39 +01:00
}
m_flowDiagSolution = flowSolution ;
2017-03-28 23:35:53 +02:00
m_showWindow = true ;
2017-03-24 15:10:39 +01:00
2017-10-31 12:49:14 +01:00
onLoadDataAndUpdate ();
2017-03-24 15:10:39 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: deleteViewWidget ()
{
if ( m_flowCharPlotWidget )
{
m_flowCharPlotWidget -> deleteLater ();
m_flowCharPlotWidget = nullptr ;
}
}
2017-03-29 14:02:32 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: updateCurrentTimeStep ()
{
if ( m_timeStepSelectionType () != ALL_AVAILABLE ) return ;
if ( ! m_flowDiagSolution ()) return ;
RigFlowDiagResults * flowResult = m_flowDiagSolution -> flowDiagResults ();
2017-08-10 15:08:30 +02:00
std :: vector < int > calculatedTimesteps = flowResult -> calculatedTimeSteps ( RigFlowDiagResultAddress :: PHASE_ALL );
2017-03-29 14:02:32 +02:00
if ( m_currentlyPlottedTimeSteps == calculatedTimesteps ) return ;
2017-10-31 12:49:14 +01:00
this -> onLoadDataAndUpdate ();
2017-03-29 14:02:32 +02:00
}
2017-03-24 15:10:39 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf :: PdmOptionItemInfo > RimFlowCharacteristicsPlot :: calculateValueOptions ( const caf :: PdmFieldHandle * fieldNeedingOptions , bool * useOptionsOnly )
{
QList < caf :: PdmOptionItemInfo > options ;
if ( fieldNeedingOptions == & m_case )
{
RimProject * proj = nullptr ;
this -> firstAncestorOrThisOfType ( proj );
if ( proj )
{
std :: vector < RimEclipseResultCase *> cases ;
proj -> descendantsIncludingThisOfType ( cases );
for ( RimEclipseResultCase * c : cases )
{
2017-04-06 11:12:51 +02:00
if ( c -> defaultFlowDiagSolution () )
{
options . push_back ( caf :: PdmOptionItemInfo ( c -> caseUserDescription (), c , false , c -> uiIcon ()));
}
2017-03-24 15:10:39 +01:00
}
}
}
2017-08-24 09:27:08 +02:00
else if ( fieldNeedingOptions == & m_cellFilterView )
{
if ( m_case )
{
for ( RimEclipseView * view : m_case () -> reservoirViews ())
{
options . push_back ( caf :: PdmOptionItemInfo ( view -> name (), view , false , view -> uiIcon ()));
}
}
}
2017-03-24 15:10:39 +01:00
else if ( fieldNeedingOptions == & m_flowDiagSolution )
{
if ( m_case )
{
std :: vector < RimFlowDiagSolution *> flowSols = m_case -> flowDiagSolutions ();
2017-04-06 11:12:51 +02:00
options . push_back ( caf :: PdmOptionItemInfo ( "None" , nullptr ));
2017-03-24 15:10:39 +01:00
for ( RimFlowDiagSolution * flowSol : flowSols )
{
options . push_back ( caf :: PdmOptionItemInfo ( flowSol -> userDescription (), flowSol , false , flowSol -> uiIcon ()));
}
}
}
2017-08-21 13:09:06 +02:00
else if ( fieldNeedingOptions == & m_selectedTimeStepsUi )
2017-03-29 09:28:14 +02:00
{
2017-08-21 13:09:06 +02:00
if ( m_flowDiagSolution && m_case )
2017-03-29 09:28:14 +02:00
{
2017-05-15 09:17:06 +02:00
QStringList timeStepDates = m_case -> timeStepStrings ();
2017-08-17 11:24:51 +02:00
std :: vector < int > calculatedTimeSteps = m_flowDiagSolution () -> flowDiagResults () -> calculatedTimeSteps ( RigFlowDiagResultAddress :: PHASE_ALL );
for ( int tsIdx = 0 ; tsIdx < timeStepDates . size (); ++ tsIdx )
2017-03-29 09:28:14 +02:00
{
2017-08-17 11:24:51 +02:00
auto it = std :: find ( calculatedTimeSteps . begin (), calculatedTimeSteps . end (), tsIdx );
QString itemText = timeStepDates [ tsIdx ];
2017-08-21 11:48:41 +02:00
if ( it != calculatedTimeSteps . end ())
2017-08-17 11:24:51 +02:00
{
itemText = itemText + " *" ;
}
options . push_back ( caf :: PdmOptionItemInfo ( itemText , tsIdx ));
}
}
}
else if ( fieldNeedingOptions == & m_selectedTracerNames )
{
if ( m_flowDiagSolution )
{
std :: vector < QString > tracerNames = m_flowDiagSolution -> tracerNames ();
2017-08-21 13:37:35 +02:00
std :: vector < std :: pair < QString , QString >> sortedTracerNames ;
2017-08-17 11:24:51 +02:00
for ( QString tracerName : tracerNames )
{
if ( ! caf :: Utils :: isStringMatch ( m_tracerFilter , tracerName )) continue ;
RimFlowDiagSolution :: TracerStatusType tracerStatus = m_flowDiagSolution -> tracerStatusOverall ( tracerName );
if ( tracerStatus == RimFlowDiagSolution :: CLOSED ) continue ;
2017-08-21 11:39:11 +02:00
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_FLOODED )
2017-08-17 11:24:51 +02:00
{
if ( tracerStatus == RimFlowDiagSolution :: INJECTOR || tracerStatus == RimFlowDiagSolution :: VARYING )
{
2017-08-21 13:37:35 +02:00
sortedTracerNames . push_back ( std :: make_pair ( tracerName , tracerName ));
2017-08-17 11:24:51 +02:00
}
}
2017-08-21 11:39:11 +02:00
else if ( m_cellFilter () == RigFlowDiagResults :: CELLS_DRAINED )
2017-08-17 11:24:51 +02:00
{
if ( tracerStatus == RimFlowDiagSolution :: PRODUCER || tracerStatus == RimFlowDiagSolution :: VARYING )
{
2017-08-21 13:37:35 +02:00
sortedTracerNames . push_back ( std :: make_pair ( tracerName , tracerName ));
2017-08-17 11:24:51 +02:00
}
}
2017-08-21 11:39:11 +02:00
else if ( m_cellFilter () == RigFlowDiagResults :: CELLS_COMMUNICATION )
2017-08-17 11:24:51 +02:00
{
QString prefix ;
switch ( tracerStatus )
{
case RimFlowDiagSolution :: INJECTOR :
prefix = "I : " ;
break ;
case RimFlowDiagSolution :: PRODUCER :
prefix = "P : " ;
break ;
case RimFlowDiagSolution :: VARYING :
prefix = "I/P: " ;
break ;
case RimFlowDiagSolution :: UNDEFINED :
prefix = "U : " ;
break ;
}
2017-08-21 13:37:35 +02:00
sortedTracerNames . push_back ( std :: make_pair ( prefix + tracerName , tracerName ));
2017-08-17 11:24:51 +02:00
}
2017-03-29 09:28:14 +02:00
}
2017-08-21 13:37:35 +02:00
std :: sort ( sortedTracerNames . begin (),
sortedTracerNames . end (),
[]( const std :: pair < QString , QString >& a , const std :: pair < QString , QString >& b ) -> bool
{
return a . first < b . first ;
});
for ( auto & tracer : sortedTracerNames )
{
options . push_back ( caf :: PdmOptionItemInfo ( tracer . first , tracer . second ));
}
2017-03-29 09:28:14 +02:00
}
}
2017-03-24 15:10:39 +01:00
return options ;
}
2017-03-29 09:28:14 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: defineUiOrdering ( QString uiConfigName , caf :: PdmUiOrdering & uiOrdering )
{
2017-08-22 11:45:06 +02:00
{
// Ensure a case is selected if one is available
RimProject * proj = nullptr ;
this -> firstAncestorOrThisOfType ( proj );
if ( proj )
{
std :: vector < RimEclipseResultCase *> cases ;
proj -> descendantsIncludingThisOfType ( cases );
RimEclipseResultCase * defaultCase = nullptr ;
for ( RimEclipseResultCase * c : cases )
{
if ( c -> defaultFlowDiagSolution ())
{
if ( ! defaultCase ) defaultCase = c ; // Select first
}
}
if ( ! m_case () && defaultCase )
{
m_case = defaultCase ;
m_flowDiagSolution = m_case -> defaultFlowDiagSolution ();
2017-08-24 09:27:08 +02:00
if ( ! m_case () -> reservoirViews . empty ())
{
m_cellFilterView = m_case () -> reservoirViews ()[ 0 ];
}
2017-08-22 11:45:06 +02:00
}
}
}
2017-05-11 21:44:44 +02:00
2017-08-22 11:46:44 +02:00
uiOrdering . add ( & m_case );
2017-08-21 11:29:34 +02:00
{
caf :: PdmUiGroup * timeStepsGroup = uiOrdering . addNewGroup ( "Time Steps" );
timeStepsGroup -> add ( & m_timeStepSelectionType );
if ( m_timeStepSelectionType == SELECTED )
{
2017-08-21 13:09:06 +02:00
timeStepsGroup -> add ( & m_selectedTimeStepsUi );
2017-08-21 11:29:34 +02:00
timeStepsGroup -> add ( & m_applyTimeSteps );
}
}
2017-08-17 11:24:51 +02:00
{
caf :: PdmUiGroup * regionGroup = uiOrdering . addNewGroup ( "Region" );
2017-08-21 11:39:11 +02:00
regionGroup -> add ( & m_cellFilter );
2017-08-24 09:27:08 +02:00
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_COMMUNICATION ||
m_cellFilter () == RigFlowDiagResults :: CELLS_DRAINED ||
m_cellFilter () == RigFlowDiagResults :: CELLS_FLOODED )
2017-08-17 11:24:51 +02:00
{
regionGroup -> add ( & m_tracerFilter );
regionGroup -> add ( & m_selectedTracerNames );
2017-08-21 11:49:54 +02:00
regionGroup -> add ( & m_showRegion );
2017-08-17 11:24:51 +02:00
}
2017-08-24 09:27:08 +02:00
else if ( m_cellFilter () == RigFlowDiagResults :: CELLS_VISIBLE )
{
regionGroup -> add ( & m_cellFilterView );
}
2017-08-29 16:21:19 +02:00
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_COMMUNICATION )
{
regionGroup -> add ( & m_minCommunication );
}
else if ( m_cellFilter () == RigFlowDiagResults :: CELLS_DRAINED ||
m_cellFilter () == RigFlowDiagResults :: CELLS_FLOODED )
{
regionGroup -> add ( & m_maxTof );
}
2017-08-17 11:24:51 +02:00
}
2017-08-21 11:51:34 +02:00
{
caf :: PdmUiGroup * optionsGroup = uiOrdering . addNewGroup ( "Options" );
optionsGroup -> add ( & m_flowDiagSolution );
optionsGroup -> add ( & m_showLegend );
optionsGroup -> add ( & m_maxPvFraction );
}
2017-03-29 09:28:14 +02:00
uiOrdering . skipRemainingFields ();
}
2017-08-17 11:24:51 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: defineEditorAttribute ( const caf :: PdmFieldHandle * field , QString uiConfigName , caf :: PdmUiEditorAttribute * attribute )
{
if ( field == & m_applyTimeSteps )
{
caf :: PdmUiPushButtonEditorAttribute * attrib = dynamic_cast < caf :: PdmUiPushButtonEditorAttribute *> ( attribute );
if ( attrib )
{
attrib -> m_buttonText = "Apply" ;
}
}
else if ( field == & m_showRegion )
{
caf :: PdmUiPushButtonEditorAttribute * attrib = dynamic_cast < caf :: PdmUiPushButtonEditorAttribute *> ( attribute );
if ( attrib )
{
attrib -> m_buttonText = "Show Region" ;
}
}
}
2017-03-24 15:10:39 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget * RimFlowCharacteristicsPlot :: viewWidget ()
{
return m_flowCharPlotWidget ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: zoomAll ()
{
2017-03-28 23:35:53 +02:00
if ( m_flowCharPlotWidget ) m_flowCharPlotWidget -> zoomAll ();
2017-03-24 15:10:39 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: fieldChangedByUi ( const caf :: PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
RimViewWindow :: fieldChangedByUi ( changedField , oldValue , newValue );
2017-03-29 09:28:14 +02:00
if ( & m_case == changedField )
2017-03-24 15:10:39 +01:00
{
2017-08-24 09:27:08 +02:00
m_flowDiagSolution = m_case -> defaultFlowDiagSolution ();
m_currentlyPlottedTimeSteps . clear ();
if ( ! m_case () -> reservoirViews . empty ())
{
m_cellFilterView = m_case () -> reservoirViews ()[ 0 ];
}
2017-03-24 15:10:39 +01:00
}
2017-08-17 11:24:51 +02:00
else if ( & m_applyTimeSteps == changedField )
{
if ( m_flowDiagSolution )
{
// Compute any missing time steps from selected
2017-08-21 13:09:06 +02:00
for ( int tsIdx : m_selectedTimeStepsUi ())
2017-08-17 11:24:51 +02:00
{
m_flowDiagSolution () -> flowDiagResults () -> maxAbsPairFlux ( tsIdx );
}
2017-08-21 13:09:06 +02:00
m_selectedTimeSteps = m_selectedTimeStepsUi ;
2017-08-17 11:24:51 +02:00
}
m_applyTimeSteps = false ;
}
else if ( & m_showRegion == changedField )
{
if ( m_case )
{
2017-08-21 11:39:11 +02:00
if ( m_cellFilter () != RigFlowDiagResults :: CELLS_ACTIVE )
2017-08-17 11:24:51 +02:00
{
2017-08-17 13:49:51 +02:00
RimEclipseView * view = RicSelectOrCreateViewFeatureImpl :: showViewSelection ( m_case , "FlowCharacteristicsLastUsedView" , "Show Region in View" );
2017-08-17 11:24:51 +02:00
2017-08-22 11:47:36 +02:00
if ( view != nullptr )
2017-08-17 11:24:51 +02:00
{
2017-08-24 09:53:27 +02:00
view -> faultCollection () -> showFaultCollection = false ;
2017-08-22 11:47:36 +02:00
view -> cellResult () -> setResultType ( RiaDefines :: FLOW_DIAGNOSTICS );
view -> cellResult () -> setFlowDiagTracerSelectionType ( RimEclipseResultDefinition :: FLOW_TR_BY_SELECTION );
view -> cellResult () -> setSelectedTracers ( m_selectedTracerNames );
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_COMMUNICATION )
{
view -> cellResult () -> setResultVariable ( RIG_FLD_COMMUNICATION_RESNAME );
}
else
{
view -> cellResult () -> setResultVariable ( RIG_FLD_TOF_RESNAME );
}
int timeStep = 0 ;
if ( m_timeStepSelectionType () == ALL_AVAILABLE )
2017-08-17 11:24:51 +02:00
{
2017-08-22 11:47:36 +02:00
if ( m_flowDiagSolution )
2017-08-17 11:24:51 +02:00
{
2017-08-22 11:47:36 +02:00
std :: vector < int > timeSteps = m_flowDiagSolution () -> flowDiagResults () -> calculatedTimeSteps ( RigFlowDiagResultAddress :: PHASE_ALL );
if ( ! timeSteps . empty ())
{
timeStep = timeSteps [ 0 ];
}
2017-08-17 11:24:51 +02:00
}
}
2017-08-22 11:47:36 +02:00
else
2017-08-17 11:24:51 +02:00
{
2017-08-22 11:47:36 +02:00
if ( ! m_selectedTimeStepsUi (). empty ())
{
timeStep = m_selectedTimeStepsUi ()[ 0 ];
}
2017-08-17 11:24:51 +02:00
}
2017-08-22 11:47:36 +02:00
// Ensure selected time step has computed results
m_flowDiagSolution () -> flowDiagResults () -> maxAbsPairFlux ( timeStep );
2017-08-17 11:24:51 +02:00
2017-08-22 11:47:36 +02:00
view -> setCurrentTimeStep ( timeStep );
2017-08-17 13:49:51 +02:00
2017-08-22 11:47:36 +02:00
for ( RimEclipsePropertyFilter * f : view -> eclipsePropertyFilterCollection () -> propertyFilters ())
{
f -> isActive = false ;
}
RicEclipsePropertyFilterFeatureImpl :: addPropertyFilter ( view -> eclipsePropertyFilterCollection ());
2017-08-17 11:24:51 +02:00
2017-08-22 11:47:36 +02:00
view -> loadDataAndUpdate ();
m_case -> updateConnectedEditors ();
2017-08-17 11:24:51 +02:00
2017-08-22 11:47:36 +02:00
RicSelectOrCreateViewFeatureImpl :: focusView ( view );
}
2017-08-17 11:24:51 +02:00
}
}
}
2017-08-21 11:39:11 +02:00
else if ( changedField == & m_cellFilter )
2017-08-17 11:24:51 +02:00
{
m_selectedTracerNames = std :: vector < QString > ();
}
2017-03-24 15:10:39 +01:00
2017-03-29 09:28:14 +02:00
// All fields update plot
2017-10-31 12:49:14 +01:00
this -> onLoadDataAndUpdate ();
2017-03-24 15:10:39 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimFlowCharacteristicsPlot :: snapshotWindowContent ()
{
QImage image ;
if ( m_flowCharPlotWidget )
{
QPixmap pix = QPixmap :: grabWidget ( m_flowCharPlotWidget );
image = pix . toImage ();
}
return image ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-31 12:49:14 +01:00
void RimFlowCharacteristicsPlot :: onLoadDataAndUpdate ()
2017-03-24 15:10:39 +01:00
{
updateMdiWindowVisibility ();
2017-03-28 23:35:53 +02:00
if ( m_flowDiagSolution && m_flowCharPlotWidget )
2017-03-24 15:10:39 +01:00
{
RigFlowDiagResults * flowResult = m_flowDiagSolution -> flowDiagResults ();
2017-08-10 15:08:30 +02:00
std :: vector < int > calculatedTimesteps = flowResult -> calculatedTimeSteps ( RigFlowDiagResultAddress :: PHASE_ALL );
2017-03-24 15:10:39 +01:00
2017-08-21 11:25:40 +02:00
if ( m_timeStepSelectionType == SELECTED )
2017-03-29 09:28:14 +02:00
{
2017-08-21 13:09:06 +02:00
for ( int tsIdx : m_selectedTimeSteps ())
2017-03-29 09:28:14 +02:00
{
2017-08-21 13:09:06 +02:00
m_flowDiagSolution () -> flowDiagResults () -> maxAbsPairFlux ( tsIdx );
2017-03-29 09:28:14 +02:00
}
2017-08-21 13:09:06 +02:00
calculatedTimesteps = m_selectedTimeSteps ();
2017-03-29 09:28:14 +02:00
}
2017-03-29 14:02:32 +02:00
m_currentlyPlottedTimeSteps = calculatedTimesteps ;
2017-03-29 09:28:14 +02:00
2017-03-24 15:10:39 +01:00
std :: vector < QDateTime > timeStepDates = m_case -> timeStepDates ();
2017-05-15 09:17:06 +02:00
QStringList timeStepStrings = m_case -> timeStepStrings ();
2017-03-24 15:10:39 +01:00
std :: vector < double > lorenzVals ( timeStepDates . size (), HUGE_VAL );
2017-03-28 23:35:53 +02:00
m_flowCharPlotWidget -> removeAllCurves ();
2017-08-17 11:24:51 +02:00
std :: vector < QString > selectedTracerNames = m_selectedTracerNames ();
2017-08-21 11:39:11 +02:00
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_ACTIVE )
2017-08-17 11:24:51 +02:00
{
if ( m_flowDiagSolution )
{
selectedTracerNames = m_flowDiagSolution -> tracerNames ();
}
}
2017-08-24 09:27:08 +02:00
std :: map < int , RigFlowDiagSolverInterface :: FlowCharacteristicsResultFrame > timeStepToFlowResultMap ;
for ( int timeStepIdx : calculatedTimesteps )
2017-03-24 15:10:39 +01:00
{
2017-08-24 09:27:08 +02:00
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_VISIBLE )
{
cvf :: UByteArray visibleCells ;
m_case () -> eclipseCaseData () -> activeCellInfo ( RiaDefines :: MATRIX_MODEL );
if ( m_cellFilterView )
{
m_cellFilterView () -> calculateCurrentTotalCellVisibility ( & visibleCells , timeStepIdx );
}
RigActiveCellInfo * activeCellInfo = m_case () -> eclipseCaseData () -> activeCellInfo ( RiaDefines :: MATRIX_MODEL );
std :: vector < char > visibleActiveCells ( activeCellInfo -> reservoirActiveCellCount (), 0 );
for ( size_t i = 0 ; i < visibleCells . size (); ++ i )
{
size_t cellIndex = activeCellInfo -> cellResultIndex ( i );
if ( cellIndex != cvf :: UNDEFINED_SIZE_T )
{
visibleActiveCells [ cellIndex ] = visibleCells [ i ];
}
}
auto flowCharResults = flowResult -> flowCharacteristicsResults ( timeStepIdx , visibleActiveCells , m_maxPvFraction ());
timeStepToFlowResultMap [ timeStepIdx ] = flowCharResults ;
}
else
{
2017-08-29 16:21:19 +02:00
auto flowCharResults = flowResult -> flowCharacteristicsResults ( timeStepIdx ,
m_cellFilter (),
selectedTracerNames ,
m_maxPvFraction (),
m_minCommunication (),
m_maxTof ());
2017-08-24 09:27:08 +02:00
timeStepToFlowResultMap [ timeStepIdx ] = flowCharResults ;
}
lorenzVals [ timeStepIdx ] = timeStepToFlowResultMap [ timeStepIdx ]. m_lorenzCoefficient ;
2017-03-28 23:35:53 +02:00
}
2017-08-24 09:27:08 +02:00
2017-05-15 09:17:06 +02:00
m_flowCharPlotWidget -> setLorenzCurve ( timeStepStrings , timeStepDates , lorenzVals );
2017-03-24 15:10:39 +01:00
2017-03-28 23:35:53 +02:00
for ( int timeStepIdx : calculatedTimesteps )
{
2017-08-24 09:27:08 +02:00
const auto & flowCharResults = timeStepToFlowResultMap [ timeStepIdx ];
2017-03-28 23:35:53 +02:00
m_flowCharPlotWidget -> addFlowCapStorageCapCurve ( timeStepDates [ timeStepIdx ],
flowCharResults . m_flowCapStorageCapCurve . first ,
flowCharResults . m_flowCapStorageCapCurve . second );
m_flowCharPlotWidget -> addSweepEfficiencyCurve ( timeStepDates [ timeStepIdx ],
flowCharResults . m_sweepEfficiencyCurve . first ,
flowCharResults . m_sweepEfficiencyCurve . second );
2017-03-24 15:10:39 +01:00
}
2017-05-11 21:44:44 +02:00
m_flowCharPlotWidget -> showLegend ( m_showLegend ());
2017-03-24 15:10:39 +01:00
}
}
2017-08-24 13:28:17 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot :: viewGeometryUpdated ()
{
if ( m_cellFilter () == RigFlowDiagResults :: CELLS_VISIBLE )
{
// Only need to reload data if cell filtering is based on visible cells in view.
2017-10-31 12:49:14 +01:00
onLoadDataAndUpdate ();
2017-08-24 13:28:17 +02:00
}
}
2017-03-24 15:10:39 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget * RimFlowCharacteristicsPlot :: createViewWidget ( QWidget * mainWindowParent )
{
m_flowCharPlotWidget = new RiuFlowCharacteristicsPlot ( this , mainWindowParent );
return m_flowCharPlotWidget ;
}