Define result address for to be used for non visible cells

Display a data source selection dialog to specify the result address to be used for cell values outside the visible cells.
This commit is contained in:
Magne Sjaastad 2024-01-16 13:39:26 +01:00
parent 35cc2127f2
commit a9598fbe0e
2 changed files with 163 additions and 28 deletions

View File

@ -36,16 +36,20 @@
#include "RimEclipseCase.h" #include "RimEclipseCase.h"
#include "RimEclipseCaseTools.h" #include "RimEclipseCaseTools.h"
#include "RimEclipseCellColors.h" #include "RimEclipseCellColors.h"
#include "RimEclipseResultAddress.h"
#include "RimEclipseStatisticsCase.h" #include "RimEclipseStatisticsCase.h"
#include "RimEclipseView.h" #include "RimEclipseView.h"
#include "RimGridCalculationCollection.h" #include "RimGridCalculationCollection.h"
#include "RimGridCalculationVariable.h" #include "RimGridCalculationVariable.h"
#include "RimProject.h" #include "RimProject.h"
#include "RimReloadCaseTools.h" #include "RimReloadCaseTools.h"
#include "RimResultSelectionUi.h"
#include "RimTools.h" #include "RimTools.h"
#include "expressionparser/ExpressionParser.h" #include "expressionparser/ExpressionParser.h"
#include "cafPdmUiPropertyViewDialog.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h" #include "cafPdmUiTreeSelectionEditor.h"
#include <QCheckBox> #include <QCheckBox>
@ -76,7 +80,18 @@ RimGridCalculation::RimGridCalculation()
CAF_PDM_InitField( &m_defaultValue, "DefaultValue", 0.0, "Custom Value" ); CAF_PDM_InitField( &m_defaultValue, "DefaultValue", 0.0, "Custom Value" );
CAF_PDM_InitFieldNoDefault( &m_destinationCase, "DestinationCase", "Destination Case" ); CAF_PDM_InitFieldNoDefault( &m_destinationCase, "DestinationCase", "Destination Case" );
CAF_PDM_InitField( &m_applyToAllCases, "AllDestinationCase", false, "Apply to All Cases" ); CAF_PDM_InitField( &m_applyToAllCases, "AllDestinationCase", false, "Apply to All Cases" );
CAF_PDM_InitField( &m_defaultPropertyVariableIndex, "DefaultPropertyVariableName", 0, "Property Variable Name" );
CAF_PDM_InitFieldNoDefault( &m_nonVisibleResultAddress, "NonVisibleResultAddress", "" );
m_nonVisibleResultAddress = new RimEclipseResultAddress;
CAF_PDM_InitField( &m_editNonVisibleResultAddress, "EditNonVisibleResultAddress", false, "Edit" );
m_editNonVisibleResultAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
m_editNonVisibleResultAddress.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitFieldNoDefault( &m_nonVisibleResultText, "NonVisibleResultText", "" );
m_nonVisibleResultText.registerGetMethod( this, &RimGridCalculation::nonVisibleResultAddressText );
m_nonVisibleResultText.uiCapability()->setUiReadOnly( true );
m_nonVisibleResultText.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "SelectedTimeSteps", "Time Step Selection" ); CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "SelectedTimeSteps", "Time Step Selection" );
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() ); m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
@ -156,6 +171,29 @@ bool RimGridCalculation::calculate()
} }
} }
if ( m_defaultValueType() == DefaultValueType::FROM_PROPERTY )
{
bool isDataSourceAvailable = false;
if ( m_nonVisibleResultAddress->eclipseCase() )
{
auto data = m_nonVisibleResultAddress->eclipseCase()->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
if ( data && data->hasResultEntry(
RigEclipseResultAddress( m_nonVisibleResultAddress->resultType(), m_nonVisibleResultAddress->resultName() ) ) )
{
isDataSourceAvailable = true;
}
}
if ( !isDataSourceAvailable )
{
QString msg = "No data available for result defined in 'Non-visible Cell Value'";
RiaLogging::errorInMessageBox( nullptr, "Grid Property Calculator", msg );
return false;
}
}
cvf::UByteArray* inputValueVisibilityFilter = nullptr; cvf::UByteArray* inputValueVisibilityFilter = nullptr;
if ( m_cellFilterView() ) if ( m_cellFilterView() )
{ {
@ -226,6 +264,20 @@ RimGridCalculation::DefaultValueConfig RimGridCalculation::defaultValueConfigura
return std::make_pair( m_defaultValueType(), HUGE_VAL ); return std::make_pair( m_defaultValueType(), HUGE_VAL );
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCalculation::nonVisibleResultAddressText() const
{
QString txt;
if ( m_nonVisibleResultAddress->eclipseCase() ) txt += m_nonVisibleResultAddress->eclipseCase()->caseUserDescription() + " : ";
txt += m_nonVisibleResultAddress->resultName();
return txt;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -251,7 +303,10 @@ void RimGridCalculation::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
filterGroup->add( &m_defaultValueType ); filterGroup->add( &m_defaultValueType );
if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::FROM_PROPERTY ) if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::FROM_PROPERTY )
filterGroup->add( &m_defaultPropertyVariableIndex ); {
filterGroup->add( &m_nonVisibleResultText );
filterGroup->add( &m_editNonVisibleResultAddress, { .newRow = false } );
}
else if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::USER_DEFINED ) else if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::USER_DEFINED )
filterGroup->add( &m_defaultValue ); filterGroup->add( &m_defaultValue );
} }
@ -320,16 +375,6 @@ QList<caf::PdmOptionItemInfo> RimGridCalculation::calculateValueOptions( const c
options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) ); options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) );
} }
else if ( fieldNeedingOptions == &m_defaultPropertyVariableIndex )
{
for ( int i = 0; i < static_cast<int>( m_variables.size() ); i++ )
{
auto v = dynamic_cast<RimGridCalculationVariable*>( m_variables[i] );
QString optionText = v->name();
options.push_back( caf::PdmOptionItemInfo( optionText, i ) );
}
}
else if ( &m_selectedTimeSteps == fieldNeedingOptions ) else if ( &m_selectedTimeSteps == fieldNeedingOptions )
{ {
RimEclipseCase* firstEclipseCase = nullptr; RimEclipseCase* firstEclipseCase = nullptr;
@ -367,6 +412,49 @@ void RimGridCalculation::initAfterRead()
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
RimUserDefinedCalculation::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_editNonVisibleResultAddress )
{
auto eclipseCase = m_nonVisibleResultAddress->eclipseCase();
if ( !eclipseCase ) eclipseCase = m_destinationCase;
RimResultSelectionUi selectionUi;
selectionUi.setEclipseResultAddress( eclipseCase, m_nonVisibleResultAddress->resultType(), m_nonVisibleResultAddress->resultName() );
caf::PdmUiPropertyViewDialog propertyDialog( nullptr, &selectionUi, "Select Result", "" );
if ( propertyDialog.exec() == QDialog::Accepted )
{
m_nonVisibleResultAddress->setEclipseCase( selectionUi.eclipseCase() );
m_nonVisibleResultAddress->setResultType( selectionUi.resultType() );
m_nonVisibleResultAddress->setResultName( selectionUi.resultVariable() );
}
m_editNonVisibleResultAddress = false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
{
RimUserDefinedCalculation::defineEditorAttribute( field, uiConfigName, attribute );
if ( field == &m_editNonVisibleResultAddress )
{
if ( auto attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute ) )
{
attrib->m_buttonText = "Edit";
}
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -423,16 +511,12 @@ RigEclipseResultAddress RimGridCalculation::outputAddress() const
std::vector<double> RimGridCalculation::getDataForVariable( RimGridCalculationVariable* variable, std::vector<double> RimGridCalculation::getDataForVariable( RimGridCalculationVariable* variable,
size_t tsId, size_t tsId,
RiaDefines::PorosityModelType porosityModel, RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* destinationCase, RimEclipseCase* sourceCase,
bool useDataFromDestinationCase ) const RimEclipseCase* destinationCase ) const
{ {
// The data can be taken from the destination case or from the calculation variable. if ( !sourceCase || !destinationCase ) return {};
auto eclipseCase = useDataFromDestinationCase ? destinationCase : variable->eclipseCase();
if ( !eclipseCase ) return {};
int timeStep = variable->timeStep();
int timeStep = variable->timeStep();
auto resultCategoryType = variable->resultCategoryType(); auto resultCategoryType = variable->resultCategoryType();
// General case is to use the data from the given time step // General case is to use the data from the given time step
@ -449,9 +533,31 @@ std::vector<double> RimGridCalculation::getDataForVariable( RimGridCalculationVa
timeStepToUse = timeStep; timeStepToUse = timeStep;
} }
RigEclipseResultAddress resAddr( resultCategoryType, variable->resultVariable() ); return getDataForResult( variable->resultVariable(), resultCategoryType, timeStepToUse, porosityModel, sourceCase, destinationCase );
}
auto eclipseCaseData = eclipseCase->eclipseCaseData(); //--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGridCalculation::getDataForResult( const QString& resultName,
const RiaDefines::ResultCatType resultCategoryType,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const
{
if ( !sourceCase || !destinationCase ) return {};
size_t timeStepToUse = tsId;
if ( resultCategoryType == RiaDefines::ResultCatType::STATIC_NATIVE )
{
// Use the first time step for static data for all time steps
timeStepToUse = 0;
}
RigEclipseResultAddress resAddr( resultCategoryType, resultName );
auto eclipseCaseData = sourceCase->eclipseCaseData();
auto rigCaseCellResultsData = eclipseCaseData->results( porosityModel ); auto rigCaseCellResultsData = eclipseCaseData->results( porosityModel );
if ( !rigCaseCellResultsData->ensureKnownResultLoaded( resAddr ) ) return {}; if ( !rigCaseCellResultsData->ensureKnownResultLoaded( resAddr ) ) return {};
@ -526,6 +632,7 @@ void RimGridCalculation::replaceFilteredValuesWithDefaultValue( double
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimGridCalculation::filterResults( RimGridView* cellFilterView, void RimGridCalculation::filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values, const std::vector<std::vector<double>>& values,
size_t timeStep,
RimGridCalculation::DefaultValueType defaultValueType, RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue, double defaultValue,
std::vector<double>& resultValues, std::vector<double>& resultValues,
@ -537,8 +644,17 @@ void RimGridCalculation::filterResults( RimGridView*
if ( defaultValueType == RimGridCalculation::DefaultValueType::FROM_PROPERTY ) if ( defaultValueType == RimGridCalculation::DefaultValueType::FROM_PROPERTY )
{ {
if ( m_defaultPropertyVariableIndex < static_cast<int>( values.size() ) ) auto nonVisibleValues = getDataForResult( m_nonVisibleResultAddress->resultName(),
replaceFilteredValuesWithVector( values[m_defaultPropertyVariableIndex], visibility, resultValues, porosityModel, outputEclipseCase ); m_nonVisibleResultAddress->resultType(),
timeStep,
porosityModel,
m_nonVisibleResultAddress->eclipseCase(),
outputEclipseCase );
if ( !nonVisibleValues.empty() )
{
replaceFilteredValuesWithVector( nonVisibleValues, visibility, resultValues, porosityModel, outputEclipseCase );
}
else else
{ {
QString errorMessage = QString errorMessage =
@ -713,8 +829,9 @@ bool RimGridCalculation::calculateForCases( const std::vector<RimEclipseCase*>&
CAF_ASSERT( v != nullptr ); CAF_ASSERT( v != nullptr );
bool useDataFromDestinationCase = ( v->eclipseCase() == m_destinationCase ); bool useDataFromDestinationCase = ( v->eclipseCase() == m_destinationCase );
auto sourceCase = useDataFromDestinationCase ? m_destinationCase : calculationCase;
auto dataForVariable = getDataForVariable( v, tsId, porosityModel, calculationCase, useDataFromDestinationCase ); auto dataForVariable = getDataForVariable( v, tsId, porosityModel, sourceCase, m_destinationCase );
if ( dataForVariable.empty() ) if ( dataForVariable.empty() )
{ {
RiaLogging::error( QString( " No data found for variable '%1'." ).arg( v->name() ) ); RiaLogging::error( QString( " No data found for variable '%1'." ).arg( v->name() ) );
@ -771,6 +888,7 @@ bool RimGridCalculation::calculateForCases( const std::vector<RimEclipseCase*>&
{ {
filterResults( m_cellFilterView(), filterResults( m_cellFilterView(),
dataForAllVariables, dataForAllVariables,
tsId,
m_defaultValueType(), m_defaultValueType(),
m_defaultValue(), m_defaultValue(),
resultValues, resultValues,

View File

@ -22,7 +22,9 @@
#include "RimGridCalculationVariable.h" #include "RimGridCalculationVariable.h"
#include "RimUserDefinedCalculation.h" #include "RimUserDefinedCalculation.h"
#include "cafPdmChildField.h"
#include "cafSignal.h" #include "cafSignal.h"
#include "cvfArray.h" #include "cvfArray.h"
#include <optional> #include <optional>
@ -30,6 +32,7 @@
class RimEclipseCase; class RimEclipseCase;
class RimGridView; class RimGridView;
class RigEclipseResultAddress; class RigEclipseResultAddress;
class RimEclipseResultAddress;
//================================================================================================== //==================================================================================================
/// ///
@ -80,11 +83,19 @@ protected:
std::vector<double> getDataForVariable( RimGridCalculationVariable* variable, std::vector<double> getDataForVariable( RimGridCalculationVariable* variable,
size_t tsId, size_t tsId,
RiaDefines::PorosityModelType porosityModel, RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* destinationCase, RimEclipseCase* sourceCase,
bool useDataFromDestinationCase ) const; RimEclipseCase* destinationCase ) const;
std::vector<double> getDataForResult( const QString& resultName,
const RiaDefines::ResultCatType resultCategoryType,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const;
void filterResults( RimGridView* cellFilterView, void filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values, const std::vector<std::vector<double>>& values,
size_t timeStep,
RimGridCalculation::DefaultValueType defaultValueType, RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue, double defaultValue,
std::vector<double>& resultValues, std::vector<double>& resultValues,
@ -106,9 +117,13 @@ protected:
using DefaultValueConfig = std::pair<RimGridCalculation::DefaultValueType, double>; using DefaultValueConfig = std::pair<RimGridCalculation::DefaultValueType, double>;
DefaultValueConfig defaultValueConfiguration() const; DefaultValueConfig defaultValueConfiguration() const;
QString nonVisibleResultAddressText() const;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
void initAfterRead() override; void initAfterRead() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
private: private:
void onVariableUpdated( const SignalEmitter* emitter ); void onVariableUpdated( const SignalEmitter* emitter );
@ -125,5 +140,7 @@ private:
caf::PdmField<std::vector<int>> m_selectedTimeSteps; caf::PdmField<std::vector<int>> m_selectedTimeSteps;
caf::PdmField<int> m_defaultPropertyVariableIndex; caf::PdmProxyValueField<QString> m_nonVisibleResultText;
caf::PdmChildField<RimEclipseResultAddress*> m_nonVisibleResultAddress;
caf::PdmField<bool> m_editNonVisibleResultAddress;
}; };