Box: add active index property

To support field properties with only active cells the Box class has been
extended to give a set of active indices for a box. In addition the BoxManager
has been refactored:

 - Use std::unique_ptr<Box> to enable "has no box" situation.
 - Removed several unused getXXX() methods.

And the begin() and end() iterators have been removed from the Box class.
This commit is contained in:
Joakim Hove
2019-10-04 16:49:18 +02:00
parent 2991ce0aea
commit b4908c6fa0
8 changed files with 120 additions and 141 deletions

View File

@@ -25,23 +25,24 @@
#include <cstddef>
namespace Opm {
class EclipseGrid;
class Box {
public:
Box() = default;
Box(int nx , int ny , int nz);
Box(const Box& globalBox , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); // Zero offset coordinates.
Box(int nx, int ny, int nz, int i1 , int i2 , int j1 , int j2 , int k1 , int k2);
struct index_pair {
std::size_t global;
std::size_t active;
};
Box(const EclipseGrid& grid);
Box(const EclipseGrid& grid , int i1 , int i2 , int j1 , int j2 , int k1 , int k2);
size_t size() const;
bool isGlobal() const;
size_t getDim(size_t idim) const;
const std::vector<index_pair>& index_list() const;
const std::vector<size_t>& getIndexList() const;
bool equal(const Box& other) const;
explicit operator bool() const;
std::vector<size_t>::const_iterator begin() const;
std::vector<size_t>::const_iterator end() const;
int I1() const;
int I2() const;
@@ -52,12 +53,14 @@ namespace Opm {
private:
void initIndexList();
const EclipseGrid& grid;
size_t m_dims[3] = { 0, 0, 0 };
size_t m_offset[3];
size_t m_stride[3];
bool m_isGlobal;
std::vector<size_t> m_indexList;
std::vector<size_t> global_index_list;
std::vector<index_pair> m_index_list;
int lower(int dim) const;
int upper(int dim) const;

View File

@@ -25,6 +25,7 @@
#include <memory>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
/*
This class implements a simple book keeping system for the current
@@ -53,7 +54,7 @@ namespace Opm {
class BoxManager {
public:
BoxManager(int nx , int ny , int nz);
BoxManager(const EclipseGrid& grid);
void setInputBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
void setKeywordBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
@@ -63,14 +64,12 @@ namespace Opm {
void endKeyword();
const Box& getActiveBox() const;
const Box& getGlobalBox() const;
const Box& getInputBox() const;
const Box& getKeywordBox() const;
private:
Box m_globalBox;
Box m_inputBox;
Box m_keywordBox;
const EclipseGrid& grid;
std::unique_ptr<Box> m_globalBox;
std::unique_ptr<Box> m_inputBox;
std::unique_ptr<Box> m_keywordBox;
};
}

View File

@@ -766,10 +766,7 @@ namespace Opm {
void Eclipse3DProperties::scanSection(const Section& section,
const EclipseGrid& eclipseGrid) {
BoxManager boxManager(eclipseGrid.getNX(),
eclipseGrid.getNY(),
eclipseGrid.getNZ());
BoxManager boxManager(eclipseGrid);
for( const auto& deckKeyword : section ) {
if (supportsGridProperty(deckKeyword.name()) )

View File

@@ -20,6 +20,7 @@
#include <stdexcept>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
namespace {
@@ -39,19 +40,12 @@ namespace {
namespace Opm {
Box::Box(int nx , int ny , int nz) {
if (nx <= 0)
throw std::invalid_argument("The input nx value is invalid");
if (ny <= 0)
throw std::invalid_argument("The input ny value is invalid");
if (nz <= 0)
throw std::invalid_argument("The input nz value is invalid");
m_dims[0] = (size_t) nx;
m_dims[1] = (size_t) ny;
m_dims[2] = (size_t) nz;
Box::Box(const EclipseGrid& grid_arg) :
grid(grid_arg)
{
m_dims[0] = grid_arg.getNX();
m_dims[1] = grid_arg.getNY();
m_dims[2] = grid_arg.getNZ();
m_offset[0] = 0;
m_offset[1] = 0;
@@ -66,7 +60,13 @@ namespace Opm {
}
Box::Box(int nx, int ny, int nz, int i1 , int i2 , int j1 , int j2 , int k1 , int k2) {
Box::Box(const EclipseGrid& grid_arg, int i1 , int i2 , int j1 , int j2 , int k1 , int k2) :
grid(grid_arg)
{
std::size_t nx = grid_arg.getNX();
std::size_t ny = grid_arg.getNY();
std::size_t nz = grid_arg.getNZ();
assert_dims(nx , i1 , i2);
assert_dims(ny , j1 , j2);
assert_dims(nz , k1 , k2);
@@ -92,11 +92,6 @@ namespace Opm {
}
Box::Box(const Box& globalBox , int i1 , int i2 , int j1 , int j2 , int k1 , int k2) :
Box(globalBox.getDim(0), globalBox.getDim(1), globalBox.getDim(2), i1,i2,j1,j2,k1,k2)
{ }
size_t Box::size() const {
return m_dims[0] * m_dims[1] * m_dims[2];
@@ -117,26 +112,20 @@ namespace Opm {
std::vector<size_t>::const_iterator Box::begin() const {
return m_indexList.begin();
}
std::vector<size_t>::const_iterator Box::end() const {
return m_indexList.end();
}
const std::vector<size_t>& Box::getIndexList() const {
return m_indexList;
return global_index_list;
}
const std::vector<Box::index_pair>& Box::index_list() const {
return m_index_list;
}
void Box::initIndexList() {
m_indexList.resize( size() );
global_index_list.clear();
m_index_list.clear();
size_t ii,ij,ik;
size_t l = 0;
for (ik=0; ik < m_dims[2]; ik++) {
size_t k = ik + m_offset[2];
for (ij=0; ij < m_dims[1]; ij++) {
@@ -145,8 +134,9 @@ namespace Opm {
size_t i = ii + m_offset[0];
size_t g = i * m_stride[0] + j*m_stride[1] + k*m_stride[2];
m_indexList[l] = g;
l++;
global_index_list.push_back(g);
if (this->grid.cellActive(g))
m_index_list.push_back({g,this->grid.activeIndex(g)});
}
}
}
@@ -173,10 +163,6 @@ namespace Opm {
return true;
}
Box::operator bool() const {
return this->size() != 0;
}
int Box::lower(int dim) const {
return m_offset[dim];

View File

@@ -24,44 +24,32 @@
namespace Opm {
BoxManager::BoxManager(int nx , int ny , int nz) :
m_globalBox( nx, ny, nz )
BoxManager::BoxManager(const EclipseGrid& grid_arg) :
grid( grid_arg ),
m_globalBox( std::unique_ptr<Box>( new Box(grid_arg) ))
{}
const Box& BoxManager::getGlobalBox() const {
return m_globalBox;
}
const Box& BoxManager::getInputBox() const {
return m_inputBox;
}
const Box& BoxManager::getKeywordBox() const {
return m_keywordBox;
}
const Box& BoxManager::getActiveBox() const {
if (m_keywordBox)
return m_keywordBox;
return *m_keywordBox;
if (m_inputBox)
return m_inputBox;
return *m_inputBox;
return m_globalBox;
return *m_globalBox;
}
void BoxManager::setInputBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2) {
this->m_inputBox = Box( this->m_globalBox, i1, i2, j1, j2, k1, k2 );
this->m_inputBox.reset(new Box( this->grid, i1, i2, j1, j2, k1, k2 ));
}
void BoxManager::endInputBox() {
if(m_keywordBox)
throw std::invalid_argument("Hmmm - this seems like an internal error - the SECTION is terminated with an active keyword box");
m_inputBox = Box{};
m_inputBox.reset( 0 );
}
void BoxManager::endSection() {
@@ -69,11 +57,11 @@ namespace Opm {
}
void BoxManager::setKeywordBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2) {
this->m_keywordBox = Box( this->m_globalBox, i1, i2, j1, j2, k1, k2 );
this->m_keywordBox.reset( new Box( this->grid, i1, i2, j1, j2, k1, k2 ));
}
void BoxManager::endKeyword() {
this->m_keywordBox = Box{};
this->m_keywordBox.reset( 0 );
}
}

View File

@@ -522,7 +522,7 @@ namespace Opm {
operate_fptr func = operations.at( operation );
setKeywordBox(record, boxManager);
for (auto index : boxManager.getActiveBox())
for (auto index : boxManager.getActiveBox().getIndexList())
targetData[index] = func( targetData[index] , srcData[index] , alpha, beta );
}
}

View File

@@ -31,11 +31,8 @@
#include <opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp>
BOOST_AUTO_TEST_CASE(CreateBox) {
BOOST_CHECK_THROW( new Opm::Box(-1,0,0) , std::invalid_argument);
BOOST_CHECK_THROW( new Opm::Box(10,0,10) , std::invalid_argument);
BOOST_CHECK_THROW( new Opm::Box(10,10,-1) , std::invalid_argument);
Opm::Box box(4,3,2);
Opm::EclipseGrid grid(4,3,2);
Opm::Box box(grid);
BOOST_CHECK_EQUAL( 24U , box.size() );
BOOST_CHECK( box.isGlobal() );
BOOST_CHECK_EQUAL( 4 , box.getDim(0) );
@@ -58,29 +55,24 @@ BOOST_AUTO_TEST_CASE(CreateBox) {
}
}
}
i = 0;
for (auto index : box) {
BOOST_CHECK_EQUAL( index , indexList[i]);
i++;
}
}
}
BOOST_AUTO_TEST_CASE(CreateSubBox) {
Opm::Box globalBox( 10,10,10 );
Opm::EclipseGrid grid(10,10,10);
Opm::Box globalBox(grid);
BOOST_CHECK_THROW( new Opm::Box( globalBox , -1 , 9 , 1 , 8 , 1, 8) , std::invalid_argument); // Negative throw
BOOST_CHECK_THROW( new Opm::Box( globalBox , 1 , 19 , 1 , 8 , 1, 8) , std::invalid_argument); // Bigger than global: throw
BOOST_CHECK_THROW( new Opm::Box( globalBox , 9 , 1 , 1 , 8 , 1, 8) , std::invalid_argument); // Inverted order: throw
BOOST_CHECK_THROW( new Opm::Box( grid , -1 , 9 , 1 , 8 , 1, 8) , std::invalid_argument); // Negative throw
BOOST_CHECK_THROW( new Opm::Box( grid , 1 , 19 , 1 , 8 , 1, 8) , std::invalid_argument); // Bigger than global: throw
BOOST_CHECK_THROW( new Opm::Box( grid , 9 , 1 , 1 , 8 , 1, 8) , std::invalid_argument); // Inverted order: throw
Opm::Box subBox1(globalBox , 0,9,0,9,0,9);
Opm::Box subBox1(grid, 0,9,0,9,0,9);
BOOST_CHECK( subBox1.isGlobal());
Opm::Box subBox2(globalBox , 1,3,1,4,1,5);
Opm::Box subBox2(grid, 1,3,1,4,1,5);
BOOST_CHECK( !subBox2.isGlobal());
BOOST_CHECK_EQUAL( 60U , subBox2.size() );
@@ -102,14 +94,17 @@ BOOST_AUTO_TEST_CASE(CreateSubBox) {
BOOST_AUTO_TEST_CASE(BoxEqual) {
Opm::Box globalBox1( 10,10,10 );
Opm::Box globalBox2( 10,10,10 );
Opm::Box globalBox3( 10,10,11 );
Opm::EclipseGrid grid1(10,10,10);
Opm::EclipseGrid grid3(10,10,11);
Opm::EclipseGrid grid4(20,20,20);
Opm::Box globalBox1( grid1 );
Opm::Box globalBox2( grid1 );
Opm::Box globalBox3( grid3 );
Opm::Box globalBox4( 20,20,20 );
Opm::Box subBox1( globalBox1 , 0 , 9 , 0 , 9 , 0, 9);
Opm::Box subBox4( globalBox4 , 0 , 9 , 0 , 9 , 0, 9);
Opm::Box subBox5( globalBox4 , 10 , 19 , 10 , 19 , 10, 19);
Opm::Box globalBox4(grid4);
Opm::Box subBox1( grid1 , 0 , 9 , 0 , 9 , 0, 9);
Opm::Box subBox4( grid4 , 0 , 9 , 0 , 9 , 0, 9);
Opm::Box subBox5( grid4 , 10 , 19 , 10 , 19 , 10, 19);
BOOST_CHECK( globalBox1.equal( globalBox2 ));
BOOST_CHECK( !globalBox1.equal( globalBox3 ));
@@ -120,45 +115,43 @@ BOOST_AUTO_TEST_CASE(BoxEqual) {
}
BOOST_AUTO_TEST_CASE(CreateBoxManager) {
Opm::BoxManager boxManager(10,10,10);
Opm::Box box(10,10,10);
Opm::EclipseGrid grid(10,10,10);
Opm::BoxManager boxManager(grid);
Opm::Box box(grid);
BOOST_CHECK( box.equal( boxManager.getGlobalBox()) );
BOOST_CHECK( box.equal( boxManager.getActiveBox()) );
BOOST_CHECK( !boxManager.getInputBox() );
BOOST_CHECK( !boxManager.getKeywordBox() );
}
BOOST_AUTO_TEST_CASE(TestInputBox) {
Opm::BoxManager boxManager(10,10,10);
Opm::Box inputBox( boxManager.getGlobalBox(), 0,4,0,4,0,4);
Opm::EclipseGrid grid(10,10,10);
Opm::BoxManager boxManager(grid);
Opm::Box inputBox( grid, 0,4,0,4,0,4);
Opm::Box globalBox( grid );
boxManager.setInputBox( 0,4,0,4,0,4 );
BOOST_CHECK( inputBox.equal( boxManager.getInputBox()) );
BOOST_CHECK( inputBox.equal( boxManager.getActiveBox()) );
boxManager.endSection();
BOOST_CHECK( !boxManager.getInputBox() );
BOOST_CHECK( boxManager.getActiveBox().equal( boxManager.getGlobalBox()));
BOOST_CHECK( boxManager.getActiveBox().equal(globalBox));
}
BOOST_AUTO_TEST_CASE(TestKeywordBox) {
Opm::BoxManager boxManager(10,10,10);
Opm::Box inputBox( boxManager.getGlobalBox() , 0,4,0,4,0,4);
Opm::Box keywordBox( boxManager.getGlobalBox() , 0,2,0,2,0,2);
Opm::EclipseGrid grid(10,10,10);
Opm::BoxManager boxManager(grid);
Opm::Box inputBox( grid, 0,4,0,4,0,4);
Opm::Box keywordBox( grid, 0,2,0,2,0,2);
Opm::Box globalBox( grid );
boxManager.setInputBox( 0,4,0,4,0,4 );
BOOST_CHECK( inputBox.equal( boxManager.getActiveBox()) );
boxManager.setKeywordBox( 0,2,0,2,0,2 );
BOOST_CHECK( inputBox.equal( boxManager.getInputBox()) );
BOOST_CHECK( keywordBox.equal( boxManager.getKeywordBox()) );
BOOST_CHECK( keywordBox.equal( boxManager.getActiveBox()) );
// Must end keyword first
@@ -166,11 +159,9 @@ BOOST_AUTO_TEST_CASE(TestKeywordBox) {
boxManager.endKeyword();
BOOST_CHECK( inputBox.equal( boxManager.getActiveBox()) );
BOOST_CHECK( !boxManager.getKeywordBox() );
boxManager.endSection();
BOOST_CHECK( !boxManager.getInputBox() );
BOOST_CHECK( boxManager.getActiveBox().equal( boxManager.getGlobalBox()));
BOOST_CHECK( boxManager.getActiveBox().equal(globalBox));
}
@@ -178,14 +169,26 @@ BOOST_AUTO_TEST_CASE(BoxNineArg) {
const size_t nx = 10;
const size_t ny = 7;
const size_t nz = 6;
BOOST_CHECK_NO_THROW( Opm::Box(nx,ny,nz,0,7,0,5,1,2) );
// Invalid x dimension
BOOST_CHECK_THROW( Opm::Box(0,ny,nz,0,0,1,1,2,2), std::invalid_argument);
Opm::EclipseGrid grid(nx,ny,nz);
BOOST_CHECK_NO_THROW( Opm::Box(grid,0,7,0,5,1,2) );
// J2 < J1
BOOST_CHECK_THROW( Opm::Box(nx,ny,nz,1,1,4,3,2,2), std::invalid_argument);
BOOST_CHECK_THROW( Opm::Box(grid,1,1,4,3,2,2), std::invalid_argument);
// K2 >= Nz
BOOST_CHECK_THROW( Opm::Box(nx,ny,nz,1,1,2,2,3,nz), std::invalid_argument);
BOOST_CHECK_THROW( Opm::Box(grid,1,1,2,2,3,nz), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(TestKeywordBox2) {
Opm::EclipseGrid grid(10,10,10);
std::vector<int> actnum(grid.getCartesianSize(), 1);
actnum[0] = 0;
grid.resetACTNUM(actnum);
Opm::BoxManager boxManager(grid);
const auto& box = boxManager.getActiveBox();
for (const auto& p : box.index_list())
BOOST_CHECK_EQUAL(p.active + 1, p.global);
BOOST_CHECK_EQUAL(box.index_list().size() + 1, grid.getCartesianSize());
}

View File

@@ -160,9 +160,9 @@ BOOST_AUTO_TEST_CASE(copy) {
SupportedKeywordInfo keywordInfo2("P2", 9, "1");
Opm::GridProperty<int> prop1(4, 4, 2, keywordInfo1);
Opm::GridProperty<int> prop2(4, 4, 2, keywordInfo2);
Opm::Box global(4, 4, 2);
Opm::Box layer0(global, 0, 3, 0, 3, 0, 0);
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop2.copyFrom(prop1, layer0);
@@ -184,8 +184,9 @@ BOOST_AUTO_TEST_CASE(SCALE) {
Opm::GridProperty<int> prop1( 4, 4, 2, keywordInfo1 );
Opm::GridProperty<int> prop2( 4, 4, 2, keywordInfo2 );
Opm::Box global( 4, 4, 2 );
Opm::Box layer0( global, 0, 3, 0, 3, 0, 0 );
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop2.copyFrom( prop1, layer0 );
prop2.scale( 2, global );
@@ -205,8 +206,9 @@ BOOST_AUTO_TEST_CASE(SET) {
SupportedKeywordInfo keywordInfo( "P1", 1, "1" );
Opm::GridProperty<int> prop( 4, 4, 2, keywordInfo );
Opm::Box global( 4, 4, 2 );
Opm::Box layer0( global, 0, 3, 0, 3, 0, 0 );
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop.setScalar( 2, global );
prop.setScalar( 4, layer0 );
@@ -227,8 +229,9 @@ BOOST_AUTO_TEST_CASE(ADD) {
Opm::GridProperty<int> prop1( 4, 4, 2, keywordInfo1 );
Opm::GridProperty<int> prop2( 4, 4, 2, keywordInfo2 );
Opm::Box global( 4, 4, 2 );
Opm::Box layer0( global, 0, 3, 0, 3, 0, 0 );
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop2.copyFrom( prop1, layer0 );
prop2.add( 2, global );