diff --git a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake index 93fa7de074..a2659a010e 100644 --- a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake @@ -88,6 +88,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommonActive.h ${CMAKE_CURRENT_LIST_DIR}/RifEclipseReportKeywords.h ${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h + ${CMAKE_CURRENT_LIST_DIR}/RifEdfmTools.h ${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.h ${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.h ${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryAddressDefines.h @@ -191,6 +192,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.cpp ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommonActive.cpp ${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.cpp + ${CMAKE_CURRENT_LIST_DIR}/RifEdfmTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.cpp ${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.cpp ${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryAddressDefines.cpp diff --git a/ApplicationLibCode/FileInterface/RifEdfmTools.cpp b/ApplicationLibCode/FileInterface/RifEdfmTools.cpp new file mode 100644 index 0000000000..16fdd9e9e2 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifEdfmTools.cpp @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 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 "RifEdfmTools.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RifEdfmTools::checkForEdfmData( QString gridFileName ) +{ + QFileInfo fi( gridFileName ); + + QString edfmFileName = fi.absolutePath() + "/_EDFM.txt"; + if ( !QFile::exists( edfmFileName ) ) return 0; + + QFile edfmFile( edfmFileName ); + if ( edfmFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + QTextStream ts( &edfmFile ); + while ( !ts.atEnd() ) + { + auto line = ts.readLine().trimmed(); + if ( line.startsWith( "NXORIGINAL" ) ) + { + auto list = line.split( " ", Qt::SkipEmptyParts ); + if ( list.size() == 2 ) + { + return list[1].toUInt(); + } + + break; + } + } + edfmFile.close(); + } + + return 0; +} diff --git a/ApplicationLibCode/FileInterface/RifEdfmTools.h b/ApplicationLibCode/FileInterface/RifEdfmTools.h new file mode 100644 index 0000000000..09303278f3 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifEdfmTools.h @@ -0,0 +1,26 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2025 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 + +namespace RifEdfmTools +{ +size_t checkForEdfmData( QString gridFileName ); +} diff --git a/ApplicationLibCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivReservoirViewPartMgr.cpp index cb9b65e766..4e290e8e6f 100644 --- a/ApplicationLibCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -605,7 +605,7 @@ void RivReservoirViewPartMgr::computeNativeVisibility( cvf::UByteArray* if ( auto activeGrid = dynamic_cast( grid ) ) { - auto cellIndices = activeGrid->activeLocalCellIndices(); + auto cellIndices = activeGrid->activeLocalCellIndices( !invalidCellsIsVisible ); #pragma omp parallel for for ( int i = 0; i < static_cast( cellIndices.size() ); i++ ) { diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp index b11f6317b5..42616b2280 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -31,6 +31,7 @@ #include "RifEclipseOutputFileTools.h" #include "RifEclipseRestartDataAccess.h" +#include "RifEdfmTools.h" #include "RifInputPropertyLoader.h" #include "RifReaderEclipseOutput.h" #include "RifReaderEclipseRft.h" @@ -255,6 +256,12 @@ bool RimEclipseResultCase::importGridAndResultMetaData( bool showTimeStepFilter setFilesContainingFaults( readerInterface->filenamesWithFaults() ); setReservoirData( eclipseCase.p() ); + + auto iLimitFromEdfm = RifEdfmTools::checkForEdfmData( gridFileName() ); + if ( iLimitFromEdfm > 0 ) + { + eclipseCase->mainGrid()->invalidateCellsAboveI( iLimitFromEdfm - 1 /* zero based index */ ); + } } results( RiaDefines::PorosityModelType::MATRIX_MODEL )->setReaderInterface( readerInterface.p() ); diff --git a/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp index 63ef1d683c..54e91fabb4 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp @@ -112,7 +112,7 @@ size_t RigActiveCellGrid::totalActiveCellCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigActiveCellGrid::activeLocalCellIndices() const +std::vector RigActiveCellGrid::activeLocalCellIndices( bool skipInvalidCells ) const { std::vector indices; indices.reserve( m_nativeCells.size() ); @@ -120,6 +120,9 @@ std::vector RigActiveCellGrid::activeLocalCellIndices() const for ( const auto& [index, cell] : m_nativeCells ) { + // skip invalid cells unless they should be included + if ( skipInvalidCells && cell.isInvalid() ) continue; + // only add cells indexes that belongs to our grid, not subgrids if ( index < maxCellIdx ) indices.emplace_back( index ); } diff --git a/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h index e3f9e21d21..f5b8bc0d2a 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h +++ b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h @@ -34,7 +34,7 @@ public: size_t totalCellCount() const override; size_t totalActiveCellCount() const; - std::vector activeLocalCellIndices() const; + std::vector activeLocalCellIndices( bool skipInvalidCells ) const; protected: // only for use by file readers! friend class RifReaderOpmCommonActive; diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp index b8fbf88406..19a144394b 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.cpp @@ -1114,3 +1114,26 @@ std::array RigMainGrid::defaultMapAxes() // Order (see Elipse Reference Manual for keyword MAPAXES): Y_x, Y_y, O_x, O_y, X_x, X_y return { yPoint[0], yPoint[1], origin[0], origin[1], xPoint[0], xPoint[1] }; } + +//-------------------------------------------------------------------------------------------------- +// Invalidate all cells with I > iLimit (0 based index) +//-------------------------------------------------------------------------------------------------- +void RigMainGrid::invalidateCellsAboveI( size_t iLimit ) +{ + const auto cells = cellCount(); + for ( size_t i = iLimit + 1; i < cellCountI(); i++ ) + { + for ( size_t j = 0; j < cellCountJ(); j++ ) + { + for ( size_t k = 0; k < cellCountK(); k++ ) + { + const auto cellIdx = cellIndexFromIJK( i, j, k ); + if ( cellIdx < cells ) + { + RigCell& c = cell( cellIdx ); + c.setInvalid( true ); + } + } + } + } +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h index 758fe82685..58d21ea6d0 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h @@ -113,6 +113,9 @@ public: bool isDualPorosity() const; void setDualPorosity( bool enable ); + // invalidate all cells with I > iLimit (0 based index) + void invalidateCellsAboveI( size_t iLimit ); + protected: // only for use by file readers and internal services. TODO: replace with a better API friend class RigGridBase; friend class RigReservoirBuilder; diff --git a/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp b/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp index 13d443a81b..cb0cfc9059 100644 --- a/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp +++ b/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp @@ -503,6 +503,7 @@ void RiuSelectionChangedHandler::addDepthCurveFromSelectionItem( const RiuSelect const RiuEclipseSelectionItem* eclipseSelectionItem = static_cast( itemAdded ); if ( eclipseSelectionItem == nullptr ) return; + if ( eclipseSelectionItem->m_view == nullptr ) return; int currentTimeStep = eclipseSelectionItem->m_view->currentTimeStep();