Match Connection-to-Region in Terms of Global Cell Indices
The simulator reports data::Connection objects tied to global Cartesian cell indices whence using the 'active_index' leads to match failures and incorrect rate attribution at the region level. In one field case we got region level rates and cumulatives, e.g., ROPR and ROPT, of zero reported to the summary file when the expected values should be non-zero.
This commit is contained in:
parent
e3fd90f965
commit
ae2f052b37
@ -40,12 +40,12 @@ RegionCache::RegionCache(const std::set<std::string>& fip_regions, const FieldPr
|
||||
continue;
|
||||
|
||||
for (const auto& c : connections) {
|
||||
if (grid.cellActive(c.getI(), c.getJ(), c.getK())) {
|
||||
size_t active_index = grid.activeIndex(c.getI(), c.getJ(), c.getK());
|
||||
if (grid.cellActive(c.global_index())) {
|
||||
size_t active_index = grid.activeIndex(c.global_index());
|
||||
int region_id = fip_region[active_index];
|
||||
auto key = std::make_pair(fip_name, region_id);
|
||||
auto& well_index_list = this->connection_map[ key ];
|
||||
well_index_list.push_back( { well.name() , active_index } );
|
||||
well_index_list.emplace_back(well.name(), c.global_index());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,57 +22,313 @@
|
||||
#define BOOST_TEST_MODULE RegionCache
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <unordered_set>
|
||||
#include <opm/output/eclipse/RegionCache.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Python/Python.hpp>
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||
#include <opm/output/eclipse/RegionCache.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/Connection.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/input/eclipse/Parser/Parser.hpp>
|
||||
|
||||
#include <opm/output/eclipse/RegionCache.hpp>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace Opm;
|
||||
namespace {
|
||||
|
||||
const char* path = "summary_deck.DATA";
|
||||
Opm::Deck summaryDeck()
|
||||
{
|
||||
return Opm::Parser{}.parseFile("summary_deck.DATA");
|
||||
}
|
||||
|
||||
bool cmp_list(const std::vector<std::string>& l1, const std::vector<std::string>& l2) {
|
||||
bool cmp_list(const std::vector<std::string>& l1,
|
||||
const std::vector<std::string>& l2)
|
||||
{
|
||||
std::unordered_set<std::string> s1(l1.begin(), l1.end());
|
||||
std::unordered_set<std::string> s2(l2.begin(), l2.end());
|
||||
return s1 == s2;
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create)
|
||||
{
|
||||
const auto deck = summaryDeck();
|
||||
const auto es = Opm::EclipseState { deck };
|
||||
const auto schedule = Opm::Schedule { deck, es, std::make_shared<Opm::Python>() };
|
||||
const auto& grid = es.getInputGrid();
|
||||
|
||||
const auto regCache = Opm::out::RegionCache {
|
||||
{"FIPNUM"}, es.fieldProps(), grid, schedule
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create) {
|
||||
auto python = std::make_shared<Python>();
|
||||
Parser parser;
|
||||
Deck deck( parser.parseFile( path ));
|
||||
EclipseState es(deck);
|
||||
const EclipseGrid& grid = es.getInputGrid();
|
||||
Schedule schedule( deck, es, python);
|
||||
out::RegionCache rc({"FIPNUM"}, es.fieldProps(), grid, schedule);
|
||||
{
|
||||
const auto& empty = rc.connections( "FIPNUM", 4 );
|
||||
const auto& empty = regCache.connections( "FIPNUM", 4 );
|
||||
BOOST_CHECK_EQUAL( empty.size() , 0U );
|
||||
}
|
||||
|
||||
{
|
||||
const auto& top_layer = rc.connections( "FIPNUM", 1 );
|
||||
const auto& top_layer = regCache.connections( "FIPNUM", 1 );
|
||||
BOOST_CHECK_EQUAL( top_layer.size() , 4U );
|
||||
{
|
||||
auto pair = top_layer[0];
|
||||
BOOST_CHECK_EQUAL( pair.first , "W_1");
|
||||
BOOST_CHECK_EQUAL( pair.second , grid.activeIndex( 0,0,0));
|
||||
BOOST_CHECK_EQUAL( pair.second , grid.getGlobalIndex(0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK( rc.wells("FIPXYZ", 100).empty() );
|
||||
BOOST_CHECK( rc.wells("FIPXYZ", 1).empty() );
|
||||
BOOST_CHECK( rc.wells("FIPNUM", 100).empty() );
|
||||
BOOST_CHECK( cmp_list(rc.wells("FIPNUM", 1), {"W_1", "W_2", "W_3", "W_4"}));
|
||||
BOOST_CHECK( cmp_list(rc.wells("FIPNUM", 11), {"W_6"}));
|
||||
BOOST_CHECK( regCache.wells("FIPXYZ", 100).empty() );
|
||||
BOOST_CHECK( regCache.wells("FIPXYZ", 1).empty() );
|
||||
BOOST_CHECK( regCache.wells("FIPNUM", 100).empty() );
|
||||
BOOST_CHECK( cmp_list(regCache.wells("FIPNUM", 1), {"W_1", "W_2", "W_3", "W_4"}));
|
||||
BOOST_CHECK( cmp_list(regCache.wells("FIPNUM", 11), {"W_6"}));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(InactiveLayers)
|
||||
{
|
||||
const auto deck = Opm::Parser{}.parseString(R"(RUNSPEC
|
||||
DIMENS
|
||||
5 5 6 /
|
||||
START
|
||||
22 'SEP' 2023 /
|
||||
GRID
|
||||
DXV
|
||||
5*100 /
|
||||
DYV
|
||||
5*100 /
|
||||
DZV
|
||||
6*10 /
|
||||
DEPTHZ
|
||||
36*2000 /
|
||||
ACTNUM
|
||||
25*1 -- K=1
|
||||
25*1 -- K=2
|
||||
25*0 -- K=3
|
||||
25*1 -- K=4
|
||||
25*1 -- K=5
|
||||
10*1
|
||||
1 1 0 1 1 -- ACTNUM(3, 3, 6) == 0
|
||||
10*1 / -- K=6
|
||||
PERMX
|
||||
150*100 /
|
||||
PERMY
|
||||
150*100 /
|
||||
PERMZ
|
||||
150*10 /
|
||||
PORO
|
||||
150*0.3 /
|
||||
REGIONS
|
||||
FIPNUM
|
||||
25*6 25*1 25*2 25*3 25*4 25*5 /
|
||||
FIPTEST1
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6 -- K=1
|
||||
--
|
||||
7 2 9 6 1
|
||||
7 2 9 6 1
|
||||
7 2 9 6 1
|
||||
7 2 9 6 1
|
||||
7 2 9 6 1 -- K=2
|
||||
--
|
||||
2 9 6 1 7
|
||||
2 9 6 1 7
|
||||
2 9 6 1 7
|
||||
2 9 6 1 7
|
||||
2 9 6 1 7 -- K=3
|
||||
--
|
||||
9 6 1 7 2
|
||||
9 6 1 7 2
|
||||
9 6 1 7 2
|
||||
9 6 1 7 2
|
||||
9 6 1 7 2 -- K=4
|
||||
--
|
||||
6 1 7 2 9
|
||||
6 1 7 2 9
|
||||
6 1 7 2 9
|
||||
6 1 7 2 9
|
||||
6 1 7 2 9 -- K=5
|
||||
--
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6
|
||||
1 7 2 9 6 / -- K=6
|
||||
SCHEDULE
|
||||
WELSPECS
|
||||
'P' 'G' 3 3 2005.0 'OIL' /
|
||||
/
|
||||
COMPDAT
|
||||
'P' 2* 1 6 /
|
||||
/
|
||||
TSTEP
|
||||
10 /
|
||||
END
|
||||
)");
|
||||
|
||||
const auto es = Opm::EclipseState { deck };
|
||||
const auto schedule = Opm::Schedule { deck, es, std::make_shared<Opm::Python>() };
|
||||
const auto& grid = es.getInputGrid();
|
||||
const auto regCache = Opm::out::RegionCache {
|
||||
std::set<std::string>{"FIPNUM", "FIPTEST1"},
|
||||
es.fieldProps(), grid, schedule
|
||||
};
|
||||
|
||||
const auto expect_conn = std::vector {
|
||||
std::size_t { 12}, // (2, 2, 0), FIP: {NUM = 6, TEST1 = 2 }
|
||||
std::size_t { 37}, // (2, 2, 1), FIP: {NUM = 1, TEST1 = 9 }
|
||||
std::size_t { 87}, // (2, 2, 3), FIP: {NUM = 3, TEST1 = 1 }
|
||||
std::size_t {112}, // (2, 2, 4), FIP: {NUM = 4, TEST1 = 7 }
|
||||
};
|
||||
|
||||
{
|
||||
const auto& wconn = schedule.back().wells("P").getConnections();
|
||||
BOOST_CHECK_EQUAL(wconn.size(), expect_conn.size());
|
||||
|
||||
for (auto i = 0*wconn.size(); i < wconn.size(); ++i) {
|
||||
BOOST_CHECK_EQUAL(wconn[i].global_index(), expect_conn[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// FIPNUM
|
||||
{
|
||||
// FIPNUM = 1
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPNUM", 1);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[1]);
|
||||
}
|
||||
|
||||
// FIPNUM = 2
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPNUM", 2);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPNUM=2");
|
||||
}
|
||||
|
||||
// FIPNUM = 3
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPNUM", 3);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[2]);
|
||||
}
|
||||
|
||||
// FIPNUM = 4
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPNUM", 4);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[3]);
|
||||
}
|
||||
|
||||
// FIPNUM = 5
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPNUM", 5);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPNUM=5");
|
||||
}
|
||||
|
||||
// FIPNUM = 6
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPNUM", 6);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// FIPTEST1
|
||||
{
|
||||
// FIPTEST1 = 1
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 1);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[2]);
|
||||
}
|
||||
|
||||
// FIPTEST1 = 2
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 2);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[0]);
|
||||
}
|
||||
|
||||
// FIPTEST1 = 3
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 3);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPTEST1=3");
|
||||
}
|
||||
|
||||
// FIPTEST1 = 4
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 4);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPTEST1=4");
|
||||
}
|
||||
|
||||
// FIPTEST1 = 5
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 5);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPTEST1=5");
|
||||
}
|
||||
|
||||
// FIPTEST1 = 6
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 6);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPTEST1=6");
|
||||
}
|
||||
|
||||
// FIPTEST1 = 7
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 7);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[3]);
|
||||
}
|
||||
|
||||
// FIPTEST1 = 8
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 8);
|
||||
BOOST_CHECK_MESSAGE(conns.empty(), "There must be no connections for FIPTEST1=8");
|
||||
}
|
||||
|
||||
// FIPTEST1 = 9
|
||||
{
|
||||
const auto& conns = regCache.connections("FIPTEST1", 9);
|
||||
BOOST_CHECK_EQUAL(conns.size(), std::size_t{1});
|
||||
|
||||
const auto& [well, cellIx] = conns.front();
|
||||
BOOST_CHECK_EQUAL(well, "P");
|
||||
BOOST_CHECK_EQUAL(cellIx, expect_conn[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user