Files
ResInsight/ApplicationLibCode/UnitTests/RigMswTableData-Test.cpp
T

301 lines
9.5 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2026 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "gtest/gtest.h"
#include "CompletionsMsw/RigMswTableData.h"
#include "CompletionsMsw/RigMswTableRows.h"
#include "RiaDefines.h"
namespace
{
constexpr auto METRIC = RiaDefines::EclipseUnitSystem::UNITS_METRIC;
WelsegsRow makeWelsegsRow( int segNum, int joinSeg = 1 )
{
WelsegsRow row;
row.segment1 = segNum;
row.segment2 = segNum;
row.branch = 1;
row.joinSegment = joinSeg;
row.length = 10.0;
row.depth = 5.0;
return row;
}
CompsegsRow makeCompsegsRow( size_t i, size_t j, size_t k, const std::string& gridName = "" )
{
CompsegsRow row;
row.i = i;
row.j = j;
row.k = k;
row.branch = 1;
row.distanceStart = 0.0;
row.distanceEnd = 10.0;
row.gridName = gridName;
return row;
}
} // anonymous namespace
//==================================================================================================
// isEmpty
//==================================================================================================
TEST( RigMswTableData, IsEmpty_NewObject )
{
RigMswTableData td( "Well_A", METRIC );
EXPECT_TRUE( td.isEmpty() );
}
TEST( RigMswTableData, IsEmpty_WithWelsegsRow )
{
RigMswTableData td( "Well_A", METRIC );
td.addWelsegsRow( makeWelsegsRow( 2 ) );
EXPECT_FALSE( td.isEmpty() );
}
TEST( RigMswTableData, IsEmpty_WithCompsegsRow )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1 ) );
EXPECT_FALSE( td.isEmpty() );
}
TEST( RigMswTableData, IsEmpty_WithWsegvalvRow )
{
RigMswTableData td( "Well_A", METRIC );
WsegvalvRow wv;
wv.well = "Well_A";
wv.segmentNumber = 2;
wv.cv = 0.5;
wv.area = 1e-4;
td.addWsegvalvRow( wv );
EXPECT_FALSE( td.isEmpty() );
}
TEST( RigMswTableData, IsEmpty_WithWsegaicdRow )
{
RigMswTableData td( "Well_A", METRIC );
WsegaicdRow aicd;
aicd.well = "Well_A";
aicd.segment1 = 2;
aicd.segment2 = 2;
aicd.strength = 1e-5;
aicd.maxAbsRate = 1000.0;
aicd.flowRateExponent = 0.9;
aicd.viscExponent = 0.1;
td.addWsegaicdRow( aicd );
EXPECT_FALSE( td.isEmpty() );
}
// isEmpty() does not check wsegsicdData — document that behaviour explicitly.
TEST( RigMswTableData, IsEmpty_WsegsicdOnlyIsConsideredEmpty )
{
RigMswTableData td( "Well_A", METRIC );
WsegsicdRow sicd;
sicd.well = "Well_A";
sicd.segment1 = 2;
sicd.segment2 = 2;
sicd.strength = 2e-5;
sicd.maxAbsRate = 500.0;
td.addWsegsicdRow( sicd );
// isEmpty() does not inspect wsegsicdData, so it returns true even though
// there is a WSEGSICD row present.
EXPECT_TRUE( td.isEmpty() );
EXPECT_FALSE( td.wsegsicdData().empty() ); // data IS there
}
//==================================================================================================
// hasLgrData / mainGridCompsegsData / lgrCompsegsData
//==================================================================================================
TEST( RigMswTableData, HasLgrData_NoCompsegs )
{
RigMswTableData td( "Well_A", METRIC );
EXPECT_FALSE( td.hasLgrData() );
}
TEST( RigMswTableData, HasLgrData_OnlyMainGrid )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1, "" ) );
td.addCompsegsRow( makeCompsegsRow( 2, 1, 1, "" ) );
EXPECT_FALSE( td.hasLgrData() );
}
TEST( RigMswTableData, HasLgrData_OneLgrRow )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1, "" ) );
td.addCompsegsRow( makeCompsegsRow( 2, 1, 1, "LGR1" ) );
EXPECT_TRUE( td.hasLgrData() );
}
TEST( RigMswTableData, HasLgrData_AllLgrRows )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1, "LGR1" ) );
td.addCompsegsRow( makeCompsegsRow( 2, 1, 1, "LGR2" ) );
EXPECT_TRUE( td.hasLgrData() );
}
TEST( RigMswTableData, MainGridCompsegsData_FiltersCorrectly )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1, "" ) );
td.addCompsegsRow( makeCompsegsRow( 2, 1, 1, "LGR1" ) );
td.addCompsegsRow( makeCompsegsRow( 3, 1, 1, "" ) );
auto mainRows = td.mainGridCompsegsData();
ASSERT_EQ( 2u, mainRows.size() );
EXPECT_EQ( 1u, mainRows[0].i );
EXPECT_EQ( 3u, mainRows[1].i );
for ( const auto& r : mainRows )
EXPECT_TRUE( r.isMainGrid() );
}
TEST( RigMswTableData, LgrCompsegsData_FiltersCorrectly )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1, "" ) );
td.addCompsegsRow( makeCompsegsRow( 2, 1, 1, "LGR1" ) );
td.addCompsegsRow( makeCompsegsRow( 3, 1, 1, "LGR2" ) );
auto lgrRows = td.lgrCompsegsData();
ASSERT_EQ( 2u, lgrRows.size() );
EXPECT_EQ( "LGR1", lgrRows[0].gridName );
EXPECT_EQ( "LGR2", lgrRows[1].gridName );
for ( const auto& r : lgrRows )
EXPECT_TRUE( r.isLgrGrid() );
}
TEST( RigMswTableData, MainGridAndLgrCompsegsData_NoOverlap )
{
RigMswTableData td( "Well_A", METRIC );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1, "" ) );
td.addCompsegsRow( makeCompsegsRow( 2, 1, 1, "LGR1" ) );
auto mainRows = td.mainGridCompsegsData();
auto lgrRows = td.lgrCompsegsData();
EXPECT_EQ( 1u, mainRows.size() );
EXPECT_EQ( 1u, lgrRows.size() );
EXPECT_EQ( mainRows.size() + lgrRows.size(), td.compsegsData().size() );
}
//==================================================================================================
// validationErrors / isValid
//==================================================================================================
TEST( RigMswTableData, ValidationErrors_EmptyWellName )
{
RigMswTableData td( "", METRIC );
td.addWelsegsRow( makeWelsegsRow( 2 ) );
auto errors = td.validationErrors();
EXPECT_FALSE( errors.empty() );
bool foundWellNameError = std::any_of( errors.begin(), errors.end(), []( const QString& e ) { return e.contains( "Well name" ); } );
EXPECT_TRUE( foundWellNameError );
EXPECT_FALSE( td.isValid() );
}
TEST( RigMswTableData, ValidationErrors_NoWelsegsRows )
{
RigMswTableData td( "Well_A", METRIC );
auto errors = td.validationErrors();
EXPECT_FALSE( errors.empty() );
bool foundWelsegsError = std::any_of( errors.begin(), errors.end(), []( const QString& e ) { return e.contains( "WELSEGS" ); } );
EXPECT_TRUE( foundWelsegsError );
EXPECT_FALSE( td.isValid() );
}
TEST( RigMswTableData, ValidationErrors_DuplicateSegmentNumber )
{
RigMswTableData td( "Well_A", METRIC );
td.addWelsegsRow( makeWelsegsRow( 2 ) );
td.addWelsegsRow( makeWelsegsRow( 3 ) );
td.addWelsegsRow( makeWelsegsRow( 2 ) ); // duplicate
auto errors = td.validationErrors();
EXPECT_FALSE( errors.empty() );
bool foundDuplicateError =
std::any_of( errors.begin(), errors.end(), []( const QString& e ) { return e.contains( "Duplicate" ) || e.contains( "2" ); } );
EXPECT_TRUE( foundDuplicateError );
EXPECT_FALSE( td.isValid() );
}
TEST( RigMswTableData, ValidationErrors_MultipleErrors )
{
// Empty well name AND no WELSEGS → two separate errors
RigMswTableData td( "", METRIC );
auto errors = td.validationErrors();
EXPECT_GE( errors.size(), 2u );
EXPECT_FALSE( td.isValid() );
}
TEST( RigMswTableData, IsValid_ValidData )
{
RigMswTableData td( "Well_A", METRIC );
td.addWelsegsRow( makeWelsegsRow( 2, 1 ) );
td.addWelsegsRow( makeWelsegsRow( 3, 2 ) );
EXPECT_TRUE( td.validationErrors().empty() );
EXPECT_TRUE( td.isValid() );
}
//==================================================================================================
// Metadata accessors
//==================================================================================================
TEST( RigMswTableData, WellNameAndUnitSystem )
{
RigMswTableData td( "MyWell", RiaDefines::EclipseUnitSystem::UNITS_FIELD );
EXPECT_EQ( "MyWell", td.wellName() );
EXPECT_EQ( RiaDefines::EclipseUnitSystem::UNITS_FIELD, td.unitSystem() );
}
TEST( RigMswTableData, HasWelsegsData_HasCompsegsData_HasValveData )
{
RigMswTableData td( "Well_A", METRIC );
EXPECT_FALSE( td.hasWelsegsData() );
EXPECT_FALSE( td.hasCompsegsData() );
EXPECT_FALSE( td.hasWsegvalvData() );
EXPECT_FALSE( td.hasWsegaicdData() );
EXPECT_FALSE( td.hasWsegsicdData() );
td.addWelsegsRow( makeWelsegsRow( 2 ) );
EXPECT_TRUE( td.hasWelsegsData() );
td.addCompsegsRow( makeCompsegsRow( 1, 1, 1 ) );
EXPECT_TRUE( td.hasCompsegsData() );
WsegvalvRow wv;
wv.well = "Well_A";
wv.segmentNumber = 2;
wv.cv = 0.5;
wv.area = 1e-4;
td.addWsegvalvRow( wv );
EXPECT_TRUE( td.hasWsegvalvData() );
}