Improve grid cell calculator

* Use full name for grid case view
* FIx signed / unsigned issue
* Support drag/drop of file names into Main Window
* Add function to check if two grid cases are of equal size
* Result Info: Show cell result text for all linked views
* Improve how to specify cells to be included in calculation

- move view filter to calculation
- improve how to assign values to non-visible cells
- avoid computation between grids of different size

Closes #9482
This commit is contained in:
Magne Sjaastad
2022-11-17 15:51:01 +01:00
committed by GitHub
parent ffc3830110
commit e7c864c6d8
18 changed files with 392 additions and 180 deletions

View File

@@ -48,7 +48,7 @@ bool RifThermalFractureTemplateSurfaceExporter::writeToFile( gsl::not_null<RimTh
out.setRealNumberPrecision( 16 );
auto nameAndUnits = fractureData->getPropertyNamesUnits();
int numProperties = nameAndUnits.size();
int numProperties = static_cast<int>( nameAndUnits.size() );
for ( auto [name, unit] : nameAndUnits )
{

View File

@@ -36,6 +36,7 @@
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigGridManager.h"
#include "RigMainGrid.h"
#include "RigNNCData.h"
#include "RigSimWellData.h"
@@ -270,6 +271,19 @@ const RigMainGrid* RimEclipseCase::mainGrid() const
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseCase::isGridSizeEqualTo( const RimEclipseCase* otherCase ) const
{
if ( !mainGrid() || !otherCase || !otherCase->mainGrid() )
{
return false;
}
return RigGridManager::isMainGridDimensionsEqual( mainGrid(), otherCase->mainGrid() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -83,6 +83,7 @@ public:
cvf::Color3f defaultWellColor( const QString& wellName );
const RigMainGrid* mainGrid() const;
bool isGridSizeEqualTo( const RimEclipseCase* otherCase ) const;
RigCaseCellResultsData* results( RiaDefines::PorosityModelType porosityModel );
const RigCaseCellResultsData* results( RiaDefines::PorosityModelType porosityModel ) const;

View File

@@ -26,10 +26,13 @@
#include "RimEclipseCellColors.h"
#include "RimEclipseView.h"
#include "RimGridCalculationVariable.h"
#include "RimProject.h"
#include "RimReloadCaseTools.h"
#include "RimTools.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseResultAddress.h"
#include "RigGridManager.h"
#include "RigMainGrid.h"
#include "RigResultAccessor.h"
#include "RigResultAccessorFactory.h"
@@ -38,20 +41,41 @@
CAF_PDM_SOURCE_INIT( RimGridCalculation, "RimGridCalculation" );
namespace caf
{
template <>
void caf::AppEnum<RimGridCalculation::DefaultValueType>::setUp()
{
addItem( RimGridCalculation::DefaultValueType::POSITIVE_INFINITY, "POSITIVE_INFINITY", "Infinity" );
addItem( RimGridCalculation::DefaultValueType::FROM_PROPERTY, "FROM_PROPERTY", "Property Value" );
addItem( RimGridCalculation::DefaultValueType::USER_DEFINED, "USER_DEFINED", "User Defined Custom Value" );
setDefault( RimGridCalculation::DefaultValueType::POSITIVE_INFINITY );
}
}; // namespace caf
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculation::RimGridCalculation()
{
CAF_PDM_InitObject( "RimGridCalculation", ":/octave.png", "Calculation", "" );
CAF_PDM_InitFieldNoDefault( &m_cellFilterView, "VisibleCellView", "Filter by 3d View Visibility" );
CAF_PDM_InitFieldNoDefault( &m_defaultValueType, "DefaultValueType", "Non-visible Cell Value" );
CAF_PDM_InitField( &m_defaultValue, "DefaultValue", 0.0, "Custom Value" );
CAF_PDM_InitFieldNoDefault( &m_destinationCase, "DestinationCase", "Destination Case" );
CAF_PDM_InitField( &m_defaultPropertyVariableIndex, "DefaultPropertyVariableName", 0, "Property Variable Name" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationVariable* RimGridCalculation::createVariable() const
RimGridCalculationVariable* RimGridCalculation::createVariable()
{
return new RimGridCalculationVariable;
auto variable = new RimGridCalculationVariable;
variable->eclipseResultChanged.connect( this, &RimGridCalculation::onVariableUpdated );
return variable;
}
//--------------------------------------------------------------------------------------------------
@@ -61,7 +85,7 @@ bool RimGridCalculation::calculate()
{
QString leftHandSideVariableName = RimGridCalculation::findLeftHandSide( m_expression );
RimEclipseCase* eclipseCase = findEclipseCaseFromVariables();
RimEclipseCase* eclipseCase = destinationEclipseCase();
if ( !eclipseCase )
{
RiaLogging::errorInMessageBox( nullptr,
@@ -77,6 +101,17 @@ bool RimGridCalculation::calculate()
return false;
}
for ( auto variableCase : inputCases() )
{
if ( !eclipseCase->isGridSizeEqualTo( variableCase ) )
{
QString msg = "Detected IJK mismatch between input cases and destination case. All grid "
"cases must have identical IJK sizes.";
RiaLogging::errorInMessageBox( nullptr, "Grid Property Calculator", msg );
return false;
}
}
auto porosityModel = RiaDefines::PorosityModelType::MATRIX_MODEL;
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::GENERATED, leftHandSideVariableName );
@@ -121,12 +156,9 @@ bool RimGridCalculation::calculate()
if ( evaluatedOk )
{
auto [cellFilterView, defaultValueConfig] = findFilterValuesFromVariables();
if ( cellFilterView )
if ( m_cellFilterView() )
{
auto [defaultValueType, defaultValue] = defaultValueConfig;
filterResults( cellFilterView, values, defaultValueType, defaultValue, resultValues );
filterResults( m_cellFilterView(), values, m_defaultValueType(), m_defaultValue(), resultValues );
}
scalarResultFrames->at( tsId ) = resultValues;
@@ -151,51 +183,166 @@ bool RimGridCalculation::calculate()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseCase* RimGridCalculation::findEclipseCaseFromVariables() const
RimEclipseCase* RimGridCalculation::destinationEclipseCase() const
{
for ( auto variable : m_variables )
{
RimGridCalculationVariable* v = dynamic_cast<RimGridCalculationVariable*>( variable.p() );
CAF_ASSERT( v != nullptr );
if ( v->eclipseCase() ) return v->eclipseCase();
}
return nullptr;
return m_destinationCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<RimGridView*, RimGridCalculationVariable::DefaultValueConfig>
RimGridCalculation::findFilterValuesFromVariables() const
std::vector<RimEclipseCase*> RimGridCalculation::inputCases() const
{
for ( auto variable : m_variables )
{
RimGridCalculationVariable* v = dynamic_cast<RimGridCalculationVariable*>( variable.p() );
CAF_ASSERT( v != nullptr );
std::vector<RimEclipseCase*> cases;
if ( v->cellFilterView() ) return std::make_pair( v->cellFilterView(), v->defaultValueConfiguration() );
for ( const auto& variable : m_variables )
{
auto* v = dynamic_cast<RimGridCalculationVariable*>( variable.p() );
if ( v->eclipseCase() ) cases.push_back( v->eclipseCase() );
}
return std::pair( nullptr, std::make_pair( RimGridCalculationVariable::DefaultValueType::POSITIVE_INFINITY, HUGE_VAL ) );
return cases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimGridCalculation::findFilterVariableIndex() const
RimGridCalculation::DefaultValueConfig RimGridCalculation::defaultValueConfiguration() const
{
for ( size_t i = 0; i < m_variables.size(); i++ )
{
auto variable = m_variables[i];
RimGridCalculationVariable* v = dynamic_cast<RimGridCalculationVariable*>( variable );
CAF_ASSERT( v != nullptr );
if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::USER_DEFINED )
return std::make_pair( m_defaultValueType(), m_defaultValue() );
if ( v->cellFilterView() ) return static_cast<int>( i );
return std::make_pair( m_defaultValueType(), HUGE_VAL );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
RimUserDefinedCalculation::defineUiOrdering( uiConfigName, uiOrdering );
uiOrdering.add( &m_destinationCase );
caf::PdmUiGroup* filterGroup = uiOrdering.addNewGroup( "Cell Filter" );
filterGroup->setCollapsedByDefault();
filterGroup->add( &m_cellFilterView );
if ( m_cellFilterView() != nullptr )
{
filterGroup->add( &m_defaultValueType );
if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::FROM_PROPERTY )
filterGroup->add( &m_defaultPropertyVariableIndex );
else if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::USER_DEFINED )
filterGroup->add( &m_defaultValue );
}
return -1;
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimGridCalculation::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_cellFilterView )
{
options.push_back( caf::PdmOptionItemInfo( "Disabled", nullptr ) );
std::vector<Rim3dView*> views;
RimProject::current()->allViews( views );
RimEclipseCase* firstEclipseCase = nullptr;
if ( !inputCases().empty() ) firstEclipseCase = inputCases().front();
if ( firstEclipseCase )
{
for ( auto* view : views )
{
auto eclipseView = dynamic_cast<RimEclipseView*>( view );
if ( !eclipseView ) continue;
if ( !firstEclipseCase->isGridSizeEqualTo( eclipseView->eclipseCase() ) ) continue;
options.push_back( caf::PdmOptionItemInfo( view->autoName(), view, false, view->uiIconProvider() ) );
}
}
}
else if ( fieldNeedingOptions == &m_destinationCase )
{
if ( inputCases().empty() )
{
RimTools::eclipseCaseOptionItems( &options );
}
else
{
RimEclipseCase* firstInputCase = inputCases()[0];
RimProject* proj = RimProject::current();
if ( proj )
{
std::vector<RimCase*> cases;
proj->allCases( cases );
for ( RimCase* c : cases )
{
auto* eclipseCase = dynamic_cast<RimEclipseCase*>( c );
if ( !eclipseCase ) continue;
if ( !firstInputCase->isGridSizeEqualTo( eclipseCase ) ) continue;
options.push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) );
}
}
}
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 ) );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::initAfterRead()
{
for ( auto& variable : m_variables )
{
auto gridVar = dynamic_cast<RimGridCalculationVariable*>( variable.p() );
if ( gridVar )
{
gridVar->eclipseResultChanged.connect( this, &RimGridCalculation::onVariableUpdated );
if ( m_destinationCase == nullptr ) m_destinationCase = gridVar->eclipseCase();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::onVariableUpdated( const SignalEmitter* emitter )
{
if ( m_destinationCase == nullptr )
{
auto variable = dynamic_cast<const RimGridCalculationVariable*>( emitter );
if ( variable && variable->eclipseCase() )
{
m_destinationCase = variable->eclipseCase();
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -289,22 +436,31 @@ void RimGridCalculation::replaceFilteredValuesWithDefaultValue( double
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values,
RimGridCalculationVariable::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues ) const
void RimGridCalculation::filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values,
RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues ) const
{
auto visibility = cellFilterView->currentTotalCellVisibility();
if ( defaultValueType == RimGridCalculationVariable::DefaultValueType::FROM_PROPERTY )
if ( defaultValueType == RimGridCalculation::DefaultValueType::FROM_PROPERTY )
{
int filterVariableIndex = findFilterVariableIndex();
replaceFilteredValuesWithVector( values[filterVariableIndex], visibility, resultValues );
if ( m_defaultPropertyVariableIndex < static_cast<int>( values.size() ) )
replaceFilteredValuesWithVector( values[m_defaultPropertyVariableIndex], visibility, resultValues );
else
{
QString errorMessage =
"Invalid input data for default result property, no data assigned to non-visible cells.";
RiaLogging::errorInMessageBox( nullptr, "Grid Property Calculator", errorMessage );
}
}
else
{
replaceFilteredValuesWithDefaultValue( defaultValue, visibility, resultValues );
double valueToUse = defaultValue;
if ( defaultValueType == RimGridCalculation::DefaultValueType::POSITIVE_INFINITY ) valueToUse = HUGE_VAL;
replaceFilteredValuesWithDefaultValue( valueToUse, visibility, resultValues );
}
}
@@ -313,7 +469,7 @@ void RimGridCalculation::filterResults( RimGridView*
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::updateDependentObjects()
{
RimEclipseCase* eclipseCase = findEclipseCaseFromVariables();
RimEclipseCase* eclipseCase = destinationEclipseCase();
if ( eclipseCase )
{
RimReloadCaseTools::updateAll3dViews( eclipseCase );
@@ -331,7 +487,7 @@ void RimGridCalculation::removeDependentObjects()
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::GENERATED, leftHandSideVariableName );
RimEclipseCase* eclipseCase = findEclipseCaseFromVariables();
RimEclipseCase* eclipseCase = destinationEclipseCase();
if ( eclipseCase )
{
// Select "None" result if the result that is being removed were displayed in a view.

View File

@@ -22,6 +22,7 @@
#include "RimGridCalculationVariable.h"
#include "RimUserDefinedCalculation.h"
#include "cafSignal.h"
#include "cvfArray.h"
class RimEclipseCase;
@@ -36,6 +37,13 @@ class RimGridCalculation : public RimUserDefinedCalculation
CAF_PDM_HEADER_INIT;
public:
enum class DefaultValueType
{
POSITIVE_INFINITY,
FROM_PROPERTY,
USER_DEFINED
};
RimGridCalculation();
bool calculate() override;
@@ -46,20 +54,21 @@ protected:
void onChildrenUpdated( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& updatedObjects ) override;
RimGridCalculationVariable* createVariable() const override;
RimGridCalculationVariable* createVariable() override;
std::pair<bool, QString> validateVariables();
RimEclipseCase* findEclipseCaseFromVariables() const;
RimEclipseCase* destinationEclipseCase() const;
std::vector<RimEclipseCase*> inputCases() const;
std::vector<double> getInputVectorForVariable( RimGridCalculationVariable* v,
size_t tsId,
RiaDefines::PorosityModelType porosityModel ) const;
void filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values,
RimGridCalculationVariable::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues ) const;
void filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values,
RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues ) const;
static void replaceFilteredValuesWithVector( const std::vector<double>& inputValues,
cvf::ref<cvf::UByteArray> visibility,
@@ -69,7 +78,20 @@ protected:
cvf::ref<cvf::UByteArray> visibility,
std::vector<double>& resultValues );
int findFilterVariableIndex() const;
using DefaultValueConfig = std::pair<RimGridCalculation::DefaultValueType, double>;
DefaultValueConfig defaultValueConfiguration() const;
std::pair<RimGridView*, RimGridCalculationVariable::DefaultValueConfig> findFilterValuesFromVariables() const;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
void initAfterRead() override;
private:
void onVariableUpdated( const SignalEmitter* emitter );
private:
caf::PdmPtrField<RimGridView*> m_cellFilterView;
caf::PdmField<caf::AppEnum<DefaultValueType>> m_defaultValueType;
caf::PdmField<double> m_defaultValue;
caf::PdmPtrField<RimEclipseCase*> m_destinationCase;
caf::PdmField<int> m_defaultPropertyVariableIndex;
};

View File

@@ -23,34 +23,23 @@
#include "RiaPorosityModel.h"
#include "RiaResultNames.h"
#include "RimGridCalculation.h"
#include "RiuDragDrop.h"
#include "RigCaseCellResultsData.h"
#include "RimEclipseCase.h"
#include "RimEclipseResultAddress.h"
#include "RimEclipseView.h"
#include "RimGridCalculation.h"
#include "RimTools.h"
CAF_PDM_SOURCE_INIT( RimGridCalculationVariable, "RimGridCalculationVariable" );
#include "RiuDragDrop.h"
namespace caf
{
template <>
void caf::AppEnum<RimGridCalculationVariable::DefaultValueType>::setUp()
{
addItem( RimGridCalculationVariable::DefaultValueType::POSITIVE_INFINITY, "POSITIVE_INFINITY", "Inf" );
addItem( RimGridCalculationVariable::DefaultValueType::FROM_PROPERTY, "FROM_PROPERTY", "Property Value" );
addItem( RimGridCalculationVariable::DefaultValueType::USER_DEFINED, "USER_DEFINED", "User Defined" );
setDefault( RimGridCalculationVariable::DefaultValueType::POSITIVE_INFINITY );
}
}; // namespace caf
CAF_PDM_SOURCE_INIT( RimGridCalculationVariable, "RimGridCalculationVariable" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationVariable::RimGridCalculationVariable()
: eclipseResultChanged( this )
{
CAF_PDM_InitObject( "RimGridCalculationVariable", ":/octave.png" );
@@ -58,9 +47,6 @@ RimGridCalculationVariable::RimGridCalculationVariable()
CAF_PDM_InitField( &m_resultVariable, "ResultVariable", RiaResultNames::undefinedResultName(), "Variable" );
CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "EclipseGridCase", "Grid Case" );
CAF_PDM_InitField( &m_timeStep, "TimeStep", allTimeStepsValue(), "Time Step" );
CAF_PDM_InitFieldNoDefault( &m_cellFilterView, "VisibleCellView", "Filter by 3d View Visibility" );
CAF_PDM_InitFieldNoDefault( &m_defaultValueType, "DefaultValueType", "Default Value Type" );
CAF_PDM_InitField( &m_defaultValue, "DefaultValue", 0.0, "Default Value" );
}
//--------------------------------------------------------------------------------------------------
@@ -86,35 +72,11 @@ void RimGridCalculationVariable::defineUiOrdering( QString uiConfigName, caf::Pd
uiOrdering.add( &m_resultType );
uiOrdering.add( &m_resultVariable );
uiOrdering.add( &m_timeStep );
uiOrdering.add( &m_cellFilterView );
uiOrdering.add( &m_defaultValueType );
uiOrdering.add( &m_defaultValue );
uiOrdering.skipRemainingFields();
m_resultType.uiCapability()->setUiReadOnly( m_eclipseCase == nullptr );
m_timeStep.uiCapability()->setUiReadOnly( m_resultType == RiaDefines::ResultCatType::STATIC_NATIVE );
// Can have only one variable with cell filter at a time.
// Set read-only state based on the state of the sibling variables.
RimGridCalculation* calculation = nullptr;
firstAncestorOfType( calculation );
bool hasOtherVariableWithFilter = false;
for ( auto variable : calculation->allVariables() )
{
auto v = dynamic_cast<RimGridCalculationVariable*>( variable );
if ( variable != this && v->cellFilterView() )
{
hasOtherVariableWithFilter = true;
}
}
m_cellFilterView.uiCapability()->setUiReadOnly( m_eclipseCase == nullptr || hasOtherVariableWithFilter );
m_defaultValueType.uiCapability()->setUiReadOnly( m_cellFilterView == nullptr || hasOtherVariableWithFilter );
m_defaultValue.uiCapability()->setUiReadOnly(
m_cellFilterView == nullptr ||
defaultValueType() != RimGridCalculationVariable::DefaultValueType::USER_DEFINED || hasOtherVariableWithFilter );
}
//--------------------------------------------------------------------------------------------------
@@ -158,18 +120,6 @@ QList<caf::PdmOptionItemInfo>
RimTools::timeStepsForCase( m_eclipseCase(), &options );
}
else if ( fieldNeedingOptions == &m_cellFilterView )
{
if ( m_eclipseCase )
{
options.push_back( caf::PdmOptionItemInfo( "Disabled", nullptr ) );
for ( RimEclipseView* view : m_eclipseCase->reservoirViews.children() )
{
CVF_ASSERT( view && "Really always should have a valid view pointer in ReservoirViews" );
options.push_back( caf::PdmOptionItemInfo( view->name(), view, false, view->uiIconProvider() ) );
}
}
}
return options;
}
@@ -234,41 +184,6 @@ int RimGridCalculationVariable::allTimeStepsValue()
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridView* RimGridCalculationVariable::cellFilterView() const
{
return m_cellFilterView;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimGridCalculationVariable::defaultValue() const
{
return m_defaultValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationVariable::DefaultValueType RimGridCalculationVariable::defaultValueType() const
{
return m_defaultValueType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationVariable::DefaultValueConfig RimGridCalculationVariable::defaultValueConfiguration() const
{
if ( m_defaultValueType() == RimGridCalculationVariable::DefaultValueType::USER_DEFINED )
return std::make_pair( m_defaultValueType(), m_defaultValue() );
return std::make_pair( m_defaultValueType(), HUGE_VAL );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -292,5 +207,8 @@ void RimGridCalculationVariable::setEclipseResultAddress( const RimEclipseResult
m_resultVariable = address.resultName();
m_resultType = address.resultType();
m_eclipseCase = address.eclipseCase();
eclipseResultChanged.send();
updateConnectedEditors();
}

View File

@@ -25,10 +25,10 @@
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include "cafSignal.h"
class RimEclipseCase;
class RimEclipseResultAddress;
class RimGridView;
class RigCaseCellResultsData;
//==================================================================================================
@@ -40,27 +40,16 @@ class RimGridCalculationVariable : public RimUserDefinedCalculationVariable
CAF_PDM_HEADER_INIT;
public:
enum class DefaultValueType
{
POSITIVE_INFINITY,
FROM_PROPERTY,
USER_DEFINED
};
RimGridCalculationVariable();
caf::Signal<> eclipseResultChanged;
QString displayString() const override;
RimEclipseCase* eclipseCase() const;
RiaDefines::ResultCatType resultCategoryType() const;
QString resultVariable() const;
int timeStep() const;
RimGridView* cellFilterView() const;
double defaultValue() const;
DefaultValueType defaultValueType() const;
using DefaultValueConfig = std::pair<RimGridCalculationVariable::DefaultValueType, double>;
DefaultValueConfig defaultValueConfiguration() const;
static int allTimeStepsValue();
@@ -81,7 +70,4 @@ private:
caf::PdmField<caf::AppEnum<RiaDefines::ResultCatType>> m_resultType;
caf::PdmField<QString> m_resultVariable;
caf::PdmField<int> m_timeStep;
caf::PdmPtrField<RimGridView*> m_cellFilterView;
caf::PdmField<caf::AppEnum<DefaultValueType>> m_defaultValueType;
caf::PdmField<double> m_defaultValue;
};

View File

@@ -54,7 +54,7 @@ RimSummaryCalculation::RimSummaryCalculation()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculationVariable* RimSummaryCalculation::createVariable() const
RimSummaryCalculationVariable* RimSummaryCalculation::createVariable()
{
return new RimSummaryCalculationVariable;
}

View File

@@ -37,5 +37,5 @@ public:
void removeDependentObjects() override;
protected:
RimSummaryCalculationVariable* createVariable() const override;
RimSummaryCalculationVariable* createVariable() override;
};

View File

@@ -298,6 +298,16 @@ void RimUserDefinedCalculation::fieldChangedByUi( const caf::PdmFieldHandle* cha
PdmObject::fieldChangedByUi( changedField, oldValue, newValue );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_description );
uiOrdering.add( &m_expression );
uiOrdering.add( &m_unit );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -69,9 +69,10 @@ public:
void attachToWidget();
protected:
virtual RimUserDefinedCalculationVariable* createVariable() const = 0;
virtual RimUserDefinedCalculationVariable* createVariable() = 0;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,

View File

@@ -120,7 +120,7 @@ bool RigGridManager::isGridDimensionsEqual( const std::vector<std::vector<int>>&
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigGridManager::isMainGridDimensionsEqual( RigMainGrid* gridA, RigMainGrid* gridB )
bool RigGridManager::isMainGridDimensionsEqual( const RigMainGrid* gridA, const RigMainGrid* gridB )
{
if ( gridA == nullptr || gridB == nullptr ) return false;

View File

@@ -38,7 +38,7 @@ public:
void clear();
static bool isEqual( RigMainGrid* gridA, RigMainGrid* gridB );
static bool isMainGridDimensionsEqual( RigMainGrid* gridA, RigMainGrid* gridB );
static bool isMainGridDimensionsEqual( const RigMainGrid* gridA, const RigMainGrid* gridB );
static bool isGridDimensionsEqual( const std::vector<std::vector<int>>& mainCaseGridDimensions,
const std::vector<std::vector<int>>& caseGridDimensions );

View File

@@ -93,6 +93,7 @@
#include <QLayout>
#include <QMdiSubWindow>
#include <QMenuBar>
#include <QMimeData>
#include <QSpinBox>
#include <QStatusBar>
#include <QTimer>
@@ -139,6 +140,8 @@ RiuMainWindow::RiuMainWindow()
createToolBars();
createDockPanels();
setAcceptDrops( true );
if ( m_undoView )
{
m_undoView->setStack( caf::CmdExecCommandManager::instance()->undoStack() );
@@ -1988,3 +1991,36 @@ QStringList RiuMainWindow::windowsMenuFeatureNames()
{
return { "RicTileWindowsFeature", "RicTileWindowsVerticallyFeature", "RicTileWindowsHorizontallyFeature" };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMainWindow::dragEnterEvent( QDragEnterEvent* event )
{
if ( event->mimeData()->hasUrls() ) event->acceptProposedAction();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMainWindow::dropEvent( QDropEvent* event )
{
if ( !event ) return;
if ( !event->mimeData()->hasUrls() ) return;
for ( const auto& url : event->mimeData()->urls() )
{
QString fileName = url.toLocalFile();
QFileInfo fi( fileName );
if ( fi.exists() )
{
if ( RiaGuiApplication::instance()->openFile( fileName ) )
{
RiaGuiApplication::instance()->addToRecentFiles( fileName );
}
}
}
event->acceptProposedAction();
}

View File

@@ -138,6 +138,9 @@ protected:
QStringList defaultDockStateNames() override;
QStringList windowsMenuFeatureNames() override;
void dragEnterEvent( QDragEnterEvent* event ) override;
void dropEvent( QDropEvent* event ) override;
private:
void createActions();
void createMenus();

View File

@@ -220,13 +220,16 @@ QPointF RiuQwtCurvePointTracker::closestCurvePoint( const QPoint& cursorPosition
*valueAxisValueString = valueAxisScaleDraw->label( valueAxisSampleVal ).text();
}
auto additionalText = m_curveInfoTextProvider->additionalText( dynamic_cast<RiuPlotCurve*>( closestCurve ),
closestPointSampleIndex );
if ( !additionalText.isEmpty() )
if ( m_curveInfoTextProvider )
{
*valueAxisValueString += "\n";
*valueAxisValueString += additionalText;
auto additionalText = m_curveInfoTextProvider->additionalText( dynamic_cast<RiuPlotCurve*>( closestCurve ),
closestPointSampleIndex );
if ( !additionalText.isEmpty() )
{
*valueAxisValueString += "\n";
*valueAxisValueString += additionalText;
}
}
}

View File

@@ -41,6 +41,7 @@
#include "RimIntersectionResultDefinition.h"
#include "RimRegularLegendConfig.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimViewLinker.h"
#include "RivExtrudedCurveIntersectionPartMgr.h"
@@ -287,17 +288,18 @@ QString RiuResultTextBuilder::gridResultDetails()
std::vector<std::unique_ptr<RimEclipseResultDefinition>> tmp;
QStringList additionalCellResultText;
resultDefinitions.push_back( m_eclResDef );
if ( m_eclipseView )
{
auto additionalResults = m_eclipseView->additionalResultsForResultInfo();
std::vector<RigEclipseResultAddress> resultAddresses = m_eclipseView->additionalResultsForResultInfo();
for ( const auto& resultName : additionalResults )
for ( const auto& result : resultAddresses )
{
auto myResDef = std::make_unique<RimEclipseResultDefinition>();
myResDef->setEclipseCase( m_eclResDef->eclipseCase() );
myResDef->simpleCopy( m_eclResDef );
myResDef->setFromEclipseResultAddress( resultName );
myResDef->setFromEclipseResultAddress( result );
myResDef->loadResult();
resultDefinitions.push_back( myResDef.get() );
@@ -305,7 +307,19 @@ QString RiuResultTextBuilder::gridResultDetails()
}
}
QString text = cellResultText( resultDefinitions );
const auto [hasMultipleCases, linkedViewText] = resultTextFromLinkedViews();
QString text = cellResultText( resultDefinitions, hasMultipleCases );
for ( const auto& txt : additionalCellResultText )
{
text += "\n" + txt;
}
for ( const auto& txt : linkedViewText )
{
text += "\n" + txt;
}
if ( !text.isEmpty() )
{
text.prepend( "-- Grid cell result details --\n" );
@@ -740,6 +754,44 @@ void RiuResultTextBuilder::appendTextFromResultColors( RigEclipseCaseData*
resultInfoText->append( cellResultText( { resultColors } ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<bool, QStringList> RiuResultTextBuilder::resultTextFromLinkedViews() const
{
if ( !m_eclipseView || !m_eclipseView->assosiatedViewLinker() ) return {};
QStringList additionalCellResultText;
bool hasMultipleCases = false;
RimEclipseCase* primaryEclipseCase = m_eclipseView->eclipseCase();
auto views = m_eclipseView->assosiatedViewLinker()->allViews();
for ( auto view : views )
{
auto eclView = dynamic_cast<RimEclipseView*>( view );
if ( !eclView || eclView == m_eclipseView ) continue;
// Match on IJK size, as the cell index is used to identify the grid cell to extract the result from
auto otherEclipseCase = eclView->eclipseCase();
if ( !primaryEclipseCase->isGridSizeEqualTo( otherEclipseCase ) ) continue;
RiuResultTextBuilder textBuilder( eclView, eclView->cellResult(), m_cellIndex, m_timeStepIndex );
auto text = textBuilder.gridResultText();
if ( primaryEclipseCase != otherEclipseCase )
{
hasMultipleCases = true;
auto caseName = otherEclipseCase->caseUserDescription();
text += "( " + caseName + " )";
}
additionalCellResultText.push_back( text );
}
return { hasMultipleCases, additionalCellResultText };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -895,7 +947,8 @@ void RiuResultTextBuilder::appendDetails( QString& text, const QString& details
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuResultTextBuilder::cellResultText( const std::vector<RimEclipseResultDefinition*>& resultDefinitions )
QString RiuResultTextBuilder::cellResultText( const std::vector<RimEclipseResultDefinition*>& resultDefinitions,
bool appendCaseName )
{
std::map<QString, QString> keyValues;
@@ -915,6 +968,12 @@ QString RiuResultTextBuilder::cellResultText( const std::vector<RimEclipseResult
{
if ( !text.isEmpty() ) text += "\n";
text += QString( "%1 : %2" ).arg( key, -maxKeyLength ).arg( value );
if ( appendCaseName && m_eclipseView && m_eclipseView->eclipseCase() )
{
auto caseName = m_eclipseView->eclipseCase()->caseUserDescription();
text += "( " + caseName + " )";
}
}
return text;
@@ -1070,7 +1129,8 @@ QString RiuResultTextBuilder::wellResultText()
wellResultFrame->findResultCellWellHeadIncluded( m_gridIndex, m_cellIndex );
if ( wellResultCell )
{
text += QString( "-- Well-cell connection info --\n Well Name: %1\n Branch Id: %2\n Segment Id: %3\n" )
text += QString( "-- Well-cell connection info --\n Well Name: %1\n Branch Id: %2\n Segment "
"Id: %3\n" )
.arg( singleWellResultData->m_wellName )
.arg( wellResultCell->m_ertBranchId )
.arg( wellResultCell->m_ertSegmentId );

View File

@@ -78,7 +78,7 @@ private:
QString nncResultText();
QString wellResultText();
QString cellResultText( const std::vector<RimEclipseResultDefinition*>& resultDefinitions );
QString cellResultText( const std::vector<RimEclipseResultDefinition*>& resultDefinitions, bool appendCaseName = false );
std::map<QString, QString> cellResultTextAndValueText( RimEclipseResultDefinition* resultDefinition );
void appendTextFromResultColors( RigEclipseCaseData* eclipseCase,
@@ -88,6 +88,8 @@ private:
RimEclipseResultDefinition* resultColors,
QString* resultInfoText );
std::pair<bool, QStringList> resultTextFromLinkedViews() const;
private:
caf::PdmPointer<RimGridView> m_displayCoordView;
caf::PdmPointer<RimEclipseView> m_eclipseView;