diff --git a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake index e913f2ac12..ed9053afbb 100644 --- a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake @@ -96,6 +96,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigWellAllocationOverTime.h ${CMAKE_CURRENT_LIST_DIR}/RigWellResultBranch.h ${CMAKE_CURRENT_LIST_DIR}/RigWellResultFrame.h + ${CMAKE_CURRENT_LIST_DIR}/RigReservoirBuilder.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -190,6 +191,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigWellResultBranch.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellResultFrame.cpp ${CMAKE_CURRENT_LIST_DIR}/RigDeclineCurveCalculator.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigReservoirBuilder.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilder.cpp b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilder.cpp new file mode 100644 index 0000000000..dc917c41ee --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilder.cpp @@ -0,0 +1,287 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigReservoirBuilder.h" + +#include "RigActiveCellInfo.h" +#include "RigCell.h" +#include "RigEclipseCaseData.h" +#include "RigMainGrid.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigReservoirBuilder::RigReservoirBuilder() + : m_minWorldCoordinate( 0.0, 0.0, 0.0 ) + , m_maxWorldCoordinate( 0.0, 0.0, 0.0 ) + , m_gridPointDimensions( 0, 0, 0 ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate ) +{ + m_minWorldCoordinate = minWorldCoordinate; + m_maxWorldCoordinate = maxWorldCoordinate; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::setIJKCount( const cvf::Vec3st& ijkCount ) +{ + m_gridPointDimensions = { ijkCount.x() + 1, ijkCount.y() + 1, ijkCount.z() + 1 }; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::addLocalGridRefinement( const cvf::Vec3st& minCellPosition, + const cvf::Vec3st& maxCellPosition, + const cvf::Vec3st& singleCellRefinementFactors ) +{ + m_localGridRefinements.push_back( LocalGridRefinement( minCellPosition, maxCellPosition, singleCellRefinementFactors ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// Build the geometry for a grids and cells +/// - create 8 nodes for each cell +/// - create cells by referencing the nodes +/// - optionally create and add LGR grids +/// - set all cells to active +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::createGridsAndCells( RigEclipseCaseData* eclipseCase ) +{ + std::vector& mainGridNodes = eclipseCase->mainGrid()->nodes(); + appendNodes( m_minWorldCoordinate, m_maxWorldCoordinate, ijkCount(), mainGridNodes ); + size_t mainGridNodeCount = mainGridNodes.size(); + size_t mainGridCellCount = mainGridNodeCount / 8; + + // Must create cells in main grid here, as this information is used when creating LGRs + appendCells( 0, mainGridCellCount, eclipseCase->mainGrid(), eclipseCase->mainGrid()->globalCellArray() ); + + size_t totalCellCount = mainGridCellCount; + + size_t lgrIdx; + for ( lgrIdx = 0; lgrIdx < m_localGridRefinements.size(); lgrIdx++ ) + { + LocalGridRefinement& lgr = m_localGridRefinements[lgrIdx]; + + // Compute all global cell indices to be replaced by local grid refinement + std::vector mainGridIndicesWithSubGrid; + { + size_t i; + for ( i = lgr.m_mainGridMinCellPosition.x(); i <= lgr.m_mainGridMaxCellPosition.x(); i++ ) + { + size_t j; + for ( j = lgr.m_mainGridMinCellPosition.y(); j <= lgr.m_mainGridMaxCellPosition.y(); j++ ) + { + size_t k; + for ( k = lgr.m_mainGridMinCellPosition.z(); k <= lgr.m_mainGridMaxCellPosition.z(); k++ ) + { + mainGridIndicesWithSubGrid.push_back( cellIndexFromIJK( i, j, k ) ); + } + } + } + } + + // Create local grid and set local grid dimensions + RigLocalGrid* localGrid = new RigLocalGrid( eclipseCase->mainGrid() ); + localGrid->setGridId( 1 ); + localGrid->setGridName( "LGR_1" ); + eclipseCase->mainGrid()->addLocalGrid( localGrid ); + localGrid->setParentGrid( eclipseCase->mainGrid() ); + + localGrid->setIndexToStartOfCells( mainGridNodes.size() / 8 ); + cvf::Vec3st gridPointDimensions( lgr.m_singleCellRefinementFactors.x() * + ( lgr.m_mainGridMaxCellPosition.x() - lgr.m_mainGridMinCellPosition.x() + 1 ) + + 1, + lgr.m_singleCellRefinementFactors.y() * + ( lgr.m_mainGridMaxCellPosition.y() - lgr.m_mainGridMinCellPosition.y() + 1 ) + + 1, + lgr.m_singleCellRefinementFactors.z() * + ( lgr.m_mainGridMaxCellPosition.z() - lgr.m_mainGridMinCellPosition.z() + 1 ) + + 1 ); + localGrid->setGridPointDimensions( gridPointDimensions ); + + cvf::BoundingBox bb; + size_t cellIdx; + for ( cellIdx = 0; cellIdx < mainGridIndicesWithSubGrid.size(); cellIdx++ ) + { + RigCell& cell = eclipseCase->mainGrid()->globalCellArray()[mainGridIndicesWithSubGrid[cellIdx]]; + + std::array& indices = cell.cornerIndices(); + int nodeIdx; + for ( nodeIdx = 0; nodeIdx < 8; nodeIdx++ ) + { + bb.add( eclipseCase->mainGrid()->nodes()[indices[nodeIdx]] ); + } + // Deactivate cell in main grid + cell.setSubGrid( localGrid ); + } + + cvf::Vec3st lgrCellDimensions = gridPointDimensions - cvf::Vec3st( 1, 1, 1 ); + appendNodes( bb.min(), bb.max(), lgrCellDimensions, mainGridNodes ); + + size_t subGridCellCount = ( mainGridNodes.size() / 8 ) - totalCellCount; + appendCells( totalCellCount * 8, subGridCellCount, localGrid, eclipseCase->mainGrid()->globalCellArray() ); + totalCellCount += subGridCellCount; + } + + eclipseCase->mainGrid()->setGridPointDimensions( m_gridPointDimensions ); + + // Set all cells active + RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ); + activeCellInfo->setReservoirCellCount( eclipseCase->mainGrid()->globalCellArray().size() ); + for ( size_t i = 0; i < eclipseCase->mainGrid()->globalCellArray().size(); i++ ) + { + activeCellInfo->setCellResultIndex( i, i ); + } + + activeCellInfo->setGridCount( 1 ); + activeCellInfo->setGridActiveCellCounts( 0, eclipseCase->mainGrid()->globalCellArray().size() ); + activeCellInfo->computeDerivedData(); + + eclipseCase->computeActiveCellBoundingBoxes(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::appendCells( size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells ) +{ + size_t cellIndexStart = cells.size(); + cells.resize( cells.size() + cellCount ); + +#pragma omp parallel for + for ( long long i = 0; i < static_cast( cellCount ); i++ ) + { + RigCell& riCell = cells[cellIndexStart + i]; + + riCell.setHostGrid( hostGrid ); + riCell.setGridLocalCellIndex( i ); + + riCell.cornerIndices()[0] = nodeStartIndex + i * 8 + 0; + riCell.cornerIndices()[1] = nodeStartIndex + i * 8 + 1; + riCell.cornerIndices()[2] = nodeStartIndex + i * 8 + 2; + riCell.cornerIndices()[3] = nodeStartIndex + i * 8 + 3; + riCell.cornerIndices()[4] = nodeStartIndex + i * 8 + 4; + riCell.cornerIndices()[5] = nodeStartIndex + i * 8 + 5; + riCell.cornerIndices()[6] = nodeStartIndex + i * 8 + 6; + riCell.cornerIndices()[7] = nodeStartIndex + i * 8 + 7; + + riCell.setParentCellIndex( 0 ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::appendNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, const cvf::Vec3st& cubeDimension, std::vector& nodes ) +{ + double dx = ( max.x() - min.x() ) / static_cast( cubeDimension.x() ); + double dy = ( max.y() - min.y() ) / static_cast( cubeDimension.y() ); + double dz = ( max.z() - min.z() ) / static_cast( cubeDimension.z() ); + + double zPos = min.z(); + + size_t k; + for ( k = 0; k < cubeDimension.z(); k++ ) + { + double yPos = min.y(); + + size_t j; + for ( j = 0; j < cubeDimension.y(); j++ ) + { + double xPos = min.x(); + + size_t i; + for ( i = 0; i < cubeDimension.x(); i++ ) + { + cvf::Vec3d cornerA( xPos, yPos, zPos ); + cvf::Vec3d cornerB( xPos + dx, yPos + dy, zPos + dz ); + + appendCubeNodes( cornerA, cornerB, nodes ); + + xPos += dx; + } + + yPos += dy; + } + + zPos += dz; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilder::appendCubeNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, std::vector& nodes ) +{ + // + // 7---------6 Faces: + // /| /| |k 0 bottom 0, 3, 2, 1 + // / | / | | /j 1 top 4, 5, 6, 7 + // 4---------5 | |/ 2 front 0, 1, 5, 4 + // | 3------|--2 *---i 3 right 1, 2, 6, 5 + // | / | / 4 back 3, 7, 6, 2 + // |/ |/ 5 left 0, 4, 7, 3 + // 0---------1 + + cvf::Vec3d v0( min.x(), min.y(), min.z() ); + cvf::Vec3d v1( max.x(), min.y(), min.z() ); + cvf::Vec3d v2( max.x(), max.y(), min.z() ); + cvf::Vec3d v3( min.x(), max.y(), min.z() ); + + cvf::Vec3d v4( min.x(), min.y(), max.z() ); + cvf::Vec3d v5( max.x(), min.y(), max.z() ); + cvf::Vec3d v6( max.x(), max.y(), max.z() ); + cvf::Vec3d v7( min.x(), max.y(), max.z() ); + + nodes.push_back( v0 ); + nodes.push_back( v1 ); + nodes.push_back( v2 ); + nodes.push_back( v3 ); + nodes.push_back( v4 ); + nodes.push_back( v5 ); + nodes.push_back( v6 ); + nodes.push_back( v7 ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigReservoirBuilder::cellIndexFromIJK( size_t i, size_t j, size_t k ) const +{ + CVF_TIGHT_ASSERT( i < ( m_gridPointDimensions.x() - 1 ) ); + CVF_TIGHT_ASSERT( j < ( m_gridPointDimensions.y() - 1 ) ); + CVF_TIGHT_ASSERT( k < ( m_gridPointDimensions.z() - 1 ) ); + + size_t ci = i + j * ( m_gridPointDimensions.x() - 1 ) + k * ( ( m_gridPointDimensions.x() - 1 ) * ( m_gridPointDimensions.y() - 1 ) ); + return ci; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3st RigReservoirBuilder::ijkCount() const +{ + return cvf::Vec3st( m_gridPointDimensions.x() - 1, m_gridPointDimensions.y() - 1, m_gridPointDimensions.z() - 1 ); +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilder.h b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilder.h new file mode 100644 index 0000000000..54ad686f38 --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilder.h @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cvfVector3.h" + +#include + +class RigGridBase; +class RigCell; +class RigEclipseCaseData; + +class LocalGridRefinement +{ +public: + LocalGridRefinement( const cvf::Vec3st& mainGridMin, const cvf::Vec3st& mainGridMax, const cvf::Vec3st& singleCellRefinementFactors ) + { + m_mainGridMinCellPosition = mainGridMin; + m_mainGridMaxCellPosition = mainGridMax; + m_singleCellRefinementFactors = singleCellRefinementFactors; + } + + cvf::Vec3st m_mainGridMinCellPosition; + cvf::Vec3st m_mainGridMaxCellPosition; + cvf::Vec3st m_singleCellRefinementFactors; +}; + +class RigReservoirBuilder +{ +public: + RigReservoirBuilder(); + + void setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate ); + + void setIJKCount( const cvf::Vec3st& ijkCount ); + cvf::Vec3st ijkCount() const; + + void addLocalGridRefinement( const cvf::Vec3st& minCellPosition, + const cvf::Vec3st& maxCellPosition, + const cvf::Vec3st& singleCellRefinementFactors ); + + void createGridsAndCells( RigEclipseCaseData* eclipseCase ); + +private: + static void appendCells( size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells ); + static void appendNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, const cvf::Vec3st& cubeDimension, std::vector& nodes ); + static void appendCubeNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, std::vector& nodes ); + + size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const; + +private: + cvf::Vec3d m_minWorldCoordinate; + cvf::Vec3d m_maxWorldCoordinate; + cvf::Vec3st m_gridPointDimensions; + + std::vector m_localGridRefinements; +}; diff --git a/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index a5e8b5b866..a130ccccb3 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -39,10 +39,9 @@ //-------------------------------------------------------------------------------------------------- RigReservoirBuilderMock::RigReservoirBuilderMock() { - m_resultCount = 0; - m_timeStepCount = 0; - m_gridPointDimensions = cvf::Vec3st::ZERO; - m_enableWellData = true; + m_resultCount = 0; + m_timeStepCount = 0; + m_enableWellData = true; } //-------------------------------------------------------------------------------------------------- @@ -50,7 +49,7 @@ RigReservoirBuilderMock::RigReservoirBuilderMock() //-------------------------------------------------------------------------------------------------- void RigReservoirBuilderMock::setGridPointDimensions( const cvf::Vec3st& gridPointDimensions ) { - m_gridPointDimensions = gridPointDimensions; + m_reservoirBuilder.setIJKCount( { gridPointDimensions.x() - 1, gridPointDimensions.y() - 1, gridPointDimensions.z() - 1 } ); } //-------------------------------------------------------------------------------------------------- @@ -62,194 +61,12 @@ void RigReservoirBuilderMock::setResultInfo( size_t resultCount, size_t timeStep m_timeStepCount = timeStepCount; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::appendNodes( const cvf::Vec3d& min, - const cvf::Vec3d& max, - const cvf::Vec3st& cubeDimension, - std::vector& nodes ) -{ - double dx = ( max.x() - min.x() ) / static_cast( cubeDimension.x() ); - double dy = ( max.y() - min.y() ) / static_cast( cubeDimension.y() ); - double dz = ( max.z() - min.z() ) / static_cast( cubeDimension.z() ); - - double zPos = min.z(); - - size_t k; - for ( k = 0; k < cubeDimension.z(); k++ ) - { - double yPos = min.y(); - - size_t j; - for ( j = 0; j < cubeDimension.y(); j++ ) - { - double xPos = min.x(); - - size_t i; - for ( i = 0; i < cubeDimension.x(); i++ ) - { - cvf::Vec3d cornerA( xPos, yPos, zPos ); - cvf::Vec3d cornerB( xPos + dx, yPos + dy, zPos + dz ); - - appendCubeNodes( cornerA, cornerB, nodes ); - - xPos += dx; - } - - yPos += dy; - } - - zPos += dz; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::appendCubeNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, std::vector& nodes ) -{ - // - // 7---------6 Faces: - // /| /| |k 0 bottom 0, 3, 2, 1 - // / | / | | /j 1 top 4, 5, 6, 7 - // 4---------5 | |/ 2 front 0, 1, 5, 4 - // | 3------|--2 *---i 3 right 1, 2, 6, 5 - // | / | / 4 back 3, 7, 6, 2 - // |/ |/ 5 left 0, 4, 7, 3 - // 0---------1 - - cvf::Vec3d v0( min.x(), min.y(), min.z() ); - cvf::Vec3d v1( max.x(), min.y(), min.z() ); - cvf::Vec3d v2( max.x(), max.y(), min.z() ); - cvf::Vec3d v3( min.x(), max.y(), min.z() ); - - cvf::Vec3d v4( min.x(), min.y(), max.z() ); - cvf::Vec3d v5( max.x(), min.y(), max.z() ); - cvf::Vec3d v6( max.x(), max.y(), max.z() ); - cvf::Vec3d v7( min.x(), max.y(), max.z() ); - - nodes.push_back( v0 ); - nodes.push_back( v1 ); - nodes.push_back( v2 ); - nodes.push_back( v3 ); - nodes.push_back( v4 ); - nodes.push_back( v5 ); - nodes.push_back( v6 ); - nodes.push_back( v7 ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::appendCells( size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells ) -{ - size_t cellIndexStart = cells.size(); - cells.resize( cells.size() + cellCount ); - -#pragma omp parallel for - for ( long long i = 0; i < static_cast( cellCount ); i++ ) - { - RigCell& riCell = cells[cellIndexStart + i]; - - riCell.setHostGrid( hostGrid ); - riCell.setGridLocalCellIndex( i ); - - riCell.cornerIndices()[0] = nodeStartIndex + i * 8 + 0; - riCell.cornerIndices()[1] = nodeStartIndex + i * 8 + 1; - riCell.cornerIndices()[2] = nodeStartIndex + i * 8 + 2; - riCell.cornerIndices()[3] = nodeStartIndex + i * 8 + 3; - riCell.cornerIndices()[4] = nodeStartIndex + i * 8 + 4; - riCell.cornerIndices()[5] = nodeStartIndex + i * 8 + 5; - riCell.cornerIndices()[6] = nodeStartIndex + i * 8 + 6; - riCell.cornerIndices()[7] = nodeStartIndex + i * 8 + 7; - - riCell.setParentCellIndex( 0 ); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigReservoirBuilderMock::populateReservoir( RigEclipseCaseData* eclipseCase ) { - std::vector& mainGridNodes = eclipseCase->mainGrid()->nodes(); - appendNodes( m_minWorldCoordinate, m_maxWorldCoordinate, cellDimension(), mainGridNodes ); - size_t mainGridNodeCount = mainGridNodes.size(); - size_t mainGridCellCount = mainGridNodeCount / 8; - - // Must create cells in main grid here, as this information is used when creating LGRs - appendCells( 0, mainGridCellCount, eclipseCase->mainGrid(), eclipseCase->mainGrid()->globalCellArray() ); - - size_t totalCellCount = mainGridCellCount; - - size_t lgrIdx; - for ( lgrIdx = 0; lgrIdx < m_localGridRefinements.size(); lgrIdx++ ) - { - LocalGridRefinement& lgr = m_localGridRefinements[lgrIdx]; - - // Compute all global cell indices to be replaced by local grid refinement - std::vector mainGridIndicesWithSubGrid; - { - size_t i; - for ( i = lgr.m_mainGridMinCellPosition.x(); i <= lgr.m_mainGridMaxCellPosition.x(); i++ ) - { - size_t j; - for ( j = lgr.m_mainGridMinCellPosition.y(); j <= lgr.m_mainGridMaxCellPosition.y(); j++ ) - { - size_t k; - for ( k = lgr.m_mainGridMinCellPosition.z(); k <= lgr.m_mainGridMaxCellPosition.z(); k++ ) - { - mainGridIndicesWithSubGrid.push_back( cellIndexFromIJK( i, j, k ) ); - } - } - } - } - - // Create local grid and set local grid dimensions - RigLocalGrid* localGrid = new RigLocalGrid( eclipseCase->mainGrid() ); - localGrid->setGridId( 1 ); - localGrid->setGridName( "LGR_1" ); - eclipseCase->mainGrid()->addLocalGrid( localGrid ); - localGrid->setParentGrid( eclipseCase->mainGrid() ); - - localGrid->setIndexToStartOfCells( mainGridNodes.size() / 8 ); - cvf::Vec3st gridPointDimensions( lgr.m_singleCellRefinementFactors.x() * - ( lgr.m_mainGridMaxCellPosition.x() - lgr.m_mainGridMinCellPosition.x() + 1 ) + - 1, - lgr.m_singleCellRefinementFactors.y() * - ( lgr.m_mainGridMaxCellPosition.y() - lgr.m_mainGridMinCellPosition.y() + 1 ) + - 1, - lgr.m_singleCellRefinementFactors.z() * - ( lgr.m_mainGridMaxCellPosition.z() - lgr.m_mainGridMinCellPosition.z() + 1 ) + - 1 ); - localGrid->setGridPointDimensions( gridPointDimensions ); - - cvf::BoundingBox bb; - size_t cellIdx; - for ( cellIdx = 0; cellIdx < mainGridIndicesWithSubGrid.size(); cellIdx++ ) - { - RigCell& cell = eclipseCase->mainGrid()->globalCellArray()[mainGridIndicesWithSubGrid[cellIdx]]; - - std::array& indices = cell.cornerIndices(); - int nodeIdx; - for ( nodeIdx = 0; nodeIdx < 8; nodeIdx++ ) - { - bb.add( eclipseCase->mainGrid()->nodes()[indices[nodeIdx]] ); - } - // Deactivate cell in main grid - cell.setSubGrid( localGrid ); - } - - cvf::Vec3st lgrCellDimensions = gridPointDimensions - cvf::Vec3st( 1, 1, 1 ); - appendNodes( bb.min(), bb.max(), lgrCellDimensions, mainGridNodes ); - - size_t subGridCellCount = ( mainGridNodes.size() / 8 ) - totalCellCount; - appendCells( totalCellCount * 8, subGridCellCount, localGrid, eclipseCase->mainGrid()->globalCellArray() ); - totalCellCount += subGridCellCount; - } - - eclipseCase->mainGrid()->setGridPointDimensions( m_gridPointDimensions ); + m_reservoirBuilder.createGridsAndCells( eclipseCase ); if ( m_enableWellData ) { @@ -258,24 +75,12 @@ void RigReservoirBuilderMock::populateReservoir( RigEclipseCaseData* eclipseCase addFaults( eclipseCase ); - // Set all cells active - RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ); - activeCellInfo->setReservoirCellCount( eclipseCase->mainGrid()->globalCellArray().size() ); - for ( size_t i = 0; i < eclipseCase->mainGrid()->globalCellArray().size(); i++ ) - { - activeCellInfo->setCellResultIndex( i, i ); - } - - activeCellInfo->setGridCount( 1 ); - activeCellInfo->setGridActiveCellCounts( 0, eclipseCase->mainGrid()->globalCellArray().size() ); - activeCellInfo->computeDerivedData(); - // Add grid coarsening for main grid - if ( cellDimension().x() > 4 && cellDimension().y() > 5 && cellDimension().z() > 6 ) - { - eclipseCase->mainGrid()->addCoarseningBox( 1, 2, 1, 3, 1, 4 ); - eclipseCase->mainGrid()->addCoarseningBox( 3, 4, 4, 5, 5, 6 ); - } + // if ( cellDimension().x() > 4 && cellDimension().y() > 5 && cellDimension().z() > 6 ) + // { + // eclipseCase->mainGrid()->addCoarseningBox( 1, 2, 1, 3, 1, 4 ); + // eclipseCase->mainGrid()->addCoarseningBox( 3, 4, 4, 5, 5, 6 ); + // } } //-------------------------------------------------------------------------------------------------- @@ -285,7 +90,7 @@ void RigReservoirBuilderMock::addLocalGridRefinement( const cvf::Vec3st& mainGri const cvf::Vec3st& mainGridEnd, const cvf::Vec3st& refinementFactors ) { - m_localGridRefinements.push_back( LocalGridRefinement( mainGridStart, mainGridEnd, refinementFactors ) ); + m_reservoirBuilder.addLocalGridRefinement( mainGridStart, mainGridEnd, refinementFactors ); } //-------------------------------------------------------------------------------------------------- @@ -293,8 +98,7 @@ void RigReservoirBuilderMock::addLocalGridRefinement( const cvf::Vec3st& mainGri //-------------------------------------------------------------------------------------------------- void RigReservoirBuilderMock::setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate ) { - m_minWorldCoordinate = minWorldCoordinate; - m_maxWorldCoordinate = maxWorldCoordinate; + m_reservoirBuilder.setWorldCoordinates( minWorldCoordinate, maxWorldCoordinate ); } //-------------------------------------------------------------------------------------------------- @@ -500,23 +304,25 @@ void RigReservoirBuilderMock::addFaults( RigEclipseCaseData* eclipseCase ) cvf::Collection faults; + auto cellDimension = m_reservoirBuilder.ijkCount(); + { cvf::ref fault = new RigFault; fault->setName( "Fault A" ); cvf::Vec3st min = cvf::Vec3st::ZERO; - cvf::Vec3st max( 0, 0, cellDimension().z() - 2 ); + cvf::Vec3st max( 0, 0, cellDimension.z() - 2 ); - if ( cellDimension().x() > 5 ) + if ( cellDimension.x() > 5 ) { - min.x() = cellDimension().x() / 2; + min.x() = cellDimension.x() / 2; max.x() = min.x() + 2; } - if ( cellDimension().y() > 5 ) + if ( cellDimension.y() > 5 ) { - min.y() = cellDimension().y() / 2; - max.y() = cellDimension().y() / 2; + min.y() = cellDimension.y() / 2; + max.y() = cellDimension.y() / 2; } cvf::CellRange cellRange( min, max ); diff --git a/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.h index c793e532dd..c38269df48 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationLibCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -21,13 +21,12 @@ #pragma once #include "RigNncConnection.h" +#include "RigReservoirBuilder.h" #include "cvfArray.h" #include "cvfObject.h" #include "cvfVector3.h" -#include - class RigEclipseCaseData; class RigMainGrid; class RigGridBase; @@ -35,21 +34,6 @@ class RigCell; class QString; -class LocalGridRefinement -{ -public: - LocalGridRefinement( const cvf::Vec3st& mainGridMin, const cvf::Vec3st& mainGridMax, const cvf::Vec3st& singleCellRefinementFactors ) - { - m_mainGridMinCellPosition = mainGridMin; - m_mainGridMaxCellPosition = mainGridMax; - m_singleCellRefinementFactors = singleCellRefinementFactors; - } - - cvf::Vec3st m_mainGridMinCellPosition; - cvf::Vec3st m_mainGridMaxCellPosition; - cvf::Vec3st m_singleCellRefinementFactors; -}; - class RigReservoirBuilderMock { public: @@ -60,9 +44,8 @@ public: void setResultInfo( size_t resultCount, size_t timeStepCount ); void enableWellData( bool enableWellData ); - size_t resultCount() const { return m_resultCount; } - size_t timeStepCount() const { return m_timeStepCount; } - cvf::Vec3st gridPointDimensions() const { return m_gridPointDimensions; } + size_t resultCount() const { return m_resultCount; } + size_t timeStepCount() const { return m_timeStepCount; } void addLocalGridRefinement( const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, @@ -79,34 +62,12 @@ private: static void addNnc( RigMainGrid* grid, size_t i1, size_t j1, size_t k1, size_t i2, size_t j2, size_t k2, RigConnectionContainer& nncConnections ); - void addWellData( RigEclipseCaseData* eclipseCase, RigGridBase* grid ); - static void appendCells( size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells ); - - static void appendNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, const cvf::Vec3st& cubeDimension, std::vector& nodes ); - static void appendCubeNodes( const cvf::Vec3d& min, const cvf::Vec3d& max, std::vector& nodes ); - - size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const - { - CVF_TIGHT_ASSERT( i < ( m_gridPointDimensions.x() - 1 ) ); - CVF_TIGHT_ASSERT( j < ( m_gridPointDimensions.y() - 1 ) ); - CVF_TIGHT_ASSERT( k < ( m_gridPointDimensions.z() - 1 ) ); - - size_t ci = i + j * ( m_gridPointDimensions.x() - 1 ) + k * ( ( m_gridPointDimensions.x() - 1 ) * ( m_gridPointDimensions.y() - 1 ) ); - return ci; - } - - cvf::Vec3st cellDimension() - { - return cvf::Vec3st( m_gridPointDimensions.x() - 1, m_gridPointDimensions.y() - 1, m_gridPointDimensions.z() - 1 ); - } + void addWellData( RigEclipseCaseData* eclipseCase, RigGridBase* grid ); private: - cvf::Vec3d m_minWorldCoordinate; - cvf::Vec3d m_maxWorldCoordinate; - cvf::Vec3st m_gridPointDimensions; - size_t m_resultCount; - size_t m_timeStepCount; - bool m_enableWellData; + size_t m_resultCount; + size_t m_timeStepCount; + bool m_enableWellData; - std::vector m_localGridRefinements; + RigReservoirBuilder m_reservoirBuilder; };