diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswTableDataTools.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswTableDataTools.cpp index 97a65824e3..6799c842ee 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswTableDataTools.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswTableDataTools.cpp @@ -53,7 +53,7 @@ void RicMswTableDataTools::collectWelsegsData( RigMswTableData& tableData, { header.wellboreVolume = exportInfo.topWellBoreVolume(); } - header.flowModel = exportInfo.lengthAndDepthText().toStdString(); + header.infoType = exportInfo.lengthAndDepthText().toStdString(); header.pressureComponents = exportInfo.pressureDropText().toStdString(); tableData.setWelsegsHeader( header ); diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswTableData.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswTableData.cpp index 54d45e69bb..e51b45146f 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswTableData.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswTableData.cpp @@ -2305,7 +2305,7 @@ RigMswUnifiedDataWIP RicWellPathExportMswTableData::extractUnifiedMswData( const std::expected RicWellPathExportMswTableData::extractSingleWellMswData( RimEclipseCase* eclipseCase, RimWellPath* wellPath, int timeStep ) { - if ( !eclipseCase || !wellPath ) + if ( !eclipseCase || !wellPath || eclipseCase->eclipseCaseData() == nullptr ) { return std::unexpected( "Invalid eclipse case or well path provided for MSW data extraction" ); } diff --git a/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.cpp b/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.cpp index 4744baa703..ae1be9d15e 100644 --- a/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.cpp +++ b/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.cpp @@ -560,6 +560,18 @@ RifTextDataTableFormatter& RifTextDataTableFormatter::addOptionalValue( const st return add( m_defaultMarker ); } +//-------------------------------------------------------------------------------------------------- +/// Add optional value or default marker if the optional is empty +//-------------------------------------------------------------------------------------------------- +RifTextDataTableFormatter& RifTextDataTableFormatter::addOptionalStdString( const std::optional& value ) +{ + if ( value.has_value() ) + { + return addStdString( value.value() ); + } + return add( m_defaultMarker ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.h b/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.h index 31780970df..c9ab767a3c 100644 --- a/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.h +++ b/ApplicationLibCode/FileInterface/RifTextDataTableFormatter.h @@ -176,6 +176,7 @@ public: RifTextDataTableFormatter& addOneBasedCellIndex( size_t zeroBasedIndex ); RifTextDataTableFormatter& addValueOrDefaultMarker( double value, double defaultValue ); RifTextDataTableFormatter& addOptionalValue( const std::optional& value ); + RifTextDataTableFormatter& addOptionalStdString( const std::optional& value ); RifTextDataTableFormatter& comment( const QString& str ); RifTextDataTableFormatter& addOptionalComment( const QString& str ); RifTextDataTableFormatter& addHorizontalLine( const QChar& str ); diff --git a/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.cpp b/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.cpp index 378bea7b2c..d5e1e51870 100644 --- a/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.cpp +++ b/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.cpp @@ -25,6 +25,7 @@ #include "RifEclipseInputFileTools.h" #include "RifOpmDeckTools.h" +#include "CompletionsMsw/RigMswTableData.h" #include "RigEclipseResultTools.h" #include "RigFault.h" #include "RigMainGrid.h" @@ -45,30 +46,6 @@ #include "opm/input/eclipse/Parser/ParserKeywords/O.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" -#include "opm/input/eclipse/Parser/ErrorGuard.hpp" -#include "opm/input/eclipse/Parser/InputErrorAction.hpp" -#include "opm/input/eclipse/Parser/ParseContext.hpp" -#include "opm/input/eclipse/Parser/Parser.hpp" - -namespace internal -{ -//-------------------------------------------------------------------------------------------------- -/// Temporary methods for MSW data while waiting for MSW export rewrite -//-------------------------------------------------------------------------------------------------- -static Opm::ParseContext defaultParseContext() -{ - // Use the same default ParseContext as flow. - Opm::ParseContext pc( Opm::InputErrorAction::WARN ); - pc.update( Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputErrorAction::IGNORE ); - pc.update( Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputErrorAction::WARN ); - pc.update( Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputErrorAction::WARN ); - pc.update( Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputErrorAction::WARN ); - - return pc; -} - -} // namespace internal - //================================================================================================== /// /// @@ -185,33 +162,61 @@ Opm::DeckKeyword compdatKeyword( RimEclipseCase* eCase, RimWellPath* wellPath ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Opm::DeckKeyword welsegsKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ) +Opm::DeckKeyword welsegsKeyword( const RigMswTableData& mswData ) { - if ( eCase == nullptr || wellPath == nullptr || wellPath->completionSettings() == nullptr || eCase->eclipseCaseData() == nullptr ) + if ( !mswData.hasWelsegsData() ) { return Opm::DeckKeyword(); } - Opm::ErrorGuard errors{}; - bool headerDone = false; - Opm::DeckKeyword newKw( ( Opm::ParserKeywords::WELSEGS() ) ); - auto deck = Opm::Parser{}.parseString( completionText, internal::defaultParseContext(), errors ); - for ( auto kwit = deck.begin(); kwit != deck.end(); kwit++ ) + // welsegs header row + auto& header = mswData.welsegsHeader(); + std::vector headerItems; + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::WELL::itemName, header.well ) ); + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::TOP_DEPTH::itemName, header.topDepth ) ); + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::TOP_LENGTH::itemName, header.topLength ) ); + + if ( header.wellboreVolume.has_value() ) + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::WELLBORE_VOLUME::itemName, header.wellboreVolume.value() ) ); + else + headerItems.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WELSEGS::WELLBORE_VOLUME::itemName ) ); + + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::INFO_TYPE::itemName, header.infoType ) ); + + if ( header.pressureComponents.has_value() ) + headerItems.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::PRESSURE_COMPONENTS::itemName, header.pressureComponents.value() ) ); + else + headerItems.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WELSEGS::PRESSURE_COMPONENTS::itemName ) ); + if ( header.flowModel.has_value() ) + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::FLOW_MODEL::itemName, header.flowModel.value() ) ); + else + headerItems.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WELSEGS::FLOW_MODEL::itemName ) ); + + newKw.addRecord( Opm::DeckRecord{ std::move( headerItems ) } ); + + // welsegs data rows + for ( auto& wsRow : mswData.welsegsData() ) { - auto& existingKw = *kwit; + std::vector items; + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::SEGMENT1::itemName, wsRow.segment1 ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::SEGMENT2::itemName, wsRow.segment2 ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::BRANCH::itemName, wsRow.branch ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::JOIN_SEGMENT::itemName, wsRow.joinSegment ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::LENGTH::itemName, wsRow.length ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::DEPTH::itemName, wsRow.depth ) ); + if ( wsRow.diameter.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::DIAMETER::itemName, wsRow.diameter.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WELSEGS::DIAMETER::itemName ) ); + if ( wsRow.roughness.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WELSEGS::ROUGHNESS::itemName, wsRow.roughness.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WELSEGS::ROUGHNESS::itemName ) ); - if ( existingKw.name() != Opm::ParserKeywords::WELSEGS::keywordName ) continue; - - for ( size_t i = 0; i < existingKw.size(); i++ ) - { - Opm::DeckRecord newRec( existingKw.getRecord( i ) ); - if ( newRec.getItem( 0 ).is_string() && headerDone ) continue; - - newKw.addRecord( std::move( newRec ) ); - headerDone = true; - } + newKw.addRecord( Opm::DeckRecord{ std::move( items ) } ); } return newKw; @@ -220,34 +225,32 @@ Opm::DeckKeyword welsegsKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Opm::DeckKeyword compsegsKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ) +Opm::DeckKeyword compsegsKeyword( const RigMswTableData& mswData ) { - if ( eCase == nullptr || wellPath == nullptr || wellPath->completionSettings() == nullptr || eCase->eclipseCaseData() == nullptr ) + if ( !mswData.hasCompsegsData() ) { return Opm::DeckKeyword(); } - Opm::ErrorGuard errors{}; - bool headerDone = false; - Opm::DeckKeyword newKw( ( Opm::ParserKeywords::COMPSEGS() ) ); - auto deck = Opm::Parser{}.parseString( completionText, internal::defaultParseContext(), errors ); - for ( auto kwit = deck.begin(); kwit != deck.end(); kwit++ ) + // header row + std::vector headerItems; + headerItems.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::WELL::itemName, mswData.wellName() ) ); + newKw.addRecord( Opm::DeckRecord{ std::move( headerItems ) } ); + + // data rows + for ( auto& csRow : mswData.compsegsData() ) { - auto& existingKw = *kwit; + std::vector items; + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::I::itemName, csRow.i ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::J::itemName, csRow.j ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::K::itemName, csRow.k ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::BRANCH::itemName, csRow.branch ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::DISTANCE_START::itemName, csRow.distanceStart ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::COMPSEGS::DISTANCE_END::itemName, csRow.distanceEnd ) ); - if ( existingKw.name() != Opm::ParserKeywords::COMPSEGS::keywordName ) continue; - - for ( size_t i = 0; i < existingKw.size(); i++ ) - { - Opm::DeckRecord newRec( existingKw.getRecord( i ) ); - - if ( newRec.size() == 1 && headerDone ) continue; - - newKw.addRecord( std::move( newRec ) ); - headerDone = true; - } + newKw.addRecord( Opm::DeckRecord{ std::move( items ) } ); } return newKw; @@ -256,29 +259,49 @@ Opm::DeckKeyword compsegsKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Opm::DeckKeyword wsegvalvKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ) +Opm::DeckKeyword wsegvalvKeyword( const RigMswTableData& mswData ) { - if ( eCase == nullptr || wellPath == nullptr || wellPath->completionSettings() == nullptr || eCase->eclipseCaseData() == nullptr ) + if ( !mswData.hasWsegvalvData() ) { return Opm::DeckKeyword(); } - Opm::ErrorGuard errors{}; - Opm::DeckKeyword newKw( ( Opm::ParserKeywords::WSEGVALV() ) ); - auto deck = Opm::Parser{}.parseString( completionText, internal::defaultParseContext(), errors ); - for ( auto kwit = deck.begin(); kwit != deck.end(); kwit++ ) + for ( auto& wvRow : mswData.wsegvalvData() ) { - auto& existingKw = *kwit; + std::vector items; - if ( existingKw.name() != Opm::ParserKeywords::WSEGVALV::keywordName ) continue; + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::WELL::itemName, wvRow.well ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::SEGMENT_NUMBER::itemName, wvRow.segmentNumber ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::CV::itemName, wvRow.cv ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::AREA::itemName, wvRow.area ) ); + if ( wvRow.extraLength.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::EXTRA_LENGTH::itemName, wvRow.extraLength.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGVALV::EXTRA_LENGTH::itemName ) ); + if ( wvRow.pipeD.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::PIPE_D::itemName, wvRow.pipeD.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGVALV::PIPE_D::itemName ) ); + if ( wvRow.roughness.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::ROUGHNESS::itemName, wvRow.roughness.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGVALV::ROUGHNESS::itemName ) ); + if ( wvRow.pipeA.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::PIPE_A::itemName, wvRow.pipeA.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGVALV::PIPE_A::itemName ) ); + if ( wvRow.status.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::STATUS::itemName, wvRow.status.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGVALV::STATUS::itemName ) ); + if ( wvRow.maxA.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGVALV::MAX_A::itemName, wvRow.maxA.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGVALV::MAX_A::itemName ) ); - for ( size_t i = 0; i < existingKw.size(); i++ ) - { - Opm::DeckRecord newRec( existingKw.getRecord( i ) ); - newKw.addRecord( std::move( newRec ) ); - } + newKw.addRecord( Opm::DeckRecord{ std::move( items ) } ); } return newKw; @@ -287,29 +310,94 @@ Opm::DeckKeyword wsegvalvKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Opm::DeckKeyword wsegaicdKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ) +Opm::DeckKeyword wsegaicdKeyword( const RigMswTableData& mswData ) { - if ( eCase == nullptr || wellPath == nullptr || wellPath->completionSettings() == nullptr || eCase->eclipseCaseData() == nullptr ) + if ( !mswData.hasWsegaicdData() ) { return Opm::DeckKeyword(); } - Opm::ErrorGuard errors{}; - Opm::DeckKeyword newKw( ( Opm::ParserKeywords::WSEGAICD() ) ); - auto deck = Opm::Parser{}.parseString( completionText, internal::defaultParseContext(), errors ); - for ( auto kwit = deck.begin(); kwit != deck.end(); kwit++ ) + for ( auto& waRow : mswData.wsegaicdData() ) { - auto& existingKw = *kwit; + std::vector items; - if ( existingKw.name() != Opm::ParserKeywords::WSEGAICD::keywordName ) continue; + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::WELL::itemName, waRow.well ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::SEGMENT1::itemName, waRow.segment1 ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::SEGMENT2::itemName, waRow.segment2 ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::STRENGTH::itemName, waRow.strength ) ); - for ( size_t i = 0; i < existingKw.size(); i++ ) - { - Opm::DeckRecord newRec( existingKw.getRecord( i ) ); - newKw.addRecord( std::move( newRec ) ); - } + if ( waRow.length.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::LENGTH::itemName, waRow.length.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::LENGTH::itemName ) ); + if ( waRow.densityCali.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::DENSITY_CALI::itemName, waRow.densityCali.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::DENSITY_CALI::itemName ) ); + if ( waRow.viscosityCali.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::VISCOSITY_CALI::itemName, waRow.viscosityCali.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::VISCOSITY_CALI::itemName ) ); + if ( waRow.criticalValue.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::CRITICAL_VALUE::itemName, waRow.criticalValue.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::CRITICAL_VALUE::itemName ) ); + if ( waRow.widthTrans.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::WIDTH_TRANS::itemName, waRow.widthTrans.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::WIDTH_TRANS::itemName ) ); + if ( waRow.maxViscRatio.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::MAX_VISC_RATIO::itemName, waRow.maxViscRatio.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::MAX_VISC_RATIO::itemName ) ); + if ( waRow.methodScalingFactor.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::METHOD_SCALING_FACTOR::itemName, + waRow.methodScalingFactor.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::METHOD_SCALING_FACTOR::itemName ) ); + + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::MAX_ABS_RATE::itemName, waRow.maxAbsRate ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::FLOW_RATE_EXPONENT::itemName, waRow.flowRateExponent ) ); + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::VISC_EXPONENT::itemName, waRow.viscExponent ) ); + + if ( waRow.status.has_value() ) + items.push_back( RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::STATUS::itemName, waRow.status.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::STATUS::itemName ) ); + if ( waRow.oilFlowFraction.has_value() ) + items.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::OIL_FLOW_FRACTION::itemName, waRow.oilFlowFraction.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::OIL_FLOW_FRACTION::itemName ) ); + if ( waRow.waterFlowFraction.has_value() ) + items.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::WATER_FLOW_FRACTION::itemName, waRow.waterFlowFraction.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::WATER_FLOW_FRACTION::itemName ) ); + if ( waRow.gasFlowFraction.has_value() ) + items.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::GAS_FLOW_FRACTION::itemName, waRow.gasFlowFraction.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::GAS_FLOW_FRACTION::itemName ) ); + if ( waRow.oilViscFraction.has_value() ) + items.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::OIL_VISC_FRACTION::itemName, waRow.oilViscFraction.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::OIL_VISC_FRACTION::itemName ) ); + if ( waRow.waterViscFraction.has_value() ) + items.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::WATER_VISC_FRACTION::itemName, waRow.waterViscFraction.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::WATER_VISC_FRACTION::itemName ) ); + if ( waRow.gasViscFraction.has_value() ) + items.push_back( + RifOpmDeckTools::item( Opm::ParserKeywords::WSEGAICD::GAS_VISC_FRACTION::itemName, waRow.gasViscFraction.value() ) ); + else + items.push_back( RifOpmDeckTools::defaultItem( Opm::ParserKeywords::WSEGAICD::GAS_VISC_FRACTION::itemName ) ); + + newKw.addRecord( Opm::DeckRecord{ std::move( items ) } ); } return newKw; diff --git a/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.h b/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.h index ce5e7b227e..9de57de517 100644 --- a/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.h +++ b/ApplicationLibCode/ProjectDataModel/Jobs/RimKeywordFactory.h @@ -25,6 +25,7 @@ #include class RigMainGrid; +class RigMswTableData; class RimEclipseCase; class RimWellPath; @@ -49,10 +50,10 @@ namespace RimKeywordFactory Opm::DeckKeyword welspecsKeyword( const std::string wellGrpName, RimEclipseCase* eCase, RimWellPath* wellPath ); Opm::DeckKeyword compdatKeyword( RimEclipseCase* eCase, RimWellPath* wellPath ); -Opm::DeckKeyword welsegsKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ); -Opm::DeckKeyword compsegsKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ); -Opm::DeckKeyword wsegvalvKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ); -Opm::DeckKeyword wsegaicdKeyword( RimEclipseCase* eCase, RimWellPath* wellPath, const std::string completionText ); +Opm::DeckKeyword welsegsKeyword( const RigMswTableData& mswData ); +Opm::DeckKeyword compsegsKeyword( const RigMswTableData& mswData ); +Opm::DeckKeyword wsegvalvKeyword( const RigMswTableData& mswData ); +Opm::DeckKeyword wsegaicdKeyword( const RigMswTableData& mswData ); Opm::DeckKeyword faultsKeyword( const RigMainGrid* mainGrid, const cvf::Vec3st& min = cvf::Vec3st::ZERO, diff --git a/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.cpp b/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.cpp index b138ea2af5..5082fd4827 100644 --- a/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.cpp +++ b/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.cpp @@ -25,12 +25,15 @@ #include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h" #include "CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h" +#include "CompletionExportCommands/RicWellPathExportMswTableData.h" #include "EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.h" #include "JobCommands/RicRunJobFeature.h" #include "JobCommands/RicStopJobFeature.h" #include "RifOpmFlowDeckFile.h" +#include "CompletionsMsw/RigMswTableData.h" + #include "Ensemble/RimSummaryFileSetEnsemble.h" #include "EnsembleFileSet/RimEnsembleFileSet.h" #include "EnsembleFileSet/RimEnsembleFileSetTools.h" @@ -657,28 +660,6 @@ QString RimOpmFlowJob::deckExtension() const return ".DATA"; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimOpmFlowJob::wellTempFile( int timeStep, bool includeMSW, bool includeLGR ) const -{ - QString postfix = ""; - if ( timeStep >= 0 ) - { - postfix = QString( "_%1" ).arg( timeStep ); - } - if ( includeLGR ) - { - postfix = postfix + "_LGR"; - } - if ( includeMSW ) - { - postfix = postfix + "_MSW"; - } - - return workingDirectory() + "/ri_new_well" + postfix + deckExtension(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1036,42 +1017,6 @@ int RimOpmFlowJob::mergeBasicWellSettings() return mergePosition; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::string RimOpmFlowJob::exportMswWellSettings( int timeStep ) -{ - RicExportCompletionDataSettingsUi exportSettings; - - QString customName = wellTempFile( timeStep ); - QString customMswName = wellTempFile( timeStep, true /*include msw*/ ); - - // this file is not used, but the export generates the file anyways, so we need to remove it - QString customMswLgrName = wellTempFile( timeStep, true /*include msw*/, true /*include LGR*/ ); - - exportSettings.fileSplit = RicExportCompletionDataSettingsUi::ExportSplit::UNIFIED_FILE; - exportSettings.caseToApply = m_eclipseCase(); - exportSettings.setCustomFileName( customName ); - exportSettings.includeMsw = true; - exportSettings.setExportDataSourceAsComment( false ); - exportSettings.timeStep = timeStep; - - exportSettings.folder = workingDirectory(); - - auto topLevelWell = m_wellPath->topLevelWellPath(); - - RicWellPathExportCompletionDataFeatureImpl::exportCompletions( { topLevelWell }, exportSettings ); - - QString fileContent = readFileContent( customName ); - fileContent += readFileContent( customMswName ); - - QFile::remove( customName ); - QFile::remove( customMswName ); - QFile::remove( customMswLgrName ); - - return fileContent.toStdString(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1079,12 +1024,17 @@ int RimOpmFlowJob::mergeMswData( int mergePosition ) { const int failure = -1; - auto mswData = exportMswWellSettings( 0 ); + auto mswDataResult = RicWellPathExportMswTableData::extractSingleWellMswData( m_eclipseCase(), m_wellPath(), 0 ); + if ( !mswDataResult.has_value() ) + { + RiaLogging::error( QString::fromStdString( mswDataResult.error() ) ); + return failure; + } - auto welsegsKw = RimKeywordFactory::welsegsKeyword( m_eclipseCase(), m_wellPath(), mswData ); - auto compsegsKw = RimKeywordFactory::compsegsKeyword( m_eclipseCase(), m_wellPath(), mswData ); - auto wsegvalvKw = RimKeywordFactory::wsegvalvKeyword( m_eclipseCase(), m_wellPath(), mswData ); - auto wsegaicdKw = RimKeywordFactory::wsegaicdKeyword( m_eclipseCase(), m_wellPath(), mswData ); + auto welsegsKw = RimKeywordFactory::welsegsKeyword( mswDataResult.value() ); + auto compsegsKw = RimKeywordFactory::compsegsKeyword( mswDataResult.value() ); + auto wsegvalvKw = RimKeywordFactory::wsegvalvKeyword( mswDataResult.value() ); + auto wsegaicdKw = RimKeywordFactory::wsegaicdKeyword( mswDataResult.value() ); if ( welsegsKw.empty() || compsegsKw.empty() ) { @@ -1185,22 +1135,6 @@ void RimOpmFlowJob::initAfterCopy() m_summaryEnsemble = nullptr; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimOpmFlowJob::readFileContent( QString filename ) -{ - QFile file( filename ); - if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) ) - { - QTextStream in( &file ); - QString fileContent = in.readAll(); - file.close(); - return fileContent; - } - return ""; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.h b/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.h index a995a15b1c..14f5f8366b 100644 --- a/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.h +++ b/ApplicationLibCode/ProjectDataModel/Jobs/RimOpmFlowJob.h @@ -89,7 +89,6 @@ protected: private: RimEclipseCase* findExistingCase( QString filename ); QString deckExtension() const; - QString wellTempFile( int timeStep = -1, bool includeMSW = false, bool includeLGR = false ) const; QString baseDeckName() const; QString restartDeckName() const; @@ -100,13 +99,10 @@ private: std::vector dateTimes(); std::vector addedDateTimes(); - static QString readFileContent( QString filename ); - - int mergeBasicWellSettings(); - std::string exportMswWellSettings( int timeStep ); - int mergeMswData( int mergePosition ); - void selectOpenWellPosition(); - void resetEnsembleRunId(); + int mergeBasicWellSettings(); + int mergeMswData( int mergePosition ); + void selectOpenWellPosition(); + void resetEnsembleRunId(); private: caf::PdmField m_deckFileName; diff --git a/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswDataFormatter.cpp b/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswDataFormatter.cpp index 5a2c0148ba..c45d4ac1a7 100644 --- a/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswDataFormatter.cpp +++ b/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswDataFormatter.cpp @@ -256,7 +256,8 @@ void RigMswDataFormatter::formatWelsegsTable( RifTextDataTableFormatter& formatt formatter.add( welsegsHeader.topLength ); formatter.addOptionalValue( welsegsHeader.wellboreVolume ); formatter.addStdString( welsegsHeader.infoType ); - formatter.addStdString( welsegsHeader.pressureComponents ); + formatter.addOptionalStdString( welsegsHeader.pressureComponents ); + formatter.addOptionalStdString( welsegsHeader.flowModel ); formatter.rowCompleted(); // Column headers for segment data diff --git a/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswTableRows.h b/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswTableRows.h index 994cd2cccc..f41b53aa2e 100644 --- a/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswTableRows.h +++ b/ApplicationLibCode/ReservoirDataModel/CompletionsMsw/RigMswTableRows.h @@ -42,7 +42,7 @@ struct WelsegsHeader double topLength; // TOPLEN std::optional wellboreVolume; // WBORVOL std::string infoType; // TUBOPT - std::string pressureComponents; // PRESOPT + std::optional pressureComponents; // PRESOPT std::optional flowModel; // FLOWOPT };