diff --git a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp index b38fb7b706..b288fa0482 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp @@ -175,7 +175,8 @@ void RicExportEclipseSectorModelFeature::executeCommand( RimEclipseView* settings.setInputDeckFileName( dataFileName ); settings.setOutputDeckFileName( exportSettings.exportGridFilename() ); - if ( auto result = RigSimulationInputTool::exportSimulationInput( *view->eclipseCase(), settings ); !result ) + cvf::ref cellVisibility = createVisibilityBasedOnBoxSelection( view, exportSettings ); + if ( auto result = RigSimulationInputTool::exportSimulationInput( *view->eclipseCase(), settings, cellVisibility.p() ); !result ) { RiaLogging::error( QString( "Failed to export simulation input: %1" ).arg( result.error() ) ); } diff --git a/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.cpp b/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.cpp index bcd70c5249..bdf212cfce 100644 --- a/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.cpp +++ b/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.cpp @@ -20,6 +20,7 @@ #include "RiaLogging.h" +#include "RiaResultNames.h" #include "RigSimulationInputSettings.h" #include "RifEclipseInputFileTools.h" @@ -56,7 +57,8 @@ /// //-------------------------------------------------------------------------------------------------- std::expected RigSimulationInputTool::exportSimulationInput( RimEclipseCase& eclipseCase, - const RigSimulationInputSettings& settings ) + const RigSimulationInputSettings& settings, + cvf::UByteArray* visibility ) { // Load the deck file QString inputDeckFileName = settings.inputDeckFileName(); @@ -77,6 +79,27 @@ std::expected RigSimulationInputTool::exportSimulationInput( RimE return result; } + // Generate BORDNUM result based on visibility + if ( visibility && visibility->size() > 0 ) + { + RigEclipseResultTools::generateBorderResult( &eclipseCase, visibility, RiaResultNames::bordnum() ); + if ( settings.boundaryCondition() == RigSimulationInputSettings::BoundaryCondition::BCCON_BCPROP ) + { + // Generate BCCON result to assign values 1-6 based on which face of the box the border cells are on + RigEclipseResultTools::generateBcconResult( &eclipseCase, settings.min(), settings.max() ); + } + else if ( settings.boundaryCondition() == RigSimulationInputSettings::BoundaryCondition::OPERNUM_OPERATER ) + { + // Generate OPERNUM result based on BORDNUM (border cells get max existing OPERNUM + 1) + int operNumRegion = RigEclipseResultTools::generateOperNumResult( &eclipseCase ); + + if ( auto result = addOperNumRegionAndOperater( &eclipseCase, settings, deckFile, operNumRegion ); !result ) + { + return result; + } + } + } + if ( auto result = replaceKeywordValuesInDeckFile( &eclipseCase, settings, deckFile ); !result ) { return result; diff --git a/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.h b/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.h index 56f8e95595..86a38f2119 100644 --- a/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.h +++ b/ApplicationLibCode/ReservoirDataModel/SimulationFile/RigSimulationInputTool.h @@ -19,6 +19,7 @@ #pragma once #include "cafVecIjk.h" +#include "cvfArray.h" #include "cvfVector3.h" #include @@ -48,7 +49,7 @@ class RigSimulationInputTool { public: static std::expected - exportSimulationInput( RimEclipseCase& eclipseCase, const RigSimulationInputSettings& settings ); + exportSimulationInput( RimEclipseCase& eclipseCase, const RigSimulationInputSettings& settings, cvf::UByteArray* visibility ); static std::expected processEqualsRecord( const Opm::DeckRecord& record, const caf::VecIjk0& min, const caf::VecIjk0& max, const cvf::Vec3st& refinement ); diff --git a/ApplicationLibCode/UnitTests/RigSimulationInputTool-Test.cpp b/ApplicationLibCode/UnitTests/RigSimulationInputTool-Test.cpp index d6df02d79e..4c59cc3ba1 100644 --- a/ApplicationLibCode/UnitTests/RigSimulationInputTool-Test.cpp +++ b/ApplicationLibCode/UnitTests/RigSimulationInputTool-Test.cpp @@ -22,8 +22,10 @@ #include "RiaTestDataDirectory.h" #include "RifOpmDeckTools.h" +#include "RifOpmFlowDeckFile.h" #include "RifReaderEclipseOutput.h" #include "RigEclipseCaseData.h" +#include "RigEclipseCaseDataTools.h" #include "RigMainGrid.h" #include "RigSimulationInputSettings.h" #include "RimEclipseResultCase.h" @@ -268,27 +270,46 @@ TEST( RigSimulationInputTool, ExportModel5 ) settings.setInputDeckFileName( dataFilePath ); settings.setOutputDeckFileName( exportFilePath ); + // Create visibility from IJK bounds + cvf::ref visibility = + RigEclipseCaseDataTools::createVisibilityFromIjkBounds( caseData.p(), settings.min(), settings.max() ); + // Export simulation input resultCase->setReservoirData( caseData.p() ); - auto exportResult = RigSimulationInputTool::exportSimulationInput( *resultCase, settings ); + auto exportResult = RigSimulationInputTool::exportSimulationInput( *resultCase, settings, visibility.p() ); ASSERT_TRUE( exportResult.has_value() ) << "Export failed: " << exportResult.error().toStdString(); // Verify exported file exists ASSERT_TRUE( QFile::exists( exportFilePath ) ); - // Read the file content and verify key elements + // Load the exported deck file using RifOpmFlowDeckFile + RifOpmFlowDeckFile deckFile; + bool deckLoadResult = deckFile.loadDeck( exportFilePath.toStdString() ); + ASSERT_TRUE( deckLoadResult ) << "Failed to load exported deck file"; + + // Get all keywords from the deck + std::vector allKeywords = deckFile.keywords( false ); + + // Verify key keywords exist in the file + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "DIMENS" ) != allKeywords.end() ); + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "SPECGRID" ) != allKeywords.end() ) + << "SPECGRID keyword missing from exported file"; + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "COORD" ) != allKeywords.end() ); + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "ZCORN" ) != allKeywords.end() ); + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "ACTNUM" ) != allKeywords.end() ); + + // Verify OPERNUM and OPERATER keywords exist (for boundary conditions with default OPERNUM_OPERATER) + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "OPERNUM" ) != allKeywords.end() ) + << "OPERNUM keyword missing from exported file"; + EXPECT_TRUE( std::find( allKeywords.begin(), allKeywords.end(), "OPERATER" ) != allKeywords.end() ) + << "OPERATER keyword missing from exported file"; + + // Read the file content to verify dimensions QFile file( exportFilePath ); ASSERT_TRUE( file.open( QIODevice::ReadOnly | QIODevice::Text ) ); QString fileContent = file.readAll(); file.close(); - // Verify key keywords exist in the file - EXPECT_TRUE( fileContent.contains( "DIMENS" ) ); - EXPECT_TRUE( fileContent.contains( "SPECGRID" ) ) << "SPECGRID keyword missing from exported file"; - EXPECT_TRUE( fileContent.contains( "COORD" ) ); - EXPECT_TRUE( fileContent.contains( "ZCORN" ) ); - EXPECT_TRUE( fileContent.contains( "ACTNUM" ) ); - // Verify dimensions are correct for the sector (20x15x10) // Max is (19,14,9) which means 20 cells in I, 15 cells in J, 10 cells in K EXPECT_TRUE( fileContent.contains( " 20 15 10 /" ) ) << "File does not contain expected sector dimensions 20 15 10";