#13606 Summary Calculator: Add support for block vectors

This commit is contained in:
Kristian Bendiksen
2026-02-18 17:38:45 +01:00
committed by Magne Sjaastad
parent 8e4000590c
commit c156d5d23c
5 changed files with 282 additions and 3 deletions
@@ -150,6 +150,7 @@ bool RimDataSourceSteppingTools::updateAddressIfMatching( const QVariant&
}
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK ||
category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK_LGR ||
category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL_CONNECTION )
{
std::string oldString = oldValue.toString().toStdString();
@@ -262,7 +262,8 @@ void RimSummaryCalculation::substituteVariables( std::vector<SummaryCalculationV
isHandledBySteppingTools = true;
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL_CONNECTION ||
category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK )
category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK ||
category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK_LGR )
{
oldValue = QString::fromStdString( firstVariable.summaryAddress.blockAsString() );
newValue = QString::fromStdString( address.blockAsString() );
@@ -641,6 +642,55 @@ std::vector<RimSummaryCalculationAddress>
}
}
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK )
{
std::set<std::array<int, 3>> uniqueBlocks;
std::for_each( allResultAddresses.begin(),
allResultAddresses.end(),
[&]( const auto& addr )
{
if ( addr.category() == SummaryCategory::SUMMARY_BLOCK )
{
uniqueBlocks.insert( { addr.cellI(), addr.cellJ(), addr.cellK() } );
}
} );
for ( auto block : uniqueBlocks )
{
addresses.push_back(
RimSummaryCalculationAddress( RifEclipseSummaryAddress::blockAddress( name, block[0], block[1], block[2], m_id ) ) );
}
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK_LGR )
{
std::set<std::string> uniqueLgrNames;
std::for_each( allResultAddresses.begin(),
allResultAddresses.end(),
[&]( const auto& addr )
{
if ( addr.category() == SummaryCategory::SUMMARY_BLOCK_LGR ) uniqueLgrNames.insert( addr.lgrName() );
} );
for ( auto lgrName : uniqueLgrNames )
{
std::set<std::array<int, 3>> uniqueBlocks;
std::for_each( allResultAddresses.begin(),
allResultAddresses.end(),
[&]( const auto& addr )
{
if ( addr.category() == SummaryCategory::SUMMARY_BLOCK_LGR && addr.lgrName() == lgrName )
{
uniqueBlocks.insert( { addr.cellI(), addr.cellJ(), addr.cellK() } );
}
} );
for ( auto block : uniqueBlocks )
{
addresses.push_back( RimSummaryCalculationAddress(
RifEclipseSummaryAddress::blockLgrAddress( name, lgrName, block[0], block[1], block[2], m_id ) ) );
}
}
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_IMPORTED )
{
addresses.push_back( RimSummaryCalculationAddress( RifEclipseSummaryAddress::importedAddress( name, m_id ) ) );
@@ -697,6 +747,14 @@ RimSummaryCalculationAddress RimSummaryCalculation::singleAddressesForCategory(
{
return RifEclipseSummaryAddress::wellConnectionAddress( name, address.wellName(), address.cellI(), address.cellJ(), address.cellK(), m_id );
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK )
{
return RifEclipseSummaryAddress::blockAddress( name, address.cellI(), address.cellJ(), address.cellK(), m_id );
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK_LGR )
{
return RifEclipseSummaryAddress::blockLgrAddress( name, address.lgrName(), address.cellI(), address.cellJ(), address.cellK(), m_id );
}
else if ( category == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_IMPORTED )
{
return RifEclipseSummaryAddress::importedAddress( name, m_id );
@@ -72,6 +72,8 @@ public:
bool isDistributeToOtherItems() const;
bool isDistributeToAllCases() const;
static void substituteVariables( std::vector<SummaryCalculationVariable>& vars, const RifEclipseSummaryAddress& address );
protected:
RimSummaryCalculationVariable* createVariable() override;
@@ -83,8 +85,6 @@ protected:
std::optional<std::pair<std::vector<double>, std::vector<time_t>>> calculateWithSubstitutions( RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& addr );
static void substituteVariables( std::vector<SummaryCalculationVariable>& vars, const RifEclipseSummaryAddress& address );
std::vector<RimSummaryCalculationAddress> allAddressesForCategory( RifEclipseSummaryAddressDefines::SummaryCategory category,
const std::set<RifEclipseSummaryAddress>& allResultAddresses ) const;
@@ -128,6 +128,7 @@ set(SOURCE_UNITTEST_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryAddressCollectionTools-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RimMockSummaryCase.h
${CMAKE_CURRENT_LIST_DIR}/RimMockSummaryCase-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculation-Test.cpp
)
if(RESINSIGHT_ENABLE_GRPC)
@@ -0,0 +1,219 @@
#include "gtest/gtest.h"
#include "RifEclipseSummaryAddress.h"
#include "RifEclipseSummaryAddressDefines.h"
#include "RimSummaryCalculation.h"
using SummaryCategory = RifEclipseSummaryAddressDefines::SummaryCategory;
//--------------------------------------------------------------------------------------------------
/// Test subclass that exposes protected methods for unit testing
//--------------------------------------------------------------------------------------------------
class RimSummaryCalculationTester : public RimSummaryCalculation
{
public:
RimSummaryCalculationTester()
{
setExpression( "CALC := a + b" );
setId( 42 );
}
std::vector<RimSummaryCalculationAddress> testAllAddressesForCategory( SummaryCategory category,
const std::set<RifEclipseSummaryAddress>& allResultAddresses ) const
{
return allAddressesForCategory( category, allResultAddresses );
}
RimSummaryCalculationAddress testSingleAddressesForCategory( const RifEclipseSummaryAddress& address ) const
{
return singleAddressesForCategory( address );
}
};
//--------------------------------------------------------------------------------------------------
// allAddressesForCategory - SUMMARY_BLOCK
//--------------------------------------------------------------------------------------------------
TEST( RimSummaryCalculation, Block_UniqueBlocks )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
addresses.insert( RifEclipseSummaryAddress::blockAddress( "BPR", 1, 2, 3 ) );
addresses.insert( RifEclipseSummaryAddress::blockAddress( "BPR", 1, 2, 3 ) ); // duplicate
addresses.insert( RifEclipseSummaryAddress::blockAddress( "BPR", 4, 5, 6 ) );
addresses.insert( RifEclipseSummaryAddress::blockAddress( "BPR", 7, 8, 9 ) );
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK, addresses );
EXPECT_EQ( 3u, result.size() );
}
TEST( RimSummaryCalculation, Block_EmptyInput )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK, addresses );
EXPECT_TRUE( result.empty() );
}
TEST( RimSummaryCalculation, Block_IgnoresOtherCategories )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
addresses.insert( RifEclipseSummaryAddress::wellAddress( "WOPR", "W1" ) );
addresses.insert( RifEclipseSummaryAddress::wellAddress( "WOPR", "W2" ) );
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK, addresses );
EXPECT_TRUE( result.empty() );
}
TEST( RimSummaryCalculation, Block_SingleBlock )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
addresses.insert( RifEclipseSummaryAddress::blockAddress( "BPR", 10, 20, 30 ) );
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK, addresses );
ASSERT_EQ( 1u, result.size() );
EXPECT_EQ( 10, result[0].address().cellI() );
EXPECT_EQ( 20, result[0].address().cellJ() );
EXPECT_EQ( 30, result[0].address().cellK() );
EXPECT_EQ( "CALC", result[0].address().vectorName() );
EXPECT_EQ( 42, result[0].address().id() );
}
//--------------------------------------------------------------------------------------------------
// allAddressesForCategory - SUMMARY_BLOCK_LGR
//--------------------------------------------------------------------------------------------------
TEST( RimSummaryCalculation, BlockLgr_MultiLgrMultiBlock )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 1, 1, 1 ) );
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 2, 2, 2 ) );
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR2", 3, 3, 3 ) );
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR2", 4, 4, 4 ) );
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK_LGR, addresses );
EXPECT_EQ( 4u, result.size() );
}
TEST( RimSummaryCalculation, BlockLgr_DeduplicatesWithinLgr )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 1, 1, 1 ) );
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 1, 1, 1 ) ); // duplicate
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 2, 2, 2 ) );
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK_LGR, addresses );
EXPECT_EQ( 2u, result.size() );
}
TEST( RimSummaryCalculation, BlockLgr_IgnoresOtherCategories )
{
RimSummaryCalculationTester calc;
std::set<RifEclipseSummaryAddress> addresses;
addresses.insert( RifEclipseSummaryAddress::blockAddress( "BPR", 1, 2, 3 ) );
addresses.insert( RifEclipseSummaryAddress::wellAddress( "WOPR", "W1" ) );
addresses.insert( RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 5, 6, 7 ) );
auto result = calc.testAllAddressesForCategory( SummaryCategory::SUMMARY_BLOCK_LGR, addresses );
ASSERT_EQ( 1u, result.size() );
EXPECT_EQ( "LGR1", result[0].address().lgrName() );
EXPECT_EQ( 5, result[0].address().cellI() );
EXPECT_EQ( 6, result[0].address().cellJ() );
EXPECT_EQ( 7, result[0].address().cellK() );
}
//--------------------------------------------------------------------------------------------------
// singleAddressesForCategory
//--------------------------------------------------------------------------------------------------
TEST( RimSummaryCalculation, SingleAddress_Block )
{
RimSummaryCalculationTester calc;
auto input = RifEclipseSummaryAddress::blockAddress( "BPR", 10, 20, 30 );
auto result = calc.testSingleAddressesForCategory( input );
EXPECT_EQ( "CALC", result.address().vectorName() );
EXPECT_EQ( 42, result.address().id() );
EXPECT_EQ( 10, result.address().cellI() );
EXPECT_EQ( 20, result.address().cellJ() );
EXPECT_EQ( 30, result.address().cellK() );
EXPECT_EQ( SummaryCategory::SUMMARY_BLOCK, result.address().category() );
}
TEST( RimSummaryCalculation, SingleAddress_BlockLgr )
{
RimSummaryCalculationTester calc;
auto input = RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 5, 6, 7 );
auto result = calc.testSingleAddressesForCategory( input );
EXPECT_EQ( "CALC", result.address().vectorName() );
EXPECT_EQ( 42, result.address().id() );
EXPECT_EQ( "LGR1", result.address().lgrName() );
EXPECT_EQ( 5, result.address().cellI() );
EXPECT_EQ( 6, result.address().cellJ() );
EXPECT_EQ( 7, result.address().cellK() );
EXPECT_EQ( SummaryCategory::SUMMARY_BLOCK_LGR, result.address().category() );
}
//--------------------------------------------------------------------------------------------------
// substituteVariables
//--------------------------------------------------------------------------------------------------
TEST( RimSummaryCalculation, SubstituteVariables_Block )
{
// Set up variables with a SUMMARY_BLOCK address at (1,2,3)
SummaryCalculationVariable var;
var.name = "a";
var.summaryCase = nullptr;
var.summaryAddress = RifEclipseSummaryAddress::blockAddress( "BPR", 1, 2, 3 );
std::vector<SummaryCalculationVariable> vars = { var };
// Substitute to (10,20,30)
auto newAddress = RifEclipseSummaryAddress::blockAddress( "BPR", 10, 20, 30 );
RimSummaryCalculation::substituteVariables( vars, newAddress );
EXPECT_EQ( 10, vars[0].summaryAddress.cellI() );
EXPECT_EQ( 20, vars[0].summaryAddress.cellJ() );
EXPECT_EQ( 30, vars[0].summaryAddress.cellK() );
}
TEST( RimSummaryCalculation, SubstituteVariables_BlockLgr )
{
// Set up variables with a SUMMARY_BLOCK_LGR address
SummaryCalculationVariable var;
var.name = "a";
var.summaryCase = nullptr;
var.summaryAddress = RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 1, 2, 3 );
std::vector<SummaryCalculationVariable> vars = { var };
// Substitute to new block coordinates - validates the SUMMARY_BLOCK_LGR bug fix
auto newAddress = RifEclipseSummaryAddress::blockLgrAddress( "LBPR", "LGR1", 10, 20, 30 );
RimSummaryCalculation::substituteVariables( vars, newAddress );
EXPECT_EQ( 10, vars[0].summaryAddress.cellI() );
EXPECT_EQ( 20, vars[0].summaryAddress.cellJ() );
EXPECT_EQ( 30, vars[0].summaryAddress.cellK() );
}