Merge pull request #3063 from bska/ensure-correct-initial-actnum
Apply Generalised ACTNUM Handling to All Grid Types
This commit is contained in:
commit
80545120b6
@ -272,7 +272,7 @@ namespace Opm {
|
|||||||
void initCartesianGrid(const Deck&);
|
void initCartesianGrid(const Deck&);
|
||||||
void initDTOPSGrid(const Deck&);
|
void initDTOPSGrid(const Deck&);
|
||||||
void initDVDEPTHZGrid(const Deck&);
|
void initDVDEPTHZGrid(const Deck&);
|
||||||
void initGrid(const Deck&);
|
void initGrid(const Deck&, const int* actnum);
|
||||||
void initCornerPointGrid(const Deck&);
|
void initCornerPointGrid(const Deck&);
|
||||||
void assertCornerPointKeywords(const Deck&);
|
void assertCornerPointKeywords(const Deck&);
|
||||||
|
|
||||||
|
@ -274,39 +274,11 @@ EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum)
|
|||||||
|
|
||||||
updateNumericalAquiferCells(deck);
|
updateNumericalAquiferCells(deck);
|
||||||
|
|
||||||
initGrid(deck);
|
initGrid(deck, actnum);
|
||||||
|
|
||||||
if (deck.hasKeyword<ParserKeywords::MAPAXES>())
|
if (deck.hasKeyword<ParserKeywords::MAPAXES>())
|
||||||
this->m_mapaxes = std::make_optional<MapAxes>( deck );
|
this->m_mapaxes = std::make_optional<MapAxes>( deck );
|
||||||
|
|
||||||
if (actnum != nullptr) {
|
|
||||||
resetACTNUM(actnum);
|
|
||||||
} else {
|
|
||||||
if (m_useActnumFromGdfile){
|
|
||||||
// actnum already reset in initBinaryGrid
|
|
||||||
} else {
|
|
||||||
if (deck.hasKeyword<ParserKeywords::ACTNUM>()) {
|
|
||||||
const auto& actnumData = deck.get<ParserKeywords::ACTNUM>().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:
|
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;
|
return this->m_circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EclipseGrid::initGrid(const Deck& deck) {
|
void EclipseGrid::initGrid(const Deck& deck, const int* actnum)
|
||||||
|
{
|
||||||
if (deck.hasKeyword<ParserKeywords::RADIAL>()) {
|
if (deck.hasKeyword<ParserKeywords::RADIAL>()) {
|
||||||
initCylindricalGrid(deck );
|
initCylindricalGrid(deck );
|
||||||
} else if (deck.hasKeyword<ParserKeywords::SPIDER>()) {
|
} else if (deck.hasKeyword<ParserKeywords::SPIDER>()) {
|
||||||
@ -389,6 +361,16 @@ EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum)
|
|||||||
m_minpvMode = MinpvMode::ModeEnum::EclSTD;
|
m_minpvMode = MinpvMode::ModeEnum::EclSTD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actnum != nullptr) {
|
||||||
|
this->resetACTNUM(actnum);
|
||||||
|
}
|
||||||
|
else if (! this->m_useActnumFromGdfile) {
|
||||||
|
const auto fp = FieldProps {
|
||||||
|
deck, EclipseGrid { static_cast<GridDims&>(*this) }
|
||||||
|
};
|
||||||
|
|
||||||
|
this->resetACTNUM(fp.actnumRaw());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EclipseGrid::initGridFromEGridFile(Opm::EclIO::EclFile& egridfile, std::string fileName){
|
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);
|
this->resetACTNUM(actnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EclipseGrid::initCornerPointGrid(const Deck& deck) {
|
void EclipseGrid::initCornerPointGrid(const Deck& deck)
|
||||||
assertCornerPointKeywords(deck);
|
{
|
||||||
{
|
this->assertCornerPointKeywords(deck);
|
||||||
const auto& ZCORNKeyWord = deck.get<ParserKeywords::ZCORN>().back();
|
|
||||||
const auto& COORDKeyWord = deck.get<ParserKeywords::COORD>().back();
|
|
||||||
|
|
||||||
const std::vector<double>& zcorn = ZCORNKeyWord.getSIDoubleData();
|
OpmLog::info(fmt::format("\nCreating corner-point grid from "
|
||||||
const std::vector<double>& coord = COORDKeyWord.getSIDoubleData();
|
"keywords COORD, ZCORN and others"));
|
||||||
|
|
||||||
EclipseGrid topologyOnlyGrid(static_cast<GridDims&>(*this));
|
const auto& coord = deck.get<ParserKeywords::COORD>().back();
|
||||||
FieldProps fp(deck, topologyOnlyGrid);
|
const auto& zcorn = deck.get<ParserKeywords::ZCORN>().back();
|
||||||
const auto& actnumVector = fp.actnumRaw();
|
|
||||||
if (actnumVector.size() != this->getCartesianSize())
|
|
||||||
throw std::invalid_argument("ACTNUM vector has wrong size");
|
|
||||||
|
|
||||||
OpmLog::info(fmt::format("\nCreating cornerpoint grid from keywords ZCORN, COORD and ACTNUM"));
|
this->initCornerPointGrid(coord.getSIDoubleData(),
|
||||||
|
zcorn.getSIDoubleData(),
|
||||||
initCornerPointGrid( coord , zcorn, actnumVector.data());
|
nullptr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EclipseGrid::hasCornerPointKeywords(const Deck& deck) {
|
bool EclipseGrid::hasCornerPointKeywords(const Deck& deck) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -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<int> {
|
||||||
|
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<int> {
|
||||||
|
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<int> {
|
||||||
|
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) {
|
BOOST_AUTO_TEST_CASE(GridActnumVia3D) {
|
||||||
auto deck = createActnumDeck();
|
auto deck = createActnumDeck();
|
||||||
|
Loading…
Reference in New Issue
Block a user