Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ if(MPI_FOUND)
set(MPIEXEC_EXECUTABLE ${MPIEXEC})
endif()
add_test(addLgrsOnDistributedGrid_test_parallel ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 4 bin/addLgrsOnDistributedGrid_test)
add_test(autoRefine_test_parallel ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 4 bin/autoRefine_test)
add_test(communicate_distributed_grid_with_lgrs_test_parallel ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 4 bin/communicate_distributed_grid_with_lgrs_test)
add_test(distribute_level_zero_from_grid_with_lgrs_and_wells_test_parallel ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 4 bin/distribute_level_zero_from_grid_with_lgrs_and_wells_test)
add_test(distribute_level_zero_from_grid_with_lgrs_test_parallel ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 4 bin/distribute_level_zero_from_grid_with_lgrs_test)
Expand Down
1 change: 1 addition & 0 deletions CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ list(APPEND TEST_SOURCE_FILES
tests/cpgrid/entity_test.cpp
tests/cpgrid/facetag_test.cpp
tests/cpgrid/lgr/addLgrsOnDistributedGrid_test.cpp
tests/cpgrid/lgr/autoRefine_test.cpp
tests/cpgrid/lgr/communicate_distributed_grid_with_lgrs_test.cpp
tests/cpgrid/lgr/distribute_level_zero_from_grid_with_lgrs_and_wells_test.cpp
tests/cpgrid/lgr/distribute_level_zero_from_grid_with_lgrs_test.cpp
Expand Down
8 changes: 8 additions & 0 deletions opm/grid/CpGrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,14 @@ namespace Dune
const std::vector<std::array<int,3>>& endIJK_vec,
const std::vector<std::string>& lgr_name_vec);

/// @brief Global refine the grid with different refinement factors in each direction.
///
/// Related to AUTOREF keyword. Each refinement factor must be odd and positive.
/// The restriction on odd factors might be related to placing the wells in the central
/// refined cell, or row of cells, depending on the well direction.
/// @param [in] nxnynz Refinement factors in x-, y-, and z-direction.
void autoRefine(const std::array<int,3>& nxnynz);

// @brief TO BE DONE
const std::map<std::string,int>& getLgrNameToLevel() const;

Expand Down
14 changes: 14 additions & 0 deletions opm/grid/cpgrid/CpGrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2824,6 +2824,20 @@ void CpGrid::addLgrsUpdateLeafView(const std::vector<std::array<int,3>>& cells_p
Opm::OpmLog::info(std::to_string(current_view_data_->size(0)) + " total cells on the leaf grid view (in " + std::to_string(comm().rank()) + " rank).\n");
}

void CpGrid::autoRefine(const std::array<int,3>& nxnynz)
{
// Refinement factors must be odd and positive.
for (const auto& nd : nxnynz) {
if (nd<=0 || (nd%2==0)) {
OPM_THROW(std::invalid_argument, "Refinement factor must be odd and positive.\n");
}
}
const auto endIJK = this->logicalCartesianSize();
addLgrsUpdateLeafView(/* cells_per_dim_vec = */ {nxnynz},
/* startIJK_vec = */ {{0,0,0}},
/* endIJK_vec = */ {endIJK},
/* lgr_name_vec = */ {"GLOBAL_REFINED"});
}

const std::map<std::string,int>& CpGrid::getLgrNameToLevel() const{
return lgr_names_;
Expand Down
4 changes: 2 additions & 2 deletions tests/cpgrid/lgr/LgrChecks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void Opm::checkReferenceElemParentCellVolume(Dune::cpgrid::HierarchicIterator it
[](double sum, const Dune::cpgrid::Entity<0>& child) {
return sum + child.geometryInFather().volume();
});
BOOST_CHECK_CLOSE(reference_elem_parent_cell_volume, 1.0, 1e-13);
BOOST_CHECK_CLOSE(reference_elem_parent_cell_volume, 1.0, 1e-12);
}

void Opm::checkReferenceElemParentCellCenter(Dune::cpgrid::HierarchicIterator it,
Expand All @@ -181,7 +181,7 @@ void Opm::checkReferenceElemParentCellCenter(Dune::cpgrid::HierarchicIterator it

for (int c = 0; c < 3; ++c) {
reference_elem_parent_cell_center[c]/= total_children;
BOOST_CHECK_CLOSE(reference_elem_parent_cell_center[c], .5, 1e-13);
BOOST_CHECK_CLOSE(reference_elem_parent_cell_center[c], .5, 1e-12);
}
}

Expand Down
91 changes: 91 additions & 0 deletions tests/cpgrid/lgr/autoRefine_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Copyright 2025 Equinor ASA.

This file is part of the Open Porous Media project (OPM).

OPM 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.

OPM 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 for more details.

You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"

#define BOOST_TEST_MODULE AutoRefineTests
#include <boost/test/unit_test.hpp>

#include <opm/grid/CpGrid.hpp>
#include <tests/cpgrid/lgr/LgrChecks.hpp>

#include <string>
#include <vector>

struct Fixture
{
Fixture()
{
int m_argc = boost::unit_test::framework::master_test_suite().argc;
char** m_argv = boost::unit_test::framework::master_test_suite().argv;
Dune::MPIHelper::instance(m_argc, m_argv);
Opm::OpmLog::setupSimpleDefaultLogging();
}
};

BOOST_GLOBAL_FIXTURE(Fixture);

BOOST_AUTO_TEST_CASE(evenRefinementFactorThrows)
{
Dune::CpGrid grid;
grid.createCartesian(/* grid_dim = */ {4,3,3}, /* cell_sizes = */ {1.0, 1.0, 1.0});

// nxnynz represents the refinement factors in x-,y-,and z-direction.
BOOST_CHECK_THROW(grid.autoRefine(/* nxnynz = */ {4,3,5}), std::invalid_argument);
BOOST_CHECK_THROW(grid.autoRefine(/* nxnynz = */ {3,4,5}), std::invalid_argument);
BOOST_CHECK_THROW(grid.autoRefine(/* nxnynz = */ {3,5,4}), std::invalid_argument);
}

BOOST_AUTO_TEST_CASE(nonPositiveRefinementFactorThrows)
{
Dune::CpGrid grid;
grid.createCartesian(/* grid_dim = */ {4,3,3}, /* cell_sizes = */ {1.0, 1.0, 1.0});

// nxnynz represents the refinement factors in x-,y-,and z-direction.
BOOST_CHECK_THROW(grid.autoRefine(/* nxnynz = */ {0,3,5}), std::invalid_argument);
BOOST_CHECK_THROW(grid.autoRefine(/* nxnynz = */ {3,-1,5}), std::invalid_argument);
BOOST_CHECK_THROW(grid.autoRefine(/* nxnynz = */ {3,5,-3}), std::invalid_argument);
}

BOOST_AUTO_TEST_CASE(autoRefine)
{
Dune::CpGrid grid;
grid.createCartesian(/* grid_dim = */ {4,3,3}, /* cell_sizes = */ {1.0, 1.0, 1.0});

if (grid.comm().size()>1) { // distribute level zero grid, in parallel
grid.loadBalance();
}

// nxnynz represents the refinement factors in x-,y-,and z-direction.
grid.autoRefine(/* nxnynz = */ {3,5,7});

// Extract the refined level grids name, excluding level zero grid name ("GLOBAL").
// Note: in this case there is only one refined level grid, storing the global
// refinement.
std::vector<std::string> lgrNames(grid.maxLevel());
for (const auto& [name, level] : grid.getLgrNameToLevel()) {
if (level==0) { // skip level zero grid name for the checks
continue;
}
lgrNames[level-1] = name; // Shift the index since level zero has been removed.
}
Opm::checkGridWithLgrs(grid,
/* cells_per_dim_vec = */ {{3,5,7}},
/* lgr_name_vec = */ lgrNames,
/* gridHasBeenGlobalRefined = */ true);
}