From 6e1ba530c492d1eb9e398b1513d6848d4b45e239 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 9 Dec 2025 11:14:22 +0100 Subject: [PATCH] Adds RiaPhaseTools for phase system analysis Adds a new utility class, RiaPhaseTools, which provides functionalities to analyze phase systems in reservoir simulations. This class includes methods for checking the presence of individual phases (oil, gas, water), identifying different phase systems (three-phase, two-phase, single-phase), and retrieving a system description for display in the UI. It also includes utility functions to retrieve the preferred name for PCOG curves based on the detected phase system. --- .../Application/Tools/CMakeLists_files.cmake | 2 + .../Application/Tools/RiaPhaseTools.cpp | 136 ++++++++++++++++++ .../Application/Tools/RiaPhaseTools.h | 51 +++++++ .../ProjectDataModel/RimEclipseResultCase.cpp | 22 ++- .../ProjectDataModel/RimEclipseResultCase.h | 1 - .../RigSoilResultCalculator.cpp | 3 +- .../RigSwatResultCalculator.cpp | 3 +- 7 files changed, 201 insertions(+), 17 deletions(-) create mode 100644 ApplicationLibCode/Application/Tools/RiaPhaseTools.cpp create mode 100644 ApplicationLibCode/Application/Tools/RiaPhaseTools.h diff --git a/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake b/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake index e9eac64466..9382f3b003 100644 --- a/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake +++ b/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake @@ -51,6 +51,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaNetworkTools.h ${CMAKE_CURRENT_LIST_DIR}/RiaOpenMPTools.h ${CMAKE_CURRENT_LIST_DIR}/RiaNumericalTools.h + ${CMAKE_CURRENT_LIST_DIR}/RiaPhaseTools.h ${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTextTools.h ${CMAKE_CURRENT_LIST_DIR}/RiaFileLogger.h ${CMAKE_CURRENT_LIST_DIR}/RiaProjectBackupTools.h @@ -107,6 +108,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaNetworkTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaOpenMPTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaNumericalTools.cpp + ${CMAKE_CURRENT_LIST_DIR}/RiaPhaseTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTextTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaFileLogger.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaProjectBackupTools.cpp diff --git a/ApplicationLibCode/Application/Tools/RiaPhaseTools.cpp b/ApplicationLibCode/Application/Tools/RiaPhaseTools.cpp new file mode 100644 index 0000000000..8b936c800a --- /dev/null +++ b/ApplicationLibCode/Application/Tools/RiaPhaseTools.cpp @@ -0,0 +1,136 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaPhaseTools.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// Check if oil phase is present +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::hasOilPhase( const std::set& phases ) +{ + return phases.contains( RiaDefines::PhaseType::OIL_PHASE ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if gas phase is present +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::hasGasPhase( const std::set& phases ) +{ + return phases.contains( RiaDefines::PhaseType::GAS_PHASE ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if water phase is present +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::hasWaterPhase( const std::set& phases ) +{ + return phases.contains( RiaDefines::PhaseType::WATER_PHASE ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if this is a three-phase system (oil, gas, and water) +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::isThreePhaseSystem( const std::set& phases ) +{ + return hasOilPhase( phases ) && hasGasPhase( phases ) && hasWaterPhase( phases ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if this is a two-phase gas-water system (gas and water, no oil) +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::isTwoPhaseGasWater( const std::set& phases ) +{ + return hasGasPhase( phases ) && hasWaterPhase( phases ) && !hasOilPhase( phases ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if this is a two-phase oil-water system (oil and water, no gas) +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::isTwoPhaseOilWater( const std::set& phases ) +{ + return hasOilPhase( phases ) && hasWaterPhase( phases ) && !hasGasPhase( phases ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if this is a two-phase oil-gas system (oil and gas, no water) +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::isTwoPhaseOilGas( const std::set& phases ) +{ + return hasOilPhase( phases ) && hasGasPhase( phases ) && !hasWaterPhase( phases ); +} + +//-------------------------------------------------------------------------------------------------- +/// Check if this is a single-phase system +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::isSinglePhase( const std::set& phases ) +{ + return phases.size() == 1; +} + +//-------------------------------------------------------------------------------------------------- +/// Check if this is a single-phase water system +//-------------------------------------------------------------------------------------------------- +bool RiaPhaseTools::isSinglePhaseWater( const std::set& phases ) +{ + return phases.size() == 1 && hasWaterPhase( phases ); +} + +//-------------------------------------------------------------------------------------------------- +/// Get the preferred name for PCOG curves based on phase system +/// Returns "PCGW" for gas-water systems, "PCOG" otherwise +//-------------------------------------------------------------------------------------------------- +QString RiaPhaseTools::getPreferredPcogName( const std::set& phases ) +{ + return isTwoPhaseGasWater( phases ) ? "PCGW" : "PCOG"; +} + +//-------------------------------------------------------------------------------------------------- +/// Get a human-readable description of the phase system +//-------------------------------------------------------------------------------------------------- +QString RiaPhaseTools::getSystemDescription( const std::set& phases ) +{ + if ( isThreePhaseSystem( phases ) ) + { + return "Three-phase (Oil/Gas/Water)"; + } + else if ( isTwoPhaseGasWater( phases ) ) + { + return "Two-phase (Gas/Water)"; + } + else if ( isTwoPhaseOilWater( phases ) ) + { + return "Two-phase (Oil/Water)"; + } + else if ( isTwoPhaseOilGas( phases ) ) + { + return "Two-phase (Oil/Gas)"; + } + else if ( isSinglePhase( phases ) ) + { + if ( hasOilPhase( phases ) ) + return "Single-phase (Oil)"; + else if ( hasGasPhase( phases ) ) + return "Single-phase (Gas)"; + else if ( hasWaterPhase( phases ) ) + return "Single-phase (Water)"; + } + + return "Unknown phase system"; +} \ No newline at end of file diff --git a/ApplicationLibCode/Application/Tools/RiaPhaseTools.h b/ApplicationLibCode/Application/Tools/RiaPhaseTools.h new file mode 100644 index 0000000000..c69eda81f1 --- /dev/null +++ b/ApplicationLibCode/Application/Tools/RiaPhaseTools.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaDefines.h" + +#include + +class QString; + +//================================================================================================== +/// +/// Tool functions for analyzing phase systems in reservoir simulations +/// +//================================================================================================== +class RiaPhaseTools +{ +public: + // Individual phase checks + static bool hasOilPhase( const std::set& phases ); + static bool hasGasPhase( const std::set& phases ); + static bool hasWaterPhase( const std::set& phases ); + + // Phase system analysis + static bool isThreePhaseSystem( const std::set& phases ); + static bool isTwoPhaseGasWater( const std::set& phases ); + static bool isTwoPhaseOilWater( const std::set& phases ); + static bool isTwoPhaseOilGas( const std::set& phases ); + static bool isSinglePhase( const std::set& phases ); + static bool isSinglePhaseWater( const std::set& phases ); + + // Specific utility functions + static QString getPreferredPcogName( const std::set& phases ); + static QString getSystemDescription( const std::set& phases ); +}; \ No newline at end of file diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp index 227957b32a..9e40d6fe41 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -23,6 +23,7 @@ #include "RiaApplication.h" #include "RiaFieldHandleTools.h" #include "RiaLogging.h" +#include "RiaPhaseTools.h" #include "RiaPreferencesGrid.h" #include "RiaRegressionTestRunner.h" #include "RiaResultNames.h" @@ -90,10 +91,6 @@ RimEclipseResultCase::RimEclipseResultCase() m_unitSystem.registerGetMethod( RimProject::current(), &RimProject::commonUnitSystemForAllCases ); m_unitSystem.uiCapability()->setUiReadOnly( true ); - CAF_PDM_InitFieldNoDefault( &m_phases, "Phases", "Phases" ); - m_phases.registerGetMethod( this, &RimEclipseResultCase::phasesAsString ); - m_phases.uiCapability()->setUiReadOnly( true ); - CAF_PDM_InitFieldNoDefault( &m_flowDiagSolutions, "FlowDiagSolutions", "Flow Diagnostics Solutions" ); m_flowDiagSolutions.uiCapability()->setUiTreeChildrenHidden( true ); @@ -140,19 +137,13 @@ QString RimEclipseResultCase::phasesAsString() const { if ( auto caseData = eclipseCaseData() ) { - QStringList phaseNames; - const auto phases = caseData->availablePhases(); - for ( const auto& phase : phases ) - { - phaseNames.append( caf::AppEnum::uiText( phase ) ); - } - - if ( phaseNames.isEmpty() ) + const auto phases = caseData->availablePhases(); + if ( phases.empty() ) { return "No phases available"; } - return phaseNames.join( ", " ); + return RiaPhaseTools::getSystemDescription( phases ); } return "No data available"; @@ -709,7 +700,10 @@ void RimEclipseResultCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrd uiOrdering.add( &m_caseId ); uiOrdering.add( &m_caseFileName ); uiOrdering.add( &m_unitSystem ); - uiOrdering.add( &m_phases ); + + QString phaseText = phasesAsString(); + uiOrdering.addNewLabel( "Phase System" ); + uiOrdering.addNewLabel( phaseText, { .newRow = false } ); auto group = uiOrdering.addNewGroup( "Case Options" ); group->add( &m_activeFormationNames ); diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h index b462eaf5c2..efb53b4320 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.h @@ -104,7 +104,6 @@ private: caf::PdmProxyValueField> m_unitSystem; caf::PdmChildArrayField m_flowDiagSolutions; caf::PdmField m_sourSimFileName; - caf::PdmProxyValueField m_phases; caf::PdmField> m_mswMergeThreshold; diff --git a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp index d0381c360d..d2c3d31222 100644 --- a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp @@ -21,6 +21,7 @@ #include "RigEclipseCaseData.h" #include "RigEclipseResultInfo.h" +#include "RiaPhaseTools.h" #include "RiaResultNames.h" //================================================================================================== @@ -210,5 +211,5 @@ bool RigSoilResultCalculator::hasOilPhase() const if ( availablePhases.empty() ) return true; // Check if oil phase is present - return availablePhases.count( RiaDefines::PhaseType::OIL_PHASE ) > 0; + return RiaPhaseTools::hasOilPhase( availablePhases ); } diff --git a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSwatResultCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSwatResultCalculator.cpp index 187cc30889..ca2917422d 100644 --- a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSwatResultCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSwatResultCalculator.cpp @@ -22,6 +22,7 @@ #include "RigEclipseCaseData.h" #include "RigEclipseResultInfo.h" +#include "RiaPhaseTools.h" #include "RiaResultNames.h" //================================================================================================== @@ -113,5 +114,5 @@ bool RigSwatResultCalculator::hasOnlyWaterPhase() const if ( !eclipseCaseData ) return false; std::set availablePhases = eclipseCaseData->availablePhases(); - return availablePhases.size() == 1 && availablePhases.contains( RiaDefines::PhaseType::WATER_PHASE ); + return RiaPhaseTools::isSinglePhaseWater( availablePhases ); } \ No newline at end of file