diff --git a/ApplicationLibCode/Application/RiaPreferencesGrid.cpp b/ApplicationLibCode/Application/RiaPreferencesGrid.cpp index 151401e58c..f75aa1c1bd 100644 --- a/ApplicationLibCode/Application/RiaPreferencesGrid.cpp +++ b/ApplicationLibCode/Application/RiaPreferencesGrid.cpp @@ -157,7 +157,8 @@ RifReaderSettings RiaPreferencesGrid::gridOnlyReaderSettings() false, // useResultIndexFile true, // skipWellData false, // import summary data - "" // include prefix + "", // include prefix, + false // only active cells }; return rs; } @@ -174,7 +175,8 @@ RifReaderSettings RiaPreferencesGrid::readerSettings() m_useResultIndexFile, m_skipWellData, true, // import summary data - m_includeFileAbsolutePathPrefix }; + m_includeFileAbsolutePathPrefix, + m_onlyLoadActiveCells }; return rs; } diff --git a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake index 89777e2723..259176ad1c 100644 --- a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake @@ -86,6 +86,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.h ${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.h ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.h + ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommonActive.h ${CMAKE_CURRENT_LIST_DIR}/RifEclipseReportKeywords.h ${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h ${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.h @@ -188,6 +189,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.cpp + ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommonActive.cpp ${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.cpp ${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.cpp diff --git a/ApplicationLibCode/FileInterface/RifReaderEclipseWell.cpp b/ApplicationLibCode/FileInterface/RifReaderEclipseWell.cpp index aee64e1e36..c6fa2e7212 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEclipseWell.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderEclipseWell.cpp @@ -132,6 +132,11 @@ size_t RifReaderEclipseWell::localGridCellIndexFromErtConnection( const RigGridB return cvf::UNDEFINED_SIZE_T; } + if ( ( cellI < 0 ) || ( cellJ < 0 ) ) + { + return cvf::UNDEFINED_SIZE_T; + } + return grid->cellIndexFromIJK( cellI, cellJ, cellK ); } @@ -158,6 +163,17 @@ RigWellResultPoint RifReaderEclipseWell::createWellResultPoint( const RigEclipse RigWellResultPoint resultPoint; + if ( ( grid->cellCount() == 0 ) || ( gridCellIndex > grid->cellCount() - 1 ) ) + { + return resultPoint; + } + + const RigCell& c = grid->cell( gridCellIndex ); + if ( c.isInvalid() ) + { + return resultPoint; + } + if ( gridCellIndex != cvf::UNDEFINED_SIZE_T ) { int branchId = -1, segmentId = -1, outletBranchId = -1, outletSegmentId = -1; @@ -857,11 +873,17 @@ void RifReaderEclipseWell::readWellCells( RifEclipseRestartDataAccess* restartDa { prevResPoint = wellResFrame.wellHead(); } - else + else if ( rpIdx > 0 ) { prevResPoint = wellResultBranch.branchResultPoints()[rpIdx - 1]; } + if ( !prevResPoint.isCell() ) + { + // When importing only active cells, this situation can occur if the well head is a inactive cell. + continue; + } + cvf::Vec3d lastConnectionPos = grids[prevResPoint.gridIndex()]->cell( prevResPoint.cellIndex() ).center(); SegmentPositionContribution diff --git a/ApplicationLibCode/FileInterface/RifReaderInterface.cpp b/ApplicationLibCode/FileInterface/RifReaderInterface.cpp index 05ddf0983a..fc6d643bd7 100644 --- a/ApplicationLibCode/FileInterface/RifReaderInterface.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderInterface.cpp @@ -80,6 +80,14 @@ const QString RifReaderInterface::faultIncludeFileAbsolutePathPrefix() const return m_readerSettings.includeFileAbsolutePathPrefix; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderInterface::onlyLoadActiveCells() const +{ + return m_readerSettings.onlyLoadActiveCells; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifReaderInterface.h b/ApplicationLibCode/FileInterface/RifReaderInterface.h index 0da770f2c4..cd391a3766 100644 --- a/ApplicationLibCode/FileInterface/RifReaderInterface.h +++ b/ApplicationLibCode/FileInterface/RifReaderInterface.h @@ -57,6 +57,7 @@ class RifReaderInterface : public cvf::Object bool includeInactiveCellsInFaultGeometry() const; bool loadWellDataEnabled() const; const QString faultIncludeFileAbsolutePathPrefix() const; + bool onlyLoadActiveCells() const; void setReaderSettings( RifReaderSettings readerSettings ); diff --git a/ApplicationLibCode/FileInterface/RifReaderOpmCommon.cpp b/ApplicationLibCode/FileInterface/RifReaderOpmCommon.cpp index 27f3aaabc0..0d48feb263 100644 --- a/ApplicationLibCode/FileInterface/RifReaderOpmCommon.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderOpmCommon.cpp @@ -29,6 +29,7 @@ #include "RifOpmRadialGridTools.h" #include "RifReaderEclipseWell.h" +#include "RigActiveCellGrid.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" @@ -87,18 +88,16 @@ bool RifReaderOpmCommon::open( const QString& fileName, RigEclipseCaseData* ecli return false; } + if ( isFaultImportEnabled() ) { auto task = progress.task( "Reading faults", 25 ); - if ( isFaultImportEnabled() ) - { - cvf::Collection faults; + cvf::Collection faults; - importFaults( fileSet, &faults ); + importFaults( fileSet, &faults ); - RigMainGrid* mainGrid = eclipseCaseData->mainGrid(); - mainGrid->setFaults( faults ); - } + RigMainGrid* mainGrid = eclipseCaseData->mainGrid(); + mainGrid->setFaults( faults ); } m_eclipseCaseData = eclipseCaseData; @@ -108,9 +107,10 @@ bool RifReaderOpmCommon::open( const QString& fileName, RigEclipseCaseData* ecli buildMetaData( eclipseCaseData, progress ); } - auto task = progress.task( "Handling NCC Result data", 25 ); if ( isNNCsEnabled() ) { + auto task = progress.task( "Handling NCC Result data", 25 ); + caf::ProgressInfo nncProgress( 10, "" ); RigMainGrid* mainGrid = eclipseCaseData->mainGrid(); @@ -278,9 +278,11 @@ bool RifReaderOpmCommon::importGrid( RigMainGrid* mainGrid, RigEclipseCaseData* mapAxes[i] = opmMapAxes[i]; } + double norm_denominator = mapAxes[2] * mapAxes[5] - mapAxes[4] * mapAxes[3]; + // Set the map axes transformation matrix on the main grid mainGrid->setMapAxes( mapAxes ); - mainGrid->setUseMapAxes( true ); + mainGrid->setUseMapAxes( norm_denominator != 0.0 ); auto transform = mainGrid->mapAxisTransform(); @@ -414,6 +416,7 @@ void RifReaderOpmCommon::transferGeometry( Opm::EclIO::EGrid& opmMainGrid, RigCell defaultCell; defaultCell.setHostGrid( localGrid ); + mainGrid->globalCellArray().resize( cellStartIndex + cellCount, defaultCell ); mainGrid->nodes().resize( nodeStartIndex + cellCount * 8, cvf::Vec3d( 0, 0, 0 ) ); @@ -724,12 +727,26 @@ void RifReaderOpmCommon::setupInitAndRestartAccess() { if ( ( m_initFile == nullptr ) && !m_initFileName.empty() ) { - m_initFile = std::make_unique( m_initFileName ); + try + { + m_initFile = std::make_unique( m_initFileName ); + } + catch ( ... ) + { + m_initFile = nullptr; + } } if ( ( m_restartFile == nullptr ) && !m_restartFileName.empty() ) { - m_restartFile = std::make_unique( m_restartFileName ); + try + { + m_restartFile = std::make_unique( m_restartFileName ); + } + catch ( ... ) + { + m_restartFile = nullptr; + } } } diff --git a/ApplicationLibCode/FileInterface/RifReaderOpmCommon.h b/ApplicationLibCode/FileInterface/RifReaderOpmCommon.h index 2400a3c15e..c33554d95d 100644 --- a/ApplicationLibCode/FileInterface/RifReaderOpmCommon.h +++ b/ApplicationLibCode/FileInterface/RifReaderOpmCommon.h @@ -32,6 +32,7 @@ class EGrid; } // namespace Opm::EclIO class RigMainGrid; +class RigActiveCellGrid; class RigGridBase; class RigEclipseCaseData; class RigEclipseTimeStepInfo; @@ -58,35 +59,37 @@ class RifReaderOpmCommon : public RifReaderInterface std::vector timeStepsOnFile( QString gridFileName ); -private: - void buildMetaData( RigEclipseCaseData* caseData, caf::ProgressInfo& progress ); - bool importGrid( RigMainGrid* mainGrid, RigEclipseCaseData* caseData ); - void transferGeometry( Opm::EclIO::EGrid& opmMainGrid, - Opm::EclIO::EGrid& opmGrid, - RigMainGrid* riMainGrid, - RigGridBase* riGrid, - RigEclipseCaseData* caseData ); +protected: + virtual bool importGrid( RigMainGrid* mainGrid, RigEclipseCaseData* caseData ); void transferActiveCells( Opm::EclIO::EGrid& opmGrid, size_t cellStartIndex, RigEclipseCaseData* eclipseCaseData, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex ); - void transferStaticNNCData( Opm::EclIO::EGrid& opmMainGrid, std::vector& lgrGrids, RigMainGrid* mainGrid ); - void transferDynamicNNCData( RigMainGrid* mainGrid ); - void locateInitAndRestartFiles( QString gridFileName ); - void setupInitAndRestartAccess(); + bool verifyActiveCellInfo( int activeSizeMat, int activeSizeFrac ); + void updateActiveCellInfo( RigEclipseCaseData* eclipseCaseData, + Opm::EclIO::EGrid& opmGrid, + std::vector& lgrGrids, + RigMainGrid* mainGrid ); + +private: + void buildMetaData( RigEclipseCaseData* caseData, caf::ProgressInfo& progress ); std::vector createFilteredTimeStepInfos(); + std::vector> readActiveCellInfoFromPorv( RigEclipseCaseData* eclipseCaseData, bool isDualPorosity ); - bool verifyActiveCellInfo( int activeSizeMat, int activeSizeFrac ); - std::vector> readActiveCellInfoFromPorv( RigEclipseCaseData* eclipseCaseData, bool isDualPorosity ); - void updateActiveCellInfo( RigEclipseCaseData* eclipseCaseData, - Opm::EclIO::EGrid& opmGrid, - std::vector& lgrGrids, - RigMainGrid* mainGrid ); + void transferGeometry( Opm::EclIO::EGrid& opmMainGrid, + Opm::EclIO::EGrid& opmGrid, + RigMainGrid* riMainGrid, + RigGridBase* riGrid, + RigEclipseCaseData* caseData ); + void transferDynamicNNCData( RigMainGrid* mainGrid ); + + void locateInitAndRestartFiles( QString gridFileName ); + void setupInitAndRestartAccess(); struct TimeDataFile { @@ -99,22 +102,22 @@ class RifReaderOpmCommon : public RifReaderInterface std::vector readTimeSteps(); -private: +protected: enum class ActiveType { ACTIVE_MATRIX_VALUE = 1, ACTIVE_FRACTURE_VALUE = 2 }; - std::string m_gridFileName; - std::string m_initFileName; - std::string m_restartFileName; - int m_gridUnit; + std::string m_gridFileName; + int m_gridUnit; + std::vector m_gridNames; RigEclipseCaseData* m_eclipseCaseData; +private: + std::string m_initFileName; + std::string m_restartFileName; std::unique_ptr m_restartFile; std::unique_ptr m_initFile; - - std::vector m_gridNames; }; diff --git a/ApplicationLibCode/FileInterface/RifReaderOpmCommonActive.cpp b/ApplicationLibCode/FileInterface/RifReaderOpmCommonActive.cpp new file mode 100644 index 0000000000..53ea8662ae --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifReaderOpmCommonActive.cpp @@ -0,0 +1,235 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RifReaderOpmCommonActive.h" + +#include "RiaLogging.h" +#include "RiaStdStringTools.h" + +#include "RifOpmRadialGridTools.h" + +#include "RigActiveCellGrid.h" +#include "RigActiveCellInfo.h" +#include "RigEclipseCaseData.h" + +#include "cafProgressInfo.h" + +#include "opm/io/eclipse/EGrid.hpp" + +#include + +using namespace Opm; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderOpmCommonActive::RifReaderOpmCommonActive() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderOpmCommonActive::~RifReaderOpmCommonActive() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderOpmCommonActive::importGrid( RigMainGrid* /* mainGrid*/, RigEclipseCaseData* eclipseCaseData ) +{ + RigActiveCellGrid* activeGrid = new RigActiveCellGrid(); + eclipseCaseData->setMainGrid( activeGrid ); + + caf::ProgressInfo progInfo( 5, "Importing Eclipse Grid" ); + + Opm::EclIO::EGrid opmGrid( m_gridFileName ); + + const auto& dims = opmGrid.dimension(); + activeGrid->setGridPointDimensions( cvf::Vec3st( dims[0] + 1, dims[1] + 1, dims[2] + 1 ) ); + activeGrid->setGridName( "Main grid" ); + activeGrid->setDualPorosity( opmGrid.porosity_mode() > 0 ); + + // assign grid unit, if found (1 = Metric, 2 = Field, 3 = Lab) + auto gridUnitStr = RiaStdStringTools::toUpper( opmGrid.grid_unit() ); + if ( gridUnitStr.starts_with( 'M' ) ) + m_gridUnit = 1; + else if ( gridUnitStr.starts_with( 'F' ) ) + m_gridUnit = 2; + else if ( gridUnitStr.starts_with( 'C' ) ) + m_gridUnit = 3; + + auto globalMatrixActiveSize = opmGrid.activeCells(); + auto globalFractureActiveSize = opmGrid.activeFracCells(); + + m_gridNames.clear(); + m_gridNames.push_back( "global" ); + + std::vector lgrGrids; // lgrs not supported here for now + + // active cell information + { + auto task = progInfo.task( "Getting Active Cell Information", 1 ); + + // in case init file and grid file disagrees with number of active cells, read extra porv information from init file to correct this + if ( !verifyActiveCellInfo( globalMatrixActiveSize, globalFractureActiveSize ) ) + { + updateActiveCellInfo( eclipseCaseData, opmGrid, lgrGrids, activeGrid ); + } + + activeGrid->transferActiveInformation( eclipseCaseData, + opmGrid.totalActiveCells(), + opmGrid.activeCells(), + opmGrid.activeFracCells(), + opmGrid.active_indexes(), + opmGrid.active_frac_indexes() ); + } + + // grid geometry + { + RiaLogging::info( QString( "Loading %0 active of %1 total cells." ) + .arg( QString::fromStdString( RiaStdStringTools::formatThousandGrouping( opmGrid.totalActiveCells() ) ) ) + .arg( QString::fromStdString( RiaStdStringTools::formatThousandGrouping( opmGrid.totalNumberOfCells() ) ) ) ); + + auto task = progInfo.task( "Loading Active Cell Main Grid Geometry", 1 ); + transferActiveGeometry( opmGrid, activeGrid, eclipseCaseData ); + } + + activeGrid->initAllSubGridsParentGridPointer(); + + if ( isNNCsEnabled() ) + { + auto task = progInfo.task( "Loading NNC data", 1 ); + transferStaticNNCData( opmGrid, lgrGrids, activeGrid ); + } + + auto opmMapAxes = opmGrid.get_mapaxes(); + if ( opmMapAxes.size() == 6 ) + { + std::array mapAxes; + for ( size_t i = 0; i < opmMapAxes.size(); ++i ) + { + mapAxes[i] = opmMapAxes[i]; + } + + double norm_denominator = mapAxes[2] * mapAxes[5] - mapAxes[4] * mapAxes[3]; + + // Set the map axes transformation matrix on the main grid + activeGrid->setMapAxes( mapAxes ); + activeGrid->setUseMapAxes( norm_denominator != 0.0 ); + + auto transform = activeGrid->mapAxisTransform(); + + // Invert the transformation matrix to convert from file coordinates to domain coordinates + transform.invert(); + +#pragma omp parallel for + for ( long i = 0; i < static_cast( activeGrid->nodes().size() ); i++ ) + { + auto& n = activeGrid->nodes()[i]; + n.transformPoint( transform ); + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderOpmCommonActive::transferActiveGeometry( Opm::EclIO::EGrid& opmMainGrid, + RigActiveCellGrid* activeGrid, + RigEclipseCaseData* eclipseCaseData ) +{ + int cellCount = opmMainGrid.totalActiveCells(); + + RigCell defaultCell; + defaultCell.setHostGrid( activeGrid ); + for ( size_t i = 0; i < 8; i++ ) + defaultCell.cornerIndices()[i] = 0; + + activeGrid->globalCellArray().resize( cellCount + 1, defaultCell ); + activeGrid->globalCellArray()[cellCount].setInvalid( true ); + + activeGrid->nodes().resize( ( cellCount + 1 ) * 8, cvf::Vec3d( 0, 0, 0 ) ); + + auto& riNodes = activeGrid->nodes(); + + opmMainGrid.loadData(); + opmMainGrid.load_grid_data(); + + const bool isRadialGrid = opmMainGrid.is_radial(); + const auto& activeMatIndexes = opmMainGrid.active_indexes(); + const auto& activeFracIndexes = opmMainGrid.active_frac_indexes(); + + // Compute the center of the LGR radial grid cells for each K layer + auto radialGridCenterTopLayerOpm = isRadialGrid + ? RifOpmRadialGridTools::computeXyCenterForTopOfCells( opmMainGrid, opmMainGrid, activeGrid ) + : std::map>(); + + // use same mapping as resdata + const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 }; + +#pragma omp parallel for + for ( int opmCellIndex = 0; opmCellIndex < static_cast( opmMainGrid.totalNumberOfCells() ); opmCellIndex++ ) + { + if ( ( activeMatIndexes[opmCellIndex] < 0 ) && ( activeFracIndexes[opmCellIndex] < 0 ) ) continue; + + auto opmIJK = opmMainGrid.ijk_from_global_index( opmCellIndex ); + + double xCenterCoordOpm = 0.0; + double yCenterCoordOpm = 0.0; + + if ( isRadialGrid && radialGridCenterTopLayerOpm.contains( opmIJK[2] ) ) + { + const auto& [xCenter, yCenter] = radialGridCenterTopLayerOpm[opmIJK[2]]; + xCenterCoordOpm = xCenter; + yCenterCoordOpm = yCenter; + } + + auto riReservoirIndex = activeGrid->cellIndexFromIJK( opmIJK[0], opmIJK[1], opmIJK[2] ); + RigCell& cell = activeGrid->globalCellArray()[riReservoirIndex]; + cell.setGridLocalCellIndex( riReservoirIndex ); + cell.setParentCellIndex( cvf::UNDEFINED_SIZE_T ); + + // corner coordinates + std::array opmX{}; + std::array opmY{}; + std::array opmZ{}; + opmMainGrid.getCellCorners( opmCellIndex, opmX, opmY, opmZ ); + + // Each cell has 8 nodes, use reservoir cell index and multiply to find first node index for cell + auto riNodeStartIndex = riReservoirIndex * 8; + + for ( size_t opmNodeIndex = 0; opmNodeIndex < 8; opmNodeIndex++ ) + { + auto riCornerIndex = cellMappingECLRi[opmNodeIndex]; + size_t riNodeIndex = riNodeStartIndex + riCornerIndex; + + auto& riNode = riNodes[riNodeIndex]; + riNode.x() = opmX[opmNodeIndex] + xCenterCoordOpm; + riNode.y() = opmY[opmNodeIndex] + yCenterCoordOpm; + riNode.z() = -opmZ[opmNodeIndex]; + + cell.cornerIndices()[riCornerIndex] = riNodeIndex; + } + + cell.setInvalid( cell.isLongPyramidCell() ); + } +} diff --git a/ApplicationLibCode/FileInterface/RifReaderOpmCommonActive.h b/ApplicationLibCode/FileInterface/RifReaderOpmCommonActive.h new file mode 100644 index 0000000000..99a2d3224c --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifReaderOpmCommonActive.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RifReaderOpmCommon.h" + +class RigActiveCellGrid; + +//================================================================================================== +// +// +//================================================================================================== +class RifReaderOpmCommonActive : public RifReaderOpmCommon +{ +public: + RifReaderOpmCommonActive(); + ~RifReaderOpmCommonActive() override; + +protected: + bool importGrid( RigMainGrid* mainGrid, RigEclipseCaseData* caseData ) override; + void transferActiveGeometry( Opm::EclIO::EGrid& opmMainGrid, RigActiveCellGrid* riMainGrid, RigEclipseCaseData* caseData ); +}; diff --git a/ApplicationLibCode/FileInterface/RifReaderSettings.h b/ApplicationLibCode/FileInterface/RifReaderSettings.h index 8041974822..689de687cd 100644 --- a/ApplicationLibCode/FileInterface/RifReaderSettings.h +++ b/ApplicationLibCode/FileInterface/RifReaderSettings.h @@ -35,4 +35,5 @@ struct RifReaderSettings bool skipWellData; bool importSummaryData; QString includeFileAbsolutePathPrefix; + bool onlyLoadActiveCells; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp index 845e4f8e19..17a4a85dc6 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp @@ -771,6 +771,12 @@ void RimEclipseCase::computeActiveCellsBoundingBox() bool useOptimizedVersion = true; + const auto gridPref = RiaPreferencesGrid::current(); + if ( ( gridPref != nullptr ) && ( gridPref->gridModelReader() == RiaDefines::GridModelReader::OPM_COMMON ) ) + { + useOptimizedVersion = !gridPref->onlyLoadActiveCells(); + } + if ( auto proj = RimProject::current() ) { if ( proj->isProjectFileVersionEqualOrOlderThan( "2023.12.0" ) ) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp index 28604204a3..07fba987c2 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -36,6 +36,7 @@ #include "RifReaderEclipseRft.h" #include "RifReaderMockModel.h" #include "RifReaderOpmCommon.h" +#include "RifReaderOpmCommonActive.h" #include "RifReaderOpmRft.h" #include "RigCaseCellResultsData.h" @@ -188,7 +189,16 @@ bool RimEclipseResultCase::importGridAndResultMetaData( bool showTimeStepFilter } else { - auto readerOpmCommon = new RifReaderOpmCommon(); + RifReaderOpmCommon* readerOpmCommon = nullptr; + + if ( RiaPreferencesGrid::current()->onlyLoadActiveCells() ) + { + readerOpmCommon = new RifReaderOpmCommonActive(); + } + else + { + readerOpmCommon = new RifReaderOpmCommon(); + } std::vector timeSteps = readerOpmCommon->timeStepsOnFile( gridFileName() ); m_timeStepFilter->setTimeStepsFromFile( timeSteps ); diff --git a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake index f42b255323..c6f90aafa8 100644 --- a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake @@ -22,6 +22,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigEclipseWellLogExtractor.h ${CMAKE_CURRENT_LIST_DIR}/RigLocalGrid.h ${CMAKE_CURRENT_LIST_DIR}/RigMainGrid.h + ${CMAKE_CURRENT_LIST_DIR}/RigActiveCellGrid.h ${CMAKE_CURRENT_LIST_DIR}/RigReservoirBuilderMock.h ${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultsData.h ${CMAKE_CURRENT_LIST_DIR}/RigSimWellData.h @@ -124,6 +125,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigEclipseWellLogExtractor.cpp ${CMAKE_CURRENT_LIST_DIR}/RigLocalGrid.cpp ${CMAKE_CURRENT_LIST_DIR}/RigMainGrid.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigActiveCellGrid.cpp ${CMAKE_CURRENT_LIST_DIR}/RigReservoirBuilderMock.cpp ${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultsData.cpp ${CMAKE_CURRENT_LIST_DIR}/RigSimWellData.cpp diff --git a/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp new file mode 100644 index 0000000000..f1c7e36617 --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.cpp @@ -0,0 +1,164 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigActiveCellGrid.h" + +#include "RigActiveCellInfo.h" +#include "RigEclipseCaseData.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellGrid::RigActiveCellGrid() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellGrid::~RigActiveCellGrid() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellGrid::transferActiveInformation( RigEclipseCaseData* eclipseCaseData, + size_t totalActiveCells, + size_t matrixActiveCells, + size_t fractureActiveCells, + const std::vector& activeMatrixIndexes, + const std::vector& activeFracIndexes ) +{ + const auto totalCells = activeMatrixIndexes.size(); + + m_globalToActiveMap.resize( totalCells ); + size_t activeCells = 0; + size_t anInactiveCellIdx = 0; + + for ( size_t i = 0; i < totalCells; i++ ) + { + if ( ( activeMatrixIndexes[i] < 0 ) && ( activeFracIndexes[i] < 0 ) ) + { + m_globalToActiveMap[i] = totalActiveCells; + anInactiveCellIdx = i; + continue; + } + m_activeToGlobalMap.push_back( i ); + m_globalToActiveMap[i] = activeCells++; + } + m_activeToGlobalMap.push_back( anInactiveCellIdx ); + + RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ); + RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ); + + activeCellInfo->setReservoirCellCount( totalActiveCells + 1 ); + fractureActiveCellInfo->setReservoirCellCount( totalActiveCells + 1 ); + + activeCellInfo->setGridCount( 1 ); + fractureActiveCellInfo->setGridCount( 1 ); + + activeCellInfo->setGridActiveCellCounts( 0, matrixActiveCells ); + fractureActiveCellInfo->setGridActiveCellCounts( 0, fractureActiveCells ); + +#pragma omp parallel for + for ( int opmCellIndex = 0; opmCellIndex < (int)totalCells; opmCellIndex++ ) + { + auto activeCellIndex = m_globalToActiveMap[opmCellIndex]; + + // active cell index + int matrixActiveIndex = activeMatrixIndexes[opmCellIndex]; + if ( matrixActiveIndex != -1 ) + { + activeCellInfo->setCellResultIndex( activeCellIndex, matrixActiveIndex ); + } + + int fractureActiveIndex = activeFracIndexes[opmCellIndex]; + if ( fractureActiveIndex != -1 ) + { + fractureActiveCellInfo->setCellResultIndex( activeCellIndex, fractureActiveIndex ); + } + } + + activeCellInfo->computeDerivedData(); + fractureActiveCellInfo->computeDerivedData(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellGrid::cellIndexFromIJK( size_t i, size_t j, size_t k ) const +{ + auto index = RigGridBase::cellIndexFromIJK( i, j, k ); + return m_globalToActiveMap[index]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellGrid::cellIndexFromIJKUnguarded( size_t i, size_t j, size_t k ) const +{ + auto index = RigGridBase::cellIndexFromIJKUnguarded( i, j, k ); + return m_globalToActiveMap[index]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigActiveCellGrid::ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const +{ + if ( cellIndex >= m_activeToGlobalMap.size() ) + { + return false; + } + auto index = m_activeToGlobalMap[cellIndex]; + return RigGridBase::ijkFromCellIndex( index, i, j, k ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellGrid::ijkFromCellIndexUnguarded( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const +{ + auto index = m_activeToGlobalMap[cellIndex]; + RigGridBase::ijkFromCellIndexUnguarded( index, i, j, k ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCell& RigActiveCellGrid::cell( size_t gridLocalCellIndex ) +{ + return m_cells[gridLocalCellIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigCell& RigActiveCellGrid::cell( size_t gridLocalCellIndex ) const +{ + return m_cells[gridLocalCellIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellGrid::cellCount() const +{ + return m_cells.size(); +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h new file mode 100644 index 0000000000..da0e124a2c --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigActiveCellGrid.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigMainGrid.h" + +#include + +class RigActiveCellGrid : public RigMainGrid +{ +public: + RigActiveCellGrid(); + ~RigActiveCellGrid() override; + + void transferActiveInformation( RigEclipseCaseData* eclipseCaseData, + size_t totalActiveCells, + size_t matrixActiveCells, + size_t fractureActiveCells, + const std::vector& activeMatrixIndexes, + const std::vector& activeFracIndexes ); + + size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const override; + size_t cellIndexFromIJKUnguarded( size_t i, size_t j, size_t k ) const override; + bool ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const override; + void ijkFromCellIndexUnguarded( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const override; + + RigCell& cell( size_t gridLocalCellIndex ) override; + const RigCell& cell( size_t gridLocalCellIndex ) const override; + size_t cellCount() const override; + +private: + std::vector m_globalToActiveMap; + std::vector m_activeToGlobalMap; + RigCell m_invalidCell; +}; diff --git a/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.cpp b/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.cpp index d10442cbd6..839d18da54 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.cpp @@ -333,12 +333,12 @@ const cvf::UIntArray* RigEclipseCaseData::gridCellToResultWellIndex( size_t grid //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RigCell& RigEclipseCaseData::cellFromWellResultCell( const RigWellResultPoint& wellResultCell ) const +const RigCell& RigEclipseCaseData::cellFromWellResultCell( const RigWellResultPoint& wellResultPoint ) const { - CVF_ASSERT( wellResultCell.isCell() ); + CVF_ASSERT( wellResultPoint.isCell() ); - size_t gridIndex = wellResultCell.gridIndex(); - size_t gridCellIndex = wellResultCell.cellIndex(); + size_t gridIndex = wellResultPoint.gridIndex(); + size_t gridCellIndex = wellResultPoint.cellIndex(); std::vector grids; allGrids( &grids ); @@ -429,12 +429,13 @@ void RigEclipseCaseData::computeActiveCellIJKBBox() CellRangeBB matrixModelActiveBB; CellRangeBB fractureModelActiveBB; - size_t idx; - for ( idx = 0; idx < m_mainGrid->cellCount(); idx++ ) + for ( size_t idx = 0; idx < m_mainGrid->cellCount(); idx++ ) { size_t i, j, k; m_mainGrid->ijkFromCellIndex( idx, &i, &j, &k ); + if ( !m_mainGrid->isCellValid( i, j, k ) ) continue; + if ( m_activeCellInfo->isActive( idx ) ) { matrixModelActiveBB.add( i, j, k ); @@ -724,13 +725,16 @@ void RigEclipseCaseData::computeActiveCellsGeometryBoundingBoxOptimized() { for ( size_t j = minBB.y(); j <= maxBB.y(); j++ ) { - size_t cellIndex = m_mainGrid->cellIndexFromIJK( i, j, k ); - - std::array hexCorners; - m_mainGrid->cellCornerVertices( cellIndex, hexCorners.data() ); - for ( const auto& corner : hexCorners ) + if ( m_mainGrid->isCellValid( i, j, k ) ) { - bb.add( corner ); + size_t cellIndex = m_mainGrid->cellIndexFromIJK( i, j, k ); + + std::array hexCorners; + m_mainGrid->cellCornerVertices( cellIndex, hexCorners.data() ); + for ( const auto& corner : hexCorners ) + { + bb.add( corner ); + } } } } diff --git a/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.h b/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.h index 63416b16cb..b37a9d527b 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.h +++ b/ApplicationLibCode/ReservoirDataModel/RigEclipseCaseData.h @@ -98,7 +98,7 @@ class RigEclipseCaseData : public cvf::Object const cvf::UByteArray* wellCellsInGrid( size_t gridIndex ); const cvf::UIntArray* gridCellToResultWellIndex( size_t gridIndex ); - const RigCell& cellFromWellResultCell( const RigWellResultPoint& wellResultCell ) const; + const RigCell& cellFromWellResultCell( const RigWellResultPoint& wellResultPoint ) const; bool findSharedSourceFace( cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultPoint& sourceWellCellResult, const RigWellResultPoint& otherWellCellResult ) const; diff --git a/ApplicationLibCode/ReservoirDataModel/RigGridBase.cpp b/ApplicationLibCode/ReservoirDataModel/RigGridBase.cpp index ac27d61adb..19d88793b8 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGridBase.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigGridBase.cpp @@ -208,7 +208,7 @@ void RigGridBase::cellMinMaxCordinates( size_t cellIndex, cvf::Vec3d* minCoordin //-------------------------------------------------------------------------------------------------- bool RigGridBase::ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const { - CVF_TIGHT_ASSERT( cellIndex < cellCount() ); + CVF_TIGHT_ASSERT( cellIndex < RigGridBase::cellCount() ); size_t index = cellIndex; @@ -413,6 +413,27 @@ double RigGridBase::characteristicIJCellSize() const return characteristicCellSize; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridBase::characteristicCellSizes( double* iSize, double* jSize, double* kSize ) const +{ + CVF_ASSERT( iSize && jSize && kSize ); + + if ( !hasValidCharacteristicCellSizes() ) + { + std::vector reservoirCellIndices; + reservoirCellIndices.resize( cellCount() ); + std::iota( reservoirCellIndices.begin(), reservoirCellIndices.end(), 0 ); + + computeCharacteristicCellSize( reservoirCellIndices ); + } + + *iSize = m_characteristicCellSizeI; + *jSize = m_characteristicCellSizeJ; + *kSize = m_characteristicCellSizeK; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigGridBase.h b/ApplicationLibCode/ReservoirDataModel/RigGridBase.h index 72af3574a0..3502e2b72a 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGridBase.h +++ b/ApplicationLibCode/ReservoirDataModel/RigGridBase.h @@ -49,9 +49,11 @@ class RigGridBase : public cvf::StructGridInterface size_t cellCountJ() const override; size_t cellCountK() const override; - size_t cellCount() const; - RigCell& cell( size_t gridLocalCellIndex ); - const RigCell& cell( size_t gridLocalCellIndex ) const; + virtual size_t cellCount() const; + virtual RigCell& cell( size_t gridLocalCellIndex ); + virtual const RigCell& cell( size_t gridLocalCellIndex ) const; + + void characteristicCellSizes( double* iSize, double* jSize, double* kSize ) const override; size_t reservoirCellIndex( size_t gridLocalCellIndex ) const; void setIndexToStartOfCells( size_t indexToStartOfCells ) { m_indexToStartOfCells = indexToStartOfCells; } @@ -91,20 +93,20 @@ class RigGridBase : public cvf::StructGridInterface cvf::Vec3d maxCoordinate() const override; cvf::Vec3d displayModelOffset() const override; - size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const override; - size_t cellIndexFromIJKUnguarded( size_t i, size_t j, size_t k ) const; - bool ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const override; - void ijkFromCellIndexUnguarded( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const; + size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const override; + virtual size_t cellIndexFromIJKUnguarded( size_t i, size_t j, size_t k ) const; + bool ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const override; + virtual void ijkFromCellIndexUnguarded( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const; std::optional ijkFromCellIndex( size_t cellIndex ) const; std::optional ijkFromCellIndexOneBased( size_t cellIndex ) const; - bool cellIJKFromCoordinate( const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k ) const override; + bool cellIJKFromCoordinate( const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k ) const override; // unused + void cellMinMaxCordinates( size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate ) const override; // unused + void cellCornerVertices( size_t cellIndex, cvf::Vec3d vertices[8] ) const override; cvf::Vec3d cellCentroid( size_t cellIndex ) const override; - void cellMinMaxCordinates( size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate ) const override; - size_t gridPointIndexFromIJK( size_t i, size_t j, size_t k ) const override; cvf::Vec3d gridPointCoordinate( size_t i, size_t j, size_t k ) const override; diff --git a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h index d0a851dad4..821f7fde94 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationLibCode/ReservoirDataModel/RigMainGrid.h @@ -43,20 +43,20 @@ class RigMainGrid : public RigGridBase RigMainGrid(); ~RigMainGrid() override; -public: std::vector& nodes(); const std::vector& nodes() const; std::vector& globalCellArray(); const std::vector& globalCellArray() const; - RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx ); - const RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx ) const; + virtual RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx ); + virtual const RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx ) const; + + virtual const RigCell& cellByGridAndGridLocalCellIdx( size_t gridIdx, size_t gridLocalCellIdx ) const; + virtual size_t reservoirCellIndexByGridAndGridLocalCellIndex( size_t gridIdx, size_t gridLocalCellIdx ) const; + virtual size_t findReservoirCellIndexFromPoint( const cvf::Vec3d& point ) const; - const RigCell& cellByGridAndGridLocalCellIdx( size_t gridIdx, size_t gridLocalCellIdx ) const; - size_t reservoirCellIndexByGridAndGridLocalCellIndex( size_t gridIdx, size_t gridLocalCellIdx ) const; - size_t findReservoirCellIndexFromPoint( const cvf::Vec3d& point ) const; - void addLocalGrid( RigLocalGrid* localGrid ); + void addLocalGrid( RigLocalGrid* localGrid ); size_t gridCountOnFile() const; size_t gridCount() const; @@ -114,7 +114,7 @@ class RigMainGrid : public RigGridBase bool isDualPorosity() const; void setDualPorosity( bool enable ); -private: +protected: void initAllSubCellsMainGridCellIndex(); void buildCellSearchTree(); void buildCellSearchTreeOptimized( size_t cellsPerBoundingBox ); @@ -123,7 +123,7 @@ class RigMainGrid : public RigGridBase static std::array defaultMapAxes(); -private: +protected: std::vector m_nodes; ///< Global vertex table std::vector m_cells; ///< Global array of all cells in the reservoir (including the ones in LGR's) cvf::Collection m_localGrids; ///< List of all the LGR's in this reservoir diff --git a/ApplicationLibCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp index 014a96d9ef..7d1e39aeb4 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp @@ -243,7 +243,10 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineForTimeSt // Well head // Match this position with well head position in RivWellHeadPartMgr::buildWellHeadParts() - const RigCell& whCell = eclipseCaseData->cellFromWellResultCell( wellFrame.wellHeadOrStartCell() ); + auto wellPoint = wellFrame.wellHeadOrStartCell(); + if ( !wellPoint.isCell() ) return; + + const RigCell& whCell = eclipseCaseData->cellFromWellResultCell( wellPoint ); cvf::Vec3d whStartPos = whCell.faceCenter( cvf::StructGridInterface::NEG_K ); RigWellResultPoint wellHead = wellFrame.wellHeadOrStartCell(); diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellResultFrame.cpp b/ApplicationLibCode/ReservoirDataModel/RigWellResultFrame.cpp index 417b1dc07d..1d5584ac22 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellResultFrame.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigWellResultFrame.cpp @@ -101,7 +101,7 @@ RigWellResultPoint RigWellResultFrame::wellHeadOrStartCell() const } } - return m_wellHead; // Nothing else to do + return RigWellResultPoint(); // Nothing else matters } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/CommonCode/cvfStructGrid.h b/Fwk/AppFwk/CommonCode/cvfStructGrid.h index 7275be352a..94adf0d436 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGrid.h +++ b/Fwk/AppFwk/CommonCode/cvfStructGrid.h @@ -85,7 +85,7 @@ class StructGridInterface : public Object virtual cvf::Vec3d minCoordinate() const = 0; virtual cvf::Vec3d maxCoordinate() const = 0; - void characteristicCellSizes( double* iSize, double* jSize, double* kSize ) const; + virtual void characteristicCellSizes( double* iSize, double* jSize, double* kSize ) const; bool hasValidCharacteristicCellSizes() const; void computeCharacteristicCellSize( const std::vector& globalCellIndices ) const; @@ -123,7 +123,7 @@ class StructGridInterface : public Object cvf::StructGridInterface::FaceType face2 ); static std::vector validFaceTypes(); -private: +protected: mutable double m_characteristicCellSizeI; mutable double m_characteristicCellSizeJ; mutable double m_characteristicCellSizeK; diff --git a/ThirdParty/custom-opm-common/opm-common b/ThirdParty/custom-opm-common/opm-common index ea6dba538b..c351cfbbdd 160000 --- a/ThirdParty/custom-opm-common/opm-common +++ b/ThirdParty/custom-opm-common/opm-common @@ -1 +1 @@ -Subproject commit ea6dba538bfb0498eb1ec6ad51a853b99e446a5b +Subproject commit c351cfbbdd7eefdf7fc76cbe846637e14eb3671e