diff --git a/opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp b/opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp index 4cc419ac3..ce38169bf 100644 --- a/opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp +++ b/opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp @@ -272,7 +272,7 @@ namespace Opm { void initCartesianGrid(const Deck&); void initDTOPSGrid(const Deck&); void initDVDEPTHZGrid(const Deck&); - void initGrid(const Deck&); + void initGrid(const Deck&, const int* actnum); void initCornerPointGrid(const Deck&); void assertCornerPointKeywords(const Deck&); diff --git a/src/opm/input/eclipse/EclipseState/Grid/EclipseGrid.cpp b/src/opm/input/eclipse/EclipseState/Grid/EclipseGrid.cpp index f57a92679..5ac6fe76b 100644 --- a/src/opm/input/eclipse/EclipseState/Grid/EclipseGrid.cpp +++ b/src/opm/input/eclipse/EclipseState/Grid/EclipseGrid.cpp @@ -274,39 +274,11 @@ EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum) updateNumericalAquiferCells(deck); - initGrid(deck); + initGrid(deck, actnum); if (deck.hasKeyword()) this->m_mapaxes = std::make_optional( deck ); - if (actnum != nullptr) { - resetACTNUM(actnum); - } else { - if (m_useActnumFromGdfile){ - // actnum already reset in initBinaryGrid - } else { - if (deck.hasKeyword()) { - const auto& actnumData = deck.get().back().getIntData(); - /* - Would have liked to fail hard in the case where the size of the - ACTNUM array disagrees with nx*ny*nz; but it is possible to embed - the ACTNUM keyword in a BOX / ENDBOX pair and in that case it is - legitimate with size(ACTNUM) < nx*ny*nz. - - If size(actnum) != nx*ny*nz it is ignored here, however it is - taken into account when creating an final actnum in the field - property manager. - */ - if (actnumData.size() == getCartesianSize()) - resetACTNUM( actnumData); - else - resetACTNUM(); - } else { - resetACTNUM(); - } - } - } - /* The GRIDUNIT handling is simplified compared to the full specification: @@ -340,8 +312,8 @@ EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum) return this->m_circle; } - void EclipseGrid::initGrid(const Deck& deck) { - + void EclipseGrid::initGrid(const Deck& deck, const int* actnum) + { if (deck.hasKeyword()) { initCylindricalGrid(deck ); } else if (deck.hasKeyword()) { @@ -389,6 +361,16 @@ EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum) m_minpvMode = MinpvMode::ModeEnum::EclSTD; } + if (actnum != nullptr) { + this->resetACTNUM(actnum); + } + else if (! this->m_useActnumFromGdfile) { + const auto fp = FieldProps { + deck, EclipseGrid { static_cast(*this) } + }; + + this->resetACTNUM(fp.actnumRaw()); + } } void EclipseGrid::initGridFromEGridFile(Opm::EclIO::EclFile& egridfile, std::string fileName){ @@ -1159,25 +1141,19 @@ EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum) this->resetACTNUM(actnum); } - void EclipseGrid::initCornerPointGrid(const Deck& deck) { - assertCornerPointKeywords(deck); - { - const auto& ZCORNKeyWord = deck.get().back(); - const auto& COORDKeyWord = deck.get().back(); + void EclipseGrid::initCornerPointGrid(const Deck& deck) + { + this->assertCornerPointKeywords(deck); - const std::vector& zcorn = ZCORNKeyWord.getSIDoubleData(); - const std::vector& coord = COORDKeyWord.getSIDoubleData(); + OpmLog::info(fmt::format("\nCreating corner-point grid from " + "keywords COORD, ZCORN and others")); - EclipseGrid topologyOnlyGrid(static_cast(*this)); - FieldProps fp(deck, topologyOnlyGrid); - const auto& actnumVector = fp.actnumRaw(); - if (actnumVector.size() != this->getCartesianSize()) - throw std::invalid_argument("ACTNUM vector has wrong size"); + const auto& coord = deck.get().back(); + const auto& zcorn = deck.get().back(); - OpmLog::info(fmt::format("\nCreating cornerpoint grid from keywords ZCORN, COORD and ACTNUM")); - - initCornerPointGrid( coord , zcorn, actnumVector.data()); - } + this->initCornerPointGrid(coord.getSIDoubleData(), + zcorn.getSIDoubleData(), + nullptr); } bool EclipseGrid::hasCornerPointKeywords(const Deck& deck) { diff --git a/tests/parser/EclipseGridTests.cpp b/tests/parser/EclipseGridTests.cpp index 04596dfb5..16855bd64 100644 --- a/tests/parser/EclipseGridTests.cpp +++ b/tests/parser/EclipseGridTests.cpp @@ -17,6 +17,7 @@ along with OPM. If not, see . */ +#include #include #include #include @@ -1082,6 +1083,178 @@ BOOST_AUTO_TEST_CASE(GridBoxActnum2) { } } +// 5-by-1-by-5 Cartesian grid in which all cells have dimension 1-by-1-by-1 +// metres. Setup otherwise very similar to createActnumBoxDeck2, but this +// deck uses a full initial ACTNUM, followed by EQUALS to reactivate. +static Opm::Deck createActnumBoxDeck3() { + return Opm::Parser{}.parseString(R"(RUNSPEC +DIMENS +5 1 5 / +GRID +SPECGRID +5 1 5 1 F / +COORD +0 0 0 0 0 0 +1 0 0 1 0 0 +2 0 0 2 0 0 +3 0 0 3 0 0 +4 0 0 4 0 0 +5 0 0 5 0 0 +0 1 0 0 1 0 +1 1 0 1 1 0 +2 1 0 2 1 0 +3 1 0 3 1 0 +4 1 0 4 1 0 +5 1 0 5 1 0 +/ +ZCORN +10*0 10*0 +10*1 10*1 +10*1 10*1 +10*2 10*2 +10*2 10*2 +10*3 10*3 +10*3 10*3 +10*4 10*4 +10*4 10*4 +10*5 10*5 +/ +ACTNUM +1 1 1 1 1 +1 1 1 1 1 +1 1 1 1 1 +0 0 1 1 1 +0 0 1 1 1 +/ +EQUALS +ACTNUM 1 1 3 1 1 5 5 / +PERMX 100.0 1 5 1 1 1 5 / +PORO 0.3 1 5 1 1 1 5 / +/ +COPY +PERMX PERMY / +PERMX PERMZ / +/ +)"); +} + +static Opm::Deck createActnumBoxDeck4() { + return Opm::Parser{}.parseString(R"(RUNSPEC +DIMENS +5 1 5 / +GRID +DXV +5*1 / +DYV +1*1 / +DZV +5*1 / +DEPTHZ +12*0 / +ACTNUM +1 1 1 1 1 +1 1 1 1 1 +1 1 1 1 1 +0 0 1 1 1 +0 0 1 1 1 +/ +EQUALS +ACTNUM 1 1 3 1 1 5 5 / +PERMX 100.0 1 5 1 1 1 5 / +PORO 0.3 1 5 1 1 1 5 / +/ +COPY +PERMX PERMY / +PERMX PERMZ / +/ +)"); +} + +static Opm::Deck createActnumBoxDeck5() { + return Opm::Parser{}.parseString(R"(RUNSPEC +DIMENS +5 1 5 / +GRID +DX +25*1 / +DY +25*1 / +DZ +25*1 / +TOPS +5*0 / +ACTNUM +1 1 1 1 1 +1 1 1 1 1 +1 1 1 1 1 +0 0 1 1 1 +0 0 1 1 1 +/ +EQUALS +ACTNUM 1 1 3 1 1 5 5 / +PERMX 100.0 1 5 1 1 1 5 / +PORO 0.3 1 5 1 1 1 5 / +/ +COPY +PERMX PERMY / +PERMX PERMZ / +/ +)"); +} + +BOOST_AUTO_TEST_CASE(GridBoxActnum3) { + const auto es = Opm::EclipseState { createActnumBoxDeck3() }; + const auto& grid = es.getInputGrid(); + BOOST_CHECK_EQUAL(grid.getNumActive(), std::size_t{23}); + + const auto expect = std::vector { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + + const auto& actnum = grid.getACTNUM(); + BOOST_CHECK_EQUAL_COLLECTIONS(actnum.begin(), actnum.end(), + expect.begin(), expect.end()); +} + +BOOST_AUTO_TEST_CASE(GridBoxActnum4) { + const auto es = Opm::EclipseState { createActnumBoxDeck4() }; + const auto& grid = es.getInputGrid(); + BOOST_CHECK_EQUAL(grid.getNumActive(), std::size_t{23}); + + const auto expect = std::vector { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + + const auto& actnum = grid.getACTNUM(); + BOOST_CHECK_EQUAL_COLLECTIONS(actnum.begin(), actnum.end(), + expect.begin(), expect.end()); +} + +BOOST_AUTO_TEST_CASE(GridBoxActnum5) { + const auto es = Opm::EclipseState { createActnumBoxDeck5() }; + const auto& grid = es.getInputGrid(); + BOOST_CHECK_EQUAL(grid.getNumActive(), std::size_t{23}); + + const auto expect = std::vector { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + + const auto& actnum = grid.getACTNUM(); + BOOST_CHECK_EQUAL_COLLECTIONS(actnum.begin(), actnum.end(), + expect.begin(), expect.end()); +} BOOST_AUTO_TEST_CASE(GridActnumVia3D) { auto deck = createActnumDeck();