///////////////////////////////////////////////////////////////////////////////// // // 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 ); }