From 10cfaafe793875b1cce7abc3e6dbed5e8479d18f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Sep 2023 10:03:49 +0200 Subject: [PATCH 1/3] Add readKeywordContentFromFile --- .../RifEclipseInputFileTools.cpp | 48 ++++++++++++++----- .../FileInterface/RifEclipseInputFileTools.h | 7 +-- .../FileInterface/RifReaderEclipseOutput.cpp | 27 +++-------- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp index ecde23dd34..4c137f8aa9 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp @@ -1181,16 +1181,15 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively( Q //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( - const QString& keyword, - const QString& keywordToStopParsing, - QFile& file, - qint64 startPos, - const std::vector>& pathAliasDefinitions, - QStringList* keywordDataContent, - std::vector* filenamesContainingKeyword, - bool* isStopParsingKeywordDetected, - const QString& faultIncludeFileAbsolutePathPrefix /* rename to includeStatementAbsolutePathPrefix */ ) +bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( const QString& keyword, + const QString& keywordToStopParsing, + QFile& file, + qint64 startPos, + const std::vector>& pathAliasDefinitions, + QStringList* keywordDataContent, + std::vector* filenamesContainingKeyword, + bool* isStopParsingKeywordDetected, + const QString& includeStatementAbsolutePathPrefix ) { QString line; @@ -1256,7 +1255,7 @@ bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( if ( includeFilename.startsWith( '/' ) ) { // Absolute UNIX path, prefix on Windows - includeFilename = faultIncludeFileAbsolutePathPrefix + includeFilename; + includeFilename = includeStatementAbsolutePathPrefix + includeFilename; } #endif @@ -1277,7 +1276,7 @@ bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keywordDataContent, filenamesContainingKeyword, isStopParsingKeywordDetected, - faultIncludeFileAbsolutePathPrefix ) ) + includeStatementAbsolutePathPrefix ) ) { qDebug() << "Error when parsing include file : " << absoluteFilename; } @@ -1437,6 +1436,31 @@ bool RifEclipseInputFileTools::hasGridData( const QString& fileName ) return coordKeywordItr != keywordAndValues.end(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RifEclipseInputFileTools::readKeywordContentFromFile( const QString& keyword, const QString& keywordToStopParsing, QFile& file ) +{ + const qint64 startPositionInFile = 0; + std::vector> pathAliasDefinitions; + QStringList keywordContent; + std::vector fileNamesContainingKeyword; + bool isStopParsingKeywordDetected = false; + const QString includeStatementAbsolutePathPrefix; + + RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, + keywordToStopParsing, + file, + startPositionInFile, + pathAliasDefinitions, + &keywordContent, + &fileNamesContainingKeyword, + &isStopParsingKeywordDetected, + includeStatementAbsolutePathPrefix ); + + return keywordContent; +} + //-------------------------------------------------------------------------------------------------- /// The file pointer is pointing at the line following the FAULTS keyword. /// Parse content of this keyword until end of file or diff --git a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h index 2e8fe0b998..105207f450 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h +++ b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h @@ -106,6 +106,9 @@ class RifEclipseInputFileTools : public cvf::Object static void parseAndReadPathAliasKeyword( const QString& fileName, std::vector>* pathAliasDefinitions ); + static QStringList readKeywordContentFromFile( const QString& keyword, const QString& keywordToStopParsing, QFile& file ); + + // Public for unit testing, use readKeywordContentFromFile() static bool readKeywordAndParseIncludeStatementsRecursively( const QString& keyword, const QString& keywordToStopParsing, QFile& file, @@ -114,9 +117,7 @@ class RifEclipseInputFileTools : public cvf::Object QStringList* keywordDataContent, std::vector* filenamesContainingKeyword, bool* isEditKeywordDetected, - const QString& faultIncludeFileAbsolutePathPrefix // rename to - // includeStatementAbsolutePathPrefix - ); + const QString& includeStatementAbsolutePathPrefix ); static RiaDefines::EclipseUnitSystem readUnitSystem( QFile& file, qint64 gridunitPos ); diff --git a/ApplicationLibCode/FileInterface/RifReaderEclipseOutput.cpp b/ApplicationLibCode/FileInterface/RifReaderEclipseOutput.cpp index 1d8ea15f8f..ec2f49fb2e 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEclipseOutput.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderEclipseOutput.cpp @@ -648,26 +648,13 @@ void RifReaderEclipseOutput::importEquilData( const QString& deckFileName, const QString& includeStatementAbsolutePathPrefix, RigEclipseCaseData* eclipseCase ) { - QFile data( deckFileName ); - if ( data.open( QFile::ReadOnly ) ) - { - const QString keyword( "EQUIL" ); - const QString keywordToStopParsing( "SCHEDULE" ); - const qint64 startPositionInFile = 0; - std::vector> pathAliasDefinitions; - QStringList keywordContent; - std::vector fileNamesContainingKeyword; - bool isStopParsingKeywordDetected = false; - - RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, - keywordToStopParsing, - data, - startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + QFile file( deckFileName ); + if ( file.open( QFile::ReadOnly ) ) + { + const QString keyword( "EQUIL" ); + const QString keywordToStopParsing( "SCHEDULE" ); + auto keywordContent = RifEclipseInputFileTools::readKeywordContentFromFile( keyword, keywordToStopParsing, file ); + std::vector equilItems; for ( const auto& s : keywordContent ) { From 53da5d972d3862f6a7f603ce71b7e00200c24d35 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Sep 2023 10:04:46 +0200 Subject: [PATCH 2/3] Add import of AICD values from Completor and Eclipse --- .../CompletionCommands/CMakeLists_files.cmake | 2 + .../RicImportValveTemplatesFeature.cpp | 93 +++++++++++ .../RicImportValveTemplatesFeature.h | 34 ++++ .../Completions/RimValveTemplate.cpp | 50 ++++++ .../Completions/RimValveTemplate.h | 3 + .../Completions/RimWellPathAicdParameters.cpp | 8 + .../Completions/RimWellPathAicdParameters.h | 2 + .../ProjectDataModel/RiaOpmParserTools.cpp | 152 ++++++++++++++++++ .../ProjectDataModel/RiaOpmParserTools.h | 6 + .../RimContextCommandBuilder.cpp | 1 + 10 files changed, 351 insertions(+) create mode 100644 ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp create mode 100644 ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.h diff --git a/ApplicationLibCode/Commands/CompletionCommands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/CompletionCommands/CMakeLists_files.cmake index e950793c68..c805413ba9 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/CompletionCommands/CMakeLists_files.cmake @@ -12,6 +12,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportPerforationIntervalsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanModelPlotFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFractureStatisticsFeature.h + ${CMAKE_CURRENT_LIST_DIR}/RicImportValveTemplatesFeature.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -28,6 +29,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportPerforationIntervalsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanModelPlotFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFractureStatisticsFeature.cpp + ${CMAKE_CURRENT_LIST_DIR}/RicImportValveTemplatesFeature.cpp ) list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp new file mode 100644 index 0000000000..0c26dc2d2c --- /dev/null +++ b/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp @@ -0,0 +1,93 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicImportValveTemplatesFeature.h" + +#include "RiaApplication.h" +#include "RiaOpmParserTools.h" + +#include "RimProject.h" +#include "RimValveTemplate.h" +#include "RimValveTemplateCollection.h" + +#include "Riu3DMainWindowTools.h" +#include "RiuFileDialogTools.h" + +#include + +CAF_CMD_SOURCE_INIT( RicImportValveTemplatesFeature, "RicImportValveTemplatesFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportValveTemplatesFeature::isCommandEnabled() const +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportValveTemplatesFeature::onActionTriggered( bool isChecked ) +{ + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->lastUsedDialogDirectory( "BINARY_GRID" ); + + QStringList fileNames = RiuFileDialogTools::getOpenFileNames( Riu3DMainWindowTools::mainWindowWidget(), + "Import Valve Templates", + defaultDir, + "Valve Files (*.sch *.case);;All Files (*.*)" ); + + RimValveTemplateCollection* templateColl = RimProject::current()->allValveTemplateCollections().front(); + for ( const auto& fileName : fileNames ) + { + std::vector aicdTemplates; + + if ( fileName.contains( ".case" ) ) + { + aicdTemplates = RiaOpmParserTools::extractWsegAicdCompletor( fileName.toStdString() ); + } + else + { + aicdTemplates = RiaOpmParserTools::extractWsegAicd( fileName.toStdString() ); + } + + // There can be multiple items of the same template, make sure we have unique templates + std::sort( aicdTemplates.begin(), aicdTemplates.end() ); + auto it = std::unique( aicdTemplates.begin(), aicdTemplates.end() ); + aicdTemplates.resize( std::distance( aicdTemplates.begin(), it ) ); + + int number = 1; + for ( const auto& aicdValue : aicdTemplates ) + { + auto newTemplate = RimValveTemplate::createAicdTemplate( aicdValue, number++ ); + templateColl->addValveTemplate( newTemplate ); + } + } + + templateColl->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportValveTemplatesFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setIcon( QIcon( ":/ICDValve16x16.png" ) ); + actionToSetup->setText( "Import Valve Templates" ); +} diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.h b/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.h new file mode 100644 index 0000000000..577abe3632 --- /dev/null +++ b/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicImportValveTemplatesFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + bool isCommandEnabled() const override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp index 411147ee3a..25cb2a9738 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp @@ -23,6 +23,8 @@ #include "cafPdmUiTreeOrdering.h" +#include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" + CAF_PDM_SOURCE_INIT( RimValveTemplate, "ValveTemplate" ); //-------------------------------------------------------------------------------------------------- @@ -166,6 +168,54 @@ void RimValveTemplate::setUserLabel( const QString& userLabel ) m_userLabel = userLabel; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimValveTemplate* RimValveTemplate::createAicdTemplate( const RiaOpmParserTools::AicdTemplateValues& aicdParameters, int templateNumber ) +{ + RimValveTemplate* aicdTemplate = new RimValveTemplate; + aicdTemplate->setType( RiaDefines::WellPathComponentType::AICD ); + + QString name; + if ( aicdParameters.contains( RiaOpmParserTools::aicdTemplateId() ) ) + { + auto id = aicdParameters.at( RiaOpmParserTools::aicdTemplateId() ); + name = QString::number( id ); + } + else + { + name = QString::number( templateNumber ); + } + + aicdTemplate->setUserLabel( name ); + + using namespace Opm::ParserKeywords; + std::map parameterMap = { { WSEGAICD::STRENGTH::itemName, AICD_STRENGTH }, + { WSEGAICD::DENSITY_CALI::itemName, AICD_DENSITY_CALIB_FLUID }, + { WSEGAICD::VISCOSITY_CALI::itemName, AICD_VISCOSITY_CALIB_FLUID }, + { WSEGAICD::FLOW_RATE_EXPONENT::itemName, AICD_VOL_FLOW_EXP }, + { WSEGAICD::VISC_EXPONENT::itemName, AICD_VISOSITY_FUNC_EXP }, + { WSEGAICD::CRITICAL_VALUE::itemName, AICD_CRITICAL_WATER_IN_LIQUID_FRAC }, + { WSEGAICD::MAX_ABS_RATE::itemName, AICD_MAX_FLOW_RATE }, + { WSEGAICD::OIL_FLOW_FRACTION::itemName, AICD_EXP_OIL_FRAC_DENSITY }, + { WSEGAICD::WATER_FLOW_FRACTION::itemName, AICD_EXP_WATER_FRAC_DENSITY }, + { WSEGAICD::GAS_FLOW_FRACTION::itemName, AICD_EXP_GAS_FRAC_DENSITY }, + { WSEGAICD::OIL_VISC_FRACTION::itemName, AICD_EXP_OIL_FRAC_VISCOSITY }, + { WSEGAICD::WATER_VISC_FRACTION::itemName, AICD_EXP_WATER_FRAC_VISCOSITY }, + { WSEGAICD::GAS_VISC_FRACTION::itemName, AICD_EXP_GAS_FRAC_VISCOSITY } }; + + for ( const auto& parameter : parameterMap ) + { + if ( aicdParameters.contains( parameter.first ) ) + { + auto incomingValue = aicdParameters.at( parameter.first ); + aicdTemplate->m_aicdParameters()->setValue( parameter.second, incomingValue ); + } + } + + return aicdTemplate; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h index 2b2b7f22e4..e5526fd20e 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h @@ -19,6 +19,7 @@ #pragma once #include "RiaDefines.h" +#include "RiaOpmParserTools.h" #include "RimCheckableNamedObject.h" @@ -48,6 +49,8 @@ class RimValveTemplate : public RimNamedObject QString fullLabel() const; void setUserLabel( const QString& userLabel ); + static RimValveTemplate* createAicdTemplate( const RiaOpmParserTools::AicdTemplateValues& aicdParameters, int templateNumber ); + protected: QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp index 1a672c7568..f46c0972c3 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp @@ -114,6 +114,14 @@ bool RimWellPathAicdParameters::isValid() const return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAicdParameters::setValue( AICDParameters parameter, double value ) +{ + m_aicdParameterFields[parameter].setValue( QString::number( value ) ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.h b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.h index 23c49920c2..e1ee11f419 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.h @@ -53,6 +53,8 @@ class RimWellPathAicdParameters : public caf::PdmObject ~RimWellPathAicdParameters() override; bool isValid() const; + void setValue( AICDParameters parameter, double value ); + bool isOpen() const; std::array doubleValues() const; diff --git a/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp b/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp index cbb5c32a6c..d548d5bd62 100644 --- a/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp @@ -17,6 +17,10 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaOpmParserTools.h" +#include "RiaLogging.h" +#include "RiaTextStringTools.h" + +#include "RifEclipseInputFileTools.h" #include "cafPdmUiItem.h" #include "cafUtils.h" @@ -29,6 +33,10 @@ #include "opm/input/eclipse/Parser/ParserKeywords/V.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" +#include + +#include + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -193,3 +201,147 @@ std::map>> RiaOpmParserTools::extra return wseglink; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaOpmParserTools::extractWsegAicd( const std::string& filename ) +{ + if ( !std::filesystem::exists( filename ) ) return {}; + + try + { + Opm::Parser parser( false ); + + const Opm::ParserKeywords::WSEGAICD kw1; + const Opm::ParserKeywords::INCLUDE kw2; + const Opm::ParserKeywords::PATHS kw3; + + parser.addParserKeyword( kw1 ); + parser.addParserKeyword( kw2 ); + parser.addParserKeyword( kw3 ); + + std::stringstream ss; + Opm::ParseContext parseContext( Opm::InputError::Action::WARN ); + auto deck = parser.parseFile( filename, parseContext ); + + const std::string keyword = "WSEGAICD"; + auto keywordList = deck.getKeywordList( keyword ); + if ( keywordList.empty() ) return {}; + + using namespace Opm::ParserKeywords; + std::set keywordsToExtract = { WSEGAICD::STRENGTH::itemName, + WSEGAICD::DENSITY_CALI::itemName, + WSEGAICD::VISCOSITY_CALI::itemName, + WSEGAICD::FLOW_RATE_EXPONENT::itemName, + WSEGAICD::VISC_EXPONENT::itemName, + WSEGAICD::CRITICAL_VALUE::itemName, + WSEGAICD::MAX_ABS_RATE::itemName, + WSEGAICD::OIL_FLOW_FRACTION::itemName, + WSEGAICD::WATER_FLOW_FRACTION::itemName, + WSEGAICD::GAS_FLOW_FRACTION::itemName, + WSEGAICD::OIL_VISC_FRACTION::itemName, + WSEGAICD::WATER_VISC_FRACTION::itemName, + WSEGAICD::GAS_VISC_FRACTION::itemName }; + + std::vector aicdData; + for ( const auto& kw : keywordList ) + { + auto name = kw->name(); + + for ( size_t i = 0; i < kw->size(); i++ ) + { + RiaOpmParserTools::AicdTemplateValues aicdTemplate; + + auto deckRecord = kw->getRecord( i ); + auto numItems = deckRecord.size(); + for ( size_t i = 0; i < numItems; i++ ) + { + auto deckItem = deckRecord.getItem( i ); + if ( !deckItem.hasValue( 0 ) ) continue; + if ( !keywordsToExtract.contains( deckItem.name() ) ) continue; + + auto typeTag = deckItem.getType(); + if ( typeTag == Opm::type_tag::fdouble ) + { + double doubleValue = deckItem.get( 0 ); + aicdTemplate[deckItem.name()] = doubleValue; + } + } + + aicdData.push_back( aicdTemplate ); + } + } + + return aicdData; + } + catch ( std::exception& e ) + { + RiaLogging::error( e.what() ); + } + + return {}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaOpmParserTools::extractWsegAicdCompletor( const std::string& filename ) +{ + QFile file( QString::fromStdString( filename ) ); + if ( !file.open( QFile::ReadOnly ) ) return {}; + + std::vector aicdTemplates; + + const QString keyword( "WSEGAICD" ); + const QString keywordToStopParsing; + + auto keywordContent = RifEclipseInputFileTools::readKeywordContentFromFile( keyword, keywordToStopParsing, file ); + for ( const auto& s : keywordContent ) + { + auto wordsInLine = RiaTextStringTools::splitSkipEmptyParts( s ); + std::vector values; + for ( const auto& word : wordsInLine ) + { + bool ok = false; + auto doubleValue = word.toDouble( &ok ); + if ( ok ) values.push_back( doubleValue ); + } + + // Completor exports the values in the following format, 12 values per row + // WSEGAICD + // --Number Alpha x y a b c d e f rhocal viscal + // 1 0.000017253 3.05 0.67 1 1 1 2.43 1.18 10.0 1000 1 + // 2 0.000027253 5.05 0.53 1 1 1 2.43 1.28 7.02 1000 1 + // + if ( values.size() == 12 ) + { + RiaOpmParserTools::AicdTemplateValues aicdValues; + aicdValues[aicdTemplateId()] = values[0]; + + aicdValues[Opm::ParserKeywords::WSEGAICD::STRENGTH::itemName] = values[1]; // Alpha + aicdValues[Opm::ParserKeywords::WSEGAICD::FLOW_RATE_EXPONENT::itemName] = values[2]; // x + aicdValues[Opm::ParserKeywords::WSEGAICD::VISC_EXPONENT::itemName] = values[3]; // y + aicdValues[Opm::ParserKeywords::WSEGAICD::OIL_FLOW_FRACTION::itemName] = values[4]; // a + aicdValues[Opm::ParserKeywords::WSEGAICD::WATER_FLOW_FRACTION::itemName] = values[5]; // b + aicdValues[Opm::ParserKeywords::WSEGAICD::GAS_FLOW_FRACTION::itemName] = values[6]; // c + aicdValues[Opm::ParserKeywords::WSEGAICD::OIL_VISC_FRACTION::itemName] = values[7]; // d + aicdValues[Opm::ParserKeywords::WSEGAICD::WATER_VISC_FRACTION::itemName] = values[8]; // e + aicdValues[Opm::ParserKeywords::WSEGAICD::GAS_VISC_FRACTION::itemName] = values[9]; // f + aicdValues[Opm::ParserKeywords::WSEGAICD::DENSITY_CALI::itemName] = values[10]; // rhocal + aicdValues[Opm::ParserKeywords::WSEGAICD::VISCOSITY_CALI::itemName] = values[11]; // viscal + + aicdTemplates.push_back( aicdValues ); + } + } + + return aicdTemplates; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RiaOpmParserTools::aicdTemplateId() +{ + return "ID_NUMBER"; +} diff --git a/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.h b/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.h index 9036f2035f..473922b596 100644 --- a/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.h +++ b/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.h @@ -35,4 +35,10 @@ class RiaOpmParserTools static std::vector extractVfpProductionTables( const std::string& filename ); static std::map>> extractWseglink( const std::string& filename ); + + using AicdTemplateValues = std::map; + static std::vector extractWsegAicd( const std::string& filename ); + static std::vector extractWsegAicdCompletor( const std::string& filename ); + + static std::string aicdTemplateId(); }; diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index 0a55f9fe5c..02933a5aa9 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -959,6 +959,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() else if ( dynamic_cast( firstUiItem ) ) { menuBuilder << "RicNewValveTemplateFeature"; + menuBuilder << "RicImportValveTemplatesFeature"; } else if ( dynamic_cast( firstUiItem ) ) { From 212c71123905c3ad22797ceb0d4bd67b4d54cf4a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 12 Sep 2023 18:37:32 +0200 Subject: [PATCH 3/3] Improvements based on review --- .../RicImportValveTemplatesFeature.cpp | 7 +++ .../RifEclipseInputFileTools.cpp | 55 +++++++---------- .../FileInterface/RifEclipseInputFileTools.h | 14 ++--- .../Completions/RimValveTemplate.cpp | 13 +++- .../Completions/RimValveTemplate.h | 3 + .../ProjectDataModel/RiaOpmParserTools.cpp | 8 +-- .../RifEclipseInputFileTools-Test.cpp | 60 +++++++++---------- 7 files changed, 86 insertions(+), 74 deletions(-) diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp index 0c26dc2d2c..8aa54abd90 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicImportValveTemplatesFeature.cpp @@ -19,6 +19,7 @@ #include "RicImportValveTemplatesFeature.h" #include "RiaApplication.h" +#include "RiaLogging.h" #include "RiaOpmParserTools.h" #include "RimProject.h" @@ -53,6 +54,12 @@ void RicImportValveTemplatesFeature::onActionTriggered( bool isChecked ) defaultDir, "Valve Files (*.sch *.case);;All Files (*.*)" ); + if ( RimProject::current()->allValveTemplateCollections().empty() ) + { + RiaLogging::error( "No valve template collection found, failed to import valves." ); + return; + } + RimValveTemplateCollection* templateColl = RimProject::current()->allValveTemplateCollections().front(); for ( const auto& fileName : fileNames ) { diff --git a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp index 4c137f8aa9..576aad266d 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.cpp @@ -1183,13 +1183,13 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively( Q //-------------------------------------------------------------------------------------------------- bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( const QString& keyword, const QString& keywordToStopParsing, - QFile& file, - qint64 startPos, const std::vector>& pathAliasDefinitions, - QStringList* keywordDataContent, - std::vector* filenamesContainingKeyword, - bool* isStopParsingKeywordDetected, - const QString& includeStatementAbsolutePathPrefix ) + const QString& includeStatementAbsolutePathPrefix, + QFile& file, + qint64 startPos, + QStringList& keywordDataContent, + std::vector& filenamesContainingKeyword, + bool& isStopParsingKeywordDetected ) { QString line; @@ -1212,10 +1212,7 @@ bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( if ( !keywordToStopParsing.isEmpty() && line.startsWith( keywordToStopParsing, Qt::CaseInsensitive ) ) { - if ( isStopParsingKeywordDetected ) - { - *isStopParsingKeywordDetected = true; - } + isStopParsingKeywordDetected = true; return false; } @@ -1266,17 +1263,15 @@ bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( QFile includeFile( absoluteFilename ); if ( includeFile.open( QFile::ReadOnly ) ) { - // qDebug() << "Found include statement, and start parsing of\n " << absoluteFilename; - if ( !readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, includeFile, 0, - pathAliasDefinitions, keywordDataContent, filenamesContainingKeyword, - isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ) ) + isStopParsingKeywordDetected ) ) { qDebug() << "Error when parsing include file : " << absoluteFilename; } @@ -1289,11 +1284,11 @@ bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( if ( !line.contains( "/" ) ) { readKeywordDataContent( file, file.pos(), keywordDataContent, isStopParsingKeywordDetected ); - filenamesContainingKeyword->push_back( file.fileName() ); + filenamesContainingKeyword.push_back( file.fileName() ); } } - if ( isStopParsingKeywordDetected && *isStopParsingKeywordDetected ) + if ( isStopParsingKeywordDetected ) { continueParsing = false; } @@ -1311,7 +1306,7 @@ bool RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifEclipseInputFileTools::readKeywordDataContent( QFile& data, qint64 filePos, QStringList* textContent, bool* isEditKeywordDetected ) +void RifEclipseInputFileTools::readKeywordDataContent( QFile& data, qint64 filePos, QStringList& textContent, bool& isStopParsingKeywordDetected ) { if ( !data.seek( filePos ) ) { @@ -1339,11 +1334,7 @@ void RifEclipseInputFileTools::readKeywordDataContent( QFile& data, qint64 fileP else if ( line.startsWith( editKeyword, Qt::CaseInsensitive ) ) { // End parsing when edit keyword is detected - - if ( isEditKeywordDetected ) - { - *isEditKeywordDetected = true; - } + isStopParsingKeywordDetected = true; return; } @@ -1355,7 +1346,7 @@ void RifEclipseInputFileTools::readKeywordDataContent( QFile& data, qint64 fileP if ( !line.isEmpty() ) { - textContent->push_back( line ); + textContent.push_back( line ); } } while ( !data.atEnd() ); @@ -1368,7 +1359,7 @@ RiaDefines::EclipseUnitSystem RifEclipseInputFileTools::readUnitSystem( QFile& f { bool stopParsing = false; QStringList unitText; - readKeywordDataContent( file, gridunitPos, &unitText, &stopParsing ); + readKeywordDataContent( file, gridunitPos, unitText, stopParsing ); for ( QString unitString : unitText ) { if ( unitString.contains( "FEET", Qt::CaseInsensitive ) ) @@ -1441,22 +1432,22 @@ bool RifEclipseInputFileTools::hasGridData( const QString& fileName ) //-------------------------------------------------------------------------------------------------- QStringList RifEclipseInputFileTools::readKeywordContentFromFile( const QString& keyword, const QString& keywordToStopParsing, QFile& file ) { - const qint64 startPositionInFile = 0; std::vector> pathAliasDefinitions; + const QString includeStatementAbsolutePathPrefix; + const qint64 startPositionInFile = 0; QStringList keywordContent; std::vector fileNamesContainingKeyword; bool isStopParsingKeywordDetected = false; - const QString includeStatementAbsolutePathPrefix; RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, file, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); return keywordContent; } diff --git a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h index 105207f450..baff69028d 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h +++ b/ApplicationLibCode/FileInterface/RifEclipseInputFileTools.h @@ -111,13 +111,13 @@ class RifEclipseInputFileTools : public cvf::Object // Public for unit testing, use readKeywordContentFromFile() static bool readKeywordAndParseIncludeStatementsRecursively( const QString& keyword, const QString& keywordToStopParsing, - QFile& file, - qint64 startPos, const std::vector>& pathAliasDefinitions, - QStringList* keywordDataContent, - std::vector* filenamesContainingKeyword, - bool* isEditKeywordDetected, - const QString& includeStatementAbsolutePathPrefix ); + const QString& includeStatementAbsolutePathPrefix, + QFile& file, + qint64 startPos, + QStringList& keywordDataContent, + std::vector& filenamesContainingKeyword, + bool& isStopParsingKeywordDetected ); static RiaDefines::EclipseUnitSystem readUnitSystem( QFile& file, qint64 gridunitPos ); @@ -137,7 +137,7 @@ class RifEclipseInputFileTools : public cvf::Object bool* isEditKeywordDetected, const QString& faultIncludeFileAbsolutePathPrefix ); - static void readKeywordDataContent( QFile& data, qint64 filePos, QStringList* textContent, bool* isEditKeywordDetected ); + static void readKeywordDataContent( QFile& data, qint64 filePos, QStringList& textContent, bool& isStopParsingKeywordDetected ); static void findGridKeywordPositions( const std::vector& keywords, qint64* coordPos, diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp index 25cb2a9738..22bb749ade 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp @@ -168,6 +168,17 @@ void RimValveTemplate::setUserLabel( const QString& userLabel ) m_userLabel = userLabel; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimValveTemplate::setAicdParameter( AICDParameters parameter, double value ) +{ + if ( m_aicdParameters() ) + { + m_aicdParameters()->setValue( parameter, value ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -209,7 +220,7 @@ RimValveTemplate* RimValveTemplate::createAicdTemplate( const RiaOpmParserTools: if ( aicdParameters.contains( parameter.first ) ) { auto incomingValue = aicdParameters.at( parameter.first ); - aicdTemplate->m_aicdParameters()->setValue( parameter.second, incomingValue ); + aicdTemplate->setAicdParameter( parameter.second, incomingValue ); } } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h index e5526fd20e..094a3a1636 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.h @@ -22,6 +22,7 @@ #include "RiaOpmParserTools.h" #include "RimCheckableNamedObject.h" +#include "RimWellPathAicdParameters.h" #include "cafPdmChildField.h" @@ -49,6 +50,8 @@ class RimValveTemplate : public RimNamedObject QString fullLabel() const; void setUserLabel( const QString& userLabel ); + void setAicdParameter( AICDParameters parameter, double value ); + static RimValveTemplate* createAicdTemplate( const RiaOpmParserTools::AicdTemplateValues& aicdParameters, int templateNumber ); protected: diff --git a/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp b/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp index d548d5bd62..59ac89bd84 100644 --- a/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/RiaOpmParserTools.cpp @@ -249,15 +249,15 @@ std::vector RiaOpmParserTools::extractWse { auto name = kw->name(); - for ( size_t i = 0; i < kw->size(); i++ ) + for ( size_t kwIndex = 0; kwIndex < kw->size(); kwIndex++ ) { RiaOpmParserTools::AicdTemplateValues aicdTemplate; - auto deckRecord = kw->getRecord( i ); + auto deckRecord = kw->getRecord( kwIndex ); auto numItems = deckRecord.size(); - for ( size_t i = 0; i < numItems; i++ ) + for ( size_t deckIndex = 0; deckIndex < numItems; deckIndex++ ) { - auto deckItem = deckRecord.getItem( i ); + auto deckItem = deckRecord.getItem( deckIndex ); if ( !deckItem.hasValue( 0 ) ) continue; if ( !keywordsToExtract.contains( deckItem.name() ) ) continue; diff --git a/ApplicationLibCode/UnitTests/RifEclipseInputFileTools-Test.cpp b/ApplicationLibCode/UnitTests/RifEclipseInputFileTools-Test.cpp index 2751442ece..0204f6a495 100644 --- a/ApplicationLibCode/UnitTests/RifEclipseInputFileTools-Test.cpp +++ b/ApplicationLibCode/UnitTests/RifEclipseInputFileTools-Test.cpp @@ -192,13 +192,13 @@ TEST( RifEclipseInputFileToolsTest, EquilData ) RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, data, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); EXPECT_EQ( (int)10, keywordContent.size() ); } } @@ -232,13 +232,13 @@ TEST( RifEclipseInputFileToolsTest, FaultData ) RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, data, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); EXPECT_EQ( (int)977, keywordContent.size() ); @@ -277,13 +277,13 @@ TEST( RifEclipseInputFileToolsTest, StopAtKeyword ) RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, data, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); EXPECT_TRUE( isStopParsingKeywordDetected ); EXPECT_TRUE( keywordContent.isEmpty() ); @@ -301,13 +301,13 @@ TEST( RifEclipseInputFileToolsTest, StopAtKeyword ) RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, data, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); EXPECT_TRUE( isStopParsingKeywordDetected ); EXPECT_TRUE( keywordContent.isEmpty() ); } @@ -338,13 +338,13 @@ TEST( RifEclipseInputFileToolsTest, DISABLED_FindFilesWithVfp ) RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, data, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); // EXPECT_TRUE( isStopParsingKeywordDetected ); // EXPECT_TRUE( keywordContent.isEmpty() ); @@ -368,13 +368,13 @@ TEST( RifEclipseInputFileToolsTest, DISABLED_FindFilesWithVfp ) RifEclipseInputFileTools::readKeywordAndParseIncludeStatementsRecursively( keyword, keywordToStopParsing, + pathAliasDefinitions, + includeStatementAbsolutePathPrefix, data, startPositionInFile, - pathAliasDefinitions, - &keywordContent, - &fileNamesContainingKeyword, - &isStopParsingKeywordDetected, - includeStatementAbsolutePathPrefix ); + keywordContent, + fileNamesContainingKeyword, + isStopParsingKeywordDetected ); // EXPECT_TRUE( isStopParsingKeywordDetected ); // EXPECT_TRUE( keywordContent.isEmpty() );