From edd61109b5c58aed56e4b2ff5a830af84dc19ad9 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 23 Dec 2024 11:53:49 +0100 Subject: [PATCH] #12017 Add caching of well target result data Write data to welltargetdata.GRDECL in a subfolder of the project. Import this data when project is load. The data in this cache is owerwritten when the project is saved. --- .../RifReaderRegularGridModel.cpp | 122 ++++++++++-------- .../FileInterface/RifReaderRegularGridModel.h | 29 +---- .../ProjectDataModel/RimRegularGridCase.cpp | 42 ++++-- .../ProjectDataModel/RimRegularGridCase.h | 6 +- .../Well/RigWellTargetCandidatesGenerator.cpp | 2 +- 5 files changed, 114 insertions(+), 87 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp index 5655c4b6ad..97f6c67859 100644 --- a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp @@ -18,77 +18,91 @@ #include "RifReaderRegularGridModel.h" +#include "RiaDefines.h" +#include "RiaLogging.h" + +#include "RifEclipseInputFileTools.h" +#include "RifEclipseInputPropertyLoader.h" +#include "RifEclipseKeywordContent.h" +#include "RifEclipseTextFileReader.h" + #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" +#include "RigEclipseResultAddress.h" + +#include "RimEclipseCase.h" + +#include +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifReaderRegularGridModel::RifReaderRegularGridModel() - : m_reservoir( nullptr ) +void RifReaderRegularGridModel::writeCache( const QString& fileName, RimEclipseCase* eclipseCase ) { + if ( !eclipseCase ) return; + + QFileInfo storageFileInfo( fileName ); + if ( storageFileInfo.exists() ) + { + QDir storageDir = storageFileInfo.dir(); + storageDir.remove( storageFileInfo.fileName() ); + } + + QDir::root().mkpath( storageFileInfo.absolutePath() ); + + QFile cacheFile( fileName ); + if ( !cacheFile.open( QIODevice::WriteOnly ) ) + { + RiaLogging::error( "Saving project: Can't open the cache file : " + fileName ); + return; + } + + auto rigCellResults = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL ); + if ( !rigCellResults ) return; + + auto resultNames = rigCellResults->resultNames( RiaDefines::ResultCatType::GENERATED ); + + std::vector keywords; + for ( const auto& resultName : resultNames ) + { + keywords.push_back( resultName ); + } + + const bool writeEchoKeywords = false; + if ( !RifEclipseInputFileTools::exportKeywords( fileName, eclipseCase->eclipseCaseData(), keywords, writeEchoKeywords ) ) + { + RiaLogging::error( "Error detected when writing the cache file : " + fileName ); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifReaderRegularGridModel::~RifReaderRegularGridModel() +void RifReaderRegularGridModel::ensureDataIsReadFromCache( const QString& fileName, RimEclipseCase* eclipseCase ) { -} + if ( !eclipseCase ) return; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifReaderRegularGridModel::open( const QString& fileName, RigEclipseCaseData* eclipseCase ) -{ - m_reservoirBuilder.createGridsAndCells( eclipseCase ); - m_reservoir = eclipseCase; - return true; -} + auto rigCellResults = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL ); + if ( !rigCellResults ) return; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifReaderRegularGridModel::staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values ) -{ - CAF_ASSERT( false ); - return true; -} + // Early return if we have already read the data from the cache + auto existingResultNames = rigCellResults->resultNames( RiaDefines::ResultCatType::GENERATED ); + if ( !existingResultNames.empty() ) return; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifReaderRegularGridModel::dynamicResult( const QString& result, - RiaDefines::PorosityModelType matrixOrFracture, - size_t stepIndex, - std::vector* values ) -{ - CAF_ASSERT( false ); - return true; -} + auto keywordsAndData = RifEclipseTextFileReader::readKeywordAndValues( fileName.toStdString() ); + for ( const auto& content : keywordsAndData ) + { + const auto resultName = QString::fromStdString( content.keyword ); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RifReaderRegularGridModel::setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate ) -{ - m_reservoirBuilder.setWorldCoordinates( minWorldCoordinate, maxWorldCoordinate ); -} + RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::GENERATED, RiaDefines::ResultDataType::FLOAT, resultName ); + rigCellResults->createResultEntry( resAddr, false ); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RifReaderRegularGridModel::setGridPointDimensions( const cvf::Vec3st& gridPointDimensions ) -{ - m_reservoirBuilder.setIJKCount( gridPointDimensions ); -} + auto newPropertyData = rigCellResults->modifiableCellScalarResultTimesteps( resAddr ); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RifReaderRegularGridModel::addLocalGridRefinement( const cvf::Vec3st& minCellPosition, - const cvf::Vec3st& maxCellPosition, - const cvf::Vec3st& singleCellRefinementFactors ) -{ - m_reservoirBuilder.addLocalGridRefinement( minCellPosition, maxCellPosition, singleCellRefinementFactors ); + std::vector doubleVals; + doubleVals.insert( doubleVals.begin(), content.values.begin(), content.values.end() ); + + newPropertyData->push_back( doubleVals ); + } } diff --git a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h index 321e10bd64..08b5067afd 100644 --- a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h +++ b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h @@ -18,28 +18,13 @@ #pragma once -#include "RifReaderInterface.h" -#include "RigReservoirBuilder.h" +#include -class RifReaderRegularGridModel : public RifReaderInterface +class RimEclipseCase; + +namespace RifReaderRegularGridModel { -public: - RifReaderRegularGridModel(); - ~RifReaderRegularGridModel() override; +void writeCache( const QString& fileName, RimEclipseCase* eclipseCase ); +void ensureDataIsReadFromCache( const QString& fileName, RimEclipseCase* eclipseCase ); - void setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate ); - void setGridPointDimensions( const cvf::Vec3st& gridPointDimensions ); - - void addLocalGridRefinement( const cvf::Vec3st& minCellPosition, - const cvf::Vec3st& maxCellPosition, - const cvf::Vec3st& singleCellRefinementFactors ); - - bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) override; - - bool staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values ) override; - bool dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values ) override; - -private: - RigReservoirBuilder m_reservoirBuilder; - RigEclipseCaseData* m_reservoir; -}; +}; // namespace RifReaderRegularGridModel diff --git a/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp b/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp index b7d2cc964d..9ee37f21ae 100644 --- a/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp @@ -22,6 +22,9 @@ #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" +#include "RigReservoirBuilder.h" + +#include "RimTools.h" CAF_PDM_SOURCE_INIT( RimRegularGridCase, "EclipseBoundingBoxCase" ); //-------------------------------------------------------------------------------------------------- @@ -69,22 +72,39 @@ void RimRegularGridCase::setCellCount( const cvf::Vec3st& cellCount ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RimRegularGridCase::createModel( QString modelName ) +void RimRegularGridCase::createModel() { - cvf::ref reader = new RifReaderRegularGridModel; - cvf::ref reservoir = new RigEclipseCaseData( this ); + cvf::ref reservoir = new RigEclipseCaseData( this ); - reader->setWorldCoordinates( m_minimum, m_maximum ); + RigReservoirBuilder reservoirBuilder; + reservoirBuilder.setWorldCoordinates( m_minimum, m_maximum ); cvf::Vec3st gridPointDimensions( m_cellCountI, m_cellCountJ, m_cellCountK ); - reader->setGridPointDimensions( gridPointDimensions ); + reservoirBuilder.setIJKCount( gridPointDimensions ); - reader->open( "", reservoir.p() ); + reservoirBuilder.createGridsAndCells( reservoir.p() ); setReservoirData( reservoir.p() ); computeCachedData(); +} - return reader.p(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimRegularGridCase::setupBeforeSave() +{ + auto fileName = cacheFileName(); + RifReaderRegularGridModel::writeCache( fileName, this ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimRegularGridCase::cacheFileName() const +{ + auto cacheDirPath = RimTools::getCacheRootDirectoryPathFromProject(); + cacheDirPath += "_welltarget/welltargetdata.GRDECL"; + return cacheDirPath; } //-------------------------------------------------------------------------------------------------- @@ -92,9 +112,13 @@ cvf::ref RimRegularGridCase::createModel( QString modelName //-------------------------------------------------------------------------------------------------- bool RimRegularGridCase::openEclipseGridFile() { - if ( eclipseCaseData() ) return true; + if ( !eclipseCaseData() ) + { + createModel(); + } - createModel( "" ); + auto fileName = cacheFileName(); + RifReaderRegularGridModel::ensureDataIsReadFromCache( fileName, this ); return true; } diff --git a/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.h b/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.h index 136491e4a6..e96e44aeee 100644 --- a/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.h @@ -43,7 +43,11 @@ public: bool openEclipseGridFile() override; - cvf::ref createModel( QString modelName ); + void createModel(); + +private: + void setupBeforeSave() override; + QString cacheFileName() const; private: caf::PdmField m_minimum; diff --git a/ApplicationLibCode/ReservoirDataModel/Well/RigWellTargetCandidatesGenerator.cpp b/ApplicationLibCode/ReservoirDataModel/Well/RigWellTargetCandidatesGenerator.cpp index b533079c3f..767336977a 100644 --- a/ApplicationLibCode/ReservoirDataModel/Well/RigWellTargetCandidatesGenerator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/Well/RigWellTargetCandidatesGenerator.cpp @@ -757,7 +757,7 @@ RimRegularGridCase* RigWellTargetCandidatesGenerator::generateEnsembleCandidates RimRegularGridCase* targetCase = new RimRegularGridCase; targetCase->setBoundingBox( boundingBox ); targetCase->setCellCount( resultGridCellCount ); - targetCase->createModel( "" ); + targetCase->createModel(); std::vector occurrence;