#12305 Well Target Mapping: add filter by view

Fixes #12305.
This commit is contained in:
Kristian Bendiksen committed 2025-04-02 17:19:57 +02:00
1 parent 712253624a
commit cfcbc03794
4 files changed
+71 -7

No files matched your search

@@ -20,9 +20,11 @@
#include "RiaGuiApplication.h" #include "RiaGuiApplication.h"
#include "RiaLogging.h" #include "RiaLogging.h"
#include "RiaOptionItemFactory.h"
#include "RiaPorosityModel.h" #include "RiaPorosityModel.h"
#include "RiaResultNames.h" #include "RiaResultNames.h"
#include "RigActiveCellInfo.h"
#include "RiuMainWindow.h" #include "RiuMainWindow.h"
#include "RigCaseCellResultsData.h" #include "RigCaseCellResultsData.h"
@@ -148,6 +150,8 @@ RimWellTargetMapping::RimWellTargetMapping()
caf::PdmUiPushButtonEditor::configureEditorLabelHidden( &m_generateButton ); caf::PdmUiPushButtonEditor::configureEditorLabelHidden( &m_generateButton );
m_generateButton.xmlCapability()->disableIO(); m_generateButton.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_filterView, "FilterView", "Filter By View" );
CAF_PDM_InitFieldNoDefault( &m_ensembleStatisticsCase, "EnsembleStatisticsCase", "Ensemble Statistics Case" ); CAF_PDM_InitFieldNoDefault( &m_ensembleStatisticsCase, "EnsembleStatisticsCase", "Ensemble Statistics Case" );
m_minimumSaturationOil = cvf::UNDEFINED_DOUBLE; m_minimumSaturationOil = cvf::UNDEFINED_DOUBLE;
@@ -235,6 +239,18 @@ QList<caf::PdmOptionItemInfo> RimWellTargetMapping::calculateValueOptions( const
caf::AppEnum<RigWellTargetMapping::VolumesType>::setEnumSubset( &m_volumesType, findAvailableVolumesTypes( fc ) ); caf::AppEnum<RigWellTargetMapping::VolumesType>::setEnumSubset( &m_volumesType, findAvailableVolumesTypes( fc ) );
} }
} }
else if ( fieldNeedingOptions == &m_filterView )
{
options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) );
if ( auto fc = firstCase() )
{
for ( const auto& view : fc->views() )
{
RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName( view, &options );
}
}
}
return options; return options;
} }
@@ -489,6 +505,9 @@ void RimWellTargetMapping::defineUiOrdering( QString uiConfigName, caf::PdmUiOrd
resultGroup->add( &m_volumesType ); resultGroup->add( &m_volumesType );
auto hasEnsembleParent = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>() != nullptr;
if ( !hasEnsembleParent ) uiOrdering.add( &m_filterView );
caf::PdmUiGroup* minimumCellValuesGroup = uiOrdering.addNewGroup( "Minimum Cell Values" ); caf::PdmUiGroup* minimumCellValuesGroup = uiOrdering.addNewGroup( "Minimum Cell Values" );
if ( showOilOptions ) minimumCellValuesGroup->add( &m_saturationOil ); if ( showOilOptions ) minimumCellValuesGroup->add( &m_saturationOil );
if ( showGasOptions ) minimumCellValuesGroup->add( &m_saturationGas ); if ( showGasOptions ) minimumCellValuesGroup->add( &m_saturationGas );
@@ -497,8 +516,6 @@ void RimWellTargetMapping::defineUiOrdering( QString uiConfigName, caf::PdmUiOrd
minimumCellValuesGroup->add( &m_transmissibility ); minimumCellValuesGroup->add( &m_transmissibility );
minimumCellValuesGroup->add( &m_resetDefaultButton ); minimumCellValuesGroup->add( &m_resetDefaultButton );
auto hasEnsembleParent = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>() != nullptr;
if ( hasEnsembleParent ) if ( hasEnsembleParent )
{ {
caf::PdmUiGroup* ensembleGridGroup = uiOrdering.addNewGroup( "Ensemble Statistics Grid" ); caf::PdmUiGroup* ensembleGridGroup = uiOrdering.addNewGroup( "Ensemble Statistics Grid" );
@@ -533,7 +550,43 @@ RigWellTargetMapping::ClusteringLimits RimWellTargetMapping::getClusteringLimits
.transmissibility = m_transmissibility, .transmissibility = m_transmissibility,
.maxNumTargets = m_maxNumTargets, .maxNumTargets = m_maxNumTargets,
.maxIterations = m_maxIterations, .maxIterations = m_maxIterations,
.filterAddress = m_resultDefinition->eclipseResultAddress() }; .filterAddress = m_resultDefinition->eclipseResultAddress(),
.filter = getVisibilityFilter() };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimWellTargetMapping::getVisibilityFilter() const
{
std::vector<double> filter = {};
// Visibility filter is only valid in the single case setting
auto hasEnsembleParent = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>() != nullptr;
if ( !hasEnsembleParent )
{
auto fc = firstCase();
if ( m_filterView() && fc )
{
cvf::ref<cvf::UByteArray> visibility = m_filterView->currentTotalCellVisibility();
auto activeReservoirCellIndices =
fc->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL )->activeReservoirCellIndices();
int numActiveCells = static_cast<int>( activeReservoirCellIndices.size() );
filter.resize( numActiveCells, std::numeric_limits<double>::infinity() );
// Create binary filter for active cells: 1.0 can be used, 0.0 is filtered out.
#pragma omp parallel for
for ( int i = 0; i < numActiveCells; i++ )
{
const auto reservoirCellIndex = activeReservoirCellIndices[i];
filter[i] = visibility->val( reservoirCellIndex ) ? 1.0 : 0.0;
}
}
}
return filter;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -21,12 +21,14 @@
#include "cafAppEnum.h" #include "cafAppEnum.h"
#include "cafPdmField.h" #include "cafPdmField.h"
#include "cafPdmObject.h" #include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include "RigFloodingSettings.h" #include "RigFloodingSettings.h"
#include "Well/RigWellTargetMapping.h" #include "Well/RigWellTargetMapping.h"
class RimEclipseResultDefinition; class RimEclipseResultDefinition;
class RimEclipseCase; class RimEclipseCase;
class RimEclipseView;
//================================================================================================== //==================================================================================================
/// ///
@@ -66,6 +68,7 @@ private:
static std::vector<RigWellTargetMapping::VolumesType> findAvailableVolumesTypes( RimEclipseCase* eclipseCase ); static std::vector<RigWellTargetMapping::VolumesType> findAvailableVolumesTypes( RimEclipseCase* eclipseCase );
RigWellTargetMapping::ClusteringLimits getClusteringLimits() const; RigWellTargetMapping::ClusteringLimits getClusteringLimits() const;
std::vector<double> getVisibilityFilter() const;
void resetMinimumCellValuesToDefault(); void resetMinimumCellValuesToDefault();
@@ -98,6 +101,8 @@ private:
caf::PdmField<bool> m_generateButton; caf::PdmField<bool> m_generateButton;
caf::PdmPtrField<RimEclipseView*> m_filterView;
caf::PdmChildField<RimEclipseCase*> m_ensembleStatisticsCase; caf::PdmChildField<RimEclipseCase*> m_ensembleStatisticsCase;
double m_minimumSaturationOil; double m_minimumSaturationOil;
@@ -145,15 +145,20 @@ void RigWellTargetMapping::generateCandidates( RimEclipseCase* eclips
} }
std::vector<double> filterVector; std::vector<double> filterVector;
if ( limits.filterAddress.isValid() ) if ( !limits.filter.empty() )
{
filterVector = limits.filter;
}
else if ( limits.filterAddress.isValid() )
{ {
resultsData->ensureKnownResultLoaded( limits.filterAddress ); resultsData->ensureKnownResultLoaded( limits.filterAddress );
filterVector = resultsData->cellScalarResults( limits.filterAddress, timeStepIdx ); filterVector = resultsData->cellScalarResults( limits.filterAddress, timeStepIdx );
} }
else
// Disable filtering if not configured: set all items to 1 (which includes all cells).
if ( filterVector.empty() || filterVector.size() != data.pressure.size() )
{ {
// Disable filter on invalid address: set all items to 1 (which includes all cells). filterVector = std::vector<double>( data.pressure.size(), 1.0 );
filterVector.resize( data.pressure.size(), 1.0 );
} }
std::vector<int> clusters( activeCellCount.value(), 0 ); std::vector<int> clusters( activeCellCount.value(), 0 );
@@ -78,6 +78,7 @@ public:
int maxNumTargets; int maxNumTargets;
int maxIterations; int maxIterations;
RigEclipseResultAddress filterAddress; RigEclipseResultAddress filterAddress;
std::vector<double> filter;
}; };
struct DataContainer struct DataContainer