mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 06:38:13 -05:00
Building the cell search tree was dominated by one small std::vector<int> allocation per leaf, and a tree with one cell per leaf becomes very deep for large grids. - BoundingBoxTree: Store leaf ids in flat arrays, and move the input data instead of copying it. The tree shape is unchanged. Queries no longer copy the ids of each leaf. - RigMainGrid: Always group at least 8 cells along K in each leaf. findIntersectingCells() removes cells not intersecting the query bounding box, so the result is the same set of cells as for a tree with one cell per leaf. This also applies to very large grids, which previously got the cells of the whole leaf. - Include cells of nested LGRs and LGR cells in invalid main grid cells in the grouped tree, as the previous tree with one cell per leaf did.
96 lines
3.8 KiB
C++
96 lines
3.8 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2026- 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 <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "RiaTestDataDirectory.h"
|
|
|
|
#include "RifReaderOpmCommon.h"
|
|
|
|
#include "RigEclipseCaseData.h"
|
|
#include "RigMainGrid.h"
|
|
|
|
#include <QDir>
|
|
|
|
#include <algorithm>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// The search tree stores several cells in each leaf. Verify that the result is the same as when testing the bounding
|
|
/// box of every valid cell, including LGR cells.
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigMainGridSearchTree, FindIntersectingCellsMatchesAllCellsTest )
|
|
{
|
|
QDir baseFolder( TEST_MODEL_DIR );
|
|
QString filename = baseFolder.absoluteFilePath( "TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" );
|
|
ASSERT_TRUE( QFile::exists( filename ) );
|
|
|
|
cvf::ref<RigEclipseCaseData> caseData = new RigEclipseCaseData( nullptr );
|
|
cvf::ref<RifReaderOpmCommon> reader = new RifReaderOpmCommon;
|
|
ASSERT_TRUE( reader->open( filename, caseData.p() ) );
|
|
|
|
RigMainGrid* mainGrid = caseData->mainGrid();
|
|
mainGrid->computeCachedData();
|
|
ASSERT_GT( mainGrid->gridCount(), 1u );
|
|
|
|
std::vector<cvf::BoundingBox> cellBoundingBoxes( mainGrid->totalCellCount() );
|
|
for ( size_t cellIdx = 0; cellIdx < mainGrid->totalCellCount(); cellIdx++ )
|
|
{
|
|
if ( mainGrid->cell( cellIdx ).isInvalid() ) continue;
|
|
|
|
for ( size_t nodeIdx : mainGrid->cell( cellIdx ).cornerIndices() )
|
|
{
|
|
cellBoundingBoxes[cellIdx].add( mainGrid->nodes()[nodeIdx] );
|
|
}
|
|
}
|
|
|
|
const std::vector<double> halfSizes = { 0.1, 20.0, 200.0 };
|
|
const size_t queryCountPerGrid = 20;
|
|
|
|
// Query around cells in the main grid and in each LGR
|
|
size_t queryCount = 0;
|
|
for ( size_t gridIdx = 0; gridIdx < mainGrid->gridCount(); gridIdx++ )
|
|
{
|
|
const RigGridBase* grid = mainGrid->gridByIndex( gridIdx );
|
|
const size_t stride = std::max( size_t( 1 ), grid->cellCount() / queryCountPerGrid );
|
|
|
|
for ( size_t localIdx = 0; localIdx < grid->cellCount(); localIdx += stride )
|
|
{
|
|
const size_t cellIdx = grid->reservoirCellIndex( localIdx );
|
|
if ( mainGrid->cell( cellIdx ).isInvalid() ) continue;
|
|
|
|
const cvf::Vec3d center = mainGrid->cell( cellIdx ).center();
|
|
const double halfSize = halfSizes[queryCount++ % halfSizes.size()];
|
|
|
|
cvf::BoundingBox queryBB( center - cvf::Vec3d( halfSize, halfSize, halfSize ), center + cvf::Vec3d( halfSize, halfSize, halfSize ) );
|
|
|
|
std::vector<size_t> expected;
|
|
for ( size_t i = 0; i < cellBoundingBoxes.size(); i++ )
|
|
{
|
|
if ( cellBoundingBoxes[i].isValid() && cellBoundingBoxes[i].intersects( queryBB ) ) expected.push_back( i );
|
|
}
|
|
|
|
std::vector<size_t> found = mainGrid->findIntersectingCells( queryBB );
|
|
std::sort( found.begin(), found.end() );
|
|
|
|
EXPECT_EQ( expected, found ) << "Query around cell " << cellIdx << " in grid " << gridIdx;
|
|
}
|
|
}
|
|
|
|
EXPECT_GT( queryCount, 2 * queryCountPerGrid );
|
|
}
|