mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 13:47:12 -05:00
152 lines
6.4 KiB
C++
152 lines
6.4 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 "RiaDefines.h"
|
|
#include "RiaResultNames.h"
|
|
#include "RiaTestDataDirectory.h"
|
|
|
|
#include "RifReaderEclipseOutput.h"
|
|
|
|
#include "RimEclipseResultCase.h"
|
|
|
|
#include "RigActiveCellInfo.h"
|
|
#include "RigCaseCellResultsData.h"
|
|
#include "RigEclipseCaseData.h"
|
|
#include "RigEclipseResultAddress.h"
|
|
|
|
#include <QDir>
|
|
#include <QFile>
|
|
|
|
#include <memory>
|
|
|
|
namespace
|
|
{
|
|
struct LoadedCase
|
|
{
|
|
std::unique_ptr<RimEclipseResultCase> resultCase;
|
|
cvf::ref<RigEclipseCaseData> eclipseCase;
|
|
};
|
|
|
|
LoadedCase loadBruggeCase()
|
|
{
|
|
QDir baseFolder( TEST_MODEL_DIR );
|
|
bool subFolderExists = baseFolder.cd( "Case_with_10_timesteps/Real0" );
|
|
EXPECT_TRUE( subFolderExists ) << "Could not find test model directory";
|
|
|
|
QString filePath = baseFolder.absoluteFilePath( "BRUGGE_0000.EGRID" );
|
|
EXPECT_TRUE( QFile::exists( filePath ) ) << "BRUGGE test model file does not exist: " << filePath.toStdString();
|
|
|
|
LoadedCase loaded;
|
|
loaded.resultCase.reset( new RimEclipseResultCase );
|
|
loaded.eclipseCase = new RigEclipseCaseData( loaded.resultCase.get() );
|
|
|
|
cvf::ref<RifReaderEclipseOutput> readerInterfaceEcl = new RifReaderEclipseOutput;
|
|
bool success = readerInterfaceEcl->open( filePath, loaded.eclipseCase.p() );
|
|
EXPECT_TRUE( success ) << "Could not load BRUGGE test model";
|
|
|
|
loaded.resultCase->setReservoirData( loaded.eclipseCase.p() );
|
|
|
|
return loaded;
|
|
}
|
|
|
|
void fillStaticResult( RigCaseCellResultsData* resultsData, const RigEclipseResultAddress& resultAddress, size_t valueCount, double value )
|
|
{
|
|
resultsData->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, resultAddress.resultName(), false, valueCount );
|
|
|
|
std::vector<double>* resultVector = resultsData->modifiableCellScalarResult( resultAddress, 0 );
|
|
ASSERT_NE( resultVector, nullptr );
|
|
ASSERT_EQ( resultVector->size(), valueCount );
|
|
|
|
std::fill( resultVector->begin(), resultVector->end(), value );
|
|
}
|
|
} // namespace
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Verify MOBILE_PORE_VOLUME handles SWCR size mismatch safely
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigMobilePoreVolumeResultCalculatorTest, MobilePvIgnoresMismatchedSwcrSize )
|
|
{
|
|
LoadedCase caseData = loadBruggeCase();
|
|
|
|
RigCaseCellResultsData* resultsData = caseData.eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
|
ASSERT_NE( resultsData, nullptr );
|
|
ASSERT_NE( resultsData->activeCellInfo(), nullptr );
|
|
|
|
const size_t activeCellCount = resultsData->activeCellInfo()->reservoirActiveCellCount();
|
|
ASSERT_GT( activeCellCount, 10u );
|
|
|
|
const RigEclipseResultAddress porvAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::porv() );
|
|
fillStaticResult( resultsData, porvAddress, activeCellCount, 2.0 );
|
|
|
|
// Deliberately shorter than PORV to reproduce mismatch that previously crashed.
|
|
const RigEclipseResultAddress swcrAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "SWCR" );
|
|
fillStaticResult( resultsData, swcrAddress, activeCellCount / 4, 0.25 );
|
|
|
|
const RigEclipseResultAddress mobilePvAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::mobilePoreVolumeName() );
|
|
resultsData->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::mobilePoreVolumeName(), false, 0 );
|
|
|
|
ASSERT_TRUE( resultsData->ensureKnownResultLoaded( mobilePvAddress ) );
|
|
|
|
const auto& mobilePvValues = resultsData->cellScalarResults( mobilePvAddress, 0 );
|
|
ASSERT_EQ( mobilePvValues.size(), activeCellCount );
|
|
|
|
// SWCR must be ignored on size mismatch, so fallback should copy PORV values.
|
|
for ( double value : mobilePvValues )
|
|
{
|
|
EXPECT_DOUBLE_EQ( value, 2.0 );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Verify MOBILE_PORE_VOLUME handles MULTPV size mismatch safely
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigMobilePoreVolumeResultCalculatorTest, MobilePvIgnoresMismatchedMultpvSize )
|
|
{
|
|
LoadedCase caseData = loadBruggeCase();
|
|
|
|
RigCaseCellResultsData* resultsData = caseData.eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
|
ASSERT_NE( resultsData, nullptr );
|
|
ASSERT_NE( resultsData->activeCellInfo(), nullptr );
|
|
|
|
const size_t activeCellCount = resultsData->activeCellInfo()->reservoirActiveCellCount();
|
|
ASSERT_GT( activeCellCount, 10u );
|
|
|
|
const RigEclipseResultAddress porvAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::porv() );
|
|
fillStaticResult( resultsData, porvAddress, activeCellCount, 3.0 );
|
|
|
|
// Deliberately shorter than PORV to reproduce mismatch that previously crashed.
|
|
const RigEclipseResultAddress multpvAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTPV" );
|
|
fillStaticResult( resultsData, multpvAddress, activeCellCount / 5, 0.5 );
|
|
|
|
const RigEclipseResultAddress mobilePvAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::mobilePoreVolumeName() );
|
|
resultsData->addStaticScalarResult( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::mobilePoreVolumeName(), false, 0 );
|
|
|
|
ASSERT_TRUE( resultsData->ensureKnownResultLoaded( mobilePvAddress ) );
|
|
|
|
const auto& mobilePvValues = resultsData->cellScalarResults( mobilePvAddress, 0 );
|
|
ASSERT_EQ( mobilePvValues.size(), activeCellCount );
|
|
|
|
// MULTPV must be ignored on size mismatch, so fallback should copy PORV values.
|
|
for ( double value : mobilePvValues )
|
|
{
|
|
EXPECT_DOUBLE_EQ( value, 3.0 );
|
|
}
|
|
}
|