Merge pull request #3069 from bska/decouple-box-from-grid

Decouple Opm::Box From EclipseGrid
This commit is contained in:
Markus Blatt 2022-07-06 15:15:51 +02:00 committed by GitHub
commit bad915fdf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 352 additions and 235 deletions

View File

@ -70,6 +70,7 @@ public:
/// \param k The index in the k direction /// \param k The index in the k direction
/// \return The local index or -1 if the cell is inactive /// \return The local index or -1 if the cell is inactive
int localCell(std::size_t i, std::size_t j, std::size_t k) const; int localCell(std::size_t i, std::size_t j, std::size_t k) const;
protected: protected:
/// \brief Maps the cartesian index to a compressed local index. /// \brief Maps the cartesian index to a compressed local index.
/// ///

View File

@ -17,61 +17,75 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BOX_HPP_ #ifndef BOX_HPP_
#define BOX_HPP_ #define BOX_HPP_
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
#include <array>
#include <cstddef> #include <cstddef>
#include <limits> #include <functional>
#include <vector> #include <vector>
namespace Opm { namespace Opm {
class DeckRecord; class DeckRecord;
class EclipseGrid; }
class Box { namespace Opm
{
class Box
{
public: public:
using IsActive = std::function<bool(const std::size_t globalIdx)>;
using ActiveIdx = std::function<std::size_t(const std::size_t globalIdx)>;
struct cell_index
struct cell_index { {
std::size_t global_index; std::size_t global_index;
std::size_t active_index; std::size_t active_index;
std::size_t data_index; std::size_t data_index;
cell_index(std::size_t g,std::size_t a, std::size_t d)
cell_index(std::size_t g,std::size_t a, std::size_t d) : : global_index(g)
global_index(g), , active_index(a)
active_index(a), , data_index(d)
data_index(d)
{} {}
// This constructor should is used by the global_index_list() member
/* // which will return a list of *all* the cells in the box. In this
This constructor should is used by the global_index_list() member // case the active_index will be set to the global_index. This is a
which will return a list of *all* the cells in the box. In this // hack to simplify the treatment of global fields in the FieldProps
case the active_index will be set to the global_index. This is a // implementation.
hack to simplify the treatment of global fields in the FieldProps cell_index(std::size_t g, std::size_t d)
implementation. : global_index(g)
*/ , active_index(g)
cell_index(std::size_t g, std::size_t d) : , data_index(d)
global_index(g),
active_index(g),
data_index(d)
{} {}
}; };
explicit Box(const EclipseGrid& grid); explicit Box(const GridDims& gridDims,
Box(const EclipseGrid& grid , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); IsActive isActive,
ActiveIdx activeIdx);
Box(const GridDims& gridDims,
IsActive isActive,
ActiveIdx activeIdx,
int i1, int i2,
int j1, int j2,
int k1, int k2);
void update(const DeckRecord& deckRecord); void update(const DeckRecord& deckRecord);
void reset(); void reset();
size_t size() const; bool isGlobal() const;
bool isGlobal() const; std::size_t size() const;
size_t getDim(size_t idim) const; std::size_t getDim(std::size_t idim) const;
const std::vector<cell_index>& index_list() const;
const std::vector<Box::cell_index>& global_index_list() const;
bool equal(const Box& other) const;
const std::vector<cell_index>& index_list() const;
const std::vector<cell_index>& global_index_list() const;
bool operator==(const Box& other) const;
bool equal(const Box& other) const;
int I1() const; int I1() const;
int I2() const; int I2() const;
@ -81,17 +95,18 @@ namespace Opm {
int K2() const; int K2() const;
private: private:
void init(int i1, int i2, int j1, int j2, int k1, int k2); GridDims m_globalGridDims_{};
void initIndexList(); IsActive m_globalIsActive_{};
const EclipseGrid& grid; ActiveIdx m_globalActiveIdx_{};
size_t m_stride[3];
size_t m_dims[3] = { 0, 0, 0 }; std::array<std::size_t, 3> m_dims{};
size_t m_offset[3]; std::array<std::size_t, 3> m_offset{};
bool m_isGlobal;
std::vector<cell_index> m_active_index_list; std::vector<cell_index> m_active_index_list;
std::vector<cell_index> m_global_index_list; std::vector<cell_index> m_global_index_list;
void init(int i1, int i2, int j1, int j2, int k1, int k2);
void initIndexList();
int lower(int dim) const; int lower(int dim) const;
int upper(int dim) const; int upper(int dim) const;
}; };

View File

@ -17,15 +17,14 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BOXMANAGER_HPP_ #ifndef BOXMANAGER_HPP_
#define BOXMANAGER_HPP_ #define BOXMANAGER_HPP_
#include <vector>
#include <memory>
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp> #include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp> #include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
#include <memory>
#include <vector>
/* /*
This class implements a simple book keeping system for the current This class implements a simple book keeping system for the current
@ -52,9 +51,12 @@
namespace Opm { namespace Opm {
class BoxManager { class BoxManager
{
public: public:
BoxManager(const EclipseGrid& grid); explicit BoxManager(const GridDims& gridDims,
Box::IsActive isActive,
Box::ActiveIdx activeIdx);
void setInputBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2); 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); void setKeywordBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
@ -67,12 +69,20 @@ namespace Opm {
const std::vector<Box::cell_index>& index_list() const; const std::vector<Box::cell_index>& index_list() const;
private: private:
const EclipseGrid& grid; GridDims gridDims_{};
Box::IsActive isActive_{};
Box::ActiveIdx activeIdx_{};
std::unique_ptr<Box> m_globalBox; std::unique_ptr<Box> m_globalBox;
std::unique_ptr<Box> m_inputBox; std::unique_ptr<Box> m_inputBox;
std::unique_ptr<Box> m_keywordBox; std::unique_ptr<Box> m_keywordBox;
std::unique_ptr<Box>
makeBox(const int i1, const int i2,
const int j1, const int j2,
const int k1, const int k2) const;
}; };
} }
#endif #endif // BOXMANAGER_HPP_

View File

@ -17,131 +17,148 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdexcept> #include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/B.hpp> // BOX
#include <opm/input/eclipse/Deck/DeckItem.hpp> #include <opm/input/eclipse/Deck/DeckItem.hpp>
#include <opm/input/eclipse/Deck/DeckRecord.hpp> #include <opm/input/eclipse/Deck/DeckRecord.hpp>
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp> #include <stdexcept>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp> #include <utility>
#include <fmt/format.h>
namespace { namespace {
void assert_dims(int len, int l1 , int l2) { void assert_dims(const int len, const int l1, const int l2)
if (len <= 0) {
throw std::invalid_argument("Box must have finite size in all directions"); if (len <= 0) {
throw std::invalid_argument {
"Box must have finite size in all directions"
};
}
if ((l1 < 0) || (l2 < 0) || (l1 > l2)) if ((l1 < 0) || (l2 < 0) || (l1 > l2)) {
throw std::invalid_argument("Invalid index values for sub box"); throw std::invalid_argument {
"Invalid index values for sub box"
};
}
if (l2 >= len) if (l2 >= len) {
throw std::invalid_argument("Invalid index values for sub box"); throw std::invalid_argument {
"Invalid index values for sub box"
};
}
} }
bool update_default(const Opm::DeckItem& item,
int& value)
{
if (item.defaultApplied(0)) {
return true;
}
void update_default(int &value, std::size_t& default_count, const Opm::DeckItem& item) { value = item.get<int>(0) - 1;
if (item.defaultApplied(0)) return false;
default_count += 1;
else
value = item.get<int>(0) - 1;
} }
} }
namespace Opm { namespace Opm
{
Box::Box(const EclipseGrid& grid_arg) : Box::Box(const GridDims& gridDims,
grid(grid_arg) IsActive isActive,
ActiveIdx activeIdx)
: m_globalGridDims_ (gridDims)
, m_globalIsActive_ (std::move(isActive))
, m_globalActiveIdx_(std::move(activeIdx))
{ {
this->reset(); this->reset();
} }
Box::Box(const GridDims& gridDims,
Box::Box(const EclipseGrid& grid_arg, int i1 , int i2 , int j1 , int j2 , int k1 , int k2) : IsActive isActive,
grid(grid_arg) ActiveIdx activeIdx,
const int i1, const int i2,
const int j1, const int j2,
const int k1, const int k2)
: m_globalGridDims_ (gridDims)
, m_globalIsActive_ (std::move(isActive))
, m_globalActiveIdx_(std::move(activeIdx))
{ {
this->init(i1,i2,j1,j2,k1,k2); this->init(i1, i2, j1, j2, k1, k2);
} }
void Box::update(const DeckRecord& deckRecord)
{
auto default_count = 0;
void Box::update(const DeckRecord& deckRecord) {
const auto& I1Item = deckRecord.getItem("I1");
const auto& I2Item = deckRecord.getItem("I2");
const auto& J1Item = deckRecord.getItem("J1");
const auto& J2Item = deckRecord.getItem("J2");
const auto& K1Item = deckRecord.getItem("K1");
const auto& K2Item = deckRecord.getItem("K2");
std::size_t default_count = 0;
int i1 = 0; int i1 = 0;
int i2 = this->grid.getNX() - 1; int i2 = this->m_globalGridDims_.getNX() - 1;
default_count += update_default(deckRecord.getItem<ParserKeywords::BOX::I1>(), i1);
default_count += update_default(deckRecord.getItem<ParserKeywords::BOX::I2>(), i2);
int j1 = 0; int j1 = 0;
int j2 = this->grid.getNY() - 1; int j2 = this->m_globalGridDims_.getNY() - 1;
default_count += update_default(deckRecord.getItem<ParserKeywords::BOX::J1>(), j1);
default_count += update_default(deckRecord.getItem<ParserKeywords::BOX::J2>(), j2);
int k1 = 0; int k1 = 0;
int k2 = this->grid.getNZ() - 1; int k2 = this->m_globalGridDims_.getNZ() - 1;
default_count += update_default(deckRecord.getItem<ParserKeywords::BOX::K1>(), k1);
default_count += update_default(deckRecord.getItem<ParserKeywords::BOX::K2>(), k2);
update_default(i1, default_count, I1Item); if (default_count != 6) {
update_default(i2, default_count, I2Item); this->init(i1, i2, j1, j2, k1, k2);
update_default(j1, default_count, J1Item); }
update_default(j2, default_count, J2Item);
update_default(k1, default_count, K1Item);
update_default(k2, default_count, K2Item);
if (default_count != 6)
this->init(i1,i2,j1,j2,k1,k2);
} }
void Box::reset() void Box::reset()
{ {
this->init(0, this->grid.getNX() - 1 , 0, this->grid.getNY() - 1, 0, this->grid.getNZ() - 1); this->init(0, this->m_globalGridDims_.getNX() - 1,
0, this->m_globalGridDims_.getNY() - 1,
0, this->m_globalGridDims_.getNZ() - 1);
} }
void Box::init(const int i1, const int i2,
const int j1, const int j2,
const int k1, const int k2)
{
assert_dims(this->m_globalGridDims_.getNX(), i1, i2);
assert_dims(this->m_globalGridDims_.getNY(), j1, j2);
assert_dims(this->m_globalGridDims_.getNZ(), k1, k2);
void Box::init(int i1, int i2, int j1, int j2, int k1, int k2) { this->m_dims[0] = static_cast<std::size_t>(i2 - i1 + 1);
assert_dims(this->grid.getNX(), i1 , i2); this->m_dims[1] = static_cast<std::size_t>(j2 - j1 + 1);
assert_dims(this->grid.getNY(), j1 , j2); this->m_dims[2] = static_cast<std::size_t>(k2 - k1 + 1);
assert_dims(this->grid.getNZ(), k1 , k2);
m_stride[0] = 1;
m_stride[1] = this->grid.getNX();
m_stride[2] = this->grid.getNX() * this->grid.getNY();
m_dims[0] = (size_t) (i2 - i1 + 1); this->m_offset[0] = static_cast<std::size_t>(i1);
m_dims[1] = (size_t) (j2 - j1 + 1); this->m_offset[1] = static_cast<std::size_t>(j1);
m_dims[2] = (size_t) (k2 - k1 + 1); this->m_offset[2] = static_cast<std::size_t>(k1);
m_offset[0] = (size_t) i1; this->initIndexList();
m_offset[1] = (size_t) j1;
m_offset[2] = (size_t) k1;
if (size() == this->grid.getCartesianSize())
m_isGlobal = true;
else
m_isGlobal = false;
initIndexList();
} }
std::size_t Box::size() const
{
size_t Box::size() const {
return m_dims[0] * m_dims[1] * m_dims[2]; return m_dims[0] * m_dims[1] * m_dims[2];
} }
bool Box::isGlobal() const
bool Box::isGlobal() const { {
return m_isGlobal; return this->size() == this->m_globalGridDims_.getCartesianSize();
} }
std::size_t Box::getDim(std::size_t idim) const
size_t Box::getDim(size_t idim) const { {
if (idim >= 3) if (idim >= 3) {
throw std::invalid_argument("The input dimension value is invalid"); throw std::invalid_argument("The input dimension value is invalid");
}
return m_dims[idim]; return m_dims[idim];
} }
const std::vector<Box::cell_index>& Box::index_list() const { const std::vector<Box::cell_index>& Box::index_list() const {
return this->m_active_index_list; return this->m_active_index_list;
} }
@ -150,54 +167,40 @@ namespace Opm {
return this->m_global_index_list; return this->m_global_index_list;
} }
void Box::initIndexList()
{
this->m_active_index_list.clear();
this->m_global_index_list.clear();
const auto boxdims = GridDims(this->m_dims[0], this->m_dims[1], this->m_dims[2]);
const auto ncells = boxdims.getCartesianSize();
void Box::initIndexList() { for (auto data_index = 0*ncells; data_index != ncells; ++data_index) {
m_active_index_list.clear(); const auto boxIJK = boxdims.getIJK(data_index);
m_global_index_list.clear(); const auto global_index = this->m_globalGridDims_
.getGlobalIndex(boxIJK[0] + this->m_offset[0],
boxIJK[1] + this->m_offset[1],
boxIJK[2] + this->m_offset[2]);
size_t ii,ij,ik; if (this->m_globalIsActive_(global_index)) {
for (ik=0; ik < m_dims[2]; ik++) { const auto active_index = this->m_globalActiveIdx_(global_index);
size_t k = ik + m_offset[2]; this->m_active_index_list.emplace_back(global_index, active_index, data_index);
for (ij=0; ij < m_dims[1]; ij++) {
size_t j = ij + m_offset[1];
for (ii=0; ii < m_dims[0]; ii++) {
std::size_t i = ii + m_offset[0];
std::size_t global_index = i * m_stride[0] + j*m_stride[1] + k*m_stride[2];
std::size_t data_index = ii + ij*this->m_dims[0] + ik*this->m_dims[0]*this->m_dims[1];
if (this->grid.cellActive(global_index)) {
std::size_t active_index = this->grid.activeIndex(global_index);
m_active_index_list.emplace_back(global_index, active_index, data_index);
}
this->m_global_index_list.emplace_back( global_index, data_index );
}
} }
this->m_global_index_list.emplace_back(global_index, data_index);
} }
} }
bool Box::equal(const Box& other) const { bool Box::operator==(const Box& other) const
{
if (size() != other.size()) return (this->m_dims == other.m_dims)
return false; && (this->m_offset == other.m_offset);
{
for (size_t idim = 0; idim < 3; idim++) {
if (m_dims[idim] != other.m_dims[idim])
return false;
if (m_stride[idim] != other.m_stride[idim])
return false;
if (m_offset[idim] != other.m_offset[idim])
return false;
}
}
return true;
} }
bool Box::equal(const Box& other) const
{
return *this == other;
}
int Box::lower(int dim) const { int Box::lower(int dim) const {
return m_offset[dim]; return m_offset[dim];

View File

@ -24,12 +24,15 @@
namespace Opm { namespace Opm {
BoxManager::BoxManager(const EclipseGrid& grid_arg) : BoxManager::BoxManager(const GridDims& gridDims,
grid( grid_arg ), Box::IsActive isActive,
m_globalBox( std::unique_ptr<Box>( new Box(grid_arg) )) Box::ActiveIdx activeIdx)
: gridDims_ (gridDims)
, isActive_ (isActive)
, activeIdx_ (activeIdx)
, m_globalBox(std::make_unique<Box>(gridDims_, isActive_, activeIdx_))
{} {}
const Box& BoxManager::getActiveBox() const { const Box& BoxManager::getActiveBox() const {
if (m_keywordBox) if (m_keywordBox)
return *m_keywordBox; return *m_keywordBox;
@ -40,31 +43,57 @@ namespace Opm {
return *m_globalBox; return *m_globalBox;
} }
void BoxManager::setInputBox(const int i1, const int i2,
void BoxManager::setInputBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2) { const int j1, const int j2,
this->m_inputBox.reset(new Box( this->grid, i1, i2, j1, j2, k1, k2 )); const int k1, const int k2)
{
this->m_inputBox = this->makeBox(i1, i2, j1, j2, k1, k2);
} }
void BoxManager::endInputBox() { 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"); if (this->m_keywordBox != nullptr) {
throw std::invalid_argument {
"Hmmm - this seems like an internal error - "
"the SECTION is terminated with an active keyword box"
};
}
m_inputBox.reset( 0 ); this->m_inputBox.reset();
} }
void BoxManager::endSection() { void BoxManager::endSection()
endInputBox(); {
this->endInputBox();
} }
void BoxManager::setKeywordBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2) { void BoxManager::setKeywordBox(const int i1, const int i2,
this->m_keywordBox.reset( new Box( this->grid, i1, i2, j1, j2, k1, k2 )); const int j1, const int j2,
const int k1, const int k2)
{
this->m_keywordBox = this->makeBox(i1, i2, j1, j2, k1, k2);
} }
void BoxManager::endKeyword() { void BoxManager::endKeyword()
this->m_keywordBox.reset( 0 ); {
this->m_keywordBox.reset();
} }
const std::vector<Box::cell_index>& BoxManager::index_list() const { const std::vector<Box::cell_index>& BoxManager::index_list() const
{
return this->getActiveBox().index_list(); return this->getActiveBox().index_list();
} }
std::unique_ptr<Box>
BoxManager::makeBox(const int i1, const int i2,
const int j1, const int j2,
const int k1, const int k2) const
{
return std::make_unique<Box>(this->gridDims_,
this->isActive_,
this->activeIdx_,
i1, i2,
j1, j2,
k1, k2);
}
} }

View File

@ -53,6 +53,23 @@
#include "Operate.hpp" #include "Operate.hpp"
namespace {
Opm::Box makeGlobalGridBox(const Opm::EclipseGrid* gridPtr)
{
return Opm::Box {
*gridPtr,
[gridPtr](const std::size_t global_index)
{
return gridPtr->cellActive(global_index);
},
[gridPtr](const std::size_t global_index)
{
return gridPtr->activeIndex(global_index);
}
};
}
}
namespace Opm { namespace Opm {
namespace Fieldprops namespace Fieldprops
@ -1190,7 +1207,7 @@ const std::vector<int>& FieldProps::actnumRaw() const {
void FieldProps::scanGRIDSection(const GRIDSection& grid_section) { void FieldProps::scanGRIDSection(const GRIDSection& grid_section) {
Box box(*this->grid_ptr); auto box = makeGlobalGridBox(this->grid_ptr);
for (const auto& keyword : grid_section) { for (const auto& keyword : grid_section) {
const std::string& name = keyword.name(); const std::string& name = keyword.name();
@ -1210,7 +1227,7 @@ void FieldProps::scanGRIDSection(const GRIDSection& grid_section) {
} }
void FieldProps::scanGRIDSectionOnlyACTNUM(const GRIDSection& grid_section) { void FieldProps::scanGRIDSectionOnlyACTNUM(const GRIDSection& grid_section) {
Box box(*this->grid_ptr); Box box(*this->grid_ptr, [](const std::size_t) { return true; }, [](const std::size_t i) { return i; });
for (const auto& keyword : grid_section) { for (const auto& keyword : grid_section) {
const std::string& name = keyword.name(); const std::string& name = keyword.name();
@ -1229,7 +1246,7 @@ void FieldProps::scanGRIDSectionOnlyACTNUM(const GRIDSection& grid_section) {
} }
void FieldProps::scanEDITSection(const EDITSection& edit_section) { void FieldProps::scanEDITSection(const EDITSection& edit_section) {
Box box(*this->grid_ptr); auto box = makeGlobalGridBox(this->grid_ptr);
for (const auto& keyword : edit_section) { for (const auto& keyword : edit_section) {
const std::string& name = keyword.name(); const std::string& name = keyword.name();
@ -1272,7 +1289,7 @@ void FieldProps::init_satfunc(const std::string& keyword, Fieldprops::FieldData<
void FieldProps::scanPROPSSection(const PROPSSection& props_section) { void FieldProps::scanPROPSSection(const PROPSSection& props_section) {
Box box(*this->grid_ptr); auto box = makeGlobalGridBox(this->grid_ptr);
for (const auto& keyword : props_section) { for (const auto& keyword : props_section) {
const std::string& name = keyword.name(); const std::string& name = keyword.name();
@ -1298,7 +1315,7 @@ void FieldProps::scanPROPSSection(const PROPSSection& props_section) {
void FieldProps::scanREGIONSSection(const REGIONSSection& regions_section) { void FieldProps::scanREGIONSSection(const REGIONSSection& regions_section) {
Box box(*this->grid_ptr); auto box = makeGlobalGridBox(this->grid_ptr);
for (const auto& keyword : regions_section) { for (const auto& keyword : regions_section) {
const std::string& name = keyword.name(); const std::string& name = keyword.name();
@ -1320,7 +1337,7 @@ void FieldProps::scanREGIONSSection(const REGIONSSection& regions_section) {
void FieldProps::scanSOLUTIONSection(const SOLUTIONSection& solution_section) { void FieldProps::scanSOLUTIONSection(const SOLUTIONSection& solution_section) {
Box box(*this->grid_ptr); auto box = makeGlobalGridBox(this->grid_ptr);
for (const auto& keyword : solution_section) { for (const auto& keyword : solution_section) {
const std::string& name = keyword.name(); const std::string& name = keyword.name();
if (Fieldprops::keywords::SOLUTION::double_keywords.count(name) == 1) { if (Fieldprops::keywords::SOLUTION::double_keywords.count(name) == 1) {
@ -1333,7 +1350,7 @@ void FieldProps::scanSOLUTIONSection(const SOLUTIONSection& solution_section) {
} }
void FieldProps::handle_schedule_keywords(const std::vector<DeckKeyword>& keywords) { void FieldProps::handle_schedule_keywords(const std::vector<DeckKeyword>& keywords) {
Box box(*this->grid_ptr); auto box = makeGlobalGridBox(this->grid_ptr);
// When called in the SCHEDULE section the context is that the scaling factors // When called in the SCHEDULE section the context is that the scaling factors
// have already been applied. // have already been applied.

View File

@ -17,10 +17,6 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdexcept>
#include <iostream>
#include <memory>
#define BOOST_TEST_MODULE BoxManagerTests #define BOOST_TEST_MODULE BoxManagerTests
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -28,9 +24,28 @@
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp> #include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/input/eclipse/EclipseState/Grid/BoxManager.hpp> #include <opm/input/eclipse/EclipseState/Grid/BoxManager.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
#include <cstddef>
#include <iostream>
#include <memory>
#include <stdexcept>
namespace {
Opm::Box::IsActive allActive()
{
return [](const std::size_t) { return true; };
}
Opm::Box::ActiveIdx identityMapping()
{
return [](const std::size_t i) { return i; };
}
}
BOOST_AUTO_TEST_CASE(CreateBox) { BOOST_AUTO_TEST_CASE(CreateBox) {
Opm::EclipseGrid grid(4,3,2); Opm::Box box(Opm::GridDims{ 4, 3, 2 }, allActive(), identityMapping());
Opm::Box box(grid);
BOOST_CHECK_EQUAL( 24U , box.size() ); BOOST_CHECK_EQUAL( 24U , box.size() );
BOOST_CHECK( box.isGlobal() ); BOOST_CHECK( box.isGlobal() );
BOOST_CHECK_EQUAL( 4U , box.getDim(0) ); BOOST_CHECK_EQUAL( 4U , box.getDim(0) );
@ -43,35 +58,34 @@ BOOST_AUTO_TEST_CASE(CreateBox) {
BOOST_AUTO_TEST_CASE(CreateSubBox) { BOOST_AUTO_TEST_CASE(CreateSubBox) {
Opm::EclipseGrid grid(10,10,10); const Opm::GridDims gridDims(10,10,10);
Opm::Box globalBox(grid); const Opm::Box globalBox(gridDims, allActive(), identityMapping());
BOOST_CHECK_THROW( new Opm::Box( grid , -1 , 9 , 1 , 8 , 1, 8) , std::invalid_argument); // Negative throw BOOST_CHECK_THROW(std::make_unique<Opm::Box>( gridDims, allActive(), identityMapping(), -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(std::make_unique<Opm::Box>( gridDims, allActive(), identityMapping(), 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 BOOST_CHECK_THROW(std::make_unique<Opm::Box>( gridDims, allActive(), identityMapping(), 9 , 1 , 1 , 8 , 1, 8), std::invalid_argument); // Inverted order: throw
Opm::Box subBox1(grid, 0,9,0,9,0,9); Opm::Box subBox1(gridDims, allActive(), identityMapping(), 0,9,0,9,0,9);
BOOST_CHECK( subBox1.isGlobal()); BOOST_CHECK( subBox1.isGlobal());
Opm::Box subBox2(gridDims, allActive(), identityMapping(), 1,3,1,4,1,5);
Opm::Box subBox2(grid, 1,3,1,4,1,5);
BOOST_CHECK( !subBox2.isGlobal()); BOOST_CHECK( !subBox2.isGlobal());
BOOST_CHECK_EQUAL( 60U , subBox2.size() ); BOOST_CHECK_EQUAL( 60U , subBox2.size() );
} }
BOOST_AUTO_TEST_CASE(BoxEqual) { BOOST_AUTO_TEST_CASE(BoxEqual) {
Opm::EclipseGrid grid1(10,10,10); Opm::GridDims gridDims1(10,10,10);
Opm::EclipseGrid grid3(10,10,11); Opm::GridDims gridDims3(10,10,11);
Opm::EclipseGrid grid4(20,20,20); Opm::GridDims gridDims4(20,20,20);
Opm::Box globalBox1( grid1 ); Opm::Box globalBox1( gridDims1, allActive(), identityMapping() );
Opm::Box globalBox2( grid1 ); Opm::Box globalBox2( gridDims1, allActive(), identityMapping() );
Opm::Box globalBox3( grid3 ); Opm::Box globalBox3( gridDims3, allActive(), identityMapping() );
Opm::Box globalBox4(grid4); Opm::Box globalBox4(gridDims4, allActive(), identityMapping());
Opm::Box subBox1( grid1 , 0 , 9 , 0 , 9 , 0, 9); Opm::Box subBox1( gridDims1 , allActive(), identityMapping() , 0 , 9 , 0 , 9 , 0, 9 );
Opm::Box subBox4( grid4 , 0 , 9 , 0 , 9 , 0, 9); Opm::Box subBox4( gridDims4 , allActive(), identityMapping() , 0 , 9 , 0 , 9 , 0, 9 );
Opm::Box subBox5( grid4 , 10 , 19 , 10 , 19 , 10, 19); Opm::Box subBox5( gridDims4 , allActive(), identityMapping() , 10 , 19 , 10 , 19 , 10, 19 );
BOOST_CHECK( globalBox1.equal( globalBox2 )); BOOST_CHECK( globalBox1.equal( globalBox2 ));
BOOST_CHECK( !globalBox1.equal( globalBox3 )); BOOST_CHECK( !globalBox1.equal( globalBox3 ));
@ -82,9 +96,9 @@ BOOST_AUTO_TEST_CASE(BoxEqual) {
} }
BOOST_AUTO_TEST_CASE(CreateBoxManager) { BOOST_AUTO_TEST_CASE(CreateBoxManager) {
Opm::EclipseGrid grid(10,10,10); Opm::GridDims gridDims(10,10,10);
Opm::BoxManager boxManager(grid); Opm::BoxManager boxManager(gridDims, allActive(), identityMapping());
Opm::Box box(grid); Opm::Box box(gridDims, allActive(), identityMapping());
BOOST_CHECK( box.equal( boxManager.getActiveBox()) ); BOOST_CHECK( box.equal( boxManager.getActiveBox()) );
} }
@ -93,10 +107,10 @@ BOOST_AUTO_TEST_CASE(CreateBoxManager) {
BOOST_AUTO_TEST_CASE(TestInputBox) { BOOST_AUTO_TEST_CASE(TestInputBox) {
Opm::EclipseGrid grid(10,10,10); Opm::GridDims gridDims(10,10,10);
Opm::BoxManager boxManager(grid); Opm::BoxManager boxManager(gridDims, allActive(), identityMapping());
Opm::Box inputBox( grid, 0,4,0,4,0,4); Opm::Box inputBox( gridDims, allActive(), identityMapping(), 0,4,0,4,0,4);
Opm::Box globalBox( grid ); Opm::Box globalBox( gridDims, allActive(), identityMapping() );
boxManager.setInputBox( 0,4,0,4,0,4 ); boxManager.setInputBox( 0,4,0,4,0,4 );
BOOST_CHECK( inputBox.equal( boxManager.getActiveBox()) ); BOOST_CHECK( inputBox.equal( boxManager.getActiveBox()) );
@ -108,11 +122,11 @@ BOOST_AUTO_TEST_CASE(TestInputBox) {
BOOST_AUTO_TEST_CASE(TestKeywordBox) { BOOST_AUTO_TEST_CASE(TestKeywordBox) {
Opm::EclipseGrid grid(10,10,10); Opm::GridDims gridDims(10,10,10);
Opm::BoxManager boxManager(grid); Opm::BoxManager boxManager(gridDims, allActive(), identityMapping());
Opm::Box inputBox( grid, 0,4,0,4,0,4); Opm::Box inputBox( gridDims, allActive(), identityMapping(), 0,4,0,4,0,4);
Opm::Box keywordBox( grid, 0,2,0,2,0,2); Opm::Box keywordBox( gridDims, allActive(), identityMapping(), 0,2,0,2,0,2);
Opm::Box globalBox( grid ); Opm::Box globalBox( gridDims, allActive(), identityMapping() );
boxManager.setInputBox( 0,4,0,4,0,4 ); boxManager.setInputBox( 0,4,0,4,0,4 );
@ -136,14 +150,14 @@ BOOST_AUTO_TEST_CASE(BoxNineArg) {
const size_t nx = 10; const size_t nx = 10;
const size_t ny = 7; const size_t ny = 7;
const size_t nz = 6; const size_t nz = 6;
Opm::EclipseGrid grid(nx,ny,nz); Opm::GridDims gridDims(nx,ny,nz);
BOOST_CHECK_NO_THROW( Opm::Box(grid,0,7,0,5,1,2) ); BOOST_CHECK_NO_THROW( Opm::Box(gridDims, allActive(), identityMapping(), 0,7,0,5,1,2) );
// J2 < J1 // J2 < J1
BOOST_CHECK_THROW( Opm::Box(grid,1,1,4,3,2,2), std::invalid_argument); BOOST_CHECK_THROW( Opm::Box(gridDims, allActive(), identityMapping(), 1,1,4,3,2,2), std::invalid_argument);
// K2 >= Nz // K2 >= Nz
BOOST_CHECK_THROW( Opm::Box(grid,1,1,2,2,3,nz), std::invalid_argument); BOOST_CHECK_THROW( Opm::Box(gridDims, allActive(), identityMapping(), 1,1,2,2,3,nz), std::invalid_argument);
} }
BOOST_AUTO_TEST_CASE(TestKeywordBox2) { BOOST_AUTO_TEST_CASE(TestKeywordBox2) {
@ -152,7 +166,22 @@ BOOST_AUTO_TEST_CASE(TestKeywordBox2) {
actnum[0] = 0; actnum[0] = 0;
grid.resetACTNUM(actnum); grid.resetACTNUM(actnum);
Opm::BoxManager boxManager(grid); auto isActive = Opm::Box::IsActive {
[&grid](const std::size_t global_index)
{
return grid.cellActive(global_index);
}
};
auto activeIdx = Opm::Box::ActiveIdx {
[&grid](const std::size_t global_index)
{
return grid.activeIndex(global_index);
}
};
Opm::BoxManager boxManager(grid, isActive, activeIdx);
const auto& box = boxManager.getActiveBox(); const auto& box = boxManager.getActiveBox();
for (const auto& p : box.index_list()) for (const auto& p : box.index_list())
@ -166,7 +195,7 @@ BOOST_AUTO_TEST_CASE(TestKeywordBox2) {
BOOST_CHECK_EQUAL(c0.active_index, c0.global_index); BOOST_CHECK_EQUAL(c0.active_index, c0.global_index);
BOOST_CHECK_EQUAL(c0.data_index, 0U); BOOST_CHECK_EQUAL(c0.data_index, 0U);
Opm::Box box2(grid,9,9,9,9,0,9); Opm::Box box2(grid, isActive, activeIdx, 9,9,9,9,0,9);
const auto& il = box2.index_list(); const auto& il = box2.index_list();
BOOST_CHECK_EQUAL(il.size(), 10U); BOOST_CHECK_EQUAL(il.size(), 10U);

View File

@ -21,30 +21,35 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <filesystem>
#include <opm/input/eclipse/Deck/Deck.hpp> #include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp> #include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp> #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp> #include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp> #include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
#include <filesystem>
using namespace Opm; using namespace Opm;
inline std::string prefix() { namespace {
std::string prefix() {
return boost::unit_test::framework::master_test_suite().argv[1]; return boost::unit_test::framework::master_test_suite().argv[1];
} }
inline Deck makeDeck(const std::string& fileName) { Deck makeDeck(const std::string& fileName) {
Parser parser; Parser parser;
std::filesystem::path boxFile(fileName); std::filesystem::path boxFile(fileName);
return parser.parseFile(boxFile.string()); return parser.parseFile(boxFile.string());
} }
inline EclipseState makeState(const std::string& fileName) { EclipseState makeState(const std::string& fileName) {
return EclipseState( makeDeck(fileName) ); return EclipseState( makeDeck(fileName) );
} }
}
BOOST_AUTO_TEST_CASE( PERMX ) { BOOST_AUTO_TEST_CASE( PERMX ) {
EclipseState state = makeState( prefix() + "BOX/BOXTEST1" ); EclipseState state = makeState( prefix() + "BOX/BOXTEST1" );
@ -157,7 +162,15 @@ BOOST_AUTO_TEST_CASE( CONSTRUCTOR_AND_UPDATE ) {
EclipseGrid grid(deck); EclipseGrid grid(deck);
const auto& box_keyword = deck["BOX"][0]; const auto& box_keyword = deck["BOX"][0];
const auto& operate_keyword = deck["OPERATE"].back(); const auto& operate_keyword = deck["OPERATE"].back();
Box box(grid); Box box(grid,
[&grid](const std::size_t global_index)
{
return grid.cellActive(global_index);
},
[&grid](const std::size_t global_index)
{
return grid.activeIndex(global_index);
});
box.update(box_keyword.getRecord(0)); box.update(box_keyword.getRecord(0));
BOOST_CHECK_EQUAL(box.size(), 8); BOOST_CHECK_EQUAL(box.size(), 8);