Added changes needed to provide connection index for restart file

This commit is contained in:
Jostein Alvestad 2018-07-10 10:34:59 +02:00
parent 690fe11e58
commit 36de4a4a31
13 changed files with 81 additions and 172 deletions

View File

@ -45,9 +45,10 @@ namespace Opm { namespace RestartIO { namespace Helpers {
explicit AggregateWellData(const std::vector<int>& inteHead);
void captureDeclaredWellData(const Schedule& sched,
const UnitSystem& units,
const std::size_t sim_step,
const std::vector<int>& inteHead);
const UnitSystem& units,
const std::size_t sim_step,
const ::Opm::SummaryState& smry,
const std::vector<int>& inteHead);
void captureDynamicWellData(const Opm::Schedule& sched,
const std::size_t sim_step,

View File

@ -47,7 +47,8 @@ namespace Opm {
double Kh,
double rw,
const int satTableId,
const WellCompletion::DirectionEnum direction);
const WellCompletion::DirectionEnum direction,
const std::size_t seqIndex);
bool attachedToSegment() const;
@ -70,6 +71,8 @@ namespace Opm {
void setComplnum(int compnum);
void scaleWellPi(double wellPi);
void updateSegment(int segment_number, double center_depth, std::size_t seqIndex);
const std::size_t& getSeqIndex() const;
void setSeqIndex(std::size_t index);
bool operator==( const Connection& ) const;
bool operator!=( const Connection& ) const;
@ -84,13 +87,12 @@ namespace Opm {
double m_rw;
std::array<int,3> ijk;
std::size_t m_seqIndex;
// related segment number
// -1 means the completion is not related to segment
int segment_number = -1;
double wPi = 1.0;
std::size_t seqIndex;
};
}

View File

@ -39,7 +39,8 @@ namespace Opm {
double Kh,
double rw,
const int satTableId,
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z);
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z,
const std::size_t seqIndex = 0);
void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
using const_iterator = std::vector< Connection >::const_iterator;
@ -81,7 +82,8 @@ namespace Opm {
double Kh,
double rw,
const int satTableId,
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z);
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z,
const std::size_t seqIndex=0);
std::vector< Connection > m_connections;
size_t findClosestConnection(int oi, int oj, double oz, size_t start_pos);

View File

@ -97,7 +97,7 @@ namespace {
using ConnState = ::Opm::WellCompletion::StateEnum;
// Wrong. Should be connection's order of appearance in COMPDAT.
iConn[0] = static_cast<int>(connID) + 1;
iConn[0] = conn.getSeqIndex()+1;
iConn[1] = conn.getI() + 1;
iConn[2] = conn.getJ() + 1;
@ -191,6 +191,7 @@ captureDeclaredConnData(const Schedule& sched,
const UnitSystem& units,
const std::size_t sim_step)
{
//const auto& actnum = grid.activeIndex;
const auto& wells = sched.getWells(sim_step);
connectionLoop(wells, grid, sim_step, [&units, this]

View File

@ -138,7 +138,8 @@ namespace {
int firstConnection = std::numeric_limits<int>::max();
for (auto it : compSet) {
auto c_Segment = it.segment_number;
auto c_SeqIndex = it.seqIndex;
//auto c_SeqIndex = it.seqIndex;
auto c_SeqIndex = it.getSeqIndex();
if ((segNumber == c_Segment) && (c_SeqIndex < firstConnection)) {
firstConnection = c_SeqIndex;
}

View File

@ -434,7 +434,7 @@ namespace {
// Initial data by Statoil ASA.
return { // 122 Items (0..121)
// 0 1 2 3 4 5
infty, infty, infty, infty, infty, infty, // 0.. 5 ( 0)
zero , zero , zero , zero ,infty , zero, // 0.. 5 ( 0)
one , zero , zero , zero , zero , 1.0e-05f, // 6.. 11 ( 1)
zero , zero , infty, infty, zero , dflt , // 12.. 17 ( 2)
infty, infty, infty, infty, infty, zero , // 18.. 23 ( 3)
@ -476,6 +476,7 @@ namespace {
void staticContrib(const Opm::Well& well,
const Opm::UnitSystem& units,
const std::size_t sim_step,
const ::Opm::SummaryState& smry,
SWellArray& sWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::SWell::index;
@ -486,6 +487,11 @@ namespace {
return static_cast<float>(units.from_si(u, x));
};
auto get = [&smry, &well](const std::string& vector)
{
return smry.get(vector + ':' + well.name());
};
assignDefaultSWell(sWell);
if (well.isProducer(sim_step)) {
@ -521,6 +527,10 @@ namespace {
sWell[Ix::ResVRateTarget] =
swprop(M::rate, pp.ResVRate);
}
//write out summary voidage production rate if target/limit is not set
else {
sWell[Ix::ResVRateTarget] = get("WVPR");
}
if (pp.THPLimit != 0.0) {
sWell[Ix::THPTarget] =
@ -785,6 +795,7 @@ Opm::RestartIO::Helpers::AggregateWellData::
captureDeclaredWellData(const Schedule& sched,
const UnitSystem& units,
const std::size_t sim_step,
const ::Opm::SummaryState& smry,
const std::vector<int>& inteHead)
{
const auto& wells = sched.getWells(sim_step);
@ -807,12 +818,12 @@ captureDeclaredWellData(const Schedule& sched,
}
// Static contributions to SWEL array.
wellLoop(wells, [&units, sim_step, this]
wellLoop(wells, [&units, sim_step, &smry, this]
(const Well& well, const std::size_t wellID) -> void
{
auto sw = this->sWell_[wellID];
SWell::staticContrib(well, units, sim_step, sw);
SWell::staticContrib(well, units, sim_step, smry, sw);
});
// Static contributions to XWEL array.

View File

@ -153,23 +153,6 @@ namespace RestartIO {
static const std::set<std::string> extra_solution = {"THRESHPR"};
static const int NIWELZ = 11; //Number of data elements per well in IWEL array in restart file
static const int NZWELZ = 3; //Number of 8-character words per well in ZWEL array restart file
static const int NICONZ = 15; //Number of data elements per connection in ICON array restart file
/**
* The constants NIWELZ and NZWELZ referes to the number of
* elements per well that we write to the IWEL and ZWEL eclipse
* restart file data arrays. The constant NICONZ refers to the
* number of elements per connection in the eclipse restart file
* ICON data array.These numbers are written to the INTEHEAD
* header.
*
* Observe that all of these values are our "current-best-guess"
* for how many numbers are needed; there might very well be third
* party applications out there which have a hard expectation for
* these values.
*/
inline int to_ert_welltype( const Well& well, size_t timestep ) {
@ -380,69 +363,6 @@ RestartValue load( const std::string& filename,
namespace {
std::vector<int> serialize_ICON( int sim_step,
int ncwmax,
const std::vector<const Well*>& sched_wells,
const EclipseGrid& /*grid*/) {
size_t well_offset = 0;
std::vector<int> data( sched_wells.size() * ncwmax * NICONZ , 0 );
for (const Well* well : sched_wells) {
const auto& connections = well->getConnections( sim_step );
size_t connection_offset = 0;
for( const auto& connection : connections) {
size_t offset = well_offset + connection_offset;
data[ offset + ICON_IC_INDEX ] = 1;
data[ offset + ICON_I_INDEX ] = connection.getI() + 1;
data[ offset + ICON_J_INDEX ] = connection.getJ() + 1;
data[ offset + ICON_K_INDEX ] = connection.getK() + 1;
data[ offset + ICON_DIRECTION_INDEX ] = connection.dir;
{
const auto open = WellCompletion::StateEnum::OPEN;
data[ offset + ICON_STATUS_INDEX ] = connection.state == open
? 1
: 0;
}
connection_offset += NICONZ;
}
well_offset += ncwmax * NICONZ;
}
return data;
}
std::vector<int> serialize_IWEL( size_t step,
const std::vector<const Well *>& wells,
const EclipseGrid& grid) {
std::vector<int> data( wells.size() * NIWELZ , 0 );
size_t offset = 0;
for (const auto well : wells) {
const auto& connections = well->getActiveConnections( step, grid );
data[ offset + IWEL_HEADI_INDEX ] = well->getHeadI( step ) + 1;
data[ offset + IWEL_HEADJ_INDEX ] = well->getHeadJ( step ) + 1;
data[ offset + IWEL_CONNECTIONS_INDEX ] = connections.size();
data[ offset + IWEL_GROUP_INDEX ] = 1;
data[ offset + IWEL_TYPE_INDEX ] = to_ert_welltype( *well, step );
data[ offset + IWEL_STATUS_INDEX ] =
well->getStatus( step ) == WellCommon::OPEN ? 1 : 0;
offset += NIWELZ;
}
return data;
}
std::vector< int > serialize_OPM_IWEL( const data::Wells& wells,
const std::vector< const Well* >& sched_wells ) {
@ -525,17 +445,6 @@ std::vector< double > serialize_OPM_XWEL( const data::Wells& wells,
}
std::vector<const char*> serialize_ZWEL( const std::vector<const Well *>& wells) {
std::vector<const char*> data( wells.size( ) * NZWELZ , "");
size_t offset = 0;
for (const auto& well : wells) {
data[ offset ] = well->name().c_str();
offset += NZWELZ;
}
return data;
}
std::vector<const char*> serialize_ZWEL( const std::vector<Opm::RestartIO::Helpers::CharArrayNullTerm<8>>& zwel) {
std::vector<const char*> data( zwel.size( ), "");
size_t it = 0;
@ -551,42 +460,6 @@ template< typename T >
void write_kw(::Opm::RestartIO::ecl_rst_file_type * rst_file , Opm::RestartIO::EclKW< T >&& kw) {
::Opm::RestartIO::ecl_rst_file_add_kw( rst_file, kw.get() );
}
/*
void writeHeader(::Opm::RestartIO::ecl_rst_file_type * rst_file,
int sim_step,
int report_step,
time_t posix_time,
double sim_days,
int ert_phase_mask,
const UnitSystem& units,
const Schedule& schedule,
const EclipseGrid& grid) {
Opm::RestartIO::ecl_rsthead_type rsthead_data = {};
rsthead_data.sim_time = posix_time;
rsthead_data.nactive = grid.getNumActive();
rsthead_data.nx = grid.getNX();
rsthead_data.ny = grid.getNY();
rsthead_data.nz = grid.getNZ();
rsthead_data.nwells = schedule.numWells(sim_step);
rsthead_data.niwelz = NIWELZ;
rsthead_data.nzwelz = NZWELZ;
rsthead_data.niconz = NICONZ;
rsthead_data.ncwmax = schedule.getMaxNumConnectionsForWells(sim_step);
rsthead_data.phase_sum = ert_phase_mask;
rsthead_data.sim_days = sim_days;
rsthead_data.unit_system = units.getEclType( );
// this function should be moved to opm (does not need to be changed)
::Opm::RestartIO::ecl_util_set_date_values( rsthead_data.sim_time,
&rsthead_data.day,
&rsthead_data.month,
&rsthead_data.year );
::Opm::RestartIO::ecl_rst_file_fwrite_header( rst_file, report_step , &rsthead_data );
}
*/
std::vector<int>
writeHeader(::Opm::RestartIO::ecl_rst_file_type* rst_file,
@ -768,7 +641,7 @@ void writeWell(::Opm::RestartIO::ecl_rst_file_type* rst_file,
const std::vector<int>& ih)
{
auto wellData = Helpers::AggregateWellData(ih);
wellData.captureDeclaredWellData(schedule, units, sim_step, ih);
wellData.captureDeclaredWellData(schedule, units, sim_step, sumState, ih);
wellData.captureDynamicWellData(schedule, sim_step, wells, sumState);
auto connectionData = Helpers::AggregateConnectionData(ih);

View File

@ -44,7 +44,8 @@ namespace Opm {
double Kh,
double rw,
const int satTableId,
const WellCompletion::DirectionEnum direction)
const WellCompletion::DirectionEnum direction,
const std::size_t seqIndex)
: direction(direction),
center_depth(depth),
open_state(stateArg),
@ -53,7 +54,8 @@ namespace Opm {
m_CF(CF),
m_Kh(Kh),
m_rw(rw),
ijk({i,j,k})
ijk({i,j,k}),
m_seqIndex(seqIndex)
{}
/*bool Connection::sameCoordinate(const Connection& other) const {
@ -91,6 +93,14 @@ namespace Opm {
return (segment_number > 0);
}
const std::size_t& Connection::getSeqIndex() const {
return m_seqIndex;
}
void Connection::setSeqIndex(std::size_t index) {
m_seqIndex = index;
}
WellCompletion::DirectionEnum Connection::dir() const {
return this->direction;
}
@ -161,7 +171,7 @@ namespace Opm {
&& this->direction == rhs.direction
&& this->segment_number == rhs.segment_number
&& this->center_depth == rhs.center_depth
&& this->seqIndex == rhs.seqIndex;
&& this->m_seqIndex == rhs.m_seqIndex;
}
bool Connection::operator!=( const Connection& rhs ) const {

View File

@ -40,7 +40,6 @@ namespace Opm {
// lateral branches should be numbered bigger than 1.
// a suboridnate branch must have a higher branch number than parent branch.
int m_branch_number;
size_t m_seqIndex;
double m_distance_start;
double m_distance_end;
@ -49,9 +48,10 @@ namespace Opm {
// we do not handle thermal length for the moment
// double m_thermal_length;
int segment_number;
std::size_t m_seqIndex;
Compsegs(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
WellCompletion::DirectionEnum dir_in, double center_depth_in, int segment_number_in, size_t seqIndex_in);
WellCompletion::DirectionEnum dir_in, double center_depth_in, int segment_number_in, std::size_t seqIndex_in);
void calculateCenterDepthWithSegments(const WellSegments& segment_set);

View File

@ -137,11 +137,12 @@ namespace {
double Kh,
double rw,
const int satTableId,
const WellCompletion::DirectionEnum direction)
const WellCompletion::DirectionEnum direction,
const std::size_t seqIndex)
{
int conn_i = (i < 0) ? this->headI : i;
int conn_j = (j < 0) ? this->headJ : j;
Connection conn(conn_i, conn_j, k, complnum, depth, state, CF, Kh, rw, satTableId, direction);
Connection conn(conn_i, conn_j, k, complnum, depth, state, CF, Kh, rw, satTableId, direction, seqIndex);
this->add(conn);
}
@ -154,7 +155,8 @@ namespace {
double Kh,
double rw,
const int satTableId,
const WellCompletion::DirectionEnum direction)
const WellCompletion::DirectionEnum direction,
const std::size_t seqIndex)
{
int complnum = -(this->m_connections.size() + 1);
this->addConnection(i,
@ -167,7 +169,8 @@ namespace {
Kh,
rw,
satTableId,
direction);
direction,
seqIndex);
}
void WellConnections::loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) {
@ -274,6 +277,7 @@ namespace {
same_ijk );
if (prev == this->m_connections.end()) {
std::size_t noConn = this->m_connections.size();
this->addConnection(I,J,k,
grid.getCellDepth( I,J,k ),
state,
@ -281,8 +285,10 @@ namespace {
Kh,
rw,
satTableId,
direction );
direction,
noConn );
} else {
std::size_t noConn = prev->getSeqIndex();
// The complnum value carries over; the rest of the state is fully specified by
// the current COMPDAT keyword.
int complnum = prev->complnum();
@ -294,7 +300,8 @@ namespace {
Kh,
rw,
satTableId,
direction );
direction,
noConn );
}
}
}

View File

@ -69,9 +69,9 @@ BOOST_AUTO_TEST_CASE(CreateWellConnectionsOK) {
BOOST_AUTO_TEST_CASE(AddCompletionSizeCorrect) {
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
Opm::WellConnections completionSet;
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir);
completionSet.add( completion1 );
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir,0);
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir,0);
completionSet.add( completion1 );
BOOST_CHECK_EQUAL( 1U , completionSet.size() );
completionSet.add( completion2 );
@ -83,8 +83,8 @@ completionSet.add( completion1 );
BOOST_AUTO_TEST_CASE(WellConnectionsGetOutOfRangeThrows) {
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir,0);
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir,0);
Opm::WellConnections completionSet;
completionSet.add( completion1 );
BOOST_CHECK_EQUAL( 1U , completionSet.size() );
@ -103,9 +103,9 @@ BOOST_AUTO_TEST_CASE(AddCompletionCopy) {
Opm::WellConnections completionSet;
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion3( 10,10,12, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir,0);
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir,0);
Opm::Connection completion3( 10,10,12, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir,0);
completionSet.add( completion1 );
completionSet.add( completion2 );
@ -125,9 +125,9 @@ BOOST_AUTO_TEST_CASE(ActiveCompletions) {
Opm::EclipseGrid grid(10,20,20);
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
Opm::WellConnections completions;
Opm::Connection completion1( 0,0,0, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion2( 0,0,1, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion3( 0,0,2, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir);
Opm::Connection completion1( 0,0,0, 1, 0.0, Opm::WellCompletion::OPEN , 99.88, 355.113, 0.25, 0, dir,0);
Opm::Connection completion2( 0,0,1, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir,0);
Opm::Connection completion3( 0,0,2, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir,0);
completions.add( completion1 );
completions.add( completion2 );

View File

@ -44,14 +44,14 @@
BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
Opm::WellConnections connection_set;
connection_set.add(Opm::Connection( 19, 0, 0, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, dir) );
connection_set.add(Opm::Connection( 19, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, dir) );
connection_set.add(Opm::Connection( 19, 0, 2, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, dir) );
connection_set.add(Opm::Connection( 19, 0, 0, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, dir,0) );
connection_set.add(Opm::Connection( 19, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, dir,0) );
connection_set.add(Opm::Connection( 19, 0, 2, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, dir,0) );
connection_set.add(Opm::Connection( 18, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X) );
connection_set.add(Opm::Connection( 17, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X) );
connection_set.add(Opm::Connection( 16, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X) );
connection_set.add(Opm::Connection( 15, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X) );
connection_set.add(Opm::Connection( 18, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X,0) );
connection_set.add(Opm::Connection( 17, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X,0) );
connection_set.add(Opm::Connection( 16, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X,0) );
connection_set.add(Opm::Connection( 15, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , 200, 17.29, 0.25, 0, Opm::WellCompletion::DirectionEnum::X,0) );
BOOST_CHECK_EQUAL( 7U , connection_set.size() );

View File

@ -370,9 +370,10 @@ BOOST_AUTO_TEST_CASE (Declared_Well_Data)
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{2});
const auto smry = sim_state();
auto awd = Opm::RestartIO::Helpers::AggregateWellData{ih.value};
awd.captureDeclaredWellData(simCase.sched,
simCase.es.getUnits(), rptStep, ih.value);
simCase.es.getUnits(), rptStep, smry, ih.value);
// IWEL (OP_1)
{