diff --git a/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp b/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp index 34b3f9959..49af62bba 100644 --- a/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.cpp @@ -43,6 +43,10 @@ namespace Opm { m_grid.reset( new_ptr , ecl_grid_free ); else throw std::invalid_argument("Could not load grid from binary file: " + filename); + + m_nx = static_cast( ecl_grid_get_nx( m_grid.get() )); + m_ny = static_cast( ecl_grid_get_ny( m_grid.get() )); + m_nz = static_cast( ecl_grid_get_nz( m_grid.get() )); } EclipseGrid::EclipseGrid(const ecl_grid_type * src_ptr) @@ -50,6 +54,26 @@ namespace Opm { m_pinch("PINCH") { m_grid.reset( ecl_grid_alloc_copy( src_ptr ) , ecl_grid_free ); + + m_nx = static_cast( ecl_grid_get_nx( m_grid.get() )); + m_ny = static_cast( ecl_grid_get_ny( m_grid.get() )); + m_nz = static_cast( ecl_grid_get_nz( m_grid.get() )); + } + + /* + This creates a grid which only has dimension, and no pointer to + a true grid structure. This grid will answer false to + hasCellInfo() - but can be used in all situations where the grid + dependency is really only on the dimensions. + */ + + EclipseGrid::EclipseGrid(size_t nx, size_t ny , size_t nz) + : m_minpv("MINPV"), + m_pinch("PINCH") + { + m_nx = nx; + m_ny = ny; + m_nz = nz; } @@ -116,16 +140,16 @@ namespace Opm { void EclipseGrid::initGrid( const std::vector& dims, DeckConstPtr deck, ParserLogPtr parserLog) { + m_nx = static_cast(dims[0]); + m_ny = static_cast(dims[1]); + m_nz = static_cast(dims[2]); + if (hasCornerPointKeywords(deck)) { initCornerPointGrid(dims , deck, parserLog); } else if (hasCartesianKeywords(deck)) { initCartesianGrid(dims , deck); - } else { - const std::string msg = "The deck must have COORD / ZCORN or D?? + TOPS keywords"; - parserLog->addError("", -1, msg); - throw std::invalid_argument(msg); - } - + } + if (deck->hasKeyword("PINCH")) { m_pinch.setValue( deck->getKeyword("PINCH")->getRecord(0)->getItem("THRESHOLD_THICKNESS")->getSIDouble(0) ); } @@ -149,21 +173,30 @@ namespace Opm { } size_t EclipseGrid::getNX( ) const { - return static_cast(ecl_grid_get_nx( m_grid.get() )); + return m_nx; } size_t EclipseGrid::getNY( ) const { - return static_cast(ecl_grid_get_ny( m_grid.get() )); + return m_ny; } size_t EclipseGrid::getNZ( ) const { - return static_cast(ecl_grid_get_nz( m_grid.get() )); + return m_nz; } size_t EclipseGrid::getCartesianSize( ) const { - return static_cast( ecl_grid_get_global_size( m_grid.get() )); + return m_nx * m_ny * m_nz; } + /* + This function checks if the grid has a pointer to an underlying + ecl_grid_type; which must be used to read cell info as + size/depth/active of individual cells. + */ + bool EclipseGrid::hasCellInfo() const { + return static_cast( m_grid ); + } + bool EclipseGrid::isPinchActive( ) const { return m_pinch.hasValue(); } diff --git a/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp b/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp index 5b0d10936..9eda6e242 100644 --- a/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp @@ -33,10 +33,41 @@ namespace Opm { + /** + About cell information and dimension: The actual grid + information is held in a pointer to an ERT ecl_grid_type + instance. This pointer must be used for access to all cell + related properties, including: + + - Size of cells + - Real world position of cells + - Active/inactive status of cells + + However in may cases the only required information is the + dimension of the grid. To facilitate simpler use, in particular + in testing, the grid dimensions are internalized separate from + the ecl_grid_type pointer. This means that in many cases a grid + without the underlying ecl_grid_type pointer is sufficient. To + create such a 'naked' grid you can parse a deck with only + DIMENS / SPECGRID and no further grid related keywords, or + alternatively use the: + + EclipseGrid::EclipseGrid(nx,ny,nz) + + constructor. + + To query a grid instance if it has proper underlying grid + support use the method: + + bool EclipseGrid::hasCellInfo(); + + */ + class EclipseGrid { public: explicit EclipseGrid(const std::string& filename); explicit EclipseGrid(const ecl_grid_type * src_ptr); + explicit EclipseGrid(size_t nx, size_t ny , size_t nz); explicit EclipseGrid(std::shared_ptr deck, ParserLogPtr parserLog = std::make_shared()); static bool hasCornerPointKeywords(std::shared_ptr deck); @@ -50,6 +81,7 @@ namespace Opm { double getPinchThresholdThickness( ) const; bool isMinpvActive( ) const; double getMinpvValue( ) const; + bool hasCellInfo() const; void assertGlobalIndex(size_t globalIndex) const; void assertIJK(size_t i , size_t j , size_t k) const; @@ -70,6 +102,9 @@ namespace Opm { std::shared_ptr m_grid; Value m_minpv; Value m_pinch; + size_t m_nx; + size_t m_ny; + size_t m_nz; void initCartesianGrid(const std::vector& dims , DeckConstPtr deck); void initCornerPointGrid(const std::vector& dims , DeckConstPtr deck, ParserLogPtr parserLog); diff --git a/opm/parser/eclipse/EclipseState/Grid/tests/EclipseGridTests.cpp b/opm/parser/eclipse/EclipseState/Grid/tests/EclipseGridTests.cpp index 5717145bd..1adedb297 100644 --- a/opm/parser/eclipse/EclipseState/Grid/tests/EclipseGridTests.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/tests/EclipseGridTests.cpp @@ -65,6 +65,23 @@ static Opm::DeckPtr createDeckHeaders() { } +static Opm::DeckPtr createDeckMissingDIMS() { + const char *deckData = + "RUNSPEC\n" + "\n" + "GRID\n" + "EDIT\n" + "\n"; + + Opm::ParserPtr parser(new Opm::Parser()); + return parser->parseString(deckData) ; +} + +BOOST_AUTO_TEST_CASE(MissingDimsThrows) { + Opm::DeckPtr deck = createDeckMissingDIMS(); + BOOST_CHECK_THROW( new Opm::EclipseGrid( deck ) , std::invalid_argument); +} + BOOST_AUTO_TEST_CASE(HasGridKeywords) { Opm::DeckPtr deck = createDeckHeaders(); @@ -72,6 +89,18 @@ BOOST_AUTO_TEST_CASE(HasGridKeywords) { BOOST_CHECK( !Opm::EclipseGrid::hasCartesianKeywords( deck )); } + +BOOST_AUTO_TEST_CASE(CreateGridNoCells) { + Opm::DeckPtr deck = createDeckHeaders(); + Opm::EclipseGrid grid( deck ); + BOOST_CHECK_EQUAL( 10 , grid.getNX()); + BOOST_CHECK_EQUAL( 10 , grid.getNY()); + BOOST_CHECK_EQUAL( 10 , grid.getNZ()); + BOOST_CHECK_EQUAL( 1000 , grid.getCartesianSize()); +} + + + static Opm::DeckPtr createCPDeck() { const char *deckData = "RUNSPEC\n" @@ -228,6 +257,17 @@ static Opm::DeckPtr createCARTInvalidDeck() { return parser->parseString(deckData) ; } +BOOST_AUTO_TEST_CASE(CREATE_SIMPLE) { + Opm::EclipseGrid grid(10,20,30); + + BOOST_CHECK_EQUAL( grid.getNX() , 10 ); + BOOST_CHECK_EQUAL( grid.getNY() , 20 ); + BOOST_CHECK_EQUAL( grid.getNZ() , 30 ); + BOOST_CHECK_EQUAL( grid.getCartesianSize() , 6000 ); + BOOST_CHECK_EQUAL( false , grid.hasCellInfo() ); + +} + BOOST_AUTO_TEST_CASE(DEPTHZ_EQUAL_TOPS) { Opm::DeckPtr deck1 = createCARTDeck(); Opm::DeckPtr deck2 = createCARTDeckDEPTHZ(); @@ -306,7 +346,8 @@ BOOST_AUTO_TEST_CASE(HasINVALIDCartKeywords) { BOOST_AUTO_TEST_CASE(CreateMissingGRID_throws) { Opm::DeckPtr deck = createDeckHeaders(); - BOOST_CHECK_THROW(new Opm::EclipseGrid( deck ) , std::invalid_argument); + Opm::EclipseGrid grid( deck ); + BOOST_CHECK_EQUAL( false , grid.hasCellInfo() ); } @@ -366,7 +407,8 @@ static Opm::DeckPtr createInvalidDXYZCARTDeckDEPTHZ() { BOOST_AUTO_TEST_CASE(CreateCartesianGRIDDEPTHZ) { Opm::DeckPtr deck = createInvalidDXYZCARTDeckDEPTHZ(); - BOOST_CHECK_THROW(new Opm::EclipseGrid( deck ) , std::invalid_argument); + Opm::EclipseGrid grid( deck ); + BOOST_CHECK_EQUAL( false , grid.hasCellInfo() ); }