From e014bfd283e3f27513b7ca1dfeba4e719587a87e Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 15 Mar 2024 11:00:55 +0100 Subject: [PATCH] Fix incorrect line breaks. --- .../RimEclipseResultDefinition.cpp | 3786 ++++++++--------- 1 file changed, 1893 insertions(+), 1893 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp index ea63ec6231..ee64dffbd6 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -1,1893 +1,1893 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011- Statoil ASA -// Copyright (C) 2013- Ceetron Solutions AS -// Copyright (C) 2011-2012 Ceetron AS -// -// 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 "RimEclipseResultDefinition.h" - -#include "RiaLogging.h" -#include "RiaQDateTimeTools.h" - -#include "RicfCommandObject.h" - -#include "RigActiveCellInfo.h" -#include "RigCaseCellResultsData.h" -#include "RigEclipseCaseData.h" -#include "RigEclipseResultInfo.h" -#include "RigFlowDiagResultAddress.h" -#include "RigFlowDiagResults.h" -#include "RigFormationNames.h" - -#include "Rim3dView.h" -#include "Rim3dWellLogCurve.h" -#include "RimCellEdgeColors.h" -#include "RimContourMapProjection.h" -#include "RimEclipseCase.h" -#include "RimEclipseCellColors.h" -#include "RimEclipseContourMapProjection.h" -#include "RimEclipseContourMapView.h" -#include "RimEclipseFaultColors.h" -#include "RimEclipsePropertyFilter.h" -#include "RimEclipseResultCase.h" -#include "RimEclipseResultDefinitionTools.h" -#include "RimEclipseView.h" -#include "RimFlowDiagSolution.h" -#include "RimFlowDiagnosticsTools.h" -#include "RimGridCrossPlot.h" -#include "RimGridCrossPlotDataSet.h" -#include "RimGridTimeHistoryCurve.h" -#include "RimIntersectionCollection.h" -#include "RimIntersectionResultDefinition.h" -#include "RimPlotCurve.h" -#include "RimProject.h" -#include "RimRegularLegendConfig.h" -#include "RimReservoirCellResultsStorage.h" -#include "RimViewLinker.h" -#include "RimWellLogExtractionCurve.h" -#include "RimWellLogTrack.h" - -#ifdef USE_QTCHARTS -#include "RimGridStatisticsPlot.h" -#endif - -#include "cafPdmFieldScriptingCapability.h" -#include "cafPdmUiToolButtonEditor.h" -#include "cafPdmUiTreeSelectionEditor.h" -#include "cafUtils.h" - -#include - -namespace caf -{ -template <> -void RimEclipseResultDefinition::FlowTracerSelectionEnum::setUp() -{ - addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD, "FLOW_TR_INJ_AND_PROD", "All Injectors and Producers" ); - addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_PRODUCERS, "FLOW_TR_PRODUCERS", "All Producers" ); - addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_INJECTORS, "FLOW_TR_INJECTORS", "All Injectors" ); - addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_BY_SELECTION, "FLOW_TR_BY_SELECTION", "By Selection" ); - - setDefault( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD ); -} -} // namespace caf - -CAF_PDM_SOURCE_INIT( RimEclipseResultDefinition, "ResultDefinition" ); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::LabelPosType labelPosition ) - : m_isDeltaResultEnabled( false ) - , m_labelPosition( labelPosition ) - , m_ternaryEnabled( true ) -{ - CAF_PDM_InitScriptableObjectWithNameAndComment( "Result Definition", "", "", "", "EclipseResult", "An eclipse result definition" ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_resultType, "ResultType", "Type" ); - m_resultType.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_porosityModel, "PorosityModelType", "Porosity" ); - m_porosityModel.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitScriptableField( &m_resultVariable, "ResultVariable", RiaResultNames::undefinedResultName(), "Variable" ); - m_resultVariable.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitFieldNoDefault( &m_flowSolution, "FlowDiagSolution", "Solution" ); - m_flowSolution.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitField( &m_timeLapseBaseTimestep, "TimeLapseBaseTimeStep", RigEclipseResultAddress::noTimeLapseValue(), "Base Time Step" ); - - CAF_PDM_InitFieldNoDefault( &m_differenceCase, "DifferenceCase", "Difference Case" ); - - CAF_PDM_InitField( &m_divideByCellFaceArea, "DivideByCellFaceArea", false, "Divide By Area" ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_selectedInjectorTracers, "SelectedInjectorTracers", "Injector Tracers" ); - m_selectedInjectorTracers.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_selectedProducerTracers, "SelectedProducerTracers", "Producer Tracers" ); - m_selectedProducerTracers.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_selectedSouringTracers, "SelectedSouringTracers", "Tracers" ); - m_selectedSouringTracers.uiCapability()->setUiHidden( true ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_flowTracerSelectionMode, "FlowTracerSelectionMode", "Tracers" ); - CAF_PDM_InitScriptableFieldNoDefault( &m_phaseSelection, "PhaseSelection", "Phases" ); - m_phaseSelection.uiCapability()->setUiLabelPosition( m_labelPosition ); - - CAF_PDM_InitScriptableField( &m_showOnlyVisibleCategoriesInLegend, - "ShowOnlyVisibleCategoriesInLegend", - true, - "Show Only Visible Categories In Legend" ); - - // Ui only fields - - CAF_PDM_InitFieldNoDefault( &m_resultTypeUiField, "MResultType", "Type" ); - m_resultTypeUiField.xmlCapability()->disableIO(); - m_resultTypeUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); - - CAF_PDM_InitFieldNoDefault( &m_porosityModelUiField, "MPorosityModelType", "Porosity" ); - m_porosityModelUiField.xmlCapability()->disableIO(); - m_porosityModelUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); - - CAF_PDM_InitField( &m_resultVariableUiField, "MResultVariable", RiaResultNames::undefinedResultName(), "Result Property" ); - m_resultVariableUiField.xmlCapability()->disableIO(); - m_resultVariableUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); - m_resultVariableUiField.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() ); - - CAF_PDM_InitFieldNoDefault( &m_inputPropertyFileName, "InputPropertyFileName", "File Name" ); - m_inputPropertyFileName.xmlCapability()->disableIO(); - m_inputPropertyFileName.uiCapability()->setUiReadOnly( true ); - - CAF_PDM_InitFieldNoDefault( &m_flowSolutionUiField, "MFlowDiagSolution", "Solution" ); - m_flowSolutionUiField.xmlCapability()->disableIO(); - m_flowSolutionUiField.uiCapability()->setUiHidden( true ); // For now since there are only one to choose from - - CAF_PDM_InitField( &m_syncInjectorToProducerSelection, "MSyncSelectedInjProd", false, "Add Communicators ->" ); - m_syncInjectorToProducerSelection.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonEditor::uiEditorTypeName() ); - - CAF_PDM_InitField( &m_syncProducerToInjectorSelection, "MSyncSelectedProdInj", false, "<- Add Communicators" ); - m_syncProducerToInjectorSelection.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonEditor::uiEditorTypeName() ); - - CAF_PDM_InitFieldNoDefault( &m_selectedInjectorTracersUiField, "MSelectedInjectorTracers", "Injector Tracers" ); - m_selectedInjectorTracersUiField.xmlCapability()->disableIO(); - m_selectedInjectorTracersUiField.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); - - CAF_PDM_InitFieldNoDefault( &m_selectedProducerTracersUiField, "MSelectedProducerTracers", "Producer Tracers" ); - m_selectedProducerTracersUiField.xmlCapability()->disableIO(); - m_selectedProducerTracersUiField.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); - - CAF_PDM_InitFieldNoDefault( &m_selectedSouringTracersUiField, "MSelectedSouringTracers", "Tracers" ); - m_selectedSouringTracersUiField.xmlCapability()->disableIO(); - m_selectedSouringTracersUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseResultDefinition::~RimEclipseResultDefinition() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::simpleCopy( const RimEclipseResultDefinition* other ) -{ - setResultVariable( other->resultVariable() ); - setPorosityModel( other->porosityModel() ); - setResultType( other->resultType() ); - setFlowSolution( other->m_flowSolution() ); - setSelectedInjectorTracers( other->m_selectedInjectorTracers() ); - setSelectedProducerTracers( other->m_selectedProducerTracers() ); - setSelectedSouringTracers( other->m_selectedSouringTracers() ); - m_flowTracerSelectionMode = other->m_flowTracerSelectionMode(); - m_phaseSelection = other->m_phaseSelection; - - m_differenceCase = other->m_differenceCase(); - m_timeLapseBaseTimestep = other->m_timeLapseBaseTimestep(); - m_divideByCellFaceArea = other->m_divideByCellFaceArea(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setEclipseCase( RimEclipseCase* eclipseCase ) -{ - m_eclipseCase = eclipseCase; - - assignFlowSolutionFromCase(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseCase* RimEclipseResultDefinition::eclipseCase() const -{ - return m_eclipseCase; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiaDefines::ResultCatType RimEclipseResultDefinition::resultType() const -{ - return m_resultType(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigCaseCellResultsData* RimEclipseResultDefinition::currentGridCellResults() const -{ - if ( !m_eclipseCase ) return nullptr; - - return m_eclipseCase->results( m_porosityModel() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) -{ - if ( &m_flowSolutionUiField == changedField || &m_resultTypeUiField == changedField || &m_porosityModelUiField == changedField ) - { - // If the user are seeing the list with the actually selected result, - // select that result in the list. Otherwise select nothing. - - QStringList varList = RimEclipseResultDefinitionTools::getResultNamesForResultType( m_resultTypeUiField(), currentGridCellResults() ); - - bool isFlowDiagFieldsRelevant = ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ); - - if ( ( m_flowSolutionUiField() == m_flowSolution() || !isFlowDiagFieldsRelevant ) && m_resultTypeUiField() == m_resultType() && - m_porosityModelUiField() == m_porosityModel() ) - { - if ( varList.contains( resultVariable() ) ) - { - m_resultVariableUiField = resultVariable(); - } - - if ( isFlowDiagFieldsRelevant ) - { - m_selectedInjectorTracersUiField = m_selectedInjectorTracers(); - m_selectedProducerTracersUiField = m_selectedProducerTracers(); - } - else - { - m_selectedInjectorTracersUiField = std::vector(); - m_selectedProducerTracersUiField = std::vector(); - } - } - else - { - m_resultVariableUiField = ""; - m_selectedInjectorTracersUiField = std::vector(); - m_selectedProducerTracersUiField = std::vector(); - } - } - - if ( &m_resultVariableUiField == changedField ) - { - m_porosityModel = m_porosityModelUiField; - m_resultType = m_resultTypeUiField; - m_resultVariable = m_resultVariableUiField; - - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - m_flowSolution = m_flowSolutionUiField(); - m_selectedInjectorTracers = m_selectedInjectorTracersUiField(); - m_selectedProducerTracers = m_selectedProducerTracersUiField(); - } - else if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INJECTION_FLOODING ) - { - m_selectedSouringTracers = m_selectedSouringTracersUiField(); - } - else if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INPUT_PROPERTY ) - { - m_inputPropertyFileName = RimEclipseResultDefinitionTools::getInputPropertyFileName( eclipseCase(), newValue.toString() ); - } - loadDataAndUpdate(); - } - - if ( &m_porosityModelUiField == changedField ) - { - m_porosityModel = m_porosityModelUiField; - m_resultVariableUiField = resultVariable(); - - auto eclipseView = firstAncestorOrThisOfType(); - if ( eclipseView ) - { - // Active cells can be different between matrix and fracture, make sure all geometry is recreated - eclipseView->scheduleReservoirGridGeometryRegen(); - } - - loadDataAndUpdate(); - } - - auto contourMapView = firstAncestorOrThisOfType(); - - if ( &m_differenceCase == changedField ) - { - m_timeLapseBaseTimestep = RigEclipseResultAddress::noTimeLapseValue(); - - if ( contourMapView ) - { - contourMapView->contourMapProjection()->clearGridMappingAndRedraw(); - } - - loadDataAndUpdate(); - } - - if ( &m_timeLapseBaseTimestep == changedField ) - { - if ( contourMapView ) - { - contourMapView->contourMapProjection()->clearGridMappingAndRedraw(); - } - - loadDataAndUpdate(); - } - - if ( &m_divideByCellFaceArea == changedField ) - { - loadDataAndUpdate(); - } - - if ( &m_flowTracerSelectionMode == changedField ) - { - loadDataAndUpdate(); - } - - if ( &m_selectedInjectorTracersUiField == changedField ) - { - changedTracerSelectionField( true ); - } - - if ( &m_selectedProducerTracersUiField == changedField ) - { - changedTracerSelectionField( false ); - } - - if ( &m_syncInjectorToProducerSelection == changedField ) - { - syncInjectorToProducerSelection(); - m_syncInjectorToProducerSelection = false; - } - - if ( &m_syncProducerToInjectorSelection == changedField ) - { - syncProducerToInjectorSelection(); - m_syncProducerToInjectorSelection = false; - } - - if ( &m_selectedSouringTracersUiField == changedField ) - { - if ( !m_resultVariable().isEmpty() ) - { - m_selectedSouringTracers = m_selectedSouringTracersUiField(); - loadDataAndUpdate(); - } - } - - if ( &m_phaseSelection == changedField ) - { - if ( m_phaseSelection() != RigFlowDiagResultAddress::PHASE_ALL ) - { - m_resultType = m_resultTypeUiField; - m_resultVariable = RIG_FLD_TOF_RESNAME; - m_resultVariableUiField = RIG_FLD_TOF_RESNAME; - } - loadDataAndUpdate(); - } - - if ( &m_showOnlyVisibleCategoriesInLegend == changedField ) - { - loadDataAndUpdate(); - } - - updateAnyFieldHasChanged(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::changedTracerSelectionField( bool injector ) -{ - m_flowSolution = m_flowSolutionUiField(); - - std::vector& selectedTracers = injector ? m_selectedInjectorTracers.v() : m_selectedProducerTracers.v(); - const std::vector& selectedTracersUi = injector ? m_selectedInjectorTracersUiField.v() : m_selectedProducerTracersUiField.v(); - - selectedTracers = selectedTracersUi; - - loadDataAndUpdate(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::updateAnyFieldHasChanged() -{ - RimEclipsePropertyFilter* propFilter = firstAncestorOrThisOfType(); - if ( propFilter ) - { - propFilter->updateConnectedEditors(); - } - - RimEclipseFaultColors* faultColors = firstAncestorOrThisOfType(); - if ( faultColors ) - { - faultColors->updateConnectedEditors(); - } - - RimCellEdgeColors* cellEdgeColors = firstAncestorOrThisOfType(); - if ( cellEdgeColors ) - { - cellEdgeColors->updateConnectedEditors(); - } - - RimEclipseCellColors* cellColors = firstAncestorOrThisOfType(); - if ( cellColors ) - { - cellColors->updateConnectedEditors(); - } - - RimIntersectionResultDefinition* intersectResDef = firstAncestorOrThisOfType(); - if ( intersectResDef ) - { - intersectResDef->setDefaultEclipseLegendConfig(); - intersectResDef->updateConnectedEditors(); - } - - RimGridCrossPlotDataSet* crossPlotCurveSet = firstAncestorOrThisOfType(); - if ( crossPlotCurveSet ) - { - crossPlotCurveSet->updateConnectedEditors(); - } - - RimPlotCurve* curve = firstAncestorOrThisOfType(); - if ( curve ) - { - curve->updateConnectedEditors(); - } - - Rim3dWellLogCurve* rim3dWellLogCurve = firstAncestorOrThisOfType(); - if ( rim3dWellLogCurve ) - { - rim3dWellLogCurve->resetMinMaxValues(); - } - - RimEclipseContourMapProjection* contourMap = firstAncestorOrThisOfType(); - if ( contourMap ) - { - contourMap->clearGridMappingAndRedraw(); - } - - RimWellLogTrack* wellLogTrack = firstAncestorOrThisOfType(); - if ( wellLogTrack ) - { - wellLogTrack->loadDataAndUpdate(); - wellLogTrack->updateEditors(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setTofAndSelectTracer( const QString& tracerName ) -{ - setResultType( RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ); - setResultVariable( "TOF" ); - setFlowDiagTracerSelectionType( FlowTracerSelectionType::FLOW_TR_BY_SELECTION ); - - if ( m_flowSolution() == nullptr ) - { - assignFlowSolutionFromCase(); - } - - if ( m_flowSolution() ) - { - RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall( tracerName ); - - std::vector tracers; - tracers.push_back( tracerName ); - if ( ( tracerStatus == RimFlowDiagSolution::TracerStatusType::INJECTOR ) || - ( tracerStatus == RimFlowDiagSolution::TracerStatusType::VARYING ) ) - { - setSelectedInjectorTracers( tracers ); - } - - if ( ( tracerStatus == RimFlowDiagSolution::TracerStatusType::PRODUCER ) || - ( tracerStatus == RimFlowDiagSolution::TracerStatusType::VARYING ) ) - { - setSelectedProducerTracers( tracers ); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::loadDataAndUpdate() -{ - auto view = firstAncestorOrThisOfType(); - - loadResult(); - - RimEclipsePropertyFilter* propFilter = firstAncestorOrThisOfType(); - if ( propFilter ) - { - propFilter->setToDefaultValues(); - propFilter->updateFilterName(); - - if ( view ) - { - view->scheduleGeometryRegen( PROPERTY_FILTERED ); - view->scheduleCreateDisplayModelAndRedraw(); - } - } - - RimEclipseCellColors* cellColors = firstAncestorOrThisOfType(); - if ( cellColors ) - { - updateLegendCategorySettings(); - - if ( view ) - { - RimViewLinker* viewLinker = view->assosiatedViewLinker(); - if ( viewLinker ) - { - viewLinker->updateCellResult(); - } - RimGridView* eclView = dynamic_cast( view ); - if ( eclView ) eclView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } - } - - RimIntersectionResultDefinition* sepIntersectionResDef = firstAncestorOrThisOfType(); - if ( sepIntersectionResDef && sepIntersectionResDef->isInAction() ) - { - if ( view ) view->scheduleCreateDisplayModelAndRedraw(); - RimGridView* gridView = dynamic_cast( view ); - if ( gridView ) gridView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } - - RimCellEdgeColors* cellEdgeColors = firstAncestorOrThisOfType(); - if ( cellEdgeColors ) - { - cellEdgeColors->loadResult(); - - if ( view ) - { - view->scheduleCreateDisplayModelAndRedraw(); - } - } - - RimGridCrossPlotDataSet* crossPlotCurveSet = firstAncestorOrThisOfType(); - if ( crossPlotCurveSet ) - { - crossPlotCurveSet->destroyCurves(); - crossPlotCurveSet->loadDataAndUpdate( true ); - } - - RimPlotCurve* curve = firstAncestorOrThisOfType(); - if ( curve ) - { - curve->loadDataAndUpdate( true ); - } - - Rim3dWellLogCurve* rim3dWellLogCurve = firstAncestorOrThisOfType(); - if ( rim3dWellLogCurve ) - { - rim3dWellLogCurve->updateCurveIn3dView(); - } - -#ifdef USE_QTCHARTS - RimGridStatisticsPlot* gridStatisticsPlot = firstAncestorOrThisOfType(); - if ( gridStatisticsPlot ) - { - gridStatisticsPlot->loadDataAndUpdate(); - } -#endif -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QList RimEclipseResultDefinition::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) -{ - QList options; - - if ( fieldNeedingOptions == &m_resultTypeUiField ) - { - bool hasSourSimRLFile = false; - RimEclipseResultCase* eclResCase = dynamic_cast( m_eclipseCase.p() ); - if ( eclResCase && eclResCase->eclipseCaseData() ) - { - hasSourSimRLFile = eclResCase->hasSourSimFile(); - } - -#ifndef USE_HDF5 - // If using ResInsight without HDF5 support, ignore SourSim files and - // do not show it as a result category. - hasSourSimRLFile = false; -#endif - - bool enableSouring = false; - -#ifdef USE_HDF5 - if ( m_eclipseCase.notNull() ) - { - RigCaseCellResultsData* cellResultsData = m_eclipseCase->results( porosityModel() ); - - if ( cellResultsData && cellResultsData->hasFlowDiagUsableFluxes() ) - { - enableSouring = true; - } - } -#endif /* USE_HDF5 */ - - RimGridTimeHistoryCurve* timeHistoryCurve = firstAncestorOrThisOfType(); - - bool isSeparateFaultResult = false; - { - RimEclipseFaultColors* sepFaultResult = firstAncestorOrThisOfType(); - if ( sepFaultResult ) isSeparateFaultResult = true; - } - - using ResCatEnum = caf::AppEnum; - for ( size_t i = 0; i < ResCatEnum::size(); ++i ) - { - RiaDefines::ResultCatType resType = ResCatEnum::fromIndex( i ); - - // Do not include flow diagnostics results if it is a time history curve - - if ( resType == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && ( timeHistoryCurve ) ) - { - continue; - } - - if ( resType == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && m_eclipseCase && m_eclipseCase->eclipseCaseData() && - m_eclipseCase->eclipseCaseData()->hasFractureResults() ) - { - // Flow diagnostics is not supported for dual porosity models - continue; - } - - // Do not include SourSimRL if no SourSim file is loaded - - if ( resType == RiaDefines::ResultCatType::SOURSIMRL && ( !hasSourSimRLFile ) ) - { - continue; - } - - if ( resType == RiaDefines::ResultCatType::INJECTION_FLOODING && !enableSouring ) - { - continue; - } - - if ( resType == RiaDefines::ResultCatType::ALLAN_DIAGRAMS && !isSeparateFaultResult ) - { - continue; - } - - QString uiString = ResCatEnum::uiTextFromIndex( i ); - options.push_back( caf::PdmOptionItemInfo( uiString, resType ) ); - } - } - - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - if ( fieldNeedingOptions == &m_resultVariableUiField ) - { - options.push_back( caf::PdmOptionItemInfo( RimEclipseResultDefinitionTools::timeOfFlightString( injectorSelectionState(), - producerSelectionState(), - false ), - RIG_FLD_TOF_RESNAME ) ); - if ( m_phaseSelection() == RigFlowDiagResultAddress::PHASE_ALL ) - { - options.push_back( caf::PdmOptionItemInfo( "Tracer Cell Fraction (Sum)", RIG_FLD_CELL_FRACTION_RESNAME ) ); - options.push_back( caf::PdmOptionItemInfo( RimEclipseResultDefinitionTools::maxFractionTracerString( injectorSelectionState(), - producerSelectionState(), - false ), - RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) ); - options.push_back( caf::PdmOptionItemInfo( "Injector Producer Communication", RIG_FLD_COMMUNICATION_RESNAME ) ); - } - } - else if ( fieldNeedingOptions == &m_flowSolutionUiField ) - { - RimEclipseResultCase* eclCase = dynamic_cast( m_eclipseCase.p() ); - if ( eclCase ) - { - std::vector flowSols = eclCase->flowDiagSolutions(); - for ( RimFlowDiagSolution* flowSol : flowSols ) - { - options.push_back( caf::PdmOptionItemInfo( flowSol->userDescription(), flowSol ) ); - } - } - } - else if ( fieldNeedingOptions == &m_selectedInjectorTracersUiField ) - { - const bool isInjector = true; - options = RimFlowDiagnosticsTools::calcOptionsForSelectedTracerField( m_flowSolutionUiField(), isInjector ); - } - else if ( fieldNeedingOptions == &m_selectedProducerTracersUiField ) - { - const bool isInjector = false; - options = RimFlowDiagnosticsTools::calcOptionsForSelectedTracerField( m_flowSolutionUiField(), isInjector ); - } - } - else if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INJECTION_FLOODING ) - { - if ( fieldNeedingOptions == &m_selectedSouringTracersUiField ) - { - RigCaseCellResultsData* cellResultsStorage = currentGridCellResults(); - if ( cellResultsStorage ) - { - QStringList dynamicResultNames = cellResultsStorage->resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE ); - - for ( const QString& resultName : dynamicResultNames ) - { - if ( !resultName.endsWith( "F" ) || resultName == RiaResultNames::completionTypeResultName() ) - { - continue; - } - options.push_back( caf::PdmOptionItemInfo( resultName, resultName ) ); - } - } - } - else if ( fieldNeedingOptions == &m_resultVariableUiField ) - { - options.push_back( caf::PdmOptionItemInfo( RIG_NUM_FLOODED_PV, RIG_NUM_FLOODED_PV ) ); - } - } - else - { - if ( fieldNeedingOptions == &m_resultVariableUiField ) - { - options = calcOptionsForVariableUiFieldStandard( m_resultTypeUiField(), - currentGridCellResults(), - showDerivedResultsFirstInVariableUiField(), - addPerCellFaceOptionsForVariableUiField(), - m_ternaryEnabled ); - } - else if ( fieldNeedingOptions == &m_differenceCase ) - { - options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) ); - - auto eclipseCase = firstAncestorOrThisOfTypeAsserted(); - if ( eclipseCase && eclipseCase->eclipseCaseData() && eclipseCase->eclipseCaseData()->mainGrid() ) - { - RimProject* proj = RimProject::current(); - - std::vector allCases = proj->eclipseCases(); - for ( RimEclipseCase* otherCase : allCases ) - { - if ( otherCase == eclipseCase ) continue; - - if ( otherCase->eclipseCaseData() && otherCase->eclipseCaseData()->mainGrid() ) - { - options.push_back( - caf::PdmOptionItemInfo( QString( "%1 (#%2)" ).arg( otherCase->caseUserDescription() ).arg( otherCase->caseId() ), - otherCase, - false, - otherCase->uiIconProvider() ) ); - } - } - } - } - else if ( fieldNeedingOptions == &m_timeLapseBaseTimestep ) - { - RimEclipseCase* currentCase = firstAncestorOrThisOfTypeAsserted(); - - RimEclipseCase* baseCase = currentCase; - if ( m_differenceCase ) - { - baseCase = m_differenceCase; - } - - options.push_back( caf::PdmOptionItemInfo( "Disabled", RigEclipseResultAddress::noTimeLapseValue() ) ); - - std::vector stepDates = baseCase->timeStepDates(); - for ( size_t stepIdx = 0; stepIdx < stepDates.size(); ++stepIdx ) - { - QString displayString = stepDates[stepIdx].toString( RiaQDateTimeTools::dateFormatString() ); - displayString += QString( " (#%1)" ).arg( stepIdx ); - - options.push_back( caf::PdmOptionItemInfo( displayString, static_cast( stepIdx ) ) ); - } - } - } - - return options; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigEclipseResultAddress RimEclipseResultDefinition::eclipseResultAddress() const -{ - if ( !isChecked() ) return RigEclipseResultAddress(); - if ( isFlowDiagOrInjectionFlooding() ) return RigEclipseResultAddress(); - - const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - if ( gridCellResults ) - { - int timelapseTimeStep = RigEclipseResultAddress::noTimeLapseValue(); - int diffCaseId = RigEclipseResultAddress::noCaseDiffValue(); - - if ( isDeltaTimeStepActive() ) - { - timelapseTimeStep = m_timeLapseBaseTimestep(); - } - - if ( isDeltaCaseActive() ) - { - diffCaseId = m_differenceCase->caseId(); - } - - return RigEclipseResultAddress( m_resultType(), m_resultVariable(), timelapseTimeStep, diffCaseId, isDivideByCellFaceAreaActive() ); - } - else - { - return RigEclipseResultAddress(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setFromEclipseResultAddress( const RigEclipseResultAddress& address ) -{ - RigEclipseResultAddress canonizedAddress = address; - - const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - if ( gridCellResults ) - { - auto rinfo = gridCellResults->resultInfo( address ); - if ( rinfo ) canonizedAddress = rinfo->eclipseResultAddress(); - } - - m_resultType = canonizedAddress.resultCatType(); - m_resultVariable = canonizedAddress.resultName(); - m_timeLapseBaseTimestep = canonizedAddress.deltaTimeStepIndex(); - m_divideByCellFaceArea = canonizedAddress.isDivideByCellFaceAreaActive(); - - if ( canonizedAddress.isDeltaCaseActive() ) - { - auto eclipseCases = RimProject::current()->eclipseCases(); - for ( RimEclipseCase* c : eclipseCases ) - { - if ( c && c->caseId() == canonizedAddress.deltaCaseId() ) - { - m_differenceCase = c; - } - } - } - - updateUiFieldsFromActiveResult(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigFlowDiagResultAddress RimEclipseResultDefinition::flowDiagResAddress() const -{ - CVF_ASSERT( isFlowDiagOrInjectionFlooding() ); - - if ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - size_t timeStep = 0; - - auto rimView = firstAncestorOrThisOfType(); - if ( rimView ) - { - timeStep = rimView->currentTimeStep(); - } - RimWellLogExtractionCurve* wellLogExtractionCurve = firstAncestorOrThisOfType(); - if ( wellLogExtractionCurve ) - { - timeStep = static_cast( wellLogExtractionCurve->currentTimeStep() ); - } - - std::set selTracerNames; - if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) - { - for ( const QString& tName : m_selectedInjectorTracers() ) - { - selTracerNames.insert( tName.toStdString() ); - } - for ( const QString& tName : m_selectedProducerTracers() ) - { - selTracerNames.insert( tName.toStdString() ); - } - } - else - { - RimFlowDiagSolution* flowSol = m_flowSolution(); - if ( flowSol ) - { - std::vector tracerNames = flowSol->tracerNames(); - - if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_INJECTORS || - m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD ) - { - for ( const QString& tracerName : tracerNames ) - { - RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusInTimeStep( tracerName, timeStep ); - if ( status == RimFlowDiagSolution::TracerStatusType::INJECTOR ) - { - selTracerNames.insert( tracerName.toStdString() ); - } - } - } - - if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_PRODUCERS || - m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD ) - { - for ( const QString& tracerName : tracerNames ) - { - RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusInTimeStep( tracerName, timeStep ); - if ( status == RimFlowDiagSolution::TracerStatusType::PRODUCER ) - { - selTracerNames.insert( tracerName.toStdString() ); - } - } - } - } - } - - return RigFlowDiagResultAddress( m_resultVariable().toStdString(), m_phaseSelection(), selTracerNames ); - } - - std::set selTracerNames; - for ( const QString& selectedTracerName : m_selectedSouringTracers() ) - { - selTracerNames.insert( selectedTracerName.toUtf8().constData() ); - } - return RigFlowDiagResultAddress( m_resultVariable().toStdString(), RigFlowDiagResultAddress::PHASE_ALL, selTracerNames ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setFlowDiagTracerSelectionType( FlowTracerSelectionType selectionType ) -{ - m_flowTracerSelectionMode = selectionType; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::resultVariableUiName() const -{ - if ( resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - return flowDiagResUiText( false, 32 ); - } - - if ( isDivideByCellFaceAreaActive() ) - { - return m_resultVariable() + " /A"; - } - - return m_resultVariable(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::resultVariableUiShortName() const -{ - if ( resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - return flowDiagResUiText( true, 24 ); - } - - if ( isDivideByCellFaceAreaActive() ) - { - return m_resultVariable() + " /A"; - } - - return m_resultVariable(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::additionalResultText() const -{ - QStringList resultText; - - if ( isDeltaTimeStepActive() ) - { - std::vector stepDates; - const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - if ( gridCellResults ) - { - stepDates = gridCellResults->timeStepDates(); - resultText += QString( "Base Time Step: %1" ) - .arg( stepDates[m_timeLapseBaseTimestep()].toString( RiaQDateTimeTools::dateFormatString() ) ); - } - } - if ( isDeltaCaseActive() ) - { - resultText += QString( "Base Case: %1" ).arg( m_differenceCase()->caseUserDescription() ); - } - return resultText.join( "
" ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::additionalResultTextShort() const -{ - QString resultTextShort; - if ( isDeltaTimeStepActive() || isDeltaCaseActive() ) - { - QStringList resultTextLines; - resultTextLines += QString( "\nDiff. Options:" ); - if ( isDeltaCaseActive() ) - { - resultTextLines += QString( "Base Case: #%1" ).arg( m_differenceCase()->caseId() ); - } - if ( isDeltaTimeStepActive() ) - { - resultTextLines += QString( "Base Time: #%1" ).arg( m_timeLapseBaseTimestep() ); - } - resultTextShort = resultTextLines.join( "\n" ); - } - - return resultTextShort; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int RimEclipseResultDefinition::timeLapseBaseTimeStep() const -{ - return m_timeLapseBaseTimestep; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int RimEclipseResultDefinition::caseDiffIndex() const -{ - if ( m_differenceCase ) - { - return m_differenceCase->caseId(); - } - return -1; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::loadResult() -{ - if ( isFlowDiagOrInjectionFlooding() ) return; // Will load automatically on access - - if ( m_eclipseCase ) - { - if ( !m_eclipseCase->ensureReservoirCaseIsOpen() ) - { - RiaLogging::error( "Could not open the Eclipse Grid file: " + m_eclipseCase->gridFileName() ); - return; - } - } - - if ( m_differenceCase ) - { - if ( !m_differenceCase->ensureReservoirCaseIsOpen() ) - { - RiaLogging::error( "Could not open the Eclipse Grid file: " + m_eclipseCase->gridFileName() ); - return; - } - } - - RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - if ( gridCellResults ) - { - if ( isDeltaTimeStepActive() || isDeltaCaseActive() || isDivideByCellFaceAreaActive() ) - { - gridCellResults->createResultEntry( eclipseResultAddress(), false ); - } - - QString resultName = m_resultVariable(); - std::set eclipseResultNamesWithNncData = RiaResultNames::nncResultNames(); - if ( eclipseResultNamesWithNncData.find( resultName ) != eclipseResultNamesWithNncData.end() ) - { - eclipseCase()->ensureFaultDataIsComputed(); - - bool dataWasComputed = eclipseCase()->ensureNncDataIsComputed(); - if ( dataWasComputed ) - { - eclipseCase()->createDisplayModelAndUpdateAllViews(); - } - } - - gridCellResults->ensureKnownResultLoaded( eclipseResultAddress() ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// Returns whether the result requested by the definition is a single frame result -/// The result needs to be loaded before asking -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::hasStaticResult() const -{ - if ( isFlowDiagOrInjectionFlooding() ) return false; - - const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - RigEclipseResultAddress gridScalarResultIndex = eclipseResultAddress(); - - return hasResult() && gridCellResults->timeStepCount( gridScalarResultIndex ) == 1; -} - -//-------------------------------------------------------------------------------------------------- -/// Returns whether the result requested by the definition is loaded or possible to load from the result file -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::hasResult() const -{ - if ( isFlowDiagOrInjectionFlooding() ) - { - if ( m_flowSolution() && !m_resultVariable().isEmpty() ) return true; - } - else if ( currentGridCellResults() ) - { - const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - - return gridCellResults->hasResultEntry( eclipseResultAddress() ); - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// Returns whether the result requested by the definition is a multi frame result -/// The result needs to be loaded before asking -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::hasDynamicResult() const -{ - if ( hasResult() ) - { - if ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE ) - { - return true; - } - else if ( m_resultType() == RiaDefines::ResultCatType::SOURSIMRL ) - { - return true; - } - else if ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - return true; - } - else if ( m_resultType() == RiaDefines::ResultCatType::INJECTION_FLOODING ) - { - return true; - } - - if ( currentGridCellResults() ) - { - const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); - RigEclipseResultAddress gridScalarResultIndex = eclipseResultAddress(); - if ( gridCellResults->timeStepCount( gridScalarResultIndex ) > 1 ) - { - return true; - } - } - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::initAfterRead() -{ - if ( m_flowSolution() == nullptr ) - { - assignFlowSolutionFromCase(); - } - - if ( m_resultVariable() == "Formation Allen" ) - { - m_resultVariable = RiaResultNames::formationAllanResultName(); - m_resultType = RiaDefines::ResultCatType::ALLAN_DIAGRAMS; - } - else if ( m_resultVariable() == "Binary Formation Allen" ) - { - m_resultVariable = RiaResultNames::formationBinaryAllanResultName(); - m_resultType = RiaDefines::ResultCatType::ALLAN_DIAGRAMS; - } - - m_porosityModelUiField = m_porosityModel; - m_resultTypeUiField = m_resultType; - m_resultVariableUiField = m_resultVariable; - - m_flowSolutionUiField = m_flowSolution(); - m_selectedInjectorTracersUiField = m_selectedInjectorTracers; - - updateUiIconFromToggleField(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setResultType( RiaDefines::ResultCatType val ) -{ - m_resultType = val; - m_resultTypeUiField = val; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiaDefines::PorosityModelType RimEclipseResultDefinition::porosityModel() const -{ - return m_porosityModel(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setPorosityModel( RiaDefines::PorosityModelType val ) -{ - m_porosityModel = val; - m_porosityModelUiField = val; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::resultVariable() const -{ - if ( !isChecked() ) return RiaResultNames::undefinedResultName(); - - return m_resultVariable(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setResultVariable( const QString& val ) -{ - m_resultVariable = val; - m_resultVariableUiField = val; -} - -//-------------------------------------------------------------------------------------------------- -/// Return phase type if the current result is known to be of a particular -/// fluid phase type. Otherwise the method will return PHASE_NOT_APPLICABLE. -//-------------------------------------------------------------------------------------------------- -RiaDefines::PhaseType RimEclipseResultDefinition::resultPhaseType() const -{ - if ( QRegularExpression( "OIL" ).match( m_resultVariable() ).hasMatch() ) - { - return RiaDefines::PhaseType::OIL_PHASE; - } - else if ( QRegularExpression( "GAS" ).match( m_resultVariable() ).hasMatch() ) - { - return RiaDefines::PhaseType::GAS_PHASE; - } - else if ( QRegularExpression( "WAT" ).match( m_resultVariable() ).hasMatch() ) - { - return RiaDefines::PhaseType::WATER_PHASE; - } - return RiaDefines::PhaseType::PHASE_NOT_APPLICABLE; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimFlowDiagSolution* RimEclipseResultDefinition::flowDiagSolution() const -{ - return m_flowSolution(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setFlowSolution( RimFlowDiagSolution* flowSol ) -{ - m_flowSolution = flowSol; - m_flowSolutionUiField = flowSol; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setSelectedTracers( const std::vector& selectedTracers ) -{ - if ( m_flowSolution() == nullptr ) - { - assignFlowSolutionFromCase(); - } - if ( m_flowSolution() ) - { - std::vector injectorTracers; - std::vector producerTracers; - for ( const QString& tracerName : selectedTracers ) - { - RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall( tracerName ); - if ( tracerStatus == RimFlowDiagSolution::TracerStatusType::INJECTOR ) - { - injectorTracers.push_back( tracerName ); - } - else if ( tracerStatus == RimFlowDiagSolution::TracerStatusType::PRODUCER ) - { - producerTracers.push_back( tracerName ); - } - else if ( tracerStatus == RimFlowDiagSolution::TracerStatusType::VARYING || - tracerStatus == RimFlowDiagSolution::TracerStatusType::UNDEFINED ) - { - injectorTracers.push_back( tracerName ); - producerTracers.push_back( tracerName ); - } - } - setSelectedInjectorTracers( injectorTracers ); - setSelectedProducerTracers( producerTracers ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setSelectedInjectorTracers( const std::vector& selectedTracers ) -{ - m_selectedInjectorTracers = selectedTracers; - m_selectedInjectorTracersUiField = selectedTracers; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setSelectedProducerTracers( const std::vector& selectedTracers ) -{ - m_selectedProducerTracers = selectedTracers; - m_selectedProducerTracersUiField = selectedTracers; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setSelectedSouringTracers( const std::vector& selectedTracers ) -{ - m_selectedSouringTracers = selectedTracers; - m_selectedSouringTracersUiField = selectedTracers; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::updateUiFieldsFromActiveResult() -{ - m_resultTypeUiField = m_resultType; - m_resultVariableUiField = resultVariable(); - m_selectedInjectorTracersUiField = m_selectedInjectorTracers; - m_selectedProducerTracersUiField = m_selectedProducerTracers; - m_selectedSouringTracersUiField = m_selectedSouringTracers; - m_porosityModelUiField = m_porosityModel; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::enableDeltaResults( bool enable ) -{ - m_isDeltaResultEnabled = enable; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isTernarySaturationSelected() const -{ - bool isTernary = ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE ) && - ( m_resultVariable().compare( RiaResultNames::ternarySaturationResultName(), Qt::CaseInsensitive ) == 0 ); - - return isTernary; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isCompletionTypeSelected() const -{ - return ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE && m_resultVariable() == RiaResultNames::completionTypeResultName() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::hasCategoryResult() const -{ - if ( auto* gridCellResults = currentGridCellResults() ) - { - const auto addresses = gridCellResults->existingResults(); - for ( const auto& address : addresses ) - { - if ( address.resultCatType() == m_resultType() && address.resultName() == m_resultVariable() ) - { - if ( address.dataType() == RiaDefines::ResultDataType::INTEGER ) return true; - break; - } - } - } - - if ( m_resultType() == RiaDefines::ResultCatType::FORMATION_NAMES && m_eclipseCase && m_eclipseCase->eclipseCaseData() && - !m_eclipseCase->eclipseCaseData()->formationNames().empty() ) - return true; - - if ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE && resultVariable() == RiaResultNames::completionTypeResultName() ) - return true; - - if ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && m_resultVariable() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) - return true; - - if ( resultVariable() == RiaResultNames::formationAllanResultName() || resultVariable() == RiaResultNames::formationBinaryAllanResultName() ) - { - return true; - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isFlowDiagOrInjectionFlooding() const -{ - return m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS || m_resultType() == RiaDefines::ResultCatType::INJECTION_FLOODING; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) -{ - uiOrdering.add( &m_resultTypeUiField ); - - if ( hasDualPorFractureResult() ) - { - uiOrdering.add( &m_porosityModelUiField ); - } - - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - uiOrdering.add( &m_flowSolutionUiField ); - - uiOrdering.add( &m_flowTracerSelectionMode ); - - if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) - { - caf::PdmUiGroup* selectionGroup = uiOrdering.addNewGroup( "Tracer Selection" ); - selectionGroup->setEnableFrame( false ); - - caf::PdmUiGroup* injectorGroup = selectionGroup->addNewGroup( "Injectors" ); - injectorGroup->add( &m_selectedInjectorTracersUiField ); - injectorGroup->add( &m_syncInjectorToProducerSelection ); - - caf::PdmUiGroup* producerGroup = selectionGroup->addNewGroup( "Producers", { .newRow = false } ); - producerGroup->add( &m_selectedProducerTracersUiField ); - producerGroup->add( &m_syncProducerToInjectorSelection ); - } - - uiOrdering.add( &m_phaseSelection ); - - if ( m_flowSolution() == nullptr ) - { - assignFlowSolutionFromCase(); - } - } - - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INJECTION_FLOODING ) - { - uiOrdering.add( &m_selectedSouringTracersUiField ); - } - - uiOrdering.add( &m_resultVariableUiField ); - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INPUT_PROPERTY ) - { - uiOrdering.add( &m_inputPropertyFileName ); - } - - if ( isDivideByCellFaceAreaPossible() ) - { - uiOrdering.add( &m_divideByCellFaceArea ); - - QString resultPropertyLabel = "Result Property"; - if ( isDivideByCellFaceAreaActive() ) - { - resultPropertyLabel += QString( "\nDivided by Area" ); - } - m_resultVariableUiField.uiCapability()->setUiName( resultPropertyLabel ); - } - - { - caf::PdmUiGroup* legendGroup = uiOrdering.addNewGroup( "Legend" ); - legendGroup->add( &m_showOnlyVisibleCategoriesInLegend ); - - bool showOnlyVisibleCategoriesOption = false; - - RimEclipseView* eclView = firstAncestorOrThisOfType(); - - if ( eclView ) - { - if ( eclView->cellResult() == this && hasCategoryResult() ) showOnlyVisibleCategoriesOption = true; - } - - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && - m_resultVariableUiField() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) - { - showOnlyVisibleCategoriesOption = true; - } - - legendGroup->setUiHidden( !showOnlyVisibleCategoriesOption ); - } - - if ( isDeltaCasePossible() || isDeltaTimeStepPossible() ) - { - caf::PdmUiGroup* differenceGroup = uiOrdering.addNewGroup( "Difference Options" ); - differenceGroup->setUiReadOnly( !( isDeltaTimeStepPossible() || isDeltaCasePossible() ) ); - - m_differenceCase.uiCapability()->setUiReadOnly( !isDeltaCasePossible() ); - m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly( !isDeltaTimeStepPossible() ); - - if ( isDeltaCasePossible() ) differenceGroup->add( &m_differenceCase ); - if ( isDeltaTimeStepPossible() ) differenceGroup->add( &m_timeLapseBaseTimestep ); - - QString resultPropertyLabel = "Result Property"; - if ( isDeltaTimeStepActive() || isDeltaCaseActive() ) - { - resultPropertyLabel += QString( "\n%1" ).arg( additionalResultTextShort() ); - } - m_resultVariableUiField.uiCapability()->setUiName( resultPropertyLabel ); - } - - uiOrdering.skipRemainingFields( true ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) -{ - if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) - { - if ( field == &m_syncInjectorToProducerSelection || field == &m_syncProducerToInjectorSelection ) - { - caf::PdmUiToolButtonEditorAttribute* toolButtonAttr = dynamic_cast( attribute ); - if ( toolButtonAttr ) - { - toolButtonAttr->m_sizePolicy.setHorizontalPolicy( QSizePolicy::MinimumExpanding ); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::assignFlowSolutionFromCase() -{ - RimFlowDiagSolution* defaultFlowDiagSolution = nullptr; - - RimEclipseResultCase* eclCase = dynamic_cast( m_eclipseCase.p() ); - - if ( eclCase ) - { - defaultFlowDiagSolution = eclCase->defaultFlowDiagSolution(); - } - setFlowSolution( defaultFlowDiagSolution ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::hasDualPorFractureResult() -{ - if ( m_eclipseCase && m_eclipseCase->eclipseCaseData() ) - { - return m_eclipseCase->eclipseCaseData()->hasFractureResults(); - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::flowDiagResUiText( bool shortLabel, int maxTracerStringLength ) const -{ - QString uiText = QString::fromStdString( flowDiagResAddress().variableName ); - if ( flowDiagResAddress().variableName == RIG_FLD_TOF_RESNAME ) - { - uiText = RimEclipseResultDefinitionTools::timeOfFlightString( injectorSelectionState(), producerSelectionState(), shortLabel ); - } - else if ( flowDiagResAddress().variableName == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) - { - uiText = RimEclipseResultDefinitionTools::maxFractionTracerString( injectorSelectionState(), producerSelectionState(), shortLabel ); - } - - QString tracersString = RimEclipseResultDefinitionTools::selectedTracersString( injectorSelectionState(), - producerSelectionState(), - m_selectedInjectorTracers(), - m_selectedProducerTracers(), - maxTracerStringLength ); - - if ( !tracersString.isEmpty() ) - { - uiText += QString( "\n%1" ).arg( tracersString ); - } - return uiText; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QList RimEclipseResultDefinition::calcOptionsForVariableUiFieldStandard( RiaDefines::ResultCatType resultCatType, - const RigCaseCellResultsData* results, - bool showDerivedResultsFirst, - bool addPerCellFaceOptionItems, - bool ternaryEnabled ) -{ - CVF_ASSERT( resultCatType != RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && resultCatType != RiaDefines::ResultCatType::INJECTION_FLOODING ); - - return RimEclipseResultDefinitionTools::calcOptionsForVariableUiFieldStandard( resultCatType, - results, - showDerivedResultsFirst, - addPerCellFaceOptionItems, - ternaryEnabled ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setTernaryEnabled( bool enabled ) -{ - m_ternaryEnabled = enabled; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::updateRangesForExplicitLegends( RimRegularLegendConfig* legendConfigToUpdate, - RimTernaryLegendConfig* ternaryLegendConfigToUpdate, - int currentTimeStep ) - -{ - if ( hasResult() ) - { - if ( isFlowDiagOrInjectionFlooding() ) - { - if ( currentTimeStep >= 0 ) - { - RimEclipseResultDefinitionTools::updateLegendForFlowDiagnostics( this, legendConfigToUpdate, currentTimeStep ); - } - } - else - { - RimEclipseResultDefinitionTools::updateCellResultLegend( this, legendConfigToUpdate, currentTimeStep ); - } - } - - if ( isTernarySaturationSelected() ) - { - RimEclipseResultDefinitionTools::updateTernaryLegend( currentGridCellResults(), ternaryLegendConfigToUpdate, currentTimeStep ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::updateLegendTitle( RimRegularLegendConfig* legendConfig, const QString& legendHeading ) -{ - QString title = legendHeading + resultVariableUiName(); - if ( !additionalResultTextShort().isEmpty() ) - { - title += additionalResultTextShort(); - } - - if ( hasDualPorFractureResult() ) - { - QString porosityModelText = caf::AppEnum::uiText( porosityModel() ); - - title += QString( "\nDual Por : %1" ).arg( porosityModelText ); - } - - legendConfig->setTitle( title ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::showOnlyVisibleCategoriesInLegend() const -{ - return m_showOnlyVisibleCategoriesInLegend(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseResultDefinition::FlowTracerSelectionState RimEclipseResultDefinition::injectorSelectionState() const -{ - const bool isInjector = true; - return RimEclipseResultDefinitionTools::getFlowTracerSelectionState( isInjector, - m_flowTracerSelectionMode(), - m_flowSolutionUiField(), - m_selectedInjectorTracers().size() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseResultDefinition::FlowTracerSelectionState RimEclipseResultDefinition::producerSelectionState() const -{ - const bool isInjector = false; - return RimEclipseResultDefinitionTools::getFlowTracerSelectionState( isInjector, - m_flowTracerSelectionMode(), - m_flowSolutionUiField(), - m_selectedProducerTracers().size() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::syncInjectorToProducerSelection() -{ - int timeStep = 0; - - auto rimView = firstAncestorOrThisOfType(); - if ( rimView ) - { - timeStep = rimView->currentTimeStep(); - } - - RimFlowDiagSolution* flowSol = m_flowSolution(); - if ( flowSol && m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) - { - std::set newProducerSelection = - RimFlowDiagnosticsTools::setOfProducerTracersFromInjectors( m_flowSolutionUiField(), m_selectedInjectorTracers(), timeStep ); - // Add all currently selected producers to set - for ( const QString& selectedProducer : m_selectedProducerTracers() ) - { - newProducerSelection.insert( selectedProducer ); - } - std::vector newProducerVector( newProducerSelection.begin(), newProducerSelection.end() ); - setSelectedProducerTracers( newProducerVector ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::syncProducerToInjectorSelection() -{ - int timeStep = 0; - - auto rimView = firstAncestorOrThisOfType(); - if ( rimView ) - { - timeStep = rimView->currentTimeStep(); - } - - RimFlowDiagSolution* flowSol = m_flowSolution(); - if ( flowSol && m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) - { - std::set newInjectorSelection = - RimFlowDiagnosticsTools::setOfInjectorTracersFromProducers( m_flowSolutionUiField(), m_selectedProducerTracers(), timeStep ); - - // Add all currently selected injectors to set - for ( const QString& selectedInjector : m_selectedInjectorTracers() ) - { - newInjectorSelection.insert( selectedInjector ); - } - std::vector newInjectorVector( newInjectorSelection.begin(), newInjectorSelection.end() ); - setSelectedInjectorTracers( newInjectorVector ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDeltaResultEnabled() const -{ - return m_isDeltaResultEnabled; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDeltaTimeStepPossible() const -{ - return isDeltaResultEnabled() && !isTernarySaturationSelected() && - ( m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE || - m_resultTypeUiField() == RiaDefines::ResultCatType::GENERATED ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDeltaTimeStepActive() const -{ - return isDeltaTimeStepPossible() && m_timeLapseBaseTimestep() >= 0; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDeltaCasePossible() const -{ - return isDeltaResultEnabled() && !isTernarySaturationSelected() && - ( m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE || - m_resultTypeUiField() == RiaDefines::ResultCatType::STATIC_NATIVE || - m_resultTypeUiField() == RiaDefines::ResultCatType::GENERATED ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDeltaCaseActive() const -{ - return isDeltaCasePossible() && m_differenceCase() != nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDivideByCellFaceAreaPossible() const -{ - return RimEclipseResultDefinitionTools::isDivideByCellFaceAreaPossible( m_resultVariable ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::isDivideByCellFaceAreaActive() const -{ - return isDivideByCellFaceAreaPossible() && m_divideByCellFaceArea; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::showDerivedResultsFirstInVariableUiField() const -{ - // Cell Face result names - bool showDerivedResultsFirstInList = false; - RimEclipseFaultColors* rimEclipseFaultColors = firstAncestorOrThisOfType(); - - if ( rimEclipseFaultColors ) showDerivedResultsFirstInList = true; - - return showDerivedResultsFirstInList; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::addPerCellFaceOptionsForVariableUiField() const -{ - RimPlotCurve* curve = firstAncestorOrThisOfType(); - RimEclipsePropertyFilter* propFilter = firstAncestorOrThisOfType(); - RimCellEdgeColors* cellEdge = firstAncestorOrThisOfType(); - - return !( propFilter || curve || cellEdge ); -} +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS +// +// 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 "RimEclipseResultDefinition.h" + +#include "RiaLogging.h" +#include "RiaQDateTimeTools.h" + +#include "RicfCommandObject.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigEclipseCaseData.h" +#include "RigEclipseResultInfo.h" +#include "RigFlowDiagResultAddress.h" +#include "RigFlowDiagResults.h" +#include "RigFormationNames.h" + +#include "Rim3dView.h" +#include "Rim3dWellLogCurve.h" +#include "RimCellEdgeColors.h" +#include "RimContourMapProjection.h" +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseContourMapProjection.h" +#include "RimEclipseContourMapView.h" +#include "RimEclipseFaultColors.h" +#include "RimEclipsePropertyFilter.h" +#include "RimEclipseResultCase.h" +#include "RimEclipseResultDefinitionTools.h" +#include "RimEclipseView.h" +#include "RimFlowDiagSolution.h" +#include "RimFlowDiagnosticsTools.h" +#include "RimGridCrossPlot.h" +#include "RimGridCrossPlotDataSet.h" +#include "RimGridTimeHistoryCurve.h" +#include "RimIntersectionCollection.h" +#include "RimIntersectionResultDefinition.h" +#include "RimPlotCurve.h" +#include "RimProject.h" +#include "RimRegularLegendConfig.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimViewLinker.h" +#include "RimWellLogExtractionCurve.h" +#include "RimWellLogTrack.h" + +#ifdef USE_QTCHARTS +#include "RimGridStatisticsPlot.h" +#endif + +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmUiToolButtonEditor.h" +#include "cafPdmUiTreeSelectionEditor.h" +#include "cafUtils.h" + +#include + +namespace caf +{ +template <> +void RimEclipseResultDefinition::FlowTracerSelectionEnum::setUp() +{ + addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD, "FLOW_TR_INJ_AND_PROD", "All Injectors and Producers" ); + addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_PRODUCERS, "FLOW_TR_PRODUCERS", "All Producers" ); + addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_INJECTORS, "FLOW_TR_INJECTORS", "All Injectors" ); + addItem( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_BY_SELECTION, "FLOW_TR_BY_SELECTION", "By Selection" ); + + setDefault( RimEclipseResultDefinition::FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD ); +} +} // namespace caf + +CAF_PDM_SOURCE_INIT( RimEclipseResultDefinition, "ResultDefinition" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::LabelPosType labelPosition ) + : m_isDeltaResultEnabled( false ) + , m_labelPosition( labelPosition ) + , m_ternaryEnabled( true ) +{ + CAF_PDM_InitScriptableObjectWithNameAndComment( "Result Definition", "", "", "", "EclipseResult", "An eclipse result definition" ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_resultType, "ResultType", "Type" ); + m_resultType.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_porosityModel, "PorosityModelType", "Porosity" ); + m_porosityModel.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitScriptableField( &m_resultVariable, "ResultVariable", RiaResultNames::undefinedResultName(), "Variable" ); + m_resultVariable.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitFieldNoDefault( &m_flowSolution, "FlowDiagSolution", "Solution" ); + m_flowSolution.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitField( &m_timeLapseBaseTimestep, "TimeLapseBaseTimeStep", RigEclipseResultAddress::noTimeLapseValue(), "Base Time Step" ); + + CAF_PDM_InitFieldNoDefault( &m_differenceCase, "DifferenceCase", "Difference Case" ); + + CAF_PDM_InitField( &m_divideByCellFaceArea, "DivideByCellFaceArea", false, "Divide By Area" ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_selectedInjectorTracers, "SelectedInjectorTracers", "Injector Tracers" ); + m_selectedInjectorTracers.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_selectedProducerTracers, "SelectedProducerTracers", "Producer Tracers" ); + m_selectedProducerTracers.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_selectedSouringTracers, "SelectedSouringTracers", "Tracers" ); + m_selectedSouringTracers.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_flowTracerSelectionMode, "FlowTracerSelectionMode", "Tracers" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_phaseSelection, "PhaseSelection", "Phases" ); + m_phaseSelection.uiCapability()->setUiLabelPosition( m_labelPosition ); + + CAF_PDM_InitScriptableField( &m_showOnlyVisibleCategoriesInLegend, + "ShowOnlyVisibleCategoriesInLegend", + true, + "Show Only Visible Categories In Legend" ); + + // Ui only fields + + CAF_PDM_InitFieldNoDefault( &m_resultTypeUiField, "MResultType", "Type" ); + m_resultTypeUiField.xmlCapability()->disableIO(); + m_resultTypeUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); + + CAF_PDM_InitFieldNoDefault( &m_porosityModelUiField, "MPorosityModelType", "Porosity" ); + m_porosityModelUiField.xmlCapability()->disableIO(); + m_porosityModelUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); + + CAF_PDM_InitField( &m_resultVariableUiField, "MResultVariable", RiaResultNames::undefinedResultName(), "Result Property" ); + m_resultVariableUiField.xmlCapability()->disableIO(); + m_resultVariableUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); + m_resultVariableUiField.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() ); + + CAF_PDM_InitFieldNoDefault( &m_inputPropertyFileName, "InputPropertyFileName", "File Name" ); + m_inputPropertyFileName.xmlCapability()->disableIO(); + m_inputPropertyFileName.uiCapability()->setUiReadOnly( true ); + + CAF_PDM_InitFieldNoDefault( &m_flowSolutionUiField, "MFlowDiagSolution", "Solution" ); + m_flowSolutionUiField.xmlCapability()->disableIO(); + m_flowSolutionUiField.uiCapability()->setUiHidden( true ); // For now since there are only one to choose from + + CAF_PDM_InitField( &m_syncInjectorToProducerSelection, "MSyncSelectedInjProd", false, "Add Communicators ->" ); + m_syncInjectorToProducerSelection.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonEditor::uiEditorTypeName() ); + + CAF_PDM_InitField( &m_syncProducerToInjectorSelection, "MSyncSelectedProdInj", false, "<- Add Communicators" ); + m_syncProducerToInjectorSelection.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonEditor::uiEditorTypeName() ); + + CAF_PDM_InitFieldNoDefault( &m_selectedInjectorTracersUiField, "MSelectedInjectorTracers", "Injector Tracers" ); + m_selectedInjectorTracersUiField.xmlCapability()->disableIO(); + m_selectedInjectorTracersUiField.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); + + CAF_PDM_InitFieldNoDefault( &m_selectedProducerTracersUiField, "MSelectedProducerTracers", "Producer Tracers" ); + m_selectedProducerTracersUiField.xmlCapability()->disableIO(); + m_selectedProducerTracersUiField.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); + + CAF_PDM_InitFieldNoDefault( &m_selectedSouringTracersUiField, "MSelectedSouringTracers", "Tracers" ); + m_selectedSouringTracersUiField.xmlCapability()->disableIO(); + m_selectedSouringTracersUiField.uiCapability()->setUiLabelPosition( m_labelPosition ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultDefinition::~RimEclipseResultDefinition() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::simpleCopy( const RimEclipseResultDefinition* other ) +{ + setResultVariable( other->resultVariable() ); + setPorosityModel( other->porosityModel() ); + setResultType( other->resultType() ); + setFlowSolution( other->m_flowSolution() ); + setSelectedInjectorTracers( other->m_selectedInjectorTracers() ); + setSelectedProducerTracers( other->m_selectedProducerTracers() ); + setSelectedSouringTracers( other->m_selectedSouringTracers() ); + m_flowTracerSelectionMode = other->m_flowTracerSelectionMode(); + m_phaseSelection = other->m_phaseSelection; + + m_differenceCase = other->m_differenceCase(); + m_timeLapseBaseTimestep = other->m_timeLapseBaseTimestep(); + m_divideByCellFaceArea = other->m_divideByCellFaceArea(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setEclipseCase( RimEclipseCase* eclipseCase ) +{ + m_eclipseCase = eclipseCase; + + assignFlowSolutionFromCase(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RimEclipseResultDefinition::eclipseCase() const +{ + return m_eclipseCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::ResultCatType RimEclipseResultDefinition::resultType() const +{ + return m_resultType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseCellResultsData* RimEclipseResultDefinition::currentGridCellResults() const +{ + if ( !m_eclipseCase ) return nullptr; + + return m_eclipseCase->results( m_porosityModel() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) +{ + if ( &m_flowSolutionUiField == changedField || &m_resultTypeUiField == changedField || &m_porosityModelUiField == changedField ) + { + // If the user are seeing the list with the actually selected result, + // select that result in the list. Otherwise select nothing. + + QStringList varList = RimEclipseResultDefinitionTools::getResultNamesForResultType( m_resultTypeUiField(), currentGridCellResults() ); + + bool isFlowDiagFieldsRelevant = ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ); + + if ( ( m_flowSolutionUiField() == m_flowSolution() || !isFlowDiagFieldsRelevant ) && m_resultTypeUiField() == m_resultType() && + m_porosityModelUiField() == m_porosityModel() ) + { + if ( varList.contains( resultVariable() ) ) + { + m_resultVariableUiField = resultVariable(); + } + + if ( isFlowDiagFieldsRelevant ) + { + m_selectedInjectorTracersUiField = m_selectedInjectorTracers(); + m_selectedProducerTracersUiField = m_selectedProducerTracers(); + } + else + { + m_selectedInjectorTracersUiField = std::vector(); + m_selectedProducerTracersUiField = std::vector(); + } + } + else + { + m_resultVariableUiField = ""; + m_selectedInjectorTracersUiField = std::vector(); + m_selectedProducerTracersUiField = std::vector(); + } + } + + if ( &m_resultVariableUiField == changedField ) + { + m_porosityModel = m_porosityModelUiField; + m_resultType = m_resultTypeUiField; + m_resultVariable = m_resultVariableUiField; + + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + m_flowSolution = m_flowSolutionUiField(); + m_selectedInjectorTracers = m_selectedInjectorTracersUiField(); + m_selectedProducerTracers = m_selectedProducerTracersUiField(); + } + else if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INJECTION_FLOODING ) + { + m_selectedSouringTracers = m_selectedSouringTracersUiField(); + } + else if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INPUT_PROPERTY ) + { + m_inputPropertyFileName = RimEclipseResultDefinitionTools::getInputPropertyFileName( eclipseCase(), newValue.toString() ); + } + loadDataAndUpdate(); + } + + if ( &m_porosityModelUiField == changedField ) + { + m_porosityModel = m_porosityModelUiField; + m_resultVariableUiField = resultVariable(); + + auto eclipseView = firstAncestorOrThisOfType(); + if ( eclipseView ) + { + // Active cells can be different between matrix and fracture, make sure all geometry is recreated + eclipseView->scheduleReservoirGridGeometryRegen(); + } + + loadDataAndUpdate(); + } + + auto contourMapView = firstAncestorOrThisOfType(); + + if ( &m_differenceCase == changedField ) + { + m_timeLapseBaseTimestep = RigEclipseResultAddress::noTimeLapseValue(); + + if ( contourMapView ) + { + contourMapView->contourMapProjection()->clearGridMappingAndRedraw(); + } + + loadDataAndUpdate(); + } + + if ( &m_timeLapseBaseTimestep == changedField ) + { + if ( contourMapView ) + { + contourMapView->contourMapProjection()->clearGridMappingAndRedraw(); + } + + loadDataAndUpdate(); + } + + if ( &m_divideByCellFaceArea == changedField ) + { + loadDataAndUpdate(); + } + + if ( &m_flowTracerSelectionMode == changedField ) + { + loadDataAndUpdate(); + } + + if ( &m_selectedInjectorTracersUiField == changedField ) + { + changedTracerSelectionField( true ); + } + + if ( &m_selectedProducerTracersUiField == changedField ) + { + changedTracerSelectionField( false ); + } + + if ( &m_syncInjectorToProducerSelection == changedField ) + { + syncInjectorToProducerSelection(); + m_syncInjectorToProducerSelection = false; + } + + if ( &m_syncProducerToInjectorSelection == changedField ) + { + syncProducerToInjectorSelection(); + m_syncProducerToInjectorSelection = false; + } + + if ( &m_selectedSouringTracersUiField == changedField ) + { + if ( !m_resultVariable().isEmpty() ) + { + m_selectedSouringTracers = m_selectedSouringTracersUiField(); + loadDataAndUpdate(); + } + } + + if ( &m_phaseSelection == changedField ) + { + if ( m_phaseSelection() != RigFlowDiagResultAddress::PHASE_ALL ) + { + m_resultType = m_resultTypeUiField; + m_resultVariable = RIG_FLD_TOF_RESNAME; + m_resultVariableUiField = RIG_FLD_TOF_RESNAME; + } + loadDataAndUpdate(); + } + + if ( &m_showOnlyVisibleCategoriesInLegend == changedField ) + { + loadDataAndUpdate(); + } + + updateAnyFieldHasChanged(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::changedTracerSelectionField( bool injector ) +{ + m_flowSolution = m_flowSolutionUiField(); + + std::vector& selectedTracers = injector ? m_selectedInjectorTracers.v() : m_selectedProducerTracers.v(); + const std::vector& selectedTracersUi = injector ? m_selectedInjectorTracersUiField.v() : m_selectedProducerTracersUiField.v(); + + selectedTracers = selectedTracersUi; + + loadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::updateAnyFieldHasChanged() +{ + RimEclipsePropertyFilter* propFilter = firstAncestorOrThisOfType(); + if ( propFilter ) + { + propFilter->updateConnectedEditors(); + } + + RimEclipseFaultColors* faultColors = firstAncestorOrThisOfType(); + if ( faultColors ) + { + faultColors->updateConnectedEditors(); + } + + RimCellEdgeColors* cellEdgeColors = firstAncestorOrThisOfType(); + if ( cellEdgeColors ) + { + cellEdgeColors->updateConnectedEditors(); + } + + RimEclipseCellColors* cellColors = firstAncestorOrThisOfType(); + if ( cellColors ) + { + cellColors->updateConnectedEditors(); + } + + RimIntersectionResultDefinition* intersectResDef = firstAncestorOrThisOfType(); + if ( intersectResDef ) + { + intersectResDef->setDefaultEclipseLegendConfig(); + intersectResDef->updateConnectedEditors(); + } + + RimGridCrossPlotDataSet* crossPlotCurveSet = firstAncestorOrThisOfType(); + if ( crossPlotCurveSet ) + { + crossPlotCurveSet->updateConnectedEditors(); + } + + RimPlotCurve* curve = firstAncestorOrThisOfType(); + if ( curve ) + { + curve->updateConnectedEditors(); + } + + Rim3dWellLogCurve* rim3dWellLogCurve = firstAncestorOrThisOfType(); + if ( rim3dWellLogCurve ) + { + rim3dWellLogCurve->resetMinMaxValues(); + } + + RimEclipseContourMapProjection* contourMap = firstAncestorOrThisOfType(); + if ( contourMap ) + { + contourMap->clearGridMappingAndRedraw(); + } + + RimWellLogTrack* wellLogTrack = firstAncestorOrThisOfType(); + if ( wellLogTrack ) + { + wellLogTrack->loadDataAndUpdate(); + wellLogTrack->updateEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setTofAndSelectTracer( const QString& tracerName ) +{ + setResultType( RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ); + setResultVariable( "TOF" ); + setFlowDiagTracerSelectionType( FlowTracerSelectionType::FLOW_TR_BY_SELECTION ); + + if ( m_flowSolution() == nullptr ) + { + assignFlowSolutionFromCase(); + } + + if ( m_flowSolution() ) + { + RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall( tracerName ); + + std::vector tracers; + tracers.push_back( tracerName ); + if ( ( tracerStatus == RimFlowDiagSolution::TracerStatusType::INJECTOR ) || + ( tracerStatus == RimFlowDiagSolution::TracerStatusType::VARYING ) ) + { + setSelectedInjectorTracers( tracers ); + } + + if ( ( tracerStatus == RimFlowDiagSolution::TracerStatusType::PRODUCER ) || + ( tracerStatus == RimFlowDiagSolution::TracerStatusType::VARYING ) ) + { + setSelectedProducerTracers( tracers ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::loadDataAndUpdate() +{ + auto view = firstAncestorOrThisOfType(); + + loadResult(); + + RimEclipsePropertyFilter* propFilter = firstAncestorOrThisOfType(); + if ( propFilter ) + { + propFilter->setToDefaultValues(); + propFilter->updateFilterName(); + + if ( view ) + { + view->scheduleGeometryRegen( PROPERTY_FILTERED ); + view->scheduleCreateDisplayModelAndRedraw(); + } + } + + RimEclipseCellColors* cellColors = firstAncestorOrThisOfType(); + if ( cellColors ) + { + updateLegendCategorySettings(); + + if ( view ) + { + RimViewLinker* viewLinker = view->assosiatedViewLinker(); + if ( viewLinker ) + { + viewLinker->updateCellResult(); + } + RimGridView* eclView = dynamic_cast( view ); + if ( eclView ) eclView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); + } + } + + RimIntersectionResultDefinition* sepIntersectionResDef = firstAncestorOrThisOfType(); + if ( sepIntersectionResDef && sepIntersectionResDef->isInAction() ) + { + if ( view ) view->scheduleCreateDisplayModelAndRedraw(); + RimGridView* gridView = dynamic_cast( view ); + if ( gridView ) gridView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); + } + + RimCellEdgeColors* cellEdgeColors = firstAncestorOrThisOfType(); + if ( cellEdgeColors ) + { + cellEdgeColors->loadResult(); + + if ( view ) + { + view->scheduleCreateDisplayModelAndRedraw(); + } + } + + RimGridCrossPlotDataSet* crossPlotCurveSet = firstAncestorOrThisOfType(); + if ( crossPlotCurveSet ) + { + crossPlotCurveSet->destroyCurves(); + crossPlotCurveSet->loadDataAndUpdate( true ); + } + + RimPlotCurve* curve = firstAncestorOrThisOfType(); + if ( curve ) + { + curve->loadDataAndUpdate( true ); + } + + Rim3dWellLogCurve* rim3dWellLogCurve = firstAncestorOrThisOfType(); + if ( rim3dWellLogCurve ) + { + rim3dWellLogCurve->updateCurveIn3dView(); + } + +#ifdef USE_QTCHARTS + RimGridStatisticsPlot* gridStatisticsPlot = firstAncestorOrThisOfType(); + if ( gridStatisticsPlot ) + { + gridStatisticsPlot->loadDataAndUpdate(); + } +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEclipseResultDefinition::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) +{ + QList options; + + if ( fieldNeedingOptions == &m_resultTypeUiField ) + { + bool hasSourSimRLFile = false; + RimEclipseResultCase* eclResCase = dynamic_cast( m_eclipseCase.p() ); + if ( eclResCase && eclResCase->eclipseCaseData() ) + { + hasSourSimRLFile = eclResCase->hasSourSimFile(); + } + +#ifndef USE_HDF5 + // If using ResInsight without HDF5 support, ignore SourSim files and + // do not show it as a result category. + hasSourSimRLFile = false; +#endif + + bool enableSouring = false; + +#ifdef USE_HDF5 + if ( m_eclipseCase.notNull() ) + { + RigCaseCellResultsData* cellResultsData = m_eclipseCase->results( porosityModel() ); + + if ( cellResultsData && cellResultsData->hasFlowDiagUsableFluxes() ) + { + enableSouring = true; + } + } +#endif /* USE_HDF5 */ + + RimGridTimeHistoryCurve* timeHistoryCurve = firstAncestorOrThisOfType(); + + bool isSeparateFaultResult = false; + { + RimEclipseFaultColors* sepFaultResult = firstAncestorOrThisOfType(); + if ( sepFaultResult ) isSeparateFaultResult = true; + } + + using ResCatEnum = caf::AppEnum; + for ( size_t i = 0; i < ResCatEnum::size(); ++i ) + { + RiaDefines::ResultCatType resType = ResCatEnum::fromIndex( i ); + + // Do not include flow diagnostics results if it is a time history curve + + if ( resType == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && ( timeHistoryCurve ) ) + { + continue; + } + + if ( resType == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && m_eclipseCase && m_eclipseCase->eclipseCaseData() && + m_eclipseCase->eclipseCaseData()->hasFractureResults() ) + { + // Flow diagnostics is not supported for dual porosity models + continue; + } + + // Do not include SourSimRL if no SourSim file is loaded + + if ( resType == RiaDefines::ResultCatType::SOURSIMRL && ( !hasSourSimRLFile ) ) + { + continue; + } + + if ( resType == RiaDefines::ResultCatType::INJECTION_FLOODING && !enableSouring ) + { + continue; + } + + if ( resType == RiaDefines::ResultCatType::ALLAN_DIAGRAMS && !isSeparateFaultResult ) + { + continue; + } + + QString uiString = ResCatEnum::uiTextFromIndex( i ); + options.push_back( caf::PdmOptionItemInfo( uiString, resType ) ); + } + } + + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + if ( fieldNeedingOptions == &m_resultVariableUiField ) + { + options.push_back( caf::PdmOptionItemInfo( RimEclipseResultDefinitionTools::timeOfFlightString( injectorSelectionState(), + producerSelectionState(), + false ), + RIG_FLD_TOF_RESNAME ) ); + if ( m_phaseSelection() == RigFlowDiagResultAddress::PHASE_ALL ) + { + options.push_back( caf::PdmOptionItemInfo( "Tracer Cell Fraction (Sum)", RIG_FLD_CELL_FRACTION_RESNAME ) ); + options.push_back( caf::PdmOptionItemInfo( RimEclipseResultDefinitionTools::maxFractionTracerString( injectorSelectionState(), + producerSelectionState(), + false ), + RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) ); + options.push_back( caf::PdmOptionItemInfo( "Injector Producer Communication", RIG_FLD_COMMUNICATION_RESNAME ) ); + } + } + else if ( fieldNeedingOptions == &m_flowSolutionUiField ) + { + RimEclipseResultCase* eclCase = dynamic_cast( m_eclipseCase.p() ); + if ( eclCase ) + { + std::vector flowSols = eclCase->flowDiagSolutions(); + for ( RimFlowDiagSolution* flowSol : flowSols ) + { + options.push_back( caf::PdmOptionItemInfo( flowSol->userDescription(), flowSol ) ); + } + } + } + else if ( fieldNeedingOptions == &m_selectedInjectorTracersUiField ) + { + const bool isInjector = true; + options = RimFlowDiagnosticsTools::calcOptionsForSelectedTracerField( m_flowSolutionUiField(), isInjector ); + } + else if ( fieldNeedingOptions == &m_selectedProducerTracersUiField ) + { + const bool isInjector = false; + options = RimFlowDiagnosticsTools::calcOptionsForSelectedTracerField( m_flowSolutionUiField(), isInjector ); + } + } + else if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INJECTION_FLOODING ) + { + if ( fieldNeedingOptions == &m_selectedSouringTracersUiField ) + { + RigCaseCellResultsData* cellResultsStorage = currentGridCellResults(); + if ( cellResultsStorage ) + { + QStringList dynamicResultNames = cellResultsStorage->resultNames( RiaDefines::ResultCatType::DYNAMIC_NATIVE ); + + for ( const QString& resultName : dynamicResultNames ) + { + if ( !resultName.endsWith( "F" ) || resultName == RiaResultNames::completionTypeResultName() ) + { + continue; + } + options.push_back( caf::PdmOptionItemInfo( resultName, resultName ) ); + } + } + } + else if ( fieldNeedingOptions == &m_resultVariableUiField ) + { + options.push_back( caf::PdmOptionItemInfo( RIG_NUM_FLOODED_PV, RIG_NUM_FLOODED_PV ) ); + } + } + else + { + if ( fieldNeedingOptions == &m_resultVariableUiField ) + { + options = calcOptionsForVariableUiFieldStandard( m_resultTypeUiField(), + currentGridCellResults(), + showDerivedResultsFirstInVariableUiField(), + addPerCellFaceOptionsForVariableUiField(), + m_ternaryEnabled ); + } + else if ( fieldNeedingOptions == &m_differenceCase ) + { + options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) ); + + auto eclipseCase = firstAncestorOrThisOfTypeAsserted(); + if ( eclipseCase && eclipseCase->eclipseCaseData() && eclipseCase->eclipseCaseData()->mainGrid() ) + { + RimProject* proj = RimProject::current(); + + std::vector allCases = proj->eclipseCases(); + for ( RimEclipseCase* otherCase : allCases ) + { + if ( otherCase == eclipseCase ) continue; + + if ( otherCase->eclipseCaseData() && otherCase->eclipseCaseData()->mainGrid() ) + { + options.push_back( + caf::PdmOptionItemInfo( QString( "%1 (#%2)" ).arg( otherCase->caseUserDescription() ).arg( otherCase->caseId() ), + otherCase, + false, + otherCase->uiIconProvider() ) ); + } + } + } + } + else if ( fieldNeedingOptions == &m_timeLapseBaseTimestep ) + { + RimEclipseCase* currentCase = firstAncestorOrThisOfTypeAsserted(); + + RimEclipseCase* baseCase = currentCase; + if ( m_differenceCase ) + { + baseCase = m_differenceCase; + } + + options.push_back( caf::PdmOptionItemInfo( "Disabled", RigEclipseResultAddress::noTimeLapseValue() ) ); + + std::vector stepDates = baseCase->timeStepDates(); + for ( size_t stepIdx = 0; stepIdx < stepDates.size(); ++stepIdx ) + { + QString displayString = stepDates[stepIdx].toString( RiaQDateTimeTools::dateFormatString() ); + displayString += QString( " (#%1)" ).arg( stepIdx ); + + options.push_back( caf::PdmOptionItemInfo( displayString, static_cast( stepIdx ) ) ); + } + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigEclipseResultAddress RimEclipseResultDefinition::eclipseResultAddress() const +{ + if ( !isChecked() ) return RigEclipseResultAddress(); + if ( isFlowDiagOrInjectionFlooding() ) return RigEclipseResultAddress(); + + const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + if ( gridCellResults ) + { + int timelapseTimeStep = RigEclipseResultAddress::noTimeLapseValue(); + int diffCaseId = RigEclipseResultAddress::noCaseDiffValue(); + + if ( isDeltaTimeStepActive() ) + { + timelapseTimeStep = m_timeLapseBaseTimestep(); + } + + if ( isDeltaCaseActive() ) + { + diffCaseId = m_differenceCase->caseId(); + } + + return RigEclipseResultAddress( m_resultType(), m_resultVariable(), timelapseTimeStep, diffCaseId, isDivideByCellFaceAreaActive() ); + } + else + { + return RigEclipseResultAddress(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setFromEclipseResultAddress( const RigEclipseResultAddress& address ) +{ + RigEclipseResultAddress canonizedAddress = address; + + const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + if ( gridCellResults ) + { + auto rinfo = gridCellResults->resultInfo( address ); + if ( rinfo ) canonizedAddress = rinfo->eclipseResultAddress(); + } + + m_resultType = canonizedAddress.resultCatType(); + m_resultVariable = canonizedAddress.resultName(); + m_timeLapseBaseTimestep = canonizedAddress.deltaTimeStepIndex(); + m_divideByCellFaceArea = canonizedAddress.isDivideByCellFaceAreaActive(); + + if ( canonizedAddress.isDeltaCaseActive() ) + { + auto eclipseCases = RimProject::current()->eclipseCases(); + for ( RimEclipseCase* c : eclipseCases ) + { + if ( c && c->caseId() == canonizedAddress.deltaCaseId() ) + { + m_differenceCase = c; + } + } + } + + updateUiFieldsFromActiveResult(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFlowDiagResultAddress RimEclipseResultDefinition::flowDiagResAddress() const +{ + CVF_ASSERT( isFlowDiagOrInjectionFlooding() ); + + if ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + size_t timeStep = 0; + + auto rimView = firstAncestorOrThisOfType(); + if ( rimView ) + { + timeStep = rimView->currentTimeStep(); + } + RimWellLogExtractionCurve* wellLogExtractionCurve = firstAncestorOrThisOfType(); + if ( wellLogExtractionCurve ) + { + timeStep = static_cast( wellLogExtractionCurve->currentTimeStep() ); + } + + std::set selTracerNames; + if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) + { + for ( const QString& tName : m_selectedInjectorTracers() ) + { + selTracerNames.insert( tName.toStdString() ); + } + for ( const QString& tName : m_selectedProducerTracers() ) + { + selTracerNames.insert( tName.toStdString() ); + } + } + else + { + RimFlowDiagSolution* flowSol = m_flowSolution(); + if ( flowSol ) + { + std::vector tracerNames = flowSol->tracerNames(); + + if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_INJECTORS || + m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD ) + { + for ( const QString& tracerName : tracerNames ) + { + RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusInTimeStep( tracerName, timeStep ); + if ( status == RimFlowDiagSolution::TracerStatusType::INJECTOR ) + { + selTracerNames.insert( tracerName.toStdString() ); + } + } + } + + if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_PRODUCERS || + m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_INJ_AND_PROD ) + { + for ( const QString& tracerName : tracerNames ) + { + RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusInTimeStep( tracerName, timeStep ); + if ( status == RimFlowDiagSolution::TracerStatusType::PRODUCER ) + { + selTracerNames.insert( tracerName.toStdString() ); + } + } + } + } + } + + return RigFlowDiagResultAddress( m_resultVariable().toStdString(), m_phaseSelection(), selTracerNames ); + } + + std::set selTracerNames; + for ( const QString& selectedTracerName : m_selectedSouringTracers() ) + { + selTracerNames.insert( selectedTracerName.toUtf8().constData() ); + } + return RigFlowDiagResultAddress( m_resultVariable().toStdString(), RigFlowDiagResultAddress::PHASE_ALL, selTracerNames ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setFlowDiagTracerSelectionType( FlowTracerSelectionType selectionType ) +{ + m_flowTracerSelectionMode = selectionType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::resultVariableUiName() const +{ + if ( resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + return flowDiagResUiText( false, 32 ); + } + + if ( isDivideByCellFaceAreaActive() ) + { + return m_resultVariable() + " /A"; + } + + return m_resultVariable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::resultVariableUiShortName() const +{ + if ( resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + return flowDiagResUiText( true, 24 ); + } + + if ( isDivideByCellFaceAreaActive() ) + { + return m_resultVariable() + " /A"; + } + + return m_resultVariable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::additionalResultText() const +{ + QStringList resultText; + + if ( isDeltaTimeStepActive() ) + { + std::vector stepDates; + const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + if ( gridCellResults ) + { + stepDates = gridCellResults->timeStepDates(); + resultText += QString( "Base Time Step: %1" ) + .arg( stepDates[m_timeLapseBaseTimestep()].toString( RiaQDateTimeTools::dateFormatString() ) ); + } + } + if ( isDeltaCaseActive() ) + { + resultText += QString( "Base Case: %1" ).arg( m_differenceCase()->caseUserDescription() ); + } + return resultText.join( "
" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::additionalResultTextShort() const +{ + QString resultTextShort; + if ( isDeltaTimeStepActive() || isDeltaCaseActive() ) + { + QStringList resultTextLines; + resultTextLines += QString( "\nDiff. Options:" ); + if ( isDeltaCaseActive() ) + { + resultTextLines += QString( "Base Case: #%1" ).arg( m_differenceCase()->caseId() ); + } + if ( isDeltaTimeStepActive() ) + { + resultTextLines += QString( "Base Time: #%1" ).arg( m_timeLapseBaseTimestep() ); + } + resultTextShort = resultTextLines.join( "\n" ); + } + + return resultTextShort; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimEclipseResultDefinition::timeLapseBaseTimeStep() const +{ + return m_timeLapseBaseTimestep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimEclipseResultDefinition::caseDiffIndex() const +{ + if ( m_differenceCase ) + { + return m_differenceCase->caseId(); + } + return -1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::loadResult() +{ + if ( isFlowDiagOrInjectionFlooding() ) return; // Will load automatically on access + + if ( m_eclipseCase ) + { + if ( !m_eclipseCase->ensureReservoirCaseIsOpen() ) + { + RiaLogging::error( "Could not open the Eclipse Grid file: " + m_eclipseCase->gridFileName() ); + return; + } + } + + if ( m_differenceCase ) + { + if ( !m_differenceCase->ensureReservoirCaseIsOpen() ) + { + RiaLogging::error( "Could not open the Eclipse Grid file: " + m_eclipseCase->gridFileName() ); + return; + } + } + + RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + if ( gridCellResults ) + { + if ( isDeltaTimeStepActive() || isDeltaCaseActive() || isDivideByCellFaceAreaActive() ) + { + gridCellResults->createResultEntry( eclipseResultAddress(), false ); + } + + QString resultName = m_resultVariable(); + std::set eclipseResultNamesWithNncData = RiaResultNames::nncResultNames(); + if ( eclipseResultNamesWithNncData.find( resultName ) != eclipseResultNamesWithNncData.end() ) + { + eclipseCase()->ensureFaultDataIsComputed(); + + bool dataWasComputed = eclipseCase()->ensureNncDataIsComputed(); + if ( dataWasComputed ) + { + eclipseCase()->createDisplayModelAndUpdateAllViews(); + } + } + + gridCellResults->ensureKnownResultLoaded( eclipseResultAddress() ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Returns whether the result requested by the definition is a single frame result +/// The result needs to be loaded before asking +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::hasStaticResult() const +{ + if ( isFlowDiagOrInjectionFlooding() ) return false; + + const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + RigEclipseResultAddress gridScalarResultIndex = eclipseResultAddress(); + + return hasResult() && gridCellResults->timeStepCount( gridScalarResultIndex ) == 1; +} + +//-------------------------------------------------------------------------------------------------- +/// Returns whether the result requested by the definition is loaded or possible to load from the result file +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::hasResult() const +{ + if ( isFlowDiagOrInjectionFlooding() ) + { + if ( m_flowSolution() && !m_resultVariable().isEmpty() ) return true; + } + else if ( currentGridCellResults() ) + { + const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + + return gridCellResults->hasResultEntry( eclipseResultAddress() ); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// Returns whether the result requested by the definition is a multi frame result +/// The result needs to be loaded before asking +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::hasDynamicResult() const +{ + if ( hasResult() ) + { + if ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE ) + { + return true; + } + else if ( m_resultType() == RiaDefines::ResultCatType::SOURSIMRL ) + { + return true; + } + else if ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + return true; + } + else if ( m_resultType() == RiaDefines::ResultCatType::INJECTION_FLOODING ) + { + return true; + } + + if ( currentGridCellResults() ) + { + const RigCaseCellResultsData* gridCellResults = currentGridCellResults(); + RigEclipseResultAddress gridScalarResultIndex = eclipseResultAddress(); + if ( gridCellResults->timeStepCount( gridScalarResultIndex ) > 1 ) + { + return true; + } + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::initAfterRead() +{ + if ( m_flowSolution() == nullptr ) + { + assignFlowSolutionFromCase(); + } + + if ( m_resultVariable() == "Formation Allen" ) + { + m_resultVariable = RiaResultNames::formationAllanResultName(); + m_resultType = RiaDefines::ResultCatType::ALLAN_DIAGRAMS; + } + else if ( m_resultVariable() == "Binary Formation Allen" ) + { + m_resultVariable = RiaResultNames::formationBinaryAllanResultName(); + m_resultType = RiaDefines::ResultCatType::ALLAN_DIAGRAMS; + } + + m_porosityModelUiField = m_porosityModel; + m_resultTypeUiField = m_resultType; + m_resultVariableUiField = m_resultVariable; + + m_flowSolutionUiField = m_flowSolution(); + m_selectedInjectorTracersUiField = m_selectedInjectorTracers; + + updateUiIconFromToggleField(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setResultType( RiaDefines::ResultCatType val ) +{ + m_resultType = val; + m_resultTypeUiField = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::PorosityModelType RimEclipseResultDefinition::porosityModel() const +{ + return m_porosityModel(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setPorosityModel( RiaDefines::PorosityModelType val ) +{ + m_porosityModel = val; + m_porosityModelUiField = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::resultVariable() const +{ + if ( !isChecked() ) return RiaResultNames::undefinedResultName(); + + return m_resultVariable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setResultVariable( const QString& val ) +{ + m_resultVariable = val; + m_resultVariableUiField = val; +} + +//-------------------------------------------------------------------------------------------------- +/// Return phase type if the current result is known to be of a particular +/// fluid phase type. Otherwise the method will return PHASE_NOT_APPLICABLE. +//-------------------------------------------------------------------------------------------------- +RiaDefines::PhaseType RimEclipseResultDefinition::resultPhaseType() const +{ + if ( QRegularExpression( "OIL" ).match( m_resultVariable() ).hasMatch() ) + { + return RiaDefines::PhaseType::OIL_PHASE; + } + else if ( QRegularExpression( "GAS" ).match( m_resultVariable() ).hasMatch() ) + { + return RiaDefines::PhaseType::GAS_PHASE; + } + else if ( QRegularExpression( "WAT" ).match( m_resultVariable() ).hasMatch() ) + { + return RiaDefines::PhaseType::WATER_PHASE; + } + return RiaDefines::PhaseType::PHASE_NOT_APPLICABLE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFlowDiagSolution* RimEclipseResultDefinition::flowDiagSolution() const +{ + return m_flowSolution(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setFlowSolution( RimFlowDiagSolution* flowSol ) +{ + m_flowSolution = flowSol; + m_flowSolutionUiField = flowSol; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedTracers( const std::vector& selectedTracers ) +{ + if ( m_flowSolution() == nullptr ) + { + assignFlowSolutionFromCase(); + } + if ( m_flowSolution() ) + { + std::vector injectorTracers; + std::vector producerTracers; + for ( const QString& tracerName : selectedTracers ) + { + RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall( tracerName ); + if ( tracerStatus == RimFlowDiagSolution::TracerStatusType::INJECTOR ) + { + injectorTracers.push_back( tracerName ); + } + else if ( tracerStatus == RimFlowDiagSolution::TracerStatusType::PRODUCER ) + { + producerTracers.push_back( tracerName ); + } + else if ( tracerStatus == RimFlowDiagSolution::TracerStatusType::VARYING || + tracerStatus == RimFlowDiagSolution::TracerStatusType::UNDEFINED ) + { + injectorTracers.push_back( tracerName ); + producerTracers.push_back( tracerName ); + } + } + setSelectedInjectorTracers( injectorTracers ); + setSelectedProducerTracers( producerTracers ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedInjectorTracers( const std::vector& selectedTracers ) +{ + m_selectedInjectorTracers = selectedTracers; + m_selectedInjectorTracersUiField = selectedTracers; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedProducerTracers( const std::vector& selectedTracers ) +{ + m_selectedProducerTracers = selectedTracers; + m_selectedProducerTracersUiField = selectedTracers; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedSouringTracers( const std::vector& selectedTracers ) +{ + m_selectedSouringTracers = selectedTracers; + m_selectedSouringTracersUiField = selectedTracers; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::updateUiFieldsFromActiveResult() +{ + m_resultTypeUiField = m_resultType; + m_resultVariableUiField = resultVariable(); + m_selectedInjectorTracersUiField = m_selectedInjectorTracers; + m_selectedProducerTracersUiField = m_selectedProducerTracers; + m_selectedSouringTracersUiField = m_selectedSouringTracers; + m_porosityModelUiField = m_porosityModel; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::enableDeltaResults( bool enable ) +{ + m_isDeltaResultEnabled = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isTernarySaturationSelected() const +{ + bool isTernary = ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE ) && + ( m_resultVariable().compare( RiaResultNames::ternarySaturationResultName(), Qt::CaseInsensitive ) == 0 ); + + return isTernary; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isCompletionTypeSelected() const +{ + return ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE && m_resultVariable() == RiaResultNames::completionTypeResultName() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::hasCategoryResult() const +{ + if ( auto* gridCellResults = currentGridCellResults() ) + { + const auto addresses = gridCellResults->existingResults(); + for ( const auto& address : addresses ) + { + if ( address.resultCatType() == m_resultType() && address.resultName() == m_resultVariable() ) + { + if ( address.dataType() == RiaDefines::ResultDataType::INTEGER ) return true; + break; + } + } + } + + if ( m_resultType() == RiaDefines::ResultCatType::FORMATION_NAMES && m_eclipseCase && m_eclipseCase->eclipseCaseData() && + !m_eclipseCase->eclipseCaseData()->formationNames().empty() ) + return true; + + if ( m_resultType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE && resultVariable() == RiaResultNames::completionTypeResultName() ) + return true; + + if ( m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && m_resultVariable() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) + return true; + + if ( resultVariable() == RiaResultNames::formationAllanResultName() || resultVariable() == RiaResultNames::formationBinaryAllanResultName() ) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isFlowDiagOrInjectionFlooding() const +{ + return m_resultType() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS || m_resultType() == RiaDefines::ResultCatType::INJECTION_FLOODING; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + uiOrdering.add( &m_resultTypeUiField ); + + if ( hasDualPorFractureResult() ) + { + uiOrdering.add( &m_porosityModelUiField ); + } + + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + uiOrdering.add( &m_flowSolutionUiField ); + + uiOrdering.add( &m_flowTracerSelectionMode ); + + if ( m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) + { + caf::PdmUiGroup* selectionGroup = uiOrdering.addNewGroup( "Tracer Selection" ); + selectionGroup->setEnableFrame( false ); + + caf::PdmUiGroup* injectorGroup = selectionGroup->addNewGroup( "Injectors" ); + injectorGroup->add( &m_selectedInjectorTracersUiField ); + injectorGroup->add( &m_syncInjectorToProducerSelection ); + + caf::PdmUiGroup* producerGroup = selectionGroup->addNewGroup( "Producers", { .newRow = false } ); + producerGroup->add( &m_selectedProducerTracersUiField ); + producerGroup->add( &m_syncProducerToInjectorSelection ); + } + + uiOrdering.add( &m_phaseSelection ); + + if ( m_flowSolution() == nullptr ) + { + assignFlowSolutionFromCase(); + } + } + + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INJECTION_FLOODING ) + { + uiOrdering.add( &m_selectedSouringTracersUiField ); + } + + uiOrdering.add( &m_resultVariableUiField ); + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::INPUT_PROPERTY ) + { + uiOrdering.add( &m_inputPropertyFileName ); + } + + if ( isDivideByCellFaceAreaPossible() ) + { + uiOrdering.add( &m_divideByCellFaceArea ); + + QString resultPropertyLabel = "Result Property"; + if ( isDivideByCellFaceAreaActive() ) + { + resultPropertyLabel += QString( "\nDivided by Area" ); + } + m_resultVariableUiField.uiCapability()->setUiName( resultPropertyLabel ); + } + + { + caf::PdmUiGroup* legendGroup = uiOrdering.addNewGroup( "Legend" ); + legendGroup->add( &m_showOnlyVisibleCategoriesInLegend ); + + bool showOnlyVisibleCategoriesOption = false; + + RimEclipseView* eclView = firstAncestorOrThisOfType(); + + if ( eclView ) + { + if ( eclView->cellResult() == this && hasCategoryResult() ) showOnlyVisibleCategoriesOption = true; + } + + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && + m_resultVariableUiField() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) + { + showOnlyVisibleCategoriesOption = true; + } + + legendGroup->setUiHidden( !showOnlyVisibleCategoriesOption ); + } + + if ( isDeltaCasePossible() || isDeltaTimeStepPossible() ) + { + caf::PdmUiGroup* differenceGroup = uiOrdering.addNewGroup( "Difference Options" ); + differenceGroup->setUiReadOnly( !( isDeltaTimeStepPossible() || isDeltaCasePossible() ) ); + + m_differenceCase.uiCapability()->setUiReadOnly( !isDeltaCasePossible() ); + m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly( !isDeltaTimeStepPossible() ); + + if ( isDeltaCasePossible() ) differenceGroup->add( &m_differenceCase ); + if ( isDeltaTimeStepPossible() ) differenceGroup->add( &m_timeLapseBaseTimestep ); + + QString resultPropertyLabel = "Result Property"; + if ( isDeltaTimeStepActive() || isDeltaCaseActive() ) + { + resultPropertyLabel += QString( "\n%1" ).arg( additionalResultTextShort() ); + } + m_resultVariableUiField.uiCapability()->setUiName( resultPropertyLabel ); + } + + uiOrdering.skipRemainingFields( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) +{ + if ( m_resultTypeUiField() == RiaDefines::ResultCatType::FLOW_DIAGNOSTICS ) + { + if ( field == &m_syncInjectorToProducerSelection || field == &m_syncProducerToInjectorSelection ) + { + caf::PdmUiToolButtonEditorAttribute* toolButtonAttr = dynamic_cast( attribute ); + if ( toolButtonAttr ) + { + toolButtonAttr->m_sizePolicy.setHorizontalPolicy( QSizePolicy::MinimumExpanding ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::assignFlowSolutionFromCase() +{ + RimFlowDiagSolution* defaultFlowDiagSolution = nullptr; + + RimEclipseResultCase* eclCase = dynamic_cast( m_eclipseCase.p() ); + + if ( eclCase ) + { + defaultFlowDiagSolution = eclCase->defaultFlowDiagSolution(); + } + setFlowSolution( defaultFlowDiagSolution ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::hasDualPorFractureResult() +{ + if ( m_eclipseCase && m_eclipseCase->eclipseCaseData() ) + { + return m_eclipseCase->eclipseCaseData()->hasFractureResults(); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::flowDiagResUiText( bool shortLabel, int maxTracerStringLength ) const +{ + QString uiText = QString::fromStdString( flowDiagResAddress().variableName ); + if ( flowDiagResAddress().variableName == RIG_FLD_TOF_RESNAME ) + { + uiText = RimEclipseResultDefinitionTools::timeOfFlightString( injectorSelectionState(), producerSelectionState(), shortLabel ); + } + else if ( flowDiagResAddress().variableName == RIG_FLD_MAX_FRACTION_TRACER_RESNAME ) + { + uiText = RimEclipseResultDefinitionTools::maxFractionTracerString( injectorSelectionState(), producerSelectionState(), shortLabel ); + } + + QString tracersString = RimEclipseResultDefinitionTools::selectedTracersString( injectorSelectionState(), + producerSelectionState(), + m_selectedInjectorTracers(), + m_selectedProducerTracers(), + maxTracerStringLength ); + + if ( !tracersString.isEmpty() ) + { + uiText += QString( "\n%1" ).arg( tracersString ); + } + return uiText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEclipseResultDefinition::calcOptionsForVariableUiFieldStandard( RiaDefines::ResultCatType resultCatType, + const RigCaseCellResultsData* results, + bool showDerivedResultsFirst, + bool addPerCellFaceOptionItems, + bool ternaryEnabled ) +{ + CVF_ASSERT( resultCatType != RiaDefines::ResultCatType::FLOW_DIAGNOSTICS && resultCatType != RiaDefines::ResultCatType::INJECTION_FLOODING ); + + return RimEclipseResultDefinitionTools::calcOptionsForVariableUiFieldStandard( resultCatType, + results, + showDerivedResultsFirst, + addPerCellFaceOptionItems, + ternaryEnabled ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setTernaryEnabled( bool enabled ) +{ + m_ternaryEnabled = enabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::updateRangesForExplicitLegends( RimRegularLegendConfig* legendConfigToUpdate, + RimTernaryLegendConfig* ternaryLegendConfigToUpdate, + int currentTimeStep ) + +{ + if ( hasResult() ) + { + if ( isFlowDiagOrInjectionFlooding() ) + { + if ( currentTimeStep >= 0 ) + { + RimEclipseResultDefinitionTools::updateLegendForFlowDiagnostics( this, legendConfigToUpdate, currentTimeStep ); + } + } + else + { + RimEclipseResultDefinitionTools::updateCellResultLegend( this, legendConfigToUpdate, currentTimeStep ); + } + } + + if ( isTernarySaturationSelected() ) + { + RimEclipseResultDefinitionTools::updateTernaryLegend( currentGridCellResults(), ternaryLegendConfigToUpdate, currentTimeStep ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::updateLegendTitle( RimRegularLegendConfig* legendConfig, const QString& legendHeading ) +{ + QString title = legendHeading + resultVariableUiName(); + if ( !additionalResultTextShort().isEmpty() ) + { + title += additionalResultTextShort(); + } + + if ( hasDualPorFractureResult() ) + { + QString porosityModelText = caf::AppEnum::uiText( porosityModel() ); + + title += QString( "\nDual Por : %1" ).arg( porosityModelText ); + } + + legendConfig->setTitle( title ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::showOnlyVisibleCategoriesInLegend() const +{ + return m_showOnlyVisibleCategoriesInLegend(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultDefinition::FlowTracerSelectionState RimEclipseResultDefinition::injectorSelectionState() const +{ + const bool isInjector = true; + return RimEclipseResultDefinitionTools::getFlowTracerSelectionState( isInjector, + m_flowTracerSelectionMode(), + m_flowSolutionUiField(), + m_selectedInjectorTracers().size() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultDefinition::FlowTracerSelectionState RimEclipseResultDefinition::producerSelectionState() const +{ + const bool isInjector = false; + return RimEclipseResultDefinitionTools::getFlowTracerSelectionState( isInjector, + m_flowTracerSelectionMode(), + m_flowSolutionUiField(), + m_selectedProducerTracers().size() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::syncInjectorToProducerSelection() +{ + int timeStep = 0; + + auto rimView = firstAncestorOrThisOfType(); + if ( rimView ) + { + timeStep = rimView->currentTimeStep(); + } + + RimFlowDiagSolution* flowSol = m_flowSolution(); + if ( flowSol && m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) + { + std::set newProducerSelection = + RimFlowDiagnosticsTools::setOfProducerTracersFromInjectors( m_flowSolutionUiField(), m_selectedInjectorTracers(), timeStep ); + // Add all currently selected producers to set + for ( const QString& selectedProducer : m_selectedProducerTracers() ) + { + newProducerSelection.insert( selectedProducer ); + } + std::vector newProducerVector( newProducerSelection.begin(), newProducerSelection.end() ); + setSelectedProducerTracers( newProducerVector ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::syncProducerToInjectorSelection() +{ + int timeStep = 0; + + auto rimView = firstAncestorOrThisOfType(); + if ( rimView ) + { + timeStep = rimView->currentTimeStep(); + } + + RimFlowDiagSolution* flowSol = m_flowSolution(); + if ( flowSol && m_flowTracerSelectionMode == FlowTracerSelectionType::FLOW_TR_BY_SELECTION ) + { + std::set newInjectorSelection = + RimFlowDiagnosticsTools::setOfInjectorTracersFromProducers( m_flowSolutionUiField(), m_selectedProducerTracers(), timeStep ); + + // Add all currently selected injectors to set + for ( const QString& selectedInjector : m_selectedInjectorTracers() ) + { + newInjectorSelection.insert( selectedInjector ); + } + std::vector newInjectorVector( newInjectorSelection.begin(), newInjectorSelection.end() ); + setSelectedInjectorTracers( newInjectorVector ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDeltaResultEnabled() const +{ + return m_isDeltaResultEnabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDeltaTimeStepPossible() const +{ + return isDeltaResultEnabled() && !isTernarySaturationSelected() && + ( m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE || + m_resultTypeUiField() == RiaDefines::ResultCatType::GENERATED ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDeltaTimeStepActive() const +{ + return isDeltaTimeStepPossible() && m_timeLapseBaseTimestep() >= 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDeltaCasePossible() const +{ + return isDeltaResultEnabled() && !isTernarySaturationSelected() && + ( m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE || + m_resultTypeUiField() == RiaDefines::ResultCatType::STATIC_NATIVE || + m_resultTypeUiField() == RiaDefines::ResultCatType::GENERATED ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDeltaCaseActive() const +{ + return isDeltaCasePossible() && m_differenceCase() != nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDivideByCellFaceAreaPossible() const +{ + return RimEclipseResultDefinitionTools::isDivideByCellFaceAreaPossible( m_resultVariable ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isDivideByCellFaceAreaActive() const +{ + return isDivideByCellFaceAreaPossible() && m_divideByCellFaceArea; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::showDerivedResultsFirstInVariableUiField() const +{ + // Cell Face result names + bool showDerivedResultsFirstInList = false; + RimEclipseFaultColors* rimEclipseFaultColors = firstAncestorOrThisOfType(); + + if ( rimEclipseFaultColors ) showDerivedResultsFirstInList = true; + + return showDerivedResultsFirstInList; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::addPerCellFaceOptionsForVariableUiField() const +{ + RimPlotCurve* curve = firstAncestorOrThisOfType(); + RimEclipsePropertyFilter* propFilter = firstAncestorOrThisOfType(); + RimCellEdgeColors* cellEdge = firstAncestorOrThisOfType(); + + return !( propFilter || curve || cellEdge ); +}