diff --git a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp index f356046d2c..7dcbd5e3dd 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp @@ -60,12 +60,12 @@ #include "cafProgressInfo.h" #include "cafSelectionManager.h" -#include "opm/common/OpmLog/KeywordLocation.hpp" #include "opm/input/eclipse/Deck/DeckItem.hpp" #include "opm/input/eclipse/Deck/DeckKeyword.hpp" #include "opm/input/eclipse/Deck/DeckRecord.hpp" #include "opm/input/eclipse/Parser/ParserKeyword.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/C.hpp" +#include "opm/input/eclipse/Parser/ParserKeywords/O.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/S.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" #include "opm/input/eclipse/Utility/Typetools.hpp" @@ -328,9 +328,9 @@ std::expected RicExportEclipseSectorModelFeature::exportSimulatio else if ( exportSettings.m_boundaryCondition() == RicExportEclipseSectorModelUi::BoundaryCondition::OPERNUM_OPERATER ) { // Generate OPERNUM result based on BORDNUM (border cells get max existing OPERNUM + 1) - RigEclipseResultTools::generateOperNumResult( &eclipseCase ); + int operNumRegion = RigEclipseResultTools::generateOperNumResult( &eclipseCase ); - if ( auto result = addOperNumRegionAndOperater( &eclipseCase, exportSettings, deckFile ); !result ) + if ( auto result = addOperNumRegionAndOperater( &eclipseCase, exportSettings, deckFile, operNumRegion ); !result ) { return result; } @@ -1180,12 +1180,11 @@ std::expected RicExportEclipseSectorModelFeature::filterAndUpdate //-------------------------------------------------------------------------------------------------- std::expected RicExportEclipseSectorModelFeature::addOperNumRegionAndOperater( RimEclipseCase* eclipseCase, const RicExportEclipseSectorModelUi& exportSettings, - RifOpmFlowDeckFile& deckFile ) + RifOpmFlowDeckFile& deckFile, + int operNumRegion ) { // Update REGDIMS and add OPERATER keyword for OPERNUM regions // Get the OPERNUM region number that was assigned to border cells - int maxOperNum = RigEclipseResultTools::findMaxOperNumValue( eclipseCase ); - int operNumRegion = maxOperNum + 1; // Border cells use this region number RiaLogging::info( QString( "Using OPERNUM region %1 for border cells" ).arg( operNumRegion ) ); @@ -1227,12 +1226,35 @@ std::expected RicExportEclipseSectorModelFeature::addOperNumRegio auto opernumKeyword = deckFile.findKeyword( "OPERNUM" ); if ( !opernumKeyword.has_value() ) { - // Add INCLUDE for OPERNUM.GRDECL in REGIONS section - if ( !deckFile.addIncludeKeyword( "REGIONS", "OPERNUM", "OPERNUM.GRDECL" ) ) + auto keywords = deckFile.keywords( false ); + if ( std::find( keywords.begin(), keywords.end(), "OPERNUM" ) == keywords.end() ) { - return std::unexpected( "Failed to add INCLUDE for OPERNUM in REGIONS section" ); + Opm::DeckKeyword newKw( ( Opm::ParserKeywords::OPERNUM() ) ); + deckFile.addKeyword( "GRID", newKw ); + } + + // Try to extract keyword data + auto result = RifEclipseInputFileTools::extractKeywordData( eclipseCase->eclipseCaseData(), + "OPERNUM", + exportSettings.min(), + exportSettings.max(), + exportSettings.refinement() ); + if ( result ) + { + // Replace keyword values in deck with extracted data + if ( deckFile.replaceKeywordData( "OPERNUM", result.value() ) ) + { + RiaLogging::info( "Added replaced opernum value in exising position." ); + } + else + { + return std::unexpected( "Unable to replace OPERNUM values" ); + } + } + else + { + return std::unexpected( "No OPERNUM result found." ); } - RiaLogging::info( "Added INCLUDE 'OPERNUM.GRDECL' to REGIONS section" ); } else { diff --git a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.h b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.h index 6ebe084551..7e5a290b24 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.h +++ b/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.h @@ -86,7 +86,8 @@ private: static std::expected addOperNumRegionAndOperater( RimEclipseCase* eclipseCase, const RicExportEclipseSectorModelUi& exportSettings, - RifOpmFlowDeckFile& deckFile ); + RifOpmFlowDeckFile& deckFile, + int operNumRegion ); static std::vector findIntersectingWells( RimEclipseCase* eclipseCase, const cvf::Vec3st& min, const cvf::Vec3st& max ); diff --git a/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.cpp b/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.cpp index 36901c6c5b..1d81cc3b86 100644 --- a/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.cpp +++ b/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.cpp @@ -964,6 +964,24 @@ bool RifOpmFlowDeckFile::addIncludeKeyword( std::string section, std::string key return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifOpmFlowDeckFile::addKeyword( const std::string& section, const Opm::DeckKeyword& keyword ) +{ + if ( m_fileDeck.get() == nullptr ) return false; + + // Add keyword to specified section if it doesn't exist + auto insertPos = internal::findSectionInsertionPoint( m_fileDeck, section ); + if ( !insertPos.has_value() ) + { + return false; // Section not found + } + + m_fileDeck->insert( insertPos.value(), keyword ); + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.h b/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.h index d9677a90dc..778eb5b5ab 100644 --- a/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.h +++ b/ApplicationLibCode/FileInterface/RifOpmFlowDeckFile.h @@ -87,6 +87,8 @@ public: bool addIncludeKeyword( std::string section, std::string keyword, std::string filePath ); + bool addKeyword( const std::string& section, const Opm::DeckKeyword& keyword ); + bool replaceKeywordData( const std::string& keyword, const std::vector& data ); bool replaceKeywordData( const std::string& keyword, const std::vector& data ); diff --git a/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp b/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp index ef91d07782..3b945175e0 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigEclipseResultTools.cpp @@ -204,6 +204,10 @@ int generateOperNumResult( RimEclipseCase* eclipseCase, int borderCellValue ) result[i] = static_cast( existingValues[i] ); } } + else + { + borderCellValue = 2; + } // Check if BORDNUM exists to modify border cells RigEclipseResultAddress bordNumAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::INTEGER, RiaResultNames::bordnum() ); @@ -213,7 +217,7 @@ int generateOperNumResult( RimEclipseCase* eclipseCase, int borderCellValue ) auto bordNumValues = resultsData->cellScalarResults( bordNumAddr, 0 ); if ( !bordNumValues.empty() ) { - result.resize( bordNumValues.size(), 0 ); + result.resize( bordNumValues.size(), 1 ); for ( auto activeCellIdx : activeReservoirCellIdxs ) { diff --git a/ApplicationLibCode/UnitTests/RigEclipseCaseDataTools-Test.cpp b/ApplicationLibCode/UnitTests/RigEclipseCaseDataTools-Test.cpp index ed85ffa619..e03fa0d17f 100644 --- a/ApplicationLibCode/UnitTests/RigEclipseCaseDataTools-Test.cpp +++ b/ApplicationLibCode/UnitTests/RigEclipseCaseDataTools-Test.cpp @@ -572,20 +572,20 @@ TEST( RigEclipseCaseDataToolsTest, GenerateOperNumResultFromBorderResult ) if ( bordnumValue == RigEclipseResultTools::BorderType::BORDER_CELL ) { borderCellsTotal++; - ASSERT_EQ( opernumValue, 1 ) << "Border cells (BORDNUM=1) should have OPERNUM=1 at index " << i; + ASSERT_EQ( opernumValue, 2 ) << "Border cells (BORDNUM=1) should have OPERNUM=2 at index " << i; borderCellsWithOperValue++; } else { - ASSERT_EQ( opernumValue, 0 ) << "Non-border cells should have OPERNUM=0 at index " << i; + ASSERT_EQ( opernumValue, 1 ) << "Non-border cells should have OPERNUM=1 at index " << i; defaultOperCells++; } } // Verify we have the expected distribution ASSERT_GT( borderCellsTotal, 0 ) << "Should have border cells (BORDNUM=1)"; - ASSERT_EQ( borderCellsWithOperValue, borderCellsTotal ) << "All border cells should get OPERNUM=1"; - ASSERT_GT( defaultOperCells, 0 ) << "Should have non-border cells with OPERNUM=0"; + ASSERT_EQ( borderCellsWithOperValue, borderCellsTotal ) << "All border cells should get OPERNUM=2"; + ASSERT_GT( defaultOperCells, 0 ) << "Should have non-border cells with OPERNUM=1"; // Test case 2: Test automatic max value detection with existing OPERNUM // First create a custom OPERNUM result with some predefined values