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