diff --git a/ApplicationLibCode/Application/RiaResultNames.cpp b/ApplicationLibCode/Application/RiaResultNames.cpp index 9bb98050d4..9752c9ff31 100644 --- a/ApplicationLibCode/Application/RiaResultNames.cpp +++ b/ApplicationLibCode/Application/RiaResultNames.cpp @@ -443,6 +443,38 @@ QString RiaResultNames::wbsPPResult() return "PP"; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsPPMinResult() +{ + return "PP_MIN"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsPPMaxResult() +{ + return "PP_MAX"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsPPExpResult() +{ + return "PP_EXP"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsPPInitialResult() +{ + return "PP_INIT"; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -459,6 +491,45 @@ QString RiaResultNames::wbsSHMkResult() return "SH_MK"; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsSHMkExpResult() +{ + return "SH_MK_EXP"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsSHMkMinResult() +{ + return "SH_MK_MIN"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsSHMkMaxResult() +{ + return "SH_MK_MAX"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsFGMkExpResult() +{ + return "FG_MK_EXP"; +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::wbsFGMkMinResult() +{ + return "FG_MK_MIN"; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -519,5 +590,10 @@ std::vector RiaResultNames::wbsDerivedResultNames() wbsSFGResult(), wbsSHResult(), wbsSHMkResult(), + wbsSHMkExpResult(), + wbsSHMkMinResult(), + wbsSHMkMaxResult(), + wbsFGMkExpResult(), + wbsFGMkMinResult(), }; } diff --git a/ApplicationLibCode/Application/RiaResultNames.h b/ApplicationLibCode/Application/RiaResultNames.h index e6b600eca9..184aa85ff6 100644 --- a/ApplicationLibCode/Application/RiaResultNames.h +++ b/ApplicationLibCode/Application/RiaResultNames.h @@ -92,6 +92,15 @@ QString wbsSHMkResult(); QString wbsOBGResult(); QString wbsFGResult(); QString wbsSFGResult(); +QString wbsFGMkExpResult(); +QString wbsFGMkMinResult(); +QString wbsSHMkExpResult(); +QString wbsSHMkMinResult(); +QString wbsSHMkMaxResult(); +QString wbsPPMinResult(); +QString wbsPPMaxResult(); +QString wbsPPExpResult(); +QString wbsPPInitialResult(); // Fault results QString formationBinaryAllanResultName(); diff --git a/ApplicationLibCode/Commands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/CMakeLists_files.cmake index d2fcebaf9a..be2b342e52 100644 --- a/ApplicationLibCode/Commands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/CMakeLists_files.cmake @@ -93,6 +93,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicImportGridCalculationExpressionsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicExportSummaryCalculationExpressionsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCalculationExpressionsFeature.h + ${CMAKE_CURRENT_LIST_DIR}/RicImportWellLogCsvFileFeature.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -189,6 +190,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicImportGridCalculationExpressionsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicExportSummaryCalculationExpressionsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCalculationExpressionsFeature.cpp + ${CMAKE_CURRENT_LIST_DIR}/RicImportWellLogCsvFileFeature.cpp ) if(RESINSIGHT_USE_QT_CHARTS) diff --git a/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesImpl.cpp b/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesImpl.cpp index 036731fa87..5850acc945 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesImpl.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesImpl.cpp @@ -33,6 +33,7 @@ #include "RimEclipseCase.h" #include "RimGeoMechCase.h" #include "RimMainPlotCollection.h" +#include "RimWellLogFile.h" #include "RimWellLogLasFile.h" #include "RimWellLogPlotCollection.h" #include "RimWellPath.h" @@ -214,14 +215,16 @@ void RicCreateDepthAdjustedLasFilesImpl::createDestinationWellLasFile( const QSt // Add tvd msl values if existing if ( !tvdMslValues.empty() ) { - const auto unitText = sourceWellLogData->wellLogChannelUnitString( RiaDefines::propertyNameTvdMslDepth(), deptUnit ).toStdString(); + const auto unitText = + sourceWellLogData->convertedWellLogChannelUnitString( RiaDefines::propertyNameTvdMslDepth(), deptUnit ).toStdString(); lasFile.AddLog( RiaDefines::propertyNameTvdMslDepth().toStdString(), unitText, "True vertical depth " + depthUnitComment, tvdMslValues ); } // Add tvd rkb values if existing if ( !tvdRkbValues.empty() ) { - const auto unitText = sourceWellLogData->wellLogChannelUnitString( RiaDefines::propertyNameTvdRkbDepth(), deptUnit ).toStdString(); + const auto unitText = + sourceWellLogData->convertedWellLogChannelUnitString( RiaDefines::propertyNameTvdRkbDepth(), deptUnit ).toStdString(); lasFile.AddLog( RiaDefines::propertyNameTvdRkbDepth().toStdString(), unitText, "True vertical depth (Rotary Kelly Bushing)", tvdRkbValues ); } diff --git a/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesUi.cpp b/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesUi.cpp index f35d1cb23a..021f429aa8 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesUi.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicCreateDepthAdjustedLasFilesUi.cpp @@ -140,7 +140,7 @@ void RicCreateDepthAdjustedLasFilesUi::fieldChangedByUi( const caf::PdmFieldHand wellLogFile = nullptr; if ( sourceWell != nullptr && !sourceWell->wellLogFiles().empty() ) { - wellLogFile = sourceWell->wellLogFiles()[0]; + wellLogFile = dynamic_cast( sourceWell->wellLogFiles()[0] ); } } if ( changedField == &wellLogFile ) @@ -188,7 +188,7 @@ void RicCreateDepthAdjustedLasFilesUi::setDefaultValues() if ( !wellPath->wellLogFiles().empty() ) { sourceWell = wellPath; - wellLogFile = wellPath->wellLogFiles()[0]; + wellLogFile = dynamic_cast( sourceWell->wellLogFiles()[0] ); break; } } diff --git a/ApplicationLibCode/Commands/RicImportWellLogCsvFileFeature.cpp b/ApplicationLibCode/Commands/RicImportWellLogCsvFileFeature.cpp new file mode 100644 index 0000000000..18b963e8e0 --- /dev/null +++ b/ApplicationLibCode/Commands/RicImportWellLogCsvFileFeature.cpp @@ -0,0 +1,98 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RicImportWellLogCsvFileFeature.h" + +#include "RiaGuiApplication.h" +#include "RiaLogging.h" + +#include "RimOilField.h" +#include "RimProject.h" +#include "RimWellLogCsvFile.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "Riu3DMainWindowTools.h" +#include "RiuFileDialogTools.h" + +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT( RicImportWellLogCsvFileFeature, "RicImportWellLogCsvFileFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportWellLogCsvFileFeature::isCommandEnabled() const +{ + return caf::SelectionManager::instance()->selectedItemOfType() != nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportWellLogCsvFileFeature::onActionTriggered( bool isChecked ) +{ + QString pathCacheName = "WELL_LOGS_DIR"; + + if ( auto wellPath = caf::SelectionManager::instance()->selectedItemOfType() ) + { + RiaGuiApplication* app = RiaGuiApplication::instance(); + + QString defaultDir = app->lastUsedDialogDirectory( pathCacheName ); + QString fileName = + RiuFileDialogTools::getOpenFileName( nullptr, "Open Well Log CSV", defaultDir, "Well Log csv (*.csv);;All files(*.*)" ); + + if ( fileName.isEmpty() ) return; + + RimOilField* oilField = RimProject::current()->activeOilField(); + if ( oilField == nullptr ) return; + + if ( !oilField->wellPathCollection ) oilField->wellPathCollection = std::make_unique(); + + RimWellLogCsvFile* wellLogCsvFile = new RimWellLogCsvFile; + wellLogCsvFile->setFileName( fileName ); + oilField->wellPathCollection->addWellLog( wellLogCsvFile, wellPath ); + + QString errorMessage; + if ( !wellLogCsvFile->readFile( &errorMessage ) ) + { + wellPath->deleteWellLogFile( wellLogCsvFile ); + QString displayMessage = "Errors opening the CSV file: \n" + errorMessage; + RiaLogging::errorInMessageBox( Riu3DMainWindowTools::mainWindowWidget(), "File open error", displayMessage ); + return; + } + else + { + wellLogCsvFile->updateConnectedEditors(); + } + + app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( fileName ).absolutePath() ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportWellLogCsvFileFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setIcon( QIcon( ":/LasFile16x16.png" ) ); + actionToSetup->setText( "Import Well Log From CSV" ); +} diff --git a/ApplicationLibCode/Commands/RicImportWellLogCsvFileFeature.h b/ApplicationLibCode/Commands/RicImportWellLogCsvFileFeature.h new file mode 100644 index 0000000000..a9f79e291c --- /dev/null +++ b/ApplicationLibCode/Commands/RicImportWellLogCsvFileFeature.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 RicImportWellLogCsvFileFeature : 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/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp b/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp index 50837d80c9..daf5eab195 100644 --- a/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp +++ b/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp @@ -21,7 +21,7 @@ #include "RimViewWindow.h" #include "RimWellAllocationPlot.h" -#include "RimWellLogLasFile.h" +#include "RimWellLogFile.h" #include "RimWellLogPlot.h" #include "RimWellPath.h" #include "RimWellPltPlot.h" @@ -40,7 +40,7 @@ CAF_CMD_SOURCE_INIT( RicWellLogFileCloseFeature, "RicWellLogFileCloseFeature" ); //-------------------------------------------------------------------------------------------------- bool RicWellLogFileCloseFeature::isCommandEnabled() const { - std::vector objects = caf::selectedObjectsByType(); + std::vector objects = caf::selectedObjectsByType(); return !objects.empty(); } @@ -49,7 +49,7 @@ bool RicWellLogFileCloseFeature::isCommandEnabled() const //-------------------------------------------------------------------------------------------------- void RicWellLogFileCloseFeature::onActionTriggered( bool isChecked ) { - std::vector objects = caf::selectedObjectsByType(); + std::vector objects = caf::selectedObjectsByType(); if ( objects.empty() ) return; @@ -85,7 +85,7 @@ void RicWellLogFileCloseFeature::setupActionLook( QAction* actionToSetup ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::set RicWellLogFileCloseFeature::referringWellLogPlots( const RimWellLogLasFile* wellLogFile ) +std::set RicWellLogFileCloseFeature::referringWellLogPlots( const RimWellLogFile* wellLogFile ) { // Remove all curves displaying data from the specified wellLogFile std::vector referringObjects = wellLogFile->objectsWithReferringPtrFields(); diff --git a/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h b/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h index 003458ce43..aba98962f1 100644 --- a/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h +++ b/ApplicationLibCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h @@ -22,7 +22,7 @@ #include "cafCmdFeature.h" #include -class RimWellLogLasFile; +class RimWellLogFile; class RimViewWindow; //================================================================================================== @@ -37,5 +37,5 @@ protected: void onActionTriggered( bool isChecked ) override; void setupActionLook( QAction* actionToSetup ) override; - std::set referringWellLogPlots( const RimWellLogLasFile* wellLogFile ); + std::set referringWellLogPlots( const RimWellLogFile* wellLogFile ); }; diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp index ae50f33846..66bf0a75ea 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.cpp @@ -78,7 +78,7 @@ public: //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellPlotTools::hasPressureData( const RimWellLogLasFile* wellLogFile ) +bool RimWellPlotTools::hasPressureData( const RimWellLogFile* wellLogFile ) { for ( RimWellLogFileChannel* const wellLogChannel : wellLogFile->wellLogChannels() ) { @@ -92,7 +92,7 @@ bool RimWellPlotTools::hasPressureData( const RimWellLogLasFile* wellLogFile ) //-------------------------------------------------------------------------------------------------- bool RimWellPlotTools::hasPressureData( RimWellPath* wellPath ) { - for ( RimWellLogLasFile* const wellLogFile : wellPath->wellLogFiles() ) + for ( RimWellLogFile* const wellLogFile : wellPath->wellLogFiles() ) { if ( hasPressureData( wellLogFile ) ) { @@ -144,7 +144,7 @@ bool RimWellPlotTools::hasPressureData( RimEclipseResultCase* gridCase ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellPlotTools::hasFlowData( const RimWellLogLasFile* wellLogFile ) +bool RimWellPlotTools::hasFlowData( const RimWellLogFile* wellLogFile ) { for ( RimWellLogFileChannel* const wellLogChannel : wellLogFile->wellLogChannels() ) { @@ -158,7 +158,7 @@ bool RimWellPlotTools::hasFlowData( const RimWellLogLasFile* wellLogFile ) //-------------------------------------------------------------------------------------------------- bool RimWellPlotTools::hasFlowData( const RimWellPath* wellPath ) { - for ( RimWellLogLasFile* const wellLogFile : wellPath->wellLogFiles() ) + for ( RimWellLogFile* const wellLogFile : wellPath->wellLogFiles() ) { if ( hasFlowData( wellLogFile ) ) { @@ -268,20 +268,20 @@ void RimWellPlotTools::addTimeStepsToMap( std::map RimWellPlotTools::wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName ) +std::vector RimWellPlotTools::wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName ) { - std::vector wellLogFiles; - const RimProject* const project = RimProject::current(); - std::vector wellPaths = project->allWellPaths(); + std::vector wellLogFiles; + const RimProject* const project = RimProject::current(); + std::vector wellPaths = project->allWellPaths(); for ( auto wellPath : wellPaths ) { if ( !wellPathNameOrSimWellName.isEmpty() && ( wellPathNameOrSimWellName == wellPath->associatedSimulationWellName() || wellPathNameOrSimWellName == wellPath->name() ) ) { - const std::vector files = wellPath->wellLogFiles(); + const std::vector files = wellPath->wellLogFiles(); - for ( RimWellLogLasFile* file : files ) + for ( RimWellLogFile* file : files ) { if ( hasPressureData( file ) ) { @@ -297,7 +297,7 @@ std::vector RimWellPlotTools::wellLogFilesContainingPressure //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogFileChannel* RimWellPlotTools::getPressureChannelFromWellFile( const RimWellLogLasFile* wellLogFile ) +RimWellLogFileChannel* RimWellPlotTools::getPressureChannelFromWellFile( const RimWellLogFile* wellLogFile ) { if ( wellLogFile != nullptr ) { @@ -315,19 +315,19 @@ RimWellLogFileChannel* RimWellPlotTools::getPressureChannelFromWellFile( const R //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimWellPlotTools::wellLogFilesContainingFlow( const QString& wellPathName ) +std::vector RimWellPlotTools::wellLogFilesContainingFlow( const QString& wellPathName ) { - std::vector wellLogFiles; - const RimProject* const project = RimProject::current(); - std::vector wellPaths = project->allWellPaths(); + std::vector wellLogFiles; + const RimProject* const project = RimProject::current(); + std::vector wellPaths = project->allWellPaths(); for ( auto wellPath : wellPaths ) { if ( wellPath->name() == wellPathName ) { - std::vector files = wellPath->wellLogFiles(); + std::vector files = wellPath->wellLogFiles(); - for ( RimWellLogLasFile* file : files ) + for ( RimWellLogFile* file : files ) { if ( hasFlowData( file ) ) { @@ -342,14 +342,14 @@ std::vector RimWellPlotTools::wellLogFilesContainingFlow( co //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellPath* RimWellPlotTools::wellPathFromWellLogFile( const RimWellLogLasFile* wellLogFile ) +RimWellPath* RimWellPlotTools::wellPathFromWellLogFile( const RimWellLogFile* wellLogFile ) { RimProject* const project = RimProject::current(); for ( const auto& oilField : project->oilFields ) { for ( const auto& wellPath : oilField->wellPathCollection()->allWellPaths() ) { - for ( RimWellLogLasFile* const file : wellPath->wellLogFiles() ) + for ( RimWellLogFile* const file : wellPath->wellLogFiles() ) { if ( file == wellLogFile ) { @@ -676,7 +676,7 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve( const RimWellLogCu } else if ( wellLogFileCurve != nullptr ) { - RimWellLogLasFile* const wellLogFile = wellLogFileCurve->wellLogFile(); + RimWellLogFile* const wellLogFile = wellLogFileCurve->wellLogFile(); if ( wellLogFile != nullptr ) { @@ -684,7 +684,10 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve( const RimWellLogCu if ( date.isValid() ) { - return RiaRftPltCurveDefinition( RifDataSourceForRftPlt( wellLogFile ), wellLogFile->wellName(), date ); + if ( auto wellLogLasFile = dynamic_cast( wellLogFile ) ) + { + return RiaRftPltCurveDefinition( RifDataSourceForRftPlt( wellLogLasFile ), wellLogFile->wellName(), date ); + } } } } diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.h b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.h index db83992e72..8ff2ccbb8a 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.h +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPlotTools.h @@ -75,24 +75,24 @@ public: static bool isTotalFlowChannel( const QString& channelName ); static FlowPhase flowPhaseFromChannelName( const QString& channelName ); - static std::vector wellLogFilesContainingFlow( const QString& wellName ); - static RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName ); + static std::vector wellLogFilesContainingFlow( const QString& wellName ); + static RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName ); // RFT Only private: static std::pair pressureResultDataInfo( const RigEclipseCaseData* eclipseCaseData ); public: - static void addTimeStepsToMap( std::map>& destMap, - const std::map>& timeStepsToAdd ); - static std::vector wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName ); - static RimWellLogFileChannel* getPressureChannelFromWellFile( const RimWellLogLasFile* wellLogFile ); - static RimWellPath* wellPathFromWellLogFile( const RimWellLogLasFile* wellLogFile ); + static void addTimeStepsToMap( std::map>& destMap, + const std::map>& timeStepsToAdd ); + static std::vector wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName ); + static RimWellLogFileChannel* getPressureChannelFromWellFile( const RimWellLogFile* wellLogFile ); + static RimWellPath* wellPathFromWellLogFile( const RimWellLogFile* wellLogFile ); static std::map> timeStepsMapFromGridCase( RimEclipseCase* gridCase ); static RiaRftPltCurveDefinition curveDefFromCurve( const RimWellLogCurve* curve ); // others - static bool hasFlowData( const RimWellLogLasFile* wellLogFile ); + static bool hasFlowData( const RimWellLogFile* wellLogFile ); static bool hasAssociatedWellPath( const QString& wellName ); // Both @@ -145,7 +145,7 @@ private: static std::set FLOW_DATA_NAMES; - static bool hasPressureData( const RimWellLogLasFile* wellLogFile ); + static bool hasPressureData( const RimWellLogFile* wellLogFile ); static bool isPressureChannel( RimWellLogFileChannel* channel ); static bool hasPressureData( RimEclipseResultCase* gridCase ); static bool hasPressureData( RimWellPath* wellPath ); diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp index 43c06c9bb8..0fc439f89e 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellPltPlot.cpp @@ -48,6 +48,7 @@ #include "RimSummaryCurveAppearanceCalculator.h" #include "RimWellFlowRateCurve.h" #include "RimWellLogExtractionCurve.h" +#include "RimWellLogFile.h" #include "RimWellLogFileChannel.h" #include "RimWellLogLasFile.h" #include "RimWellLogLasFileCurve.h" @@ -780,10 +781,13 @@ QList RimWellPltPlot::calculateValueOptions( const caf:: for ( const auto& wellLogFile : wellLogFiles ) { - auto addr = RifDataSourceForRftPlt( wellLogFile ); - auto item = caf::PdmOptionItemInfo( wellLogFile->name(), QVariant::fromValue( addr ) ); - item.setLevel( 1 ); - options.push_back( item ); + if ( auto wellLogLasFile = dynamic_cast( wellLogFile ) ) + { + auto addr = RifDataSourceForRftPlt( wellLogLasFile ); + auto item = caf::PdmOptionItemInfo( wellLogFile->name(), QVariant::fromValue( addr ) ); + item.setLevel( 1 ); + options.push_back( item ); + } } } } @@ -994,8 +998,11 @@ void RimWellPltPlot::initAfterLoad() { for ( const auto& wellLogFile : wellLogFiles ) { - auto addr = RifDataSourceForRftPlt( wellLogFile ); - selectedSources.push_back( addr ); + if ( auto wellLogLasFile = dynamic_cast( wellLogFile ) ) + { + auto addr = RifDataSourceForRftPlt( wellLogLasFile ); + selectedSources.push_back( addr ); + } } } diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp index c9d7e4faa2..160c401fba 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftPlot.cpp @@ -294,12 +294,15 @@ void RimWellRftPlot::applyInitialSelections( std::variant wellLogFiles = RimWellPlotTools::wellLogFilesContainingPressure( m_wellPathNameOrSimWellName ); + std::vector wellLogFiles = RimWellPlotTools::wellLogFilesContainingPressure( m_wellPathNameOrSimWellName ); if ( !wellLogFiles.empty() ) { - for ( RimWellLogLasFile* const wellLogFile : wellLogFiles ) + for ( RimWellLogFile* const wellLogFile : wellLogFiles ) { - sourcesToSelect.push_back( RifDataSourceForRftPlt( wellLogFile ) ); + if ( auto wellLogLasFile = dynamic_cast( wellLogFile ) ) + { + sourcesToSelect.push_back( RifDataSourceForRftPlt( wellLogLasFile ) ); + } } } @@ -721,9 +724,12 @@ std::vector RimWellRftPlot::selectedSourcesExpanded() co { if ( addr.sourceType() == RifDataSourceForRftPlt::SourceType::OBSERVED_LAS_FILE ) { - for ( RimWellLogLasFile* const wellLogFile : RimWellPlotTools::wellLogFilesContainingPressure( m_wellPathNameOrSimWellName ) ) + for ( RimWellLogFile* const wellLogFile : RimWellPlotTools::wellLogFilesContainingPressure( m_wellPathNameOrSimWellName ) ) { - sources.push_back( RifDataSourceForRftPlt( wellLogFile ) ); + if ( auto wellLogLasFile = dynamic_cast( wellLogFile ) ) + { + sources.push_back( RifDataSourceForRftPlt( wellLogLasFile ) ); + } } } else @@ -931,10 +937,13 @@ QList RimWellRftPlot::calculateValueOptionsForSources() for ( const auto& wellLogFile : wellLogFiles ) { - auto addr = RifDataSourceForRftPlt( wellLogFile ); - auto item = caf::PdmOptionItemInfo( "Observed Data", QVariant::fromValue( addr ) ); - item.setLevel( 1 ); - options.push_back( item ); + if ( auto wellLogLasFile = dynamic_cast( wellLogFile ) ) + { + auto addr = RifDataSourceForRftPlt( wellLogLasFile ); + auto item = caf::PdmOptionItemInfo( "Observed Data", QVariant::fromValue( addr ) ); + item.setLevel( 1 ); + options.push_back( item ); + } } } const std::vector observedFmuRftCases = RimWellPlotTools::observedFmuRftDataForWell( m_wellPathNameOrSimWellName ); diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index 8745c6db91..d036783239 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -1492,6 +1492,7 @@ int RimContextCommandBuilder::appendImportMenu( caf::CmdFeatureMenuBuilder& menu candidates << "RicWellPathsImportFileFeature"; candidates << "RicWellPathFormationsImportFileFeature"; candidates << "RicWellLogsImportFileFeature"; + candidates << "RicImportWellLogCsvFileFeature"; candidates << "RicReloadWellPathFormationNamesFeature"; return appendSubMenuWithCommands( menuBuilder, candidates, "Import", QIcon(), addSeparatorBeforeMenu ); diff --git a/ApplicationLibCode/ProjectDataModel/RimWbsParameters.cpp b/ApplicationLibCode/ProjectDataModel/RimWbsParameters.cpp index dc3567aeae..5b644a9add 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWbsParameters.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWbsParameters.cpp @@ -120,6 +120,8 @@ RimWbsParameters::RimWbsParameters() { RigWbsParameter::K0_FG(), &m_userDefinedK0FG }, { RigWbsParameter::K0_SH(), &m_userDefinedK0SH }, { RigWbsParameter::FG_Shale(), &m_FGShaleMultiplier }, + { RigWbsParameter::FG_MkMin(), &m_FGShaleMultiplier }, + { RigWbsParameter::FG_MkExp(), &m_FGShaleMultiplier }, { RigWbsParameter::waterDensity(), &m_userDefinedDensity } }; for ( auto parameterFieldPair : m_parameterSourceFields ) diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/WellLog/CMakeLists_files.cmake index 1b2f2bbe05..f3030b156c 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/WellLog/CMakeLists_files.cmake @@ -19,6 +19,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimWellLogLasCurve.h ${CMAKE_CURRENT_LIST_DIR}/RimWellLogExtractionCurve.h ${CMAKE_CURRENT_LIST_DIR}/RimWellLogLasFile.h + ${CMAKE_CURRENT_LIST_DIR}/RimWellLogCsvFile.h ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFile.h ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileUtil.h ${CMAKE_CURRENT_LIST_DIR}/RimWellLogChannel.h @@ -38,6 +39,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurve.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellLogExtractionCurve.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellLogLasFile.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimWellLogCsvFile.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFile.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileUtil.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileChannel.cpp diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.cpp index f143200c63..78673e7dd7 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.cpp @@ -25,6 +25,8 @@ #include "RimWellLogLasFileCurveNameConfig.h" #include "RimWellPath.h" +#include "RiaQDateTimeTools.h" + #include //================================================================================================== @@ -89,7 +91,7 @@ void Rim3dWellLogFileCurve::curveValuesAndMds( std::vector* values, std: if ( m_wellLogFile ) { - RigWellLogLasFile* wellLogFile = m_wellLogFile->wellLogFileData(); + RigWellLogFile* wellLogFile = m_wellLogFile->wellLogFileData(); if ( wellLogFile ) { *values = wellLogFile->values( m_wellLogChannelName ); @@ -135,7 +137,7 @@ QString Rim3dWellLogFileCurve::createAutoName() const channelNameAvailable = true; } - RigWellLogLasFile* wellLogFile = m_wellLogFile ? m_wellLogFile->wellLogFileData() : nullptr; + RigWellLogFile* wellLogFile = m_wellLogFile ? m_wellLogFile->wellLogFileData() : nullptr; if ( wellLogFile ) { @@ -153,10 +155,10 @@ QString Rim3dWellLogFileCurve::createAutoName() const } */ } - QString date = wellLogFile->date(); + QString date = m_wellLogFile->date().toString( RiaQDateTimeTools::dateFormatString() ); if ( !date.isEmpty() ) { - name.push_back( wellLogFile->date() ); + name.push_back( date ); } } @@ -223,7 +225,7 @@ QList Rim3dWellLogFileCurve::calculateValueOptions( cons if ( wellPath && !wellPath->wellLogFiles().empty() ) { - for ( RimWellLogLasFile* const wellLogFile : wellPath->wellLogFiles() ) + for ( RimWellLogFile* const wellLogFile : wellPath->wellLogFiles() ) { QFileInfo fileInfo( wellLogFile->fileName() ); options.push_back( caf::PdmOptionItemInfo( fileInfo.baseName(), wellLogFile ) ); diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.h b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.h index 838cf3c5f9..e4adbb1be6 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/Rim3dWellLogFileCurve.h @@ -24,7 +24,7 @@ #include "cafPdmField.h" #include "cafPdmPtrField.h" -class RimWellLogLasFile; +class RimWellLogFile; class RimWellLogLasFileCurveNameConfig; //================================================================================================== @@ -55,7 +55,7 @@ private: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; private: - caf::PdmPtrField m_wellLogFile; + caf::PdmPtrField m_wellLogFile; caf::PdmField m_wellLogChannelName; caf::PdmChildField m_nameConfig; }; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.cpp index 9bd9af99b6..671fd42427 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.cpp @@ -1021,7 +1021,7 @@ std::vector RimEnsembleWellLogCurveSet::filterEnsembleCases( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimEnsembleWellLogCurveSet::isSameRealization( RimSummaryCase* summaryCase, RimWellLogLasFile* wellLogFile ) const +bool RimEnsembleWellLogCurveSet::isSameRealization( RimSummaryCase* summaryCase, RimWellLogFile* wellLogFile ) const { QString wellLogFileName = wellLogFile->fileName(); diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.h index 3834101bb5..c8af6c95e4 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimEnsembleWellLogCurveSet.h @@ -45,7 +45,7 @@ class RimEnsembleStatistics; class RimEnsembleStatisticsCase; class RimWellLogCurve; class RimWellLogLasFileCurve; -class RimWellLogLasFile; +class RimWellLogFile; class RimPlotCurveAppearance; class RigWellPathFormations; @@ -150,7 +150,7 @@ private: void updateCurveColors(); - bool isSameRealization( RimSummaryCase* summaryCase, RimWellLogLasFile* wellLogFile ) const; + bool isSameRealization( RimSummaryCase* summaryCase, RimWellLogFile* wellLogFile ) const; RimSummaryCase* findMatchingSummaryCase( RimWellLogLasFileCurve* wellLogCurve ) const; void connectEnsembleCurveSetFilterSignals(); diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCsvFile.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCsvFile.cpp new file mode 100644 index 0000000000..f5e38452d1 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCsvFile.cpp @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimWellLogCsvFile.h" + +#include "RiaFieldHandleTools.h" +#include "RiaLogging.h" + +#include "RigWellLogCsvFile.h" + +#include "RimFileWellPath.h" +#include "RimTools.h" +#include "RimWellLogFileChannel.h" + +#include +#include +#include + +CAF_PDM_SOURCE_INIT( RimWellLogCsvFile, "WellLogCsvFile" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogCsvFile::RimWellLogCsvFile() +{ + CAF_PDM_InitObject( "Well CSV File Info", ":/LasFile16x16.png" ); + + CAF_PDM_InitFieldNoDefault( &m_wellName, "WellName", "" ); + m_wellName.uiCapability()->setUiReadOnly( true ); + RiaFieldHandleTools::disableWriteAndSetFieldHidden( &m_wellName ); + + CAF_PDM_InitFieldNoDefault( &m_name, "Name", "" ); + m_name.uiCapability()->setUiReadOnly( true ); + RiaFieldHandleTools::disableWriteAndSetFieldHidden( &m_name ); + + m_wellLogDataFile = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogCsvFile::~RimWellLogCsvFile() +{ + m_wellLogChannelNames.deleteChildren(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogCsvFile::readFile( QString* errorMessage ) +{ + if ( !m_wellLogDataFile.p() ) + { + m_wellLogDataFile = new RigWellLogCsvFile; + } + + m_name = QFileInfo( m_fileName().path() ).fileName(); + + auto wellPath = firstAncestorOrThisOfType(); + if ( !wellPath ) + { + RiaLogging::error( "No well path found" ); + return false; + } + + if ( !m_wellLogDataFile->open( m_fileName().path(), wellPath->wellPathGeometry(), errorMessage ) ) + { + m_wellLogDataFile = nullptr; + RiaLogging::error( "Failed to open file." ); + + return false; + } + + m_wellLogChannelNames.deleteChildren(); + + QStringList wellLogNames = m_wellLogDataFile->wellLogChannelNames(); + for ( int logIdx = 0; logIdx < wellLogNames.size(); logIdx++ ) + { + RimWellLogFileChannel* wellLog = new RimWellLogFileChannel(); + wellLog->setName( wellLogNames[logIdx] ); + m_wellLogChannelNames.push_back( wellLog ); + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogCsvFile::wellName() const +{ + return m_wellName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimWellLogCsvFile::findMdAndChannelValuesForWellPath( const RimWellPath& wellPath, + const QString& channelName, + QString* unitString /*=nullptr*/ ) +{ + std::vector wellLogFiles = wellPath.descendantsIncludingThisOfType(); + for ( RimWellLogCsvFile* wellLogFile : wellLogFiles ) + { + RigWellLogCsvFile* fileData = wellLogFile->wellLogFileData(); + std::vector channelValues = fileData->values( channelName ); + if ( !channelValues.empty() ) + { + if ( unitString ) + { + *unitString = fileData->wellLogChannelUnitString( channelName ); + } + std::vector depthValues = fileData->depthValues(); + CVF_ASSERT( depthValues.size() == channelValues.size() ); + std::vector> depthValuePairs; + for ( size_t i = 0; i < depthValues.size(); ++i ) + { + depthValuePairs.push_back( std::make_pair( depthValues[i], channelValues[i] ) ); + } + return depthValuePairs; + } + } + return std::vector>(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogCsvFile* RimWellLogCsvFile::wellLogFileData() +{ + return m_wellLogDataFile.p(); +} diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCsvFile.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCsvFile.h new file mode 100644 index 0000000000..c67a0b4058 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCsvFile.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 "RimWellLogFile.h" + +#include "RigWellLogCsvFile.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include +#include + +class RimWellPath; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogCsvFile : public RimWellLogFile +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogCsvFile(); + ~RimWellLogCsvFile() override; + + QString name() const override { return m_name; } + + bool readFile( QString* errorMessage ) override; + + QString wellName() const override; + + RigWellLogCsvFile* wellLogFileData() override; + + std::vector> + findMdAndChannelValuesForWellPath( const RimWellPath& wellPath, const QString& channelName, QString* unitString = nullptr ) override; + +private: + caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } + +private: + cvf::ref m_wellLogDataFile; + caf::PdmField m_wellName; + caf::PdmField m_name; +}; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurveCommonDataSource.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurveCommonDataSource.cpp index 11c7d2757f..8cfc90978c 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurveCommonDataSource.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogCurveCommonDataSource.cpp @@ -527,7 +527,7 @@ void RimWellLogCurveCommonDataSource::applyDataSourceChanges( const std::vector< fileCurve->setWellPath( wellPathToApply() ); if ( !fileCurve->wellLogChannelUiName().isEmpty() ) { - RimWellLogLasFile* logFile = wellPathToApply()->firstWellLogFileMatchingChannelName( fileCurve->wellLogChannelUiName() ); + RimWellLogFile* logFile = wellPathToApply()->firstWellLogFileMatchingChannelName( fileCurve->wellLogChannelUiName() ); fileCurve->setWellLogFile( logFile ); auto parentPlot = fileCurve->firstAncestorOrThisOfTypeAsserted(); plots.insert( parentPlot ); diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogExtractionCurve.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogExtractionCurve.cpp index 471553c879..a3a15de576 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogExtractionCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogExtractionCurve.cpp @@ -885,12 +885,10 @@ void RimWellLogExtractionCurve::findAndLoadWbsParametersFromFiles( const RimWell else { QString errMsg = - QString( "Could not convert units of LAS-channel %1 from %2 to %3" ).arg( lasAddress ).arg( lasUnits ).arg( extractorUnits ); + QString( "Could not convert units of LAS-channel '%1' from '%2' to '%3'" ).arg( lasAddress ).arg( lasUnits ).arg( extractorUnits ); RiaLogging::error( errMsg ); } } - - // csv } } diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.cpp index a84520b0ed..c863c37bce 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.cpp @@ -23,11 +23,19 @@ #include "RimWellLogFileChannel.h" #include "RiaFieldHandleTools.h" +#include "RiaQDateTimeTools.h" + +#include "cafPdmUiDateEditor.h" #include CAF_PDM_ABSTRACT_SOURCE_INIT( RimWellLogFile, "WellLogFileInterface" ); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QDateTime RimWellLogFile::DEFAULT_DATE_TIME = RiaQDateTimeTools::createUtcDateTime( QDate( 1900, 1, 1 ) ); + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -38,6 +46,8 @@ RimWellLogFile::RimWellLogFile() CAF_PDM_InitFieldNoDefault( &m_fileName, "FileName", "Filename" ); m_fileName.uiCapability()->setUiReadOnly( true ); + CAF_PDM_InitFieldNoDefault( &m_date, "Date", "Date" ); + CAF_PDM_InitFieldNoDefault( &m_wellLogChannelNames, "WellLogFileChannels", "" ); RiaFieldHandleTools::disableWriteAndSetFieldHidden( &m_wellLogChannelNames ); } @@ -78,3 +88,33 @@ std::vector RimWellLogFile::wellLogChannels() const } return channels; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QDateTime RimWellLogFile::date() const +{ + return m_date; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFile::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) +{ + if ( changedField == &m_date ) + { + // Due to a possible bug in QDateEdit/PdmUiDateEditor, convert m_date to a QDateTime having UTC timespec + m_date = RiaQDateTimeTools::createUtcDateTime( m_date().date(), m_date().time() ); + } +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFile::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) +{ + if ( caf::PdmUiDateEditorAttribute* attrib = dynamic_cast( attribute ) ) + { + attrib->dateFormat = RiaQDateTimeTools::dateFormatString(); + } +} diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.h index 3c38d5afda..399cf23367 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogFile.h @@ -22,11 +22,14 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include #include class RimWellLogFileChannel; class RimWellPath; +class RigWellLogFile; + //================================================================================================== /// /// @@ -43,10 +46,23 @@ public: virtual QString fileName() const; virtual std::vector wellLogChannels() const; + virtual QString wellName() const = 0; + virtual QString name() const = 0; + virtual bool readFile( QString* errorMessage ) = 0; + virtual RigWellLogFile* wellLogFileData() = 0; + + virtual QDateTime date() const; + virtual std::vector> findMdAndChannelValuesForWellPath( const RimWellPath& wellPath, const QString& channelName, QString* unitString = nullptr ) = 0; + const static QDateTime DEFAULT_DATE_TIME; + protected: + void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + caf::PdmChildArrayField m_wellLogChannelNames; caf::PdmField m_fileName; + caf::PdmField m_date; }; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.cpp index 964aadc33e..45ccea42ee 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.cpp @@ -36,8 +36,6 @@ #include "Riu3DMainWindowTools.h" -#include "cafPdmUiDateEditor.h" - #include #include #include @@ -54,11 +52,6 @@ void caf::AppEnum::setUp() } } // namespace caf -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const QDateTime RimWellLogLasFile::DEFAULT_DATE_TIME = RiaQDateTimeTools::createUtcDateTime( QDate( 1900, 1, 1 ) ); - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -70,13 +63,12 @@ RimWellLogLasFile::RimWellLogLasFile() m_wellName.uiCapability()->setUiReadOnly( true ); RiaFieldHandleTools::disableWriteAndSetFieldHidden( &m_wellName ); - CAF_PDM_InitFieldNoDefault( &m_date, "Date", "Date" ); - m_date.uiCapability()->setUiReadOnly( true ); - CAF_PDM_InitFieldNoDefault( &m_name, "Name", "" ); m_name.uiCapability()->setUiReadOnly( true ); RiaFieldHandleTools::disableWriteAndSetFieldHidden( &m_name ); + m_date.uiCapability()->setUiReadOnly( true ); + CAF_PDM_InitField( &m_wellFlowCondition, "WellFlowCondition", caf::AppEnum( RimWellLogLasFile::WELL_FLOW_COND_STANDARD ), @@ -188,14 +180,6 @@ QString RimWellLogLasFile::wellName() const return m_wellName; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QDateTime RimWellLogLasFile::date() const -{ - return m_date; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -265,30 +249,6 @@ void RimWellLogLasFile::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi uiOrdering.skipRemainingFields( true ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellLogLasFile::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) -{ - if ( changedField == &m_date ) - { - // Due to a possible bug in QDateEdit/PdmUiDateEditor, convert m_date to a QDateTime having UTC timespec - m_date = RiaQDateTimeTools::createUtcDateTime( m_date().date(), m_date().time() ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellLogLasFile::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) -{ - caf::PdmUiDateEditorAttribute* attrib = dynamic_cast( attribute ); - if ( attrib != nullptr ) - { - attrib->dateFormat = RiaQDateTimeTools::dateFormatString(); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.h index f2d8f1c9a6..cc34eb4499 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFile.h @@ -42,22 +42,19 @@ class RimWellLogLasFile : public RimWellLogFile { CAF_PDM_HEADER_INIT; - const static QDateTime DEFAULT_DATE_TIME; - public: RimWellLogLasFile(); ~RimWellLogLasFile() override; static RimWellLogLasFile* readWellLogFile( const QString& logFilePath, QString* errorMessage ); - QString name() const { return m_name; } + QString name() const override { return m_name; } - bool readFile( QString* errorMessage ); + bool readFile( QString* errorMessage ) override; - QString wellName() const; - QDateTime date() const; + QString wellName() const override; - RigWellLogLasFile* wellLogFileData() { return m_wellLogDataFile.p(); } + RigWellLogLasFile* wellLogFileData() override { return m_wellLogDataFile.p(); } bool hasFlowData() const; @@ -75,8 +72,6 @@ public: private: void setupBeforeSave() override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } @@ -86,7 +81,6 @@ private: cvf::ref m_wellLogDataFile; caf::PdmField m_wellName; caf::PdmField m_name; - caf::PdmField m_date; bool m_lasFileHasValidDate; caf::PdmField> m_wellFlowCondition; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.cpp index 99eed65c98..4f857a210e 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.cpp @@ -22,6 +22,7 @@ #include "RiaLogging.h" #include "RiaPreferences.h" +#include "RiaQDateTimeTools.h" #include "RiaResultNames.h" #include "RigWellLogCurveData.h" #include "RigWellLogIndexDepthOffset.h" @@ -84,7 +85,7 @@ void RimWellLogLasFileCurve::onLoadDataAndUpdate( bool updateParentPlot ) if ( m_wellPath && m_wellLogFile ) { - RigWellLogLasFile* wellLogFile = m_wellLogFile->wellLogFileData(); + RigWellLogFile* wellLogFile = m_wellLogFile->wellLogFileData(); if ( wellLogFile ) { std::vector values = wellLogFile->values( m_wellLogChannelName ); @@ -286,7 +287,7 @@ void RimWellLogLasFileCurve::setWellLogChannelName( const QString& name ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogLasFileCurve::setWellLogFile( RimWellLogLasFile* wellLogFile ) +void RimWellLogLasFileCurve::setWellLogFile( RimWellLogFile* wellLogFile ) { m_wellLogFile = wellLogFile; } @@ -401,7 +402,7 @@ QList RimWellLogLasFileCurve::calculateValueOptions( con { if ( m_wellPath() && !m_wellPath->wellLogFiles().empty() ) { - for ( RimWellLogLasFile* const wellLogFile : m_wellPath->wellLogFiles() ) + for ( RimWellLogFile* const wellLogFile : m_wellPath->wellLogFiles() ) { QFileInfo fileInfo( wellLogFile->fileName() ); options.push_back( caf::PdmOptionItemInfo( fileInfo.baseName(), wellLogFile ) ); @@ -423,7 +424,7 @@ void RimWellLogLasFileCurve::initAfterRead() if ( m_wellPath->wellLogFiles().size() == 1 ) { - m_wellLogFile = m_wellPath->wellLogFiles().front(); + m_wellLogFile = dynamic_cast( m_wellPath->wellLogFiles().front() ); } } @@ -456,14 +457,14 @@ QString RimWellLogLasFileCurve::createCurveAutoName() channelNameAvailable = true; } - RigWellLogLasFile* wellLogFile = m_wellLogFile ? m_wellLogFile->wellLogFileData() : nullptr; + RigWellLogFile* wellLogFile = m_wellLogFile ? m_wellLogFile->wellLogFileData() : nullptr; if ( wellLogFile ) { if ( channelNameAvailable ) { auto wellLogPlot = firstAncestorOrThisOfTypeAsserted(); - QString unitName = wellLogFile->wellLogChannelUnitString( m_wellLogChannelName, wellLogPlot->depthUnit() ); + QString unitName = wellLogFile->convertedWellLogChannelUnitString( m_wellLogChannelName, wellLogPlot->depthUnit() ); if ( !unitName.isEmpty() ) { @@ -471,10 +472,10 @@ QString RimWellLogLasFileCurve::createCurveAutoName() } } - QString date = wellLogFile->date(); + QString date = m_wellLogFile->date().toString( RiaQDateTimeTools::dateFormatString() ); if ( !date.isEmpty() ) { - name.push_back( wellLogFile->date() ); + name.push_back( date ); } } @@ -507,7 +508,7 @@ QString RimWellLogLasFileCurve::wellLogChannelUnits() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogLasFile* RimWellLogLasFileCurve::wellLogFile() const +RimWellLogFile* RimWellLogLasFileCurve::wellLogFile() const { return m_wellLogFile(); } diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.h b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.h index 37c3531cac..12c8bca896 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.h +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogLasFileCurve.h @@ -28,7 +28,7 @@ class RimWellPath; class RimWellLogFileChannel; -class RimWellLogLasFile; +class RimWellLogFile; class RigWellLogIndexDepthOffset; //================================================================================================== @@ -46,7 +46,7 @@ public: void setWellPath( RimWellPath* wellPath ); RimWellPath* wellPath() const; void setWellLogChannelName( const QString& name ); - void setWellLogFile( RimWellLogLasFile* wellLogFile ); + void setWellLogFile( RimWellLogFile* wellLogFile ); void setIndexDepthOffsets( std::shared_ptr depthOffsets ); // Overrides from RimWellLogPlotCurve @@ -54,7 +54,7 @@ public: QString wellLogChannelUiName() const override; QString wellLogChannelUnits() const override; - RimWellLogLasFile* wellLogFile() const; + RimWellLogFile* wellLogFile() const; protected: // Overrides from RimWellLogPlotCurve @@ -75,10 +75,10 @@ protected: const std::vector& kIndexValues ) const; protected: - caf::PdmPtrField m_wellPath; - caf::PdmPtrField m_wellLogFile; - caf::PdmField m_wellLogChannelName; - caf::PdmField m_wellLogChannnelUnit; + caf::PdmPtrField m_wellPath; + caf::PdmPtrField m_wellLogFile; + caf::PdmField m_wellLogChannelName; + caf::PdmField m_wellLogChannnelUnit; std::shared_ptr m_indexDepthOffsets; }; diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.cpp index 049a8e56d2..c6c3399b76 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.cpp @@ -578,18 +578,18 @@ void RimWellPath::setNameNoUpdateOfExportName( const QString& name ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimWellPath::wellLogFiles() const +std::vector RimWellPath::wellLogFiles() const { - return std::vector( m_wellLogFiles.begin(), m_wellLogFiles.end() ); + return std::vector( m_wellLogFiles.begin(), m_wellLogFiles.end() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogLasFile* RimWellPath::firstWellLogFileMatchingChannelName( const QString& channelName ) const +RimWellLogFile* RimWellPath::firstWellLogFileMatchingChannelName( const QString& channelName ) const { - std::vector allWellLogFiles = wellLogFiles(); - for ( RimWellLogLasFile* logFile : allWellLogFiles ) + std::vector allWellLogFiles = wellLogFiles(); + for ( RimWellLogFile* logFile : allWellLogFiles ) { std::vector channels = logFile->wellLogChannels(); for ( RimWellLogFileChannel* channel : channels ) @@ -895,12 +895,12 @@ double RimWellPath::datumElevation() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPath::addWellLogFile( RimWellLogLasFile* logFileInfo ) +void RimWellPath::addWellLogFile( RimWellLogFile* logFileInfo ) { // Prevent the same file from being loaded more than once auto itr = std::find_if( m_wellLogFiles.begin(), m_wellLogFiles.end(), - [&]( const RimWellLogLasFile* file ) + [&]( const RimWellLogFile* file ) { return QString::compare( file->fileName(), logFileInfo->fileName(), Qt::CaseInsensitive ) == 0; } ); // Todo: Verify well name to ensure all well log files having the same well name @@ -919,7 +919,7 @@ void RimWellPath::addWellLogFile( RimWellLogLasFile* logFileInfo ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPath::deleteWellLogFile( RimWellLogLasFile* logFileInfo ) +void RimWellPath::deleteWellLogFile( RimWellLogFile* logFileInfo ) { detachWellLogFile( logFileInfo ); delete logFileInfo; @@ -928,7 +928,7 @@ void RimWellPath::deleteWellLogFile( RimWellLogLasFile* logFileInfo ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPath::detachWellLogFile( RimWellLogLasFile* logFileInfo ) +void RimWellPath::detachWellLogFile( RimWellLogFile* logFileInfo ) { auto pdmObject = dynamic_cast( logFileInfo ); for ( size_t i = 0; i < m_wellLogFiles.size(); i++ ) diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h index a19f02eedc..e1d8a03bf8 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h @@ -47,7 +47,7 @@ class RigWellPath; class RigWellPathFormations; class RimProject; -class RimWellLogLasFile; +class RimWellLogFile; class RimFractureTemplateCollection; class RimStimPlanModelCollection; class RimFishbonesCollection; @@ -61,6 +61,7 @@ class Rim3dWellLogCurveCollection; class RimWellPathTieIn; class RimMswCompletionParameters; class RimWellIASettingsCollection; +class RimWellLogFile; //================================================================================================== /// @@ -104,11 +105,11 @@ public: double uniqueStartMD() const; double uniqueEndMD() const; - void addWellLogFile( RimWellLogLasFile* logFileInfo ); - void deleteWellLogFile( RimWellLogLasFile* logFileInfo ); - void detachWellLogFile( RimWellLogLasFile* logFileInfo ); - std::vector wellLogFiles() const; - RimWellLogLasFile* firstWellLogFileMatchingChannelName( const QString& channelName ) const; + void addWellLogFile( RimWellLogFile* logFileInfo ); + void deleteWellLogFile( RimWellLogFile* logFileInfo ); + void detachWellLogFile( RimWellLogFile* logFileInfo ); + std::vector wellLogFiles() const; + RimWellLogFile* firstWellLogFileMatchingChannelName( const QString& channelName ) const; void setFormationsGeometry( cvf::ref wellPathFormations ); bool readWellPathFormationsFile( QString* errorMessage, RifWellPathFormationsImporter* wellPathFormationsImporter ); @@ -209,7 +210,7 @@ private: caf::PdmField m_wellPathRadiusScaleFactor; caf::PdmField m_wellPathColor; - caf::PdmChildArrayField m_wellLogFiles; + caf::PdmChildArrayField m_wellLogFiles; caf::PdmChildField m_3dWellLogCurves; caf::PdmChildField m_completionSettings; caf::PdmChildField m_completions; diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp index 574cfb2ebc..7f6f564ae2 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp @@ -169,7 +169,7 @@ void RimWellPathCollection::loadDataAndUpdate() if ( wellPath ) { - for ( RimWellLogLasFile* const wellLogFile : wellPath->wellLogFiles() ) + for ( RimWellLogFile* const wellLogFile : wellPath->wellLogFiles() ) { if ( wellLogFile ) { @@ -386,6 +386,16 @@ std::vector RimWellPathCollection::addWellLogs( const QStrin return logFileInfos; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::addWellLog( RimWellLogFile* wellLogFile, RimWellPath* wellPath ) +{ + wellPath->addWellLogFile( wellLogFile ); + sortWellsByName(); + updateAllRequiredEditors(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h index c102be81bc..db57a69225 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h @@ -44,6 +44,7 @@ class RimFileWellPath; class RimEclipseView; class RimProject; class RimWellLogLasFile; +class RimWellLogFile; class RimWellPath; class RifWellPathFormationsImporter; class RimWellMeasurementCollection; @@ -116,6 +117,7 @@ public: std::vector addWellLogs( const QStringList& filePaths, QStringList* errorMessages ); void addWellPathFormations( const QStringList& filePaths ); + void addWellLog( RimWellLogFile* wellLogFile, RimWellPath* wellPath ); void scheduleRedrawAffectedViews(); diff --git a/ApplicationLibCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake b/ApplicationLibCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake index 5de8178360..a004e95cd4 100644 --- a/ApplicationLibCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake +++ b/ApplicationLibCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake @@ -4,7 +4,9 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigCaseToCaseCellMapperTools.h ${CMAKE_CURRENT_LIST_DIR}/RigCaseToCaseRangeFilterMapper.h ${CMAKE_CURRENT_LIST_DIR}/RigSimulationWellCenterLineCalculator.h + ${CMAKE_CURRENT_LIST_DIR}/RigWellLogFile.h ${CMAKE_CURRENT_LIST_DIR}/RigWellLogLasFile.h + ${CMAKE_CURRENT_LIST_DIR}/RigWellLogCsvFile.h ${CMAKE_CURRENT_LIST_DIR}/RigReservoirGridTools.h ) @@ -14,7 +16,9 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigCaseToCaseCellMapperTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RigCaseToCaseRangeFilterMapper.cpp ${CMAKE_CURRENT_LIST_DIR}/RigSimulationWellCenterLineCalculator.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigWellLogFile.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellLogLasFile.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigWellLogCsvFile.cpp ${CMAKE_CURRENT_LIST_DIR}/RigReservoirGridTools.cpp ) diff --git a/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp b/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp index a1f2cf6a55..f8d99514cc 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp @@ -36,6 +36,7 @@ #include "RigGeoMechCaseData.h" #include "RigFemAddressDefines.h" +#include "RigWbsParameter.h" #include "RigWellLogExtractionTools.h" #include "RigWellPath.h" #include "RigWellPathGeometryTools.h" @@ -147,13 +148,21 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd { wellBoreWallCurveData( resAddr, timeStepIndex, frameIndex, values ); // Try to replace invalid values with Shale-values - wellBoreFGShale( timeStepIndex, frameIndex, values ); + wellBoreFGShale( RigWbsParameter::FG_Shale(), timeStepIndex, frameIndex, values ); values->front() = wbsCurveValuesAtMsl(); } else if ( resAddr.fieldName == RiaResultNames::wbsSFGResult().toStdString() ) { wellBoreWallCurveData( resAddr, timeStepIndex, frameIndex, values ); } + else if ( resAddr.fieldName == RiaResultNames::wbsFGMkMinResult().toStdString() ) + { + wellBoreFG_MatthewsKelly( RigWbsParameter::FG_MkMin(), timeStepIndex, frameIndex, values ); + } + else if ( resAddr.fieldName == RiaResultNames::wbsFGMkExpResult().toStdString() ) + { + wellBoreFG_MatthewsKelly( RigWbsParameter::FG_MkExp(), timeStepIndex, frameIndex, values ); + } else if ( resAddr.fieldName == RiaResultNames::wbsPPResult().toStdString() || resAddr.fieldName == RiaResultNames::wbsOBGResult().toStdString() || resAddr.fieldName == RiaResultNames::wbsSHResult().toStdString() ) @@ -166,9 +175,26 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd { wellPathAngles( resAddr, values ); } - else if ( resAddr.fieldName == RiaResultNames::wbsSHMkResult().toStdString() ) + else if ( resAddr.fieldName == RiaResultNames::wbsSHMkResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsSHMkMinResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsSHMkMaxResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsSHMkExpResult().toStdString() ) { - wellBoreSH_MatthewsKelly( timeStepIndex, frameIndex, values ); + auto mapSHMkToPP = []( const QString& SHMkName ) -> std::pair + { + if ( SHMkName == RiaResultNames::wbsSHMkMinResult() ) + return { RiaResultNames::wbsPPMinResult(), RiaResultNames::wbsPPInitialResult() }; + if ( SHMkName == RiaResultNames::wbsSHMkMaxResult() ) + return { RiaResultNames::wbsPPMaxResult(), RiaResultNames::wbsPPInitialResult() }; + if ( SHMkName == RiaResultNames::wbsSHMkExpResult() ) + return { RiaResultNames::wbsPPExpResult(), RiaResultNames::wbsPPInitialResult() }; + + CAF_ASSERT( SHMkName == RiaResultNames::wbsSHMkResult() ); + return { RiaResultNames::wbsPPResult(), RiaResultNames::wbsPPResult() }; + }; + + auto [ppResultName, pp0ResultName] = mapSHMkToPP( QString::fromStdString( resAddr.fieldName ) ); + wellBoreSH_MatthewsKelly( timeStepIndex, frameIndex, ppResultName, pp0ResultName, values ); values->front() = wbsCurveValuesAtMsl(); } else @@ -179,7 +205,7 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd { if ( param == RigWbsParameter::FG_Shale() ) { - wellBoreFGShale( timeStepIndex, frameIndex, values ); + wellBoreFGShale( param, timeStepIndex, frameIndex, values ); } else { @@ -200,6 +226,11 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd { return RiaWellLogUnitTools::noUnitString(); } + else if ( param == RigWbsParameter::PP_Min() || param == RigWbsParameter::PP_Max() || + param == RigWbsParameter::PP_Exp() || param == RigWbsParameter::PP_Initial() ) + { + return RiaWellLogUnitTools::barUnitString(); + } } } } @@ -565,6 +596,16 @@ std::vector { sources = calculateWbsParameterForAllSegments( RigWbsParameter::OBG(), timeStepIndex, frameIndex, values, true ); } + else if ( resAddr.fieldName == RiaResultNames::wbsPPExpResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsPPMinResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsPPMaxResult().toStdString() ) + { + RigWbsParameter param; + bool ok = RigWbsParameter::findParameter( QString::fromStdString( resAddr.fieldName ), ¶m ); + + CAF_ASSERT( ok ); + sources = calculateWbsParameterForAllSegments( param, timeStepIndex, frameIndex, values, true ); + } else { sources = calculateWbsParameterForAllSegments( RigWbsParameter::SH(), timeStepIndex, frameIndex, values, true ); @@ -583,7 +624,9 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres { CVF_ASSERT( values ); CVF_ASSERT( resAddr.fieldName == RiaResultNames::wbsFGResult().toStdString() || - resAddr.fieldName == RiaResultNames::wbsSFGResult().toStdString() ); + resAddr.fieldName == RiaResultNames::wbsSFGResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsFGMkMinResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsFGMkExpResult().toStdString() ); // The result addresses needed RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, "ST", "" ); @@ -591,6 +634,15 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults(); + auto mapFGResultToPP = []( const QString& fgResultName ) + { + if ( fgResultName == RiaResultNames::wbsFGMkMinResult() ) return RigWbsParameter::PP_Min(); + if ( fgResultName == RiaResultNames::wbsFGMkExpResult() ) return RigWbsParameter::PP_Exp(); + return RigWbsParameter::PP_Reservoir(); + }; + + RigWbsParameter ppParameter = mapFGResultToPP( QString::fromStdString( resAddr.fieldName ) ); + // Load results std::vector vertexStressesFloat = resultCollection->tensors( stressResAddr, m_partId, timeStepIndex, frameIndex ); if ( vertexStressesFloat.empty() ) return; @@ -609,7 +661,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres std::vector ppSandAllSegments( intersections().size(), std::numeric_limits::infinity() ); std::vector ppSources = - calculateWbsParameterForAllSegments( RigWbsParameter::PP_Reservoir(), RigWbsParameter::GRID, frameIndex, &ppSandAllSegments, false ); + calculateWbsParameterForAllSegments( ppParameter, timeStepIndex, frameIndex, &ppSandAllSegments, false ); std::vector poissonAllSegments( intersections().size(), std::numeric_limits::infinity() ); calculateWbsParameterForAllSegments( RigWbsParameter::poissonRatio(), timeStepIndex, frameIndex, &poissonAllSegments, false ); @@ -622,6 +674,12 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres { // FG is for sands, SFG for shale. Sands has valid PP, shale does not. bool isFGregion = ppSources[intersectionIdx] == RigWbsParameter::GRID; + if ( resAddr.fieldName == RiaResultNames::wbsFGMkMinResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsFGMkExpResult().toStdString() ) + { + // Assume only FG for entire well log for FG_MK_MIN/EXP. + isFGregion = true; + } double hydroStaticPorePressureBar = hydroStaticPorePressureForSegment( intersectionIdx ); @@ -644,7 +702,9 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble, porePressureBar, poissonRatio, ucsBar, 32 ); double resultValue = std::numeric_limits::infinity(); - if ( resAddr.fieldName == RiaResultNames::wbsFGResult().toStdString() ) + if ( resAddr.fieldName == RiaResultNames::wbsFGResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsFGMkMinResult().toStdString() || + resAddr.fieldName == RiaResultNames::wbsFGMkExpResult().toStdString() ) { if ( isFGregion && validSegmentStress ) { @@ -673,41 +733,21 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigGeoMechWellLogExtractor::wellBoreFGShale( int timeStepIndex, int frameIndex, std::vector* values ) +void RigGeoMechWellLogExtractor::wellBoreFGShale( const RigWbsParameter& parameter, int timeStepIndex, int frameIndex, std::vector* values ) { if ( values->empty() ) values->resize( intersections().size(), std::numeric_limits::infinity() ); - WbsParameterSource source = m_parameterSources.at( RigWbsParameter::FG_Shale() ); + WbsParameterSource source = m_parameterSources.at( parameter ); if ( source == RigWbsParameter::DERIVED_FROM_K0FG ) { - std::vector PP0; // results - std::vector K0_FG, OBG0; // parameters - - RigFemResultAddress ppAddr( RIG_WELLPATH_DERIVED, RiaResultNames::wbsPPResult().toStdString(), "" ); - wellPathScaledCurveData( ppAddr, 0, 0, &PP0, true ); - - calculateWbsParameterForAllSegments( RigWbsParameter::K0_FG(), timeStepIndex, frameIndex, &K0_FG, true ); - calculateWbsParameterForAllSegments( RigWbsParameter::OBG0(), 0, 0, &OBG0, true ); - -#pragma omp parallel for - for ( int64_t intersectionIdx = 0; intersectionIdx < static_cast( intersections().size() ); ++intersectionIdx ) - { - if ( !isValid( ( *values )[intersectionIdx] ) ) - { - if ( isValid( PP0[intersectionIdx] ) && isValid( OBG0[intersectionIdx] ) && isValid( K0_FG[intersectionIdx] ) ) - { - ( *values )[intersectionIdx] = - ( K0_FG[intersectionIdx] * ( OBG0[intersectionIdx] - PP0[intersectionIdx] ) + PP0[intersectionIdx] ); - } - } - } + wellBoreFGDerivedFromK0FG( RiaResultNames::wbsPPResult(), timeStepIndex, frameIndex, values ); } else { std::vector SH; calculateWbsParameterForAllSegments( RigWbsParameter::SH(), timeStepIndex, frameIndex, &SH, true ); CVF_ASSERT( SH.size() == intersections().size() ); - double multiplier = m_userDefinedValues.at( RigWbsParameter::FG_Shale() ); + double multiplier = m_userDefinedValues.at( parameter ); CVF_ASSERT( multiplier != std::numeric_limits::infinity() ); #pragma omp parallel for for ( int64_t intersectionIdx = 0; intersectionIdx < static_cast( intersections().size() ); ++intersectionIdx ) @@ -726,21 +766,116 @@ void RigGeoMechWellLogExtractor::wellBoreFGShale( int timeStepIndex, int frameIn //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigGeoMechWellLogExtractor::wellBoreSH_MatthewsKelly( int timeStepIndex, int frameIndex, std::vector* values ) +void RigGeoMechWellLogExtractor::wellBoreFGDerivedFromK0FG( const QString& ppResult, int timeStepIndex, int frameIndex, std::vector* values ) +{ + std::vector PP0; // results + std::vector K0_FG, OBG0; // parameters + + RigFemResultAddress ppAddr( RIG_WELLPATH_DERIVED, ppResult.toStdString(), "" ); + wellPathScaledCurveData( ppAddr, 0, 0, &PP0, true ); + + calculateWbsParameterForAllSegments( RigWbsParameter::K0_FG(), timeStepIndex, frameIndex, &K0_FG, true ); + calculateWbsParameterForAllSegments( RigWbsParameter::OBG0(), 0, 0, &OBG0, true ); + +#pragma omp parallel for + for ( int64_t intersectionIdx = 0; intersectionIdx < static_cast( intersections().size() ); ++intersectionIdx ) + { + if ( !isValid( ( *values )[intersectionIdx] ) ) + { + if ( isValid( PP0[intersectionIdx] ) && isValid( OBG0[intersectionIdx] ) && isValid( K0_FG[intersectionIdx] ) ) + { + ( *values )[intersectionIdx] = + ( K0_FG[intersectionIdx] * ( OBG0[intersectionIdx] - PP0[intersectionIdx] ) + PP0[intersectionIdx] ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::wellBoreFG_MatthewsKelly( const RigWbsParameter& parameter, + int timeStepIndex, + int frameIndex, + std::vector* values ) +{ + values->resize( intersections().size(), std::numeric_limits::infinity() ); + + WbsParameterSource source = m_parameterSources.at( parameter ); + if ( source == RigWbsParameter::DERIVED_FROM_K0FG ) + { + auto mapParameterToPPResult = []( const RigWbsParameter& parameter ) + { + if ( parameter.name() == RiaResultNames::wbsFGMkMinResult() ) return RiaResultNames::wbsPPMinResult(); + if ( parameter.name() == RiaResultNames::wbsFGMkExpResult() ) return RiaResultNames::wbsPPExpResult(); + return RiaResultNames::wbsPPResult(); + }; + + QString ppResultName = mapParameterToPPResult( parameter ); + wellBoreFGDerivedFromK0FG( ppResultName, timeStepIndex, frameIndex, values ); + } + else + { + auto mapParameterToSHMkResult = []( const RigWbsParameter& parameter ) + { + if ( parameter.name() == RiaResultNames::wbsFGMkMinResult() ) return RiaResultNames::wbsSHMkMinResult(); + if ( parameter.name() == RiaResultNames::wbsFGMkExpResult() ) return RiaResultNames::wbsSHMkExpResult(); + return RiaResultNames::wbsSHMkResult(); + }; + + std::vector SH; + QString SHMkResultName = mapParameterToSHMkResult( parameter ); + RigFemResultAddress SHMkAddr( RIG_WELLPATH_DERIVED, SHMkResultName.toStdString(), "" ); + + curveData( SHMkAddr, timeStepIndex, frameIndex, &SH ); + + CVF_ASSERT( SH.size() == intersections().size() ); + double multiplier = m_userDefinedValues.at( parameter ); + CVF_ASSERT( multiplier != std::numeric_limits::infinity() ); +#pragma omp parallel for + for ( int64_t intersectionIdx = 0; intersectionIdx < static_cast( intersections().size() ); ++intersectionIdx ) + { + if ( !isValid( ( *values )[intersectionIdx] ) ) + { + if ( isValid( SH[intersectionIdx] ) ) + { + ( *values )[intersectionIdx] = SH[intersectionIdx] * multiplier; + } + } + } + } + + values->front() = wbsCurveValuesAtMsl(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::wellBoreSH_MatthewsKelly( int timeStepIndex, + int frameIndex, + const QString& wbsPPResultName, + const QString& wbsPP0ResultName, + std::vector* values ) { std::vector PP, PP0; // results std::vector K0_SH, OBG0, DF; // parameters - RigFemResultAddress ppAddr( RIG_WELLPATH_DERIVED, RiaResultNames::wbsPPResult().toStdString(), "" ); + RigFemResultAddress ppAddr( RIG_WELLPATH_DERIVED, wbsPPResultName.toStdString(), "" ); + RigFemResultAddress pp0Addr( RIG_WELLPATH_DERIVED, wbsPP0ResultName.toStdString(), "" ); curveData( ppAddr, timeStepIndex, frameIndex, &PP ); - curveData( ppAddr, 0, 0, &PP0 ); + curveData( pp0Addr, 0, 0, &PP0 ); calculateWbsParameterForAllSegments( RigWbsParameter::K0_SH(), timeStepIndex, frameIndex, &K0_SH, true ); calculateWbsParameterForAllSegments( RigWbsParameter::OBG0(), 0, 0, &OBG0, true ); calculateWbsParameterForAllSegments( RigWbsParameter::DF(), timeStepIndex, frameIndex, &DF, true ); values->resize( intersections().size(), std::numeric_limits::infinity() ); + if ( PP.size() != intersections().size() || PP0.size() != intersections().size() ) return; + + CAF_ASSERT( OBG0.size() == intersections().size() ); + CAF_ASSERT( K0_SH.size() == intersections().size() ); + CAF_ASSERT( DF.size() == intersections().size() ); #pragma omp parallel for for ( int64_t intersectionIdx = 0; intersectionIdx < static_cast( intersections().size() ); ++intersectionIdx ) @@ -791,7 +926,9 @@ void RigGeoMechWellLogExtractor::setWbsUserDefinedValue( RigWbsParameter paramet //-------------------------------------------------------------------------------------------------- QString RigGeoMechWellLogExtractor::parameterInputUnits( const RigWbsParameter& parameter ) { - if ( parameter == RigWbsParameter::PP_NonReservoir() || parameter == RigWbsParameter::PP_Reservoir() || parameter == RigWbsParameter::UCS() ) + if ( parameter == RigWbsParameter::PP_NonReservoir() || parameter == RigWbsParameter::PP_Reservoir() || + parameter == RigWbsParameter::UCS() || parameter == RigWbsParameter::PP_Min() || parameter == RigWbsParameter::PP_Max() || + parameter == RigWbsParameter::PP_Exp() || parameter == RigWbsParameter::PP_Initial() ) { return RiaWellLogUnitTools::barUnitString(); } diff --git a/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h b/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h index 9c90cf1c1a..aead1a2d45 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h +++ b/ApplicationLibCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h @@ -124,8 +124,16 @@ private: bool forceGridSourceforPPReservoir = false ); void wellBoreWallCurveData( const RigFemResultAddress& resAddr, int timeStepIndex, int frameIndex, std::vector* values ); - void wellBoreFGShale( int timeStepIndex, int frameIndex, std::vector* values ); - void wellBoreSH_MatthewsKelly( int timeStepIndex, int frameIndex, std::vector* values ); + void wellBoreFGShale( const RigWbsParameter& parameter, int timeStepIndex, int frameIndex, std::vector* values ); + void wellBoreSH_MatthewsKelly( int timeStepIndex, + int frameIndex, + const QString& wbsPPResultName, + const QString& wbsPP0ResultName, + std::vector* values ); + + void wellBoreFGDerivedFromK0FG( const QString& ppResult, int timeStepIndex, int frameIndex, std::vector* values ); + + void wellBoreFG_MatthewsKelly( const RigWbsParameter& parameter, int timeStepIndex, int frameIndex, std::vector* values ); template T interpolateGridResultValue( RigFemResultPosEnum resultPosType, const std::vector& gridResultValues, int64_t intersectionIdx ) const; diff --git a/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.cpp b/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.cpp index 5d0cc11aff..0535752604 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RigWbsParameter.h" +#include "RiaResultNames.h" #include "RiaWellLogUnitTools.h" #include "RigFemAddressDefines.h" @@ -259,6 +260,47 @@ RigWbsParameter RigWbsParameter::PP_NonReservoir() return RigWbsParameter( "PP_Non-Reservoir", true, sources ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWbsParameter RigWbsParameter::PP_Min() +{ + SourceVector sources = { { LAS_FILE, SourceAddress( RiaResultNames::wbsPPMinResult(), "", RiaWellLogUnitTools::barUnitString() ) } }; + + return RigWbsParameter( "PP_MIN", true, sources ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWbsParameter RigWbsParameter::PP_Max() +{ + SourceVector sources = { { LAS_FILE, SourceAddress( RiaResultNames::wbsPPMaxResult(), "", RiaWellLogUnitTools::barUnitString() ) } }; + + return RigWbsParameter( "PP_MAX", true, sources ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWbsParameter RigWbsParameter::PP_Exp() +{ + SourceVector sources = { { LAS_FILE, SourceAddress( RiaResultNames::wbsPPExpResult(), "", RiaWellLogUnitTools::barUnitString() ) } }; + + return RigWbsParameter( "PP_EXP", true, sources ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWbsParameter RigWbsParameter::PP_Initial() +{ + SourceVector sources = { + { LAS_FILE, SourceAddress( RiaResultNames::wbsPPInitialResult(), "", RiaWellLogUnitTools::barUnitString() ) } }; + + return RigWbsParameter( "PP_INIT", true, sources ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -365,6 +407,26 @@ RigWbsParameter RigWbsParameter::FG_Shale() return param; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWbsParameter RigWbsParameter::FG_MkMin() +{ + RigWbsParameter param( "FG_MK_MIN", false, { { DERIVED_FROM_K0FG, SourceAddress() }, { PROPORTIONAL_TO_SH, SourceAddress() } } ); + param.setOptionsExclusive( true ); + return param; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWbsParameter RigWbsParameter::FG_MkExp() +{ + RigWbsParameter param( "FG_MK_EXP", false, { { DERIVED_FROM_K0FG, SourceAddress() }, { PROPORTIONAL_TO_SH, SourceAddress() } } ); + param.setOptionsExclusive( true ); + return param; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -381,7 +443,24 @@ RigWbsParameter RigWbsParameter::waterDensity() //-------------------------------------------------------------------------------------------------- std::set RigWbsParameter::allParameters() { - return { PP_Reservoir(), PP_NonReservoir(), poissonRatio(), UCS(), OBG(), OBG0(), SH(), DF(), K0_FG(), K0_SH(), FG_Shale(), waterDensity() }; + return { PP_Reservoir(), + PP_NonReservoir(), + PP_Min(), + PP_Max(), + PP_Exp(), + PP_Initial(), + poissonRatio(), + UCS(), + OBG(), + OBG0(), + SH(), + DF(), + K0_FG(), + K0_SH(), + FG_Shale(), + FG_MkMin(), + FG_MkExp(), + waterDensity() }; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.h b/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.h index 34186d862a..5e8bd726d3 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.h +++ b/ApplicationLibCode/ReservoirDataModel/RigWbsParameter.h @@ -74,6 +74,11 @@ public: static RigWbsParameter PP_Reservoir(); static RigWbsParameter PP_NonReservoir(); + static RigWbsParameter PP_Min(); + static RigWbsParameter PP_Max(); + static RigWbsParameter PP_Exp(); + static RigWbsParameter PP_Initial(); + static RigWbsParameter poissonRatio(); static RigWbsParameter UCS(); static RigWbsParameter OBG(); @@ -83,6 +88,9 @@ public: static RigWbsParameter K0_FG(); static RigWbsParameter K0_SH(); static RigWbsParameter FG_Shale(); + static RigWbsParameter FG_MkMin(); + static RigWbsParameter FG_MkExp(); + static RigWbsParameter waterDensity(); static std::set allParameters(); diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogCsvFile.cpp b/ApplicationLibCode/ReservoirDataModel/RigWellLogCsvFile.cpp new file mode 100644 index 0000000000..849a32c29f --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogCsvFile.cpp @@ -0,0 +1,231 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 "RigWellLogCsvFile.h" + +#include "RiaInterpolationTools.h" +#include "RifCsvUserDataParser.h" +#include "RigWellLogCurveData.h" +#include "RigWellPathGeometryTools.h" + +#include "SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.h" + +#include "RiaLogging.h" +#include "RiaStringEncodingTools.h" + +#include "RimWellLogCurve.h" +#include "RimWellPath.h" + +#include +#include + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogCsvFile::RigWellLogCsvFile() + : RigWellLogFile() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogCsvFile::~RigWellLogCsvFile() +{ + close(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigWellLogCsvFile::open( const QString& fileName, RigWellPath* wellPath, QString* errorMessage ) +{ + m_wellLogChannelNames.clear(); + + RifCsvUserDataFileParser parser( fileName, errorMessage ); + + AsciiDataParseOptions parseOptions; + parseOptions.useCustomDateTimeFormat = true; + parseOptions.dateTimeFormat = "dd.MM.yyyy hh:mm:ss"; + parseOptions.fallbackDateTimeFormat = "dd.MM.yyyy"; + parseOptions.cellSeparator = ";"; + parseOptions.decimalSeparator = ","; + + if ( !parser.parse( parseOptions ) ) + { + return false; + } + + std::map> readValues; + + for ( auto s : parser.tableData().columnInfos() ) + { + if ( s.dataType != Column::NUMERIC ) continue; + QString columnName = QString::fromStdString( s.columnName() ); + m_wellLogChannelNames.append( columnName ); + readValues[columnName] = s.values; + m_units[columnName] = QString::fromStdString( s.unitName ); + + if ( columnName.toUpper() == "TVDMSL" || columnName.toUpper().contains( "TVD" ) ) + { + m_tvdMslLogName = columnName; + } + } + + if ( m_tvdMslLogName.isEmpty() ) + { + QString message = "CSV file does not have TVD values."; + RiaLogging::error( message ); + if ( errorMessage ) *errorMessage = message; + return false; + } + + std::vector readTvds = readValues[m_tvdMslLogName]; + + for ( auto [channelName, readValues] : readValues ) + { + if ( channelName == m_tvdMslLogName ) + { + // Use TVD from well path. + m_values[m_tvdMslLogName] = wellPath->trueVerticalDepths(); + } + else + { + CAF_ASSERT( readValues.size() == readTvds.size() ); + + auto wellPathMds = wellPath->measuredDepths(); + auto wellPathTvds = wellPath->trueVerticalDepths(); + + // Interpolate values for the well path depths (from TVD). + // Assumes that the well channel values is dependent on TVD only (MD is not considered). + std::vector values; + for ( auto tvd : wellPathTvds ) + { + double value = RiaInterpolationTools::linear( readTvds, readValues, tvd, RiaInterpolationTools::ExtrapolationMode::TREND ); + values.push_back( value ); + } + + m_values[channelName] = values; + } + } + + // Use MD from well path. + m_depthLogName = "DEPTH"; + m_values[m_depthLogName] = wellPath->measuredDepths(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCsvFile::close() +{ + m_wellLogChannelNames.clear(); + m_depthLogName.clear(); + m_values.clear(); + m_units.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RigWellLogCsvFile::wellLogChannelNames() const +{ + return m_wellLogChannelNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCsvFile::depthValues() const +{ + return values( m_depthLogName ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCsvFile::tvdMslValues() const +{ + return values( m_tvdMslLogName ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCsvFile::tvdRkbValues() const +{ + // Not supported. + return std::vector(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCsvFile::values( const QString& name ) const +{ + if ( auto it = m_values.find( name ); it != m_values.end() ) return it->second; + return std::vector(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RigWellLogCsvFile::depthUnitString() const +{ + return wellLogChannelUnitString( m_tvdMslLogName ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RigWellLogCsvFile::wellLogChannelUnitString( const QString& wellLogChannelName ) const +{ + auto unit = m_units.find( wellLogChannelName ); + if ( unit != m_units.end() ) + return unit->second; + else + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigWellLogCsvFile::hasTvdMslChannel() const +{ + return !m_tvdMslLogName.isEmpty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigWellLogCsvFile::hasTvdRkbChannel() const +{ + return !m_tvdRkbLogName.isEmpty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigWellLogCsvFile::getMissingValue() const +{ + return std::numeric_limits::infinity(); +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogCsvFile.h b/ApplicationLibCode/ReservoirDataModel/RigWellLogCsvFile.h new file mode 100644 index 0000000000..78857d8779 --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogCsvFile.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 "RigWellLogFile.h" + +#include "RiaDefines.h" + +#include + +#include +#include + +class RigWellPath; + +//================================================================================================== +/// +//================================================================================================== +class RigWellLogCsvFile : public RigWellLogFile +{ +public: + RigWellLogCsvFile(); + ~RigWellLogCsvFile() override; + + bool open( const QString& fileName, RigWellPath* wellPath, QString* errorMessage ); + + QStringList wellLogChannelNames() const override; + + std::vector depthValues() const override; + std::vector tvdMslValues() const override; + std::vector tvdRkbValues() const override; + + std::vector values( const QString& name ) const override; + + QString wellLogChannelUnitString( const QString& wellLogChannelName ) const override; + RiaDefines::DepthUnitType depthUnit() const; + + bool hasTvdMslChannel() const override; + bool hasTvdRkbChannel() const override; + + double getMissingValue() const override; + +private: + void close(); + QString depthUnitString() const override; + + QStringList m_wellLogChannelNames; + QString m_depthLogName; + QString m_tvdMslLogName; + QString m_tvdRkbLogName; + std::map> m_values; + std::map m_units; +}; diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogFile.cpp b/ApplicationLibCode/ReservoirDataModel/RigWellLogFile.cpp new file mode 100644 index 0000000000..50f720d8ae --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogFile.cpp @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 "RigWellLogFile.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogFile::RigWellLogFile() + : cvf::Object() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogFile::~RigWellLogFile() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::DepthUnitType RigWellLogFile::depthUnit() const +{ + RiaDefines::DepthUnitType unitType = RiaDefines::DepthUnitType::UNIT_METER; + + if ( depthUnitString().toUpper() == "F" || depthUnitString().toUpper() == "FT" ) + { + unitType = RiaDefines::DepthUnitType::UNIT_FEET; + } + + return unitType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RigWellLogFile::convertedWellLogChannelUnitString( const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit ) const +{ + QString unit = wellLogChannelUnitString( wellLogChannelName ); + + if ( unit == depthUnitString() ) + { + if ( displayDepthUnit != depthUnit() ) + { + if ( displayDepthUnit == RiaDefines::DepthUnitType::UNIT_METER ) + { + return "M"; + } + else if ( displayDepthUnit == RiaDefines::DepthUnitType::UNIT_FEET ) + { + return "FT"; + } + else if ( displayDepthUnit == RiaDefines::DepthUnitType::UNIT_NONE ) + { + CVF_ASSERT( false ); + return ""; + } + } + } + + return unit; +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogFile.h b/ApplicationLibCode/ReservoirDataModel/RigWellLogFile.h new file mode 100644 index 0000000000..ed91a3f5f5 --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogFile.h @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 "RiaDefines.h" + +#include "cvfObject.h" + +#include +#include + +class RimWellLogCurve; + +//================================================================================================== +/// +//================================================================================================== +class RigWellLogFile : public cvf::Object +{ +public: + RigWellLogFile(); + ~RigWellLogFile() override; + + virtual QStringList wellLogChannelNames() const = 0; + + virtual std::vector depthValues() const = 0; + virtual std::vector tvdMslValues() const = 0; + virtual std::vector tvdRkbValues() const = 0; + + virtual std::vector values( const QString& name ) const = 0; + + virtual QString wellLogChannelUnitString( const QString& wellLogChannelName ) const = 0; + virtual QString depthUnitString() const = 0; + + QString convertedWellLogChannelUnitString( const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit ) const; + RiaDefines::DepthUnitType depthUnit() const; + + virtual bool hasTvdMslChannel() const = 0; + virtual bool hasTvdRkbChannel() const = 0; + + virtual double getMissingValue() const = 0; +}; diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.cpp b/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.cpp index 743ebf357a..661ea3110f 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.cpp @@ -38,7 +38,7 @@ /// //-------------------------------------------------------------------------------------------------- RigWellLogLasFile::RigWellLogLasFile() - : cvf::Object() + : RigWellLogFile() { m_wellLogFile = nullptr; } @@ -223,42 +223,6 @@ QString RigWellLogLasFile::depthUnitString() const return unit; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RigWellLogLasFile::wellLogChannelUnitString( const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit ) const -{ - QString unit; - - NRLib::LasWell* lasWell = dynamic_cast( m_wellLogFile ); - if ( lasWell ) - { - unit = QString::fromStdString( lasWell->unitName( wellLogChannelName.toStdString() ) ); - } - - if ( unit == depthUnitString() ) - { - if ( displayDepthUnit != depthUnit() ) - { - if ( displayDepthUnit == RiaDefines::DepthUnitType::UNIT_METER ) - { - return "M"; - } - else if ( displayDepthUnit == RiaDefines::DepthUnitType::UNIT_FEET ) - { - return "FT"; - } - else if ( displayDepthUnit == RiaDefines::DepthUnitType::UNIT_NONE ) - { - CVF_ASSERT( false ); - return ""; - } - } - } - - return unit; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -297,18 +261,3 @@ double RigWellLogLasFile::getMissingValue() const { return m_wellLogFile->GetContMissing(); } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiaDefines::DepthUnitType RigWellLogLasFile::depthUnit() const -{ - RiaDefines::DepthUnitType unitType = RiaDefines::DepthUnitType::UNIT_METER; - - if ( depthUnitString().toUpper() == "F" || depthUnitString().toUpper() == "FT" ) - { - unitType = RiaDefines::DepthUnitType::UNIT_FEET; - } - - return unitType; -} diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.h b/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.h index 8e473f37f1..1be8f381ff 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.h +++ b/ApplicationLibCode/ReservoirDataModel/RigWellLogLasFile.h @@ -19,9 +19,9 @@ #pragma once -#include "RiaDefines.h" +#include "RigWellLogFile.h" -#include "cvfObject.h" +#include "RiaDefines.h" #include #include @@ -36,7 +36,7 @@ class RimWellLogCurve; //================================================================================================== /// //================================================================================================== -class RigWellLogLasFile : public cvf::Object +class RigWellLogLasFile : public RigWellLogFile { public: RigWellLogLasFile(); @@ -46,26 +46,24 @@ public: QString wellName() const; QString date() const; - QStringList wellLogChannelNames() const; + QStringList wellLogChannelNames() const override; - std::vector depthValues() const; - std::vector tvdMslValues() const; - std::vector tvdRkbValues() const; + std::vector depthValues() const override; + std::vector tvdMslValues() const override; + std::vector tvdRkbValues() const override; - std::vector values( const QString& name ) const; + std::vector values( const QString& name ) const override; - QString wellLogChannelUnitString( const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit ) const; - QString wellLogChannelUnitString( const QString& wellLogChannelName ) const; - RiaDefines::DepthUnitType depthUnit() const; + QString wellLogChannelUnitString( const QString& wellLogChannelName ) const override; - bool hasTvdMslChannel() const; - bool hasTvdRkbChannel() const; + bool hasTvdMslChannel() const override; + bool hasTvdRkbChannel() const override; - double getMissingValue() const; + double getMissingValue() const override; private: void close(); - QString depthUnitString() const; + QString depthUnitString() const override; NRLib::Well* m_wellLogFile; QStringList m_wellLogChannelNames;