From 4a5b71d8c1048cb2dadcf1cae545464fab3728b8 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 16 Aug 2018 14:43:07 +0200 Subject: [PATCH] Include Peaceman calculation in Connection class - The calculation of well connection transmissibility CF and effective permeability is calculated. - The Connection objects are immutable; should never be updated. - The properties of the Connection class are just plain properties, have removed getter methods and the use of Value. --- .../EclipseState/Schedule/Connection.hpp | 57 +++-- .../EclipseState/Schedule/WellConnections.hpp | 15 +- src/opm/output/eclipse/RestartIO.cpp | 8 +- .../output/eclipse/WellDataSerializers.cpp | 37 +-- .../EclipseState/Schedule/Connection.cpp | 117 +++++---- .../EclipseState/Schedule/MSW/Compsegs.cpp | 3 +- .../eclipse/EclipseState/Schedule/Well.cpp | 22 +- .../EclipseState/Schedule/WellConnections.cpp | 151 ++++++++---- tests/parser/ConnectionTests.cpp | 230 +++++++++++++++--- tests/parser/MultisegmentWellTests.cpp | 36 +-- tests/parser/ScheduleTests.cpp | 124 +++++----- tests/parser/WellTests.cpp | 17 +- tests/parser/integration/ParseKEYWORD.cpp | 16 +- .../integration/ScheduleCreateFromDeck.cpp | 8 +- tests/test_serialize_ICON.cpp | 8 +- tests/test_serialize_SCON.cpp | 11 +- 16 files changed, 544 insertions(+), 316 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Connection.hpp b/opm/parser/eclipse/EclipseState/Schedule/Connection.hpp index 300b25dcc..f77bb89ce 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Connection.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Connection.hpp @@ -41,50 +41,57 @@ namespace Opm { Connection(int i, int j , int k , int complnum, double depth, - WellCompletion::StateEnum state , - const Value& connectionTransmissibilityFactor, - const Value& diameter, - const Value& skinFactor, - const Value& Kh, + WellCompletion::StateEnum state, + double CF, + double Kh, + double rw, const int satTableId, const WellCompletion::DirectionEnum direction); + bool attachedToSegment() const; bool sameCoordinate(const int i, const int j, const int k) const; int getI() const; int getJ() const; int getK() const; - double getConnectionTransmissibilityFactor() const; - double getDiameter() const; - double getSkinFactor() const; - bool attachedToSegment() const; - const Value& getConnectionTransmissibilityFactorAsValueObject() const; - const Value& getEffectiveKhAsValueObject() const; + WellCompletion::StateEnum state() const; + WellCompletion::DirectionEnum dir() const; + double depth() const; + int satTableId() const; + int complnum() const; + int segment() const; + double CF() const; + double Kh() const; + double rw() const; + double wellPi() const; + + void setState(WellCompletion::StateEnum state); + void setComplnum(int compnum); + void scaleWellPi(double wellPi); + void updateSegment(int segment_number, double center_depth); bool operator==( const Connection& ) const; bool operator!=( const Connection& ) const; - - WellCompletion::DirectionEnum dir; - double center_depth; - WellCompletion::StateEnum state; - int sat_tableId; - int complnum; - private: - std::array ijk; - Value m_diameter; - Value m_connectionTransmissibilityFactor; - Value m_skinFactor; - Value m_Kh; + WellCompletion::DirectionEnum direction; + double center_depth; + WellCompletion::StateEnum open_state; + int sat_tableId; + int m_complnum; + double m_CF; + double m_Kh; + double m_rw; + + std::array ijk; - public: // related segment number // -1 means the completion is not related to segment int segment_number = -1; - double wellPi = 1.0; + double wPi = 1.0; }; } #endif /* COMPLETION_HPP_ */ + diff --git a/opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp b/opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp index c651edf38..3b28e77f6 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp @@ -35,10 +35,9 @@ namespace Opm { void addConnection(int i, int j , int k , double depth, WellCompletion::StateEnum state , - const Value& connectionTransmissibilityFactor, - const Value& diameter, - const Value& skinFactor, - const Value& Kh, + double CF, + double Kh, + double rw, const int satTableId, const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z); void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties); @@ -47,6 +46,7 @@ namespace Opm { void add( Connection ); size_t size() const; + const Connection& operator[](size_t index) const; const Connection& get(size_t index) const; const Connection& getFromIJK(const int i, const int j, const int k) const; Connection& getFromIJK(const int i, const int j, const int k); @@ -77,10 +77,9 @@ namespace Opm { int complnum, double depth, WellCompletion::StateEnum state , - const Value& connectionTransmissibilityFactor, - const Value& diameter, - const Value& skinFactor, - const Value& Kh, + double CF, + double Kh, + double rw, const int satTableId, const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z); diff --git a/src/opm/output/eclipse/RestartIO.cpp b/src/opm/output/eclipse/RestartIO.cpp index 755f10224..226f83bff 100644 --- a/src/opm/output/eclipse/RestartIO.cpp +++ b/src/opm/output/eclipse/RestartIO.cpp @@ -206,7 +206,7 @@ data::Wells restore_wells( const ecl_kw_type * opm_xwel, for( const auto& sc : sched_well->getConnections( sim_step ) ) { const auto i = sc.getI(), j = sc.getJ(), k = sc.getK(); - if( !grid.cellActive( i, j, k ) || sc.state == WellCompletion::SHUT ) { + if( !grid.cellActive( i, j, k ) || sc.state() == WellCompletion::SHUT ) { opm_xwel_data += data::Connection::restart_size + phases.size(); continue; } @@ -310,10 +310,10 @@ std::vector serialize_ICON( int sim_step, 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; + data[ offset + ICON_DIRECTION_INDEX ] = connection.dir(); { const auto open = WellCompletion::StateEnum::OPEN; - data[ offset + ICON_STATUS_INDEX ] = connection.state == open + data[ offset + ICON_STATUS_INDEX ] = connection.state() == open ? 1 : 0; } @@ -408,7 +408,7 @@ std::vector< double > serialize_OPM_XWEL( const data::Wells& wells, const auto i = sc.getI(), j = sc.getJ(), k = sc.getK(); const auto rs_size = phases.size() + data::Connection::restart_size; - if( !grid.cellActive( i, j, k ) || sc.state == WellCompletion::SHUT ) { + if( !grid.cellActive( i, j, k ) || sc.state() == WellCompletion::SHUT ) { xwel.insert( xwel.end(), rs_size, 0.0 ); continue; } diff --git a/src/opm/output/eclipse/WellDataSerializers.cpp b/src/opm/output/eclipse/WellDataSerializers.cpp index da3cdb7e1..d13a17517 100644 --- a/src/opm/output/eclipse/WellDataSerializers.cpp +++ b/src/opm/output/eclipse/WellDataSerializers.cpp @@ -42,29 +42,8 @@ serialize_SCON(int lookup_step, bool explicit_ctf_not_found = false; for (const auto& connection : connections) { const size_t offset = well_offset + connection_offset; - const auto& ctf = connection.getConnectionTransmissibilityFactorAsValueObject(); - if (ctf.hasValue()) { - // CTF explicitly set in deck, overrides calculation - // from Peaceman model. We should also give the Kh - // factor, we output an explicitly invalid value - // instead. This is acceptable since it will not be - // used (the explicit CTF factor is used instead). - const double ctf_SI = ctf.getValue(); - const double ctf_output = units.from_si(UnitSystem::measure::transmissibility, ctf_SI); - data[ offset + SCON_CF_INDEX ] = ctf_output; - data[ offset + SCON_KH_INDEX ] = UNIMPLEMENTED_VALUE; - } else { - // CTF not set in deck, Peaceman formula used to - // compute it. Here we should store the data for the - // connection required to recalculate the CTF (the Kh - // factor), as well as the actual CTF used by the - // simulator, but that requires access to more data - // from the simulator. As an interim measure we write - // invalid values and give a warning. - data[ offset + SCON_CF_INDEX ] = UNIMPLEMENTED_VALUE; - data[ offset + SCON_KH_INDEX ] = UNIMPLEMENTED_VALUE; - explicit_ctf_not_found = true; - } + data[ offset + SCON_CF_INDEX ] = units.from_si(Opm::UnitSystem::measure::transmissibility,connection.CF()); + data[ offset + SCON_KH_INDEX ] = units.from_si(Opm::UnitSystem::measure::effective_Kh, connection.Kh()); connection_offset += nsconz; } if (explicit_ctf_not_found) { @@ -73,7 +52,7 @@ serialize_SCON(int lookup_step, } well_offset += well_field_size; } - return data; + return data; } // ---------------------------------------------------------------------------- @@ -83,7 +62,7 @@ serialize_ICON(int lookup_step, int ncwmax, int niconz, const std::vector& sched_wells) -// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- { const size_t well_field_size = ncwmax * niconz; std::vector data(sched_wells.size() * well_field_size, 0); @@ -94,17 +73,17 @@ serialize_ICON(int lookup_step, for (const auto& connection : connections) { const size_t offset = well_offset + connection_offset; - data[ offset + ICON_IC_INDEX ] = connection.complnum; + data[ offset + ICON_IC_INDEX ] = connection.complnum(); 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; + data[ offset + ICON_DIRECTION_INDEX ] = connection.dir(); data[ offset + ICON_STATUS_INDEX ] = - (connection.state == WellCompletion::StateEnum::OPEN) ? + (connection.state() == WellCompletion::StateEnum::OPEN) ? 1 : -1000; data[ offset + ICON_SEGMENT_INDEX ] = connection.attachedToSegment() ? - connection.segment_number : 0; + connection.segment() : 0; connection_offset += niconz; } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp index f608f6670..8086b6e53 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -36,26 +35,25 @@ namespace Opm { + Connection::Connection(int i, int j , int k , int compnum, double depth, WellCompletion::StateEnum stateArg , - const Value& connectionTransmissibilityFactor, - const Value& diameter, - const Value& skinFactor, - const Value& Kh, + double CF, + double Kh, + double rw, const int satTableId, const WellCompletion::DirectionEnum direction) - : dir(direction), + : direction(direction), center_depth(depth), - state(stateArg), + open_state(stateArg), sat_tableId(satTableId), - complnum( compnum ), - ijk({i,j,k}), - m_diameter(diameter), - m_connectionTransmissibilityFactor(connectionTransmissibilityFactor), - m_skinFactor(skinFactor), - m_Kh(Kh) + m_complnum( compnum ), + m_CF(CF), + m_Kh(Kh), + m_rw(rw), + ijk({i,j,k}) {} bool Connection::sameCoordinate(const int i, const int j, const int k) const { @@ -80,42 +78,77 @@ namespace Opm { return ijk[2]; } - - double Connection::getConnectionTransmissibilityFactor() const { - return m_connectionTransmissibilityFactor.getValue(); - } - - double Connection::getDiameter() const { - return m_diameter.getValue(); - } - - double Connection::getSkinFactor() const { - return m_skinFactor.getValue(); - } - - - const Value& Connection::getConnectionTransmissibilityFactorAsValueObject() const { - return m_connectionTransmissibilityFactor; - } - - const Value& Connection::getEffectiveKhAsValueObject() const { - return m_Kh; - } - bool Connection::attachedToSegment() const { return (segment_number > 0); } + WellCompletion::DirectionEnum Connection::dir() const { + return this->direction; + } + + double Connection::depth() const { + return this->center_depth; + } + + WellCompletion::StateEnum Connection::state() const { + return this->open_state; + } + + int Connection::satTableId() const { + return this->sat_tableId; + } + + int Connection::complnum() const { + return this->m_complnum; + } + + void Connection::setComplnum(int complnum) { + this->m_complnum = complnum; + } + + double Connection::CF() const { + return this->m_CF; + } + + double Connection::Kh() const { + return this->m_Kh; + } + + double Connection::rw() const { + return this->m_rw; + } + + void Connection::setState(WellCompletion::StateEnum state) { + this->open_state = state; + } + + void Connection::updateSegment(int segment_number, double center_depth) { + this->segment_number = segment_number; + this->center_depth = center_depth; + } + + int Connection::segment() const { + return this->segment_number; + } + + void Connection::scaleWellPi(double wellPi) { + this->wPi *= wellPi; + } + + double Connection::wellPi() const { + return this->wPi; + } + bool Connection::operator==( const Connection& rhs ) const { return this->ijk == rhs.ijk - && this->complnum == rhs.complnum - && this->m_diameter == rhs.m_diameter - && this->m_connectionTransmissibilityFactor == rhs.m_connectionTransmissibilityFactor - && this->wellPi == rhs.wellPi - && this->m_skinFactor == rhs.m_skinFactor + && this->m_complnum == rhs.m_complnum + && this->m_CF == rhs.m_CF + && this->m_rw == rhs.m_rw + && this->wPi == rhs.wPi + && this->m_Kh == rhs.m_Kh && this->sat_tableId == rhs.sat_tableId - && this->state == rhs.state - && this->dir == rhs.dir + && this->open_state == rhs.open_state + && this->direction == rhs.direction && this->segment_number == rhs.segment_number && this->center_depth == rhs.center_depth; } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp index bbf91d4b3..ed53b8f6b 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp @@ -239,8 +239,7 @@ namespace Opm { const int k = compseg.m_k; Connection& connection = connection_set.getFromIJK( i, j, k ); - connection.segment_number = compseg.segment_number; - connection.center_depth = compseg.center_depth; + connection.updateSegment(compseg.segment_number, compseg.center_depth); } for (size_t ic = 0; ic < connection_set.size(); ++ic) { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp index 54c36cf8a..90347460a 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp @@ -335,7 +335,7 @@ namespace Opm { + ". Can not infer reference depth" ); } - return completions.get( 0 ).center_depth; + return completions.get( 0 ).depth(); } void Well::setRefDepth( size_t timestep, double depth ) { @@ -356,11 +356,11 @@ namespace Opm { const auto& connections = this->getConnections(time_step); for (const auto& conn : connections) { - auto pair = completions.find( conn.complnum ); + auto pair = completions.find( conn.complnum() ); if (pair == completions.end()) - completions[conn.complnum] = {}; + completions[conn.complnum()] = {}; - pair = completions.find(conn.complnum); + pair = completions.find(conn.complnum()); pair->second.push_back(conn); } @@ -641,7 +641,7 @@ namespace Opm { for (auto c : this->getConnections(time_step)) { if (match(c)) - c.complnum = complnum; + c.setComplnum( complnum ); new_connections->add(c); } @@ -654,8 +654,8 @@ namespace Opm { if (!match_eq(c.getI(), record, "I" , -1)) return false; if (!match_eq(c.getJ(), record, "J" , -1)) return false; if (!match_eq(c.getK(), record, "K", -1)) return false; - if (!match_ge(c.complnum, record, "C1")) return false; - if (!match_le(c.complnum, record, "C2")) return false; + if (!match_ge(c.complnum(), record, "C1")) return false; + if (!match_le(c.complnum(), record, "C2")) return false; return true; }; @@ -664,7 +664,7 @@ namespace Opm { for (auto c : this->getConnections(time_step)) { if (match(c)) - c.state = status; + c.setState( status ); new_connections->add(c); } @@ -692,8 +692,8 @@ namespace Opm { void Well::handleWPIMULT(const DeckRecord& record, size_t time_step) { auto match = [=]( const Connection &c) -> bool { - if (!match_ge(c.complnum, record, "FIRST")) return false; - if (!match_le(c.complnum, record, "LAST")) return false; + if (!match_ge(c.complnum(), record, "FIRST")) return false; + if (!match_le(c.complnum(), record, "LAST")) return false; if (!match_eq(c.getI() , record, "I", -1)) return false; if (!match_eq(c.getJ() , record, "J", -1)) return false; if (!match_eq(c.getK() , record, "K", -1)) return false; @@ -706,7 +706,7 @@ namespace Opm { for (auto c : this->getConnections(time_step)) { if (match(c)) - c.wellPi *= wellPi; + c.scaleWellPi( wellPi ); new_connections->add(c); } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp index 523426f54..3ed6e75b6 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -58,7 +59,7 @@ namespace { // completion's direction. inline std::array permComponents(const Opm::WellCompletion::DirectionEnum direction, - const std::array perm) + const std::array& perm) { const auto p = directionIndices(direction); @@ -131,17 +132,16 @@ namespace { void WellConnections::addConnection(int i, int j , int k , int complnum, double depth, - WellCompletion::StateEnum state , - const Value& connectionTransmissibilityFactor, - const Value& diameter, - const Value& skinFactor, - const Value& Kh, + WellCompletion::StateEnum state, + double CF, + double Kh, + double rw, const int satTableId, const WellCompletion::DirectionEnum direction) { 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, connectionTransmissibilityFactor, diameter, skinFactor, Kh, satTableId, direction); + Connection conn(conn_i, conn_j, k, complnum, depth, state, CF, Kh, rw, satTableId, direction); this->add(conn); } @@ -150,10 +150,9 @@ namespace { void WellConnections::addConnection(int i, int j , int k , double depth, WellCompletion::StateEnum state , - const Value& connectionTransmissibilityFactor, - const Value& diameter, - const Value& skinFactor, - const Value& Kh, + double CF, + double Kh, + double rw, const int satTableId, const WellCompletion::DirectionEnum direction) { @@ -164,15 +163,19 @@ namespace { complnum, depth, state, - connectionTransmissibilityFactor, - diameter, - skinFactor, + CF, Kh, + rw, satTableId, direction); } void WellConnections::loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) { + const auto& permx = eclipseProperties.getDoubleGridProperty("PERMX").getData(); + const auto& permy = eclipseProperties.getDoubleGridProperty("PERMY").getData(); + const auto& permz = eclipseProperties.getDoubleGridProperty("PERMZ").getData(); + const auto& ntg = eclipseProperties.getDoubleGridProperty("NTG").getData(); + const auto& itemI = record.getItem( "I" ); const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0; const int I = !defaulted_I ? itemI.get< int >( 0 ) - 1 : this->headI; @@ -184,42 +187,37 @@ namespace { int K1 = record.getItem("K1").get< int >(0) - 1; int K2 = record.getItem("K2").get< int >(0) - 1; WellCompletion::StateEnum state = WellCompletion::StateEnumFromString( record.getItem("STATE").getTrimmedString(0) ); - Value connectionTransmissibilityFactor("CompletionTransmissibilityFactor"); - Value diameter("Diameter"); - Value skinFactor("SkinFactor"); - Value Kh("Kh"); + const auto& satnum = eclipseProperties.getIntGridProperty("SATNUM"); int satTableId = -1; bool defaultSatTable = true; + const auto& CFItem = record.getItem("CONNECTION_TRANSMISSIBILITY_FACTOR"); + const auto& diameterItem = record.getItem("DIAMETER"); + const auto& KhItem = record.getItem("Kh"); + const auto& satTableIdItem = record.getItem("SAT_TABLE"); + const auto& r0Item = record.getItem("PR"); + const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnumFromString(record.getItem("DIR").getTrimmedString(0)); + double skin_factor = record.getItem("SKIN").getSIDouble(0); + double rw; + + if (satTableIdItem.hasValue(0) && satTableIdItem.get < int > (0) > 0) { - const auto& connectionTransmissibilityFactorItem = record.getItem("CONNECTION_TRANSMISSIBILITY_FACTOR"); - const auto& diameterItem = record.getItem("DIAMETER"); - const auto& skinFactorItem = record.getItem("SKIN"); - const auto& KhItem = record.getItem("Kh"); - const auto& satTableIdItem = record.getItem("SAT_TABLE"); - - if (connectionTransmissibilityFactorItem.hasValue(0) && connectionTransmissibilityFactorItem.getSIDouble(0) > 0) - connectionTransmissibilityFactor.setValue(connectionTransmissibilityFactorItem.getSIDouble(0)); - - if (diameterItem.hasValue(0)) - diameter.setValue( diameterItem.getSIDouble(0)); - - if (skinFactorItem.hasValue(0)) - skinFactor.setValue( skinFactorItem.get< double >(0)); - - if (KhItem.hasValue(0) && (KhItem.get< double >(0) > 0.0)) - Kh.setValue( KhItem.getSIDouble(0)); - - if (satTableIdItem.hasValue(0) && satTableIdItem.get < int > (0) > 0) - { - satTableId = satTableIdItem.get< int >(0); - defaultSatTable = false; - } + satTableId = satTableIdItem.get< int >(0); + defaultSatTable = false; } - const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnumFromString(record.getItem("DIR").getTrimmedString(0)); + if (diameterItem.hasValue(0)) + rw = 0.50 * diameterItem.getSIDouble(0); + else + // The Eclipse100 manual does not specify a default value for the wellbore + // diameter, but the Opm codebase has traditionally implemented a default + // value of one foot. The same default value is used by Eclipse300. + rw = 0.5*unit::feet; for (int k = K1; k <= K2; k++) { + double CF = -1; + double Kh = -1; + if (defaultSatTable) satTableId = satnum.iget(grid.getGlobalIndex(I,J,k)); @@ -227,6 +225,50 @@ namespace { return c.sameCoordinate( I,J,k ); }; + if (KhItem.hasValue(0) && KhItem.getSIDouble(0) > 0.0) + Kh = KhItem.getSIDouble(0); + + if (CFItem.hasValue(0) && CFItem.getSIDouble(0) > 0.0) + CF = CFItem.getSIDouble(0); + + /* We start with the absolute happy path; both CF and Kh are explicitly given in the deck. */ + if (CF > 0 && Kh > 0) + goto CF_done; + + + /* We must calculate CF and Kh from the items in the COMPDAT record and cell properties. */ + { + // Angle of completion exposed to flow. We assume centre + // placement so there's complete exposure (= 2\pi). + const double angle = 6.2831853071795864769252867665590057683943387987502116419498; + size_t global_index = grid.getGlobalIndex(I,J,k); + std::array cell_perm = {{ permx[global_index], permy[global_index], permz[global_index]}}; + std::array cell_size = grid.getCellDims(global_index); + double r0; + const auto& K = permComponents(direction, cell_perm); + const auto& D = effectiveExtent(direction, ntg[global_index], cell_size); + + if (r0Item.hasValue(0)) + r0 = r0Item.getSIDouble(0); + else + r0 = effectiveRadius(K,D); + + if (CF < 0) { + if (Kh < 0) + Kh = std::sqrt(K[0] * K[1]) * D[2]; + CF = angle * Kh / (std::log(r0 / std::min(rw, r0)) + skin_factor); + } else { + if (KhItem.defaultApplied(0) || KhItem.getSIDouble(0) < 0) { + Kh = CF * (std::log(r0 / std::min(r0, rw)) + skin_factor) / angle; + } else { + if (Kh < 0) + Kh = std::sqrt(K[0] * K[1]) * D[2]; + } + } + } + + + CF_done: auto prev = std::find_if( this->m_connections.begin(), this->m_connections.end(), same_ijk ); @@ -235,24 +277,22 @@ namespace { this->addConnection(I,J,k, grid.getCellDepth( I,J,k ), state, - connectionTransmissibilityFactor, - diameter, - skinFactor, + CF, Kh, + rw, satTableId, direction ); } else { // The complnum value carries over; the rest of the state is fully specified by // the current COMPDAT keyword. - int complnum = prev->complnum; + int complnum = prev->complnum(); *prev = Connection(I,J,k, complnum, grid.getCellDepth(I,J,k), state, - connectionTransmissibilityFactor, - diameter, - skinFactor, + CF, Kh, + rw, satTableId, direction ); } @@ -267,9 +307,14 @@ namespace { } const Connection& WellConnections::get(size_t index) const { - return this->m_connections.at( index ); + return (*this)[index]; } + const Connection& WellConnections::operator[](size_t index) const { + return this->m_connections.at(index); + } + + const Connection& WellConnections::getFromIJK(const int i, const int j, const int k) const { for (size_t ic = 0; ic < size(); ++ic) { if (get(ic).sameCoordinate(i, j, k)) { @@ -296,7 +341,7 @@ namespace { bool WellConnections::allConnectionsShut( ) const { auto shut = []( const Connection& c ) { - return c.state == WellCompletion::StateEnum::SHUT; + return c.state() == WellCompletion::StateEnum::SHUT; }; return std::all_of( this->m_connections.begin(), @@ -327,7 +372,7 @@ namespace { for (size_t pos = 1; pos < m_connections.size() - 1; ++pos) { const auto& prev = m_connections[pos - 1]; - const double prevz = prev.center_depth; + const double prevz = prev.depth(); size_t next_index = findClosestConnection(prev.getI(), prev.getJ(), prevz, pos); std::swap(m_connections[next_index], m_connections[pos]); } @@ -343,7 +388,7 @@ namespace { for (size_t pos = start_pos; pos < m_connections.size(); ++pos) { const auto& connection = m_connections[ pos ]; - const double depth = connection.center_depth; + const double depth = connection.depth(); const int ci = connection.getI(); const int cj = connection.getJ(); // Using square of distance to avoid non-integer arithmetics. diff --git a/tests/parser/ConnectionTests.cpp b/tests/parser/ConnectionTests.cpp index 98536c831..3907b6cf4 100644 --- a/tests/parser/ConnectionTests.cpp +++ b/tests/parser/ConnectionTests.cpp @@ -27,7 +27,8 @@ - +#include +#include #include #include #include @@ -36,6 +37,9 @@ #include #include #include +#include + +#include namespace Opm { @@ -54,22 +58,6 @@ inline std::ostream& operator<<( std::ostream& stream, const WellConnections& cs -BOOST_AUTO_TEST_CASE(testGetFunctions) { - Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z; - Opm::Connection completion(10,11,12, 1, 0.0, Opm::WellCompletion::OPEN,Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",17.29), 0, dir); - BOOST_CHECK_EQUAL( 10 , completion.getI() ); - BOOST_CHECK_EQUAL( 11 , completion.getJ() ); - BOOST_CHECK_EQUAL( 12 , completion.getK() ); - - BOOST_CHECK_EQUAL( Opm::WellCompletion::OPEN , completion.state); - BOOST_CHECK_EQUAL( 99.88 , completion.getConnectionTransmissibilityFactor()); - BOOST_CHECK_EQUAL( 22.33 , completion.getDiameter()); - BOOST_CHECK_EQUAL( 33.22 , completion.getSkinFactor()); - BOOST_CHECK_CLOSE( 17.29 , completion.getEffectiveKhAsValueObject().getValue() , 1.0e-10); - BOOST_CHECK_EQUAL( 0 , completion.sat_tableId); -} - - BOOST_AUTO_TEST_CASE(CreateWellConnectionsOK) { Opm::WellConnections completionSet; @@ -81,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 , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",2.718), 0, dir); - Opm::Connection completion2( 11,10,10, 1, 0.0,Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",3.141), 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); + Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , 99.88, 355.113, 0.25, 0, dir); +completionSet.add( completion1 ); BOOST_CHECK_EQUAL( 1U , completionSet.size() ); completionSet.add( completion2 ); @@ -95,9 +83,9 @@ BOOST_AUTO_TEST_CASE(AddCompletionSizeCorrect) { 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::WellConnections completionSet; - Opm::Connection completion1( 10,10,10,1, 0.0,Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",17.29), 0, dir); - Opm::Connection completion2( 11,10,10,1, 0.0,Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); completionSet.add( completion1 ); BOOST_CHECK_EQUAL( 1U , completionSet.size() ); @@ -115,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 , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); - Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); - Opm::Connection completion3( 10,10,12, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); + 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); completionSet.add( completion1 ); completionSet.add( completion2 ); @@ -134,12 +122,12 @@ BOOST_AUTO_TEST_CASE(AddCompletionCopy) { BOOST_AUTO_TEST_CASE(ActiveCompletions) { - Opm::EclipseGrid grid(10,10,10); + 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 , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); - Opm::Connection completion2( 0,0,1, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); - Opm::Connection completion3( 0,0,2, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value("ConnectionTransmissibilityFactor",99.88), Opm::Value("D",22.33), Opm::Value("SKIN",33.22), Opm::Value("Kh",355.113), 0, dir); + 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); completions.add( completion1 ); completions.add( completion2 ); @@ -154,3 +142,187 @@ BOOST_AUTO_TEST_CASE(ActiveCompletions) { BOOST_CHECK_EQUAL( completion2, active_completions.get(0)); BOOST_CHECK_EQUAL( completion3, active_completions.get(1)); } + +Opm::WellConnections loadCOMPDAT(const std::string& compdat_keyword) { + Opm::EclipseGrid grid(10,10,10); + Opm::TableManager tables; + Opm::Parser parser; + const auto deck = parser.parseString(compdat_keyword, Opm::ParseContext()); + Opm::Eclipse3DProperties props(deck, tables, grid ); + const auto& keyword = deck.getKeyword("COMPDAT", 0); + Opm::WellConnections connections; + for (const auto& rec : keyword) + connections.loadCOMPDAT(rec, grid, props); + + return connections; +} + +BOOST_AUTO_TEST_CASE(loadCOMPDATTEST) { + Opm::UnitSystem units(Opm::UnitSystem::UnitType::UNIT_TYPE_METRIC); // Unit system used in deck FIRST_SIM.DATA. + { + const std::string deck = R"(COMPDAT +-- CF Diam Kh Skin Df + 'WELL' 1 1 1 1 'OPEN' 1* 1.168 0.311 107.872 1* 1* 'Z' 21.925 / +/)"; + Opm::WellConnections connections = loadCOMPDAT(deck); + const auto& conn0 = connections[0]; + BOOST_CHECK_EQUAL(conn0.CF(), units.to_si(Opm::UnitSystem::measure::transmissibility, 1.168)); + BOOST_CHECK_EQUAL(conn0.Kh(), units.to_si(Opm::UnitSystem::measure::effective_Kh, 107.872)); + } + + { + const std::string deck = R"(GRID + +PERMX + 1000*0.10 / + +COPY + 'PERMX' 'PERMZ' / + 'PERMX' 'PERMY' / +/ + +SCHEDULE + +COMPDAT +-- CF Diam Kh Skin Df +'WELL' 1 1 1 1 'OPEN' 1* 1.168 0.311 0 1* 1* 'Z' 21.925 / +/)"; + Opm::WellConnections connections = loadCOMPDAT(deck); + const auto& conn0 = connections[0]; + BOOST_CHECK_EQUAL(conn0.CF(), units.to_si(Opm::UnitSystem::measure::transmissibility, 1.168)); + BOOST_CHECK_EQUAL(conn0.Kh(), units.to_si(Opm::UnitSystem::measure::effective_Kh, 0.10 * 1.0)); + } +} + + +BOOST_AUTO_TEST_CASE(loadCOMPDATTESTSPE1) { + Opm::ParseContext parseContext; + Opm::Parser parser; + + const auto deck = parser.parseFile("SPE1CASE1.DATA", parseContext); + Opm::EclipseState state(deck, parseContext); + Opm::Schedule sched(deck, state, parseContext); + const auto& units = deck.getActiveUnitSystem(); + + const auto& prod = sched.getWell("PROD"); + const auto& connections = prod->getConnections(0); + const auto& conn0 = connections[0]; + /* Expected values come from Eclipse simulation. */ + BOOST_CHECK_CLOSE(conn0.CF(), units.to_si(Opm::UnitSystem::measure::transmissibility, 10.609), 2e-2); + BOOST_CHECK_CLOSE(conn0.Kh(), units.to_si(Opm::UnitSystem::measure::effective_Kh, 10000), 1e-6); +} + + +struct exp_conn { + std::string well; + int ci; + double CF; + double Kh; +}; + +BOOST_AUTO_TEST_CASE(loadCOMPDATTESTSPE9) { + Opm::ParseContext parseContext; + Opm::Parser parser; + + const auto deck = parser.parseFile("SPE9_CP_PACKED.DATA", parseContext); + Opm::EclipseState state(deck, parseContext); + Opm::Schedule sched(deck, state, parseContext); + const auto& units = deck.getActiveUnitSystem(); +/* + The list of the expected values come from the PRT file in an ECLIPSE simulation. +*/ + std::vector expected = { + {"INJE1" ,1 , 0.166, 111.9}, + {"INJE1" ,2 , 0.597, 402.6}, + {"INJE1" ,3 , 1.866, 1259.2}, + {"INJE1" ,4 , 12.442, 8394.2}, + {"INJE1" ,5 , 6.974, 4705.3}, + + {"PRODU2" ,1 , 0.893, 602.8}, + {"PRODU2" ,2 , 3.828, 2582.8}, + {"PRODU2" ,3 , 0.563, 380.0}, + + {"PRODU3" ,1 , 1.322, 892.1}, + {"PRODU3" ,2 , 3.416, 2304.4}, + + {"PRODU4" ,1 , 4.137, 2791.2}, + {"PRODU4" ,2 , 66.455, 44834.7}, + + {"PRODU5" ,1 , 0.391, 264.0}, + {"PRODU5" ,2 , 7.282, 4912.6}, + {"PRODU5" ,3 , 1.374, 927.3}, + + {"PRODU6" ,1 , 1.463, 987.3}, + {"PRODU6" ,2 , 1.891, 1275.8}, + + {"PRODU7" ,1 , 1.061, 716.1}, + {"PRODU7" ,2 , 5.902, 3982.0}, + {"PRODU7" ,3 , 0.593, 400.1}, + + {"PRODU8" ,1 , 0.993, 670.1}, + {"PRODU8" ,2 , 17.759, 11981.5}, + + {"PRODU9" ,1 , 0.996, 671.9}, + {"PRODU9" ,2 , 2.548, 1719.0}, + + {"PRODU10" ,1 , 11.641, 7853.9}, + {"PRODU10" ,2 , 7.358, 4964.1}, + {"PRODU10" ,3 , 0.390, 262.8}, + + {"PRODU11" ,2 , 3.536, 2385.6}, + + {"PRODU12" ,1 , 3.028, 2043.1}, + {"PRODU12" ,2 , 0.301, 202.7}, + {"PRODU12" ,3 , 0.279, 188.3}, + + {"PRODU13" ,2 , 5.837, 3938.1}, + + {"PRODU14" ,1 , 180.976, 122098.1}, + {"PRODU14" ,2 , 25.134, 16957.0}, + {"PRODU14" ,3 , 0.532, 358.7}, + + {"PRODU15" ,1 , 4.125, 2783.1}, + {"PRODU15" ,2 , 6.431, 4338.7}, + + {"PRODU16" ,2 , 5.892, 3975.0}, + + {"PRODU17" ,1 , 80.655, 54414.9}, + {"PRODU17" ,2 , 9.098, 6138.3}, + + {"PRODU18" ,1 , 1.267, 855.1}, + {"PRODU18" ,2 , 18.556, 12518.9}, + + {"PRODU19" ,1 , 15.589, 10517.2}, + {"PRODU19" ,3 , 1.273, 859.1}, + + {"PRODU20" ,1 , 3.410, 2300.5}, + {"PRODU20" ,2 , 0.191, 128.8}, + {"PRODU20" ,3 , 0.249, 168.1}, + + {"PRODU21" ,1 , 0.596, 402.0}, + {"PRODU21" ,2 , 0.163, 109.9}, + + {"PRODU22" ,1 , 4.021, 2712.8}, + {"PRODU22" ,2 , 0.663, 447.1}, + + {"PRODU23" ,1 , 1.542, 1040.2}, + + {"PRODU24" ,1 , 78.939, 53257.0}, + {"PRODU24" ,3 , 17.517, 11817.8}, + + {"PRODU25" ,1 , 3.038, 2049.5}, + {"PRODU25" ,2 , 0.926, 624.9}, + {"PRODU25" ,3 , 0.891, 601.3}, + + {"PRODU26" ,1 , 0.770, 519.6}, + {"PRODU26" ,3 , 0.176, 118.6}}; + + for (const auto& ec : expected) { + const auto& well = sched.getWell(ec.well); + const auto& connections = well->getConnections(0); + const auto& conn = connections[ec.ci - 1]; + + BOOST_CHECK_CLOSE( conn.CF(), units.to_si(Opm::UnitSystem::measure::transmissibility, ec.CF), 2e-1); + BOOST_CHECK_CLOSE( conn.Kh(), units.to_si(Opm::UnitSystem::measure::effective_Kh, ec.Kh), 1e-1); + } +} diff --git a/tests/parser/MultisegmentWellTests.cpp b/tests/parser/MultisegmentWellTests.cpp index 41ef05514..25e252546 100644 --- a/tests/parser/MultisegmentWellTests.cpp +++ b/tests/parser/MultisegmentWellTests.cpp @@ -43,15 +43,15 @@ 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 , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.5), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 0, dir) ); - connection_set.add(Opm::Connection( 19, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.5), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 0, dir) ); - connection_set.add(Opm::Connection( 19, 0, 2, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.4), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 0, dir) ); + 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( 18, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.4), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 0, Opm::WellCompletion::DirectionEnum::X) ); - connection_set.add(Opm::Connection( 17, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.4), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 0, Opm::WellCompletion::DirectionEnum::X) ); - connection_set.add(Opm::Connection( 16, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.4), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 0, Opm::WellCompletion::DirectionEnum::X) ); - connection_set.add(Opm::Connection( 15, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value("ConnectionTransmissibilityFactor", 200.), Opm::Value("D", 0.4), Opm::Value("SKIN", 0.), Opm::Value("Kh", 17.29), 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) ); + 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) ); BOOST_CHECK_EQUAL( 7U , connection_set.size() ); @@ -93,32 +93,32 @@ Opm::WellConnections connection_set; BOOST_CHECK_EQUAL(7U, new_connection_set->size()); const Opm::Connection& connection1 = new_connection_set->get(0); - const int segment_number_connection1 = connection1.segment_number; - const double center_depth_connection1 = connection1.center_depth; + const int segment_number_connection1 = connection1.segment(); + const double center_depth_connection1 = connection1.depth(); BOOST_CHECK_EQUAL(segment_number_connection1, 1); BOOST_CHECK_EQUAL(center_depth_connection1, 2512.5); const Opm::Connection& connection3 = new_connection_set->get(2); - const int segment_number_connection3 = connection3.segment_number; - const double center_depth_connection3 = connection3.center_depth; + const int segment_number_connection3 = connection3.segment(); + const double center_depth_connection3 = connection3.depth(); BOOST_CHECK_EQUAL(segment_number_connection3, 3); BOOST_CHECK_EQUAL(center_depth_connection3, 2562.5); const Opm::Connection& connection5 = new_connection_set->get(4); - const int segment_number_connection5 = connection5.segment_number; - const double center_depth_connection5 = connection5.center_depth; + const int segment_number_connection5 = connection5.segment(); + const double center_depth_connection5 = connection5.depth(); BOOST_CHECK_EQUAL(segment_number_connection5, 6); BOOST_CHECK_CLOSE(center_depth_connection5, 2538.83, 0.001); const Opm::Connection& connection6 = new_connection_set->get(5); - const int segment_number_connection6 = connection6.segment_number; - const double center_depth_connection6 = connection6.center_depth; + const int segment_number_connection6 = connection6.segment(); + const double center_depth_connection6 = connection6.depth(); BOOST_CHECK_EQUAL(segment_number_connection6, 6); BOOST_CHECK_CLOSE(center_depth_connection6, 2537.83, 0.001); const Opm::Connection& connection7 = new_connection_set->get(6); - const int segment_number_connection7 = connection7.segment_number; - const double center_depth_connection7 = connection7.center_depth; + const int segment_number_connection7 = connection7.segment(); + const double center_depth_connection7 = connection7.depth(); BOOST_CHECK_EQUAL(segment_number_connection7, 7); BOOST_CHECK_EQUAL(center_depth_connection7, 2534.5); } diff --git a/tests/parser/ScheduleTests.cpp b/tests/parser/ScheduleTests.cpp index 8aca43705..801e7ead6 100644 --- a/tests/parser/ScheduleTests.cpp +++ b/tests/parser/ScheduleTests.cpp @@ -654,25 +654,25 @@ BOOST_AUTO_TEST_CASE(CreateScheduleDeckWellsAndConnectionDataWithWELOPEN) { constexpr auto open = WellCompletion::StateEnum::OPEN; BOOST_CHECK_EQUAL( 7U, cs.size() ); - BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 2 ).state); - BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 3 ).state); - BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 4 ).state); - BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 7, 2 ).state); + BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 2 ).state()); + BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 3 ).state()); + BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 4 ).state()); + BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 7, 2 ).state()); const auto& cs2 = well->getConnections( 4 ); - BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 2 ).state); - BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 3 ).state); - BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 4 ).state); - BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 7, 2 ).state); + BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 2 ).state()); + BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 3 ).state()); + BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 4 ).state()); + BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 7, 2 ).state()); well = schedule.getWell("OP_3"); const auto& cs3 = well->getConnections( 3 ); - BOOST_CHECK_EQUAL(shut, cs3.get( 0 ).state); + BOOST_CHECK_EQUAL(shut, cs3.get( 0 ).state()); const auto& cs4 = well->getConnections( 4 ); - BOOST_CHECK_EQUAL(open, cs4.get( 0 ).state); + BOOST_CHECK_EQUAL(open, cs4.get( 0 ).state()); well = schedule.getWell("OP_1"); BOOST_CHECK_EQUAL(WellCommon::StatusEnum::SHUT, well->getStatus( 3 )); @@ -1072,17 +1072,17 @@ BOOST_AUTO_TEST_CASE(createDeckWithWPIMULT) { const auto& cs2 = well->getConnections( 2 ); for(size_t i = 0; i < cs2.size(); i++) { - BOOST_CHECK_EQUAL(cs2.get( i ).wellPi, 1.3); + BOOST_CHECK_EQUAL(cs2.get( i ).wellPi(), 1.3); } const auto& cs3 = well->getConnections( 3 ); for(size_t i = 0; i < cs3.size(); i++ ) { - BOOST_CHECK_EQUAL(cs3.get( i ).wellPi, (1.3*1.3)); + BOOST_CHECK_EQUAL(cs3.get( i ).wellPi(), (1.3*1.3)); } const auto& cs4 = well->getConnections( 4 ); for(size_t i = 0; i < cs4.size(); i++ ) { - BOOST_CHECK_EQUAL(cs4.get( i ).wellPi, 1.0); + BOOST_CHECK_EQUAL(cs4.get( i ).wellPi(), 1.0); } } @@ -1673,16 +1673,16 @@ BOOST_AUTO_TEST_CASE( COMPDAT_sets_automatic_complnum ) { Schedule schedule( deck, grid, eclipseProperties, Phases( true, true, true ) ,ctx); const auto& cs1 = schedule.getWell( "W1" )->getConnections( 1 ); - BOOST_CHECK_EQUAL( -1, cs1.get( 0 ).complnum ); - BOOST_CHECK_EQUAL( -2, cs1.get( 1 ).complnum ); - BOOST_CHECK_EQUAL( -3, cs1.get( 2 ).complnum ); - BOOST_CHECK_EQUAL( -4, cs1.get( 3 ).complnum ); + BOOST_CHECK_EQUAL( -1, cs1.get( 0 ).complnum() ); + BOOST_CHECK_EQUAL( -2, cs1.get( 1 ).complnum() ); + BOOST_CHECK_EQUAL( -3, cs1.get( 2 ).complnum() ); + BOOST_CHECK_EQUAL( -4, cs1.get( 3 ).complnum() ); const auto& cs2 = schedule.getWell( "W1" )->getConnections( 2 ); - BOOST_CHECK_EQUAL( -1, cs2.get( 0 ).complnum ); - BOOST_CHECK_EQUAL( -2, cs2.get( 1 ).complnum ); - BOOST_CHECK_EQUAL( -3, cs2.get( 2 ).complnum ); - BOOST_CHECK_EQUAL( -4, cs2.get( 3 ).complnum ); + BOOST_CHECK_EQUAL( -1, cs2.get( 0 ).complnum() ); + BOOST_CHECK_EQUAL( -2, cs2.get( 1 ).complnum() ); + BOOST_CHECK_EQUAL( -3, cs2.get( 2 ).complnum() ); + BOOST_CHECK_EQUAL( -4, cs2.get( 3 ).complnum() ); } BOOST_AUTO_TEST_CASE( COMPDAT_multiple_wells ) { @@ -1717,20 +1717,20 @@ BOOST_AUTO_TEST_CASE( COMPDAT_multiple_wells ) { Schedule schedule( deck, grid, eclipseProperties, Phases( true, true, true ) ,ctx); const auto& w1cs = schedule.getWell( "W1" )->getConnections(); - BOOST_CHECK_EQUAL( -1, w1cs.get( 0 ).complnum ); - BOOST_CHECK_EQUAL( -2, w1cs.get( 1 ).complnum ); - BOOST_CHECK_EQUAL( -3, w1cs.get( 2 ).complnum ); - BOOST_CHECK_EQUAL( -4, w1cs.get( 3 ).complnum ); - BOOST_CHECK_EQUAL( -5, w1cs.get( 4 ).complnum ); + BOOST_CHECK_EQUAL( -1, w1cs.get( 0 ).complnum() ); + BOOST_CHECK_EQUAL( -2, w1cs.get( 1 ).complnum() ); + BOOST_CHECK_EQUAL( -3, w1cs.get( 2 ).complnum() ); + BOOST_CHECK_EQUAL( -4, w1cs.get( 3 ).complnum() ); + BOOST_CHECK_EQUAL( -5, w1cs.get( 4 ).complnum() ); const auto& w2cs = schedule.getWell( "W2" )->getConnections(); - BOOST_CHECK_EQUAL( -1, w2cs.getFromIJK( 4, 4, 2 ).complnum ); - BOOST_CHECK_EQUAL( -2, w2cs.getFromIJK( 4, 4, 0 ).complnum ); - BOOST_CHECK_EQUAL( -3, w2cs.getFromIJK( 4, 4, 1 ).complnum ); - BOOST_CHECK_EQUAL( -4, w2cs.getFromIJK( 4, 4, 3 ).complnum ); - BOOST_CHECK_EQUAL( -5, w2cs.getFromIJK( 4, 4, 4 ).complnum ); + BOOST_CHECK_EQUAL( -1, w2cs.getFromIJK( 4, 4, 2 ).complnum() ); + BOOST_CHECK_EQUAL( -2, w2cs.getFromIJK( 4, 4, 0 ).complnum() ); + BOOST_CHECK_EQUAL( -3, w2cs.getFromIJK( 4, 4, 1 ).complnum() ); + BOOST_CHECK_EQUAL( -4, w2cs.getFromIJK( 4, 4, 3 ).complnum() ); + BOOST_CHECK_EQUAL( -5, w2cs.getFromIJK( 4, 4, 4 ).complnum() ); - BOOST_CHECK_THROW( w2cs.get( 5 ).complnum, std::out_of_range ); + BOOST_CHECK_THROW( w2cs.get( 5 ).complnum(), std::out_of_range ); } BOOST_AUTO_TEST_CASE( COMPDAT_multiple_records_same_completion ) { @@ -1762,9 +1762,9 @@ BOOST_AUTO_TEST_CASE( COMPDAT_multiple_records_same_completion ) { const auto& cs = schedule.getWell( "W1" )->getConnections(); BOOST_CHECK_EQUAL( 3U, cs.size() ); - BOOST_CHECK_EQUAL( -1, cs.get( 0 ).complnum ); - BOOST_CHECK_EQUAL( -2, cs.get( 1 ).complnum ); - BOOST_CHECK_EQUAL( -3, cs.get( 2 ).complnum ); + BOOST_CHECK_EQUAL( -1, cs.get( 0 ).complnum() ); + BOOST_CHECK_EQUAL( -2, cs.get( 1 ).complnum() ); + BOOST_CHECK_EQUAL( -3, cs.get( 2 ).complnum() ); } BOOST_AUTO_TEST_CASE( complump_less_than_1 ) { @@ -1843,20 +1843,20 @@ BOOST_AUTO_TEST_CASE( complump ) { const auto& sc0 = well.getConnections( 0 ); /* complnum should be modified by COMPLNUM */ - BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 0 ).complnum ); - BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 1 ).complnum ); - BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 2 ).complnum ); - BOOST_CHECK( sc0.getFromIJK( 2, 2, 3 ).complnum < 0); + BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 0 ).complnum() ); + BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 1 ).complnum() ); + BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 2 ).complnum() ); + BOOST_CHECK( sc0.getFromIJK( 2, 2, 3 ).complnum() < 0); - BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 0 ).state ); - BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 1 ).state ); - BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 2 ).state ); + BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 0 ).state() ); + BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 1 ).state() ); + BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 2 ).state() ); const auto& sc1 = well.getConnections( 1 ); - BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 0 ).state ); - BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 1 ).state ); - BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 2 ).state ); - BOOST_CHECK_EQUAL( shut, sc1.getFromIJK( 2, 2, 3 ).state ); + BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 0 ).state() ); + BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 1 ).state() ); + BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 2 ).state() ); + BOOST_CHECK_EQUAL( shut, sc1.getFromIJK( 2, 2, 3 ).state() ); const auto completions = well.getCompletions(1); BOOST_CHECK_EQUAL(completions.size(), 4); @@ -1930,23 +1930,23 @@ BOOST_AUTO_TEST_CASE( COMPLUMP_specific_coordinates ) { const auto& cs2 = well.getConnections( 2 ); BOOST_CHECK_EQUAL( 9U, cs1.size() ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 0, 0, 1 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 0 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 1 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 2 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 0 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 3 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 4 ).state ); - BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 5 ).state ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 0, 0, 1 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 0 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 1 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 2 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 0 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 3 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 4 ).state() ); + BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 5 ).state() ); - BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 1 ).state ); - BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 2, 2, 0 ).state ); - BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 1 ).state ); - BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 2 ).state ); - BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 0 ).state ); - BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 3 ).state ); - BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 4 ).state ); - BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 1, 1, 5 ).state ); + BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 1 ).state() ); + BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 2, 2, 0 ).state() ); + BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 1 ).state() ); + BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 2 ).state() ); + BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 0 ).state() ); + BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 3 ).state() ); + BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 4 ).state() ); + BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 1, 1, 5 ).state() ); } BOOST_AUTO_TEST_CASE(TestCompletionStateEnum2String) { diff --git a/tests/parser/WellTests.cpp b/tests/parser/WellTests.cpp index 960f493cf..334f0a34e 100644 --- a/tests/parser/WellTests.cpp +++ b/tests/parser/WellTests.cpp @@ -340,15 +340,14 @@ BOOST_AUTO_TEST_CASE(NewWellZeroCompletions) { // Helper function for CompletionOrder test. inline Opm::Connection connection( int i, int j, int k, int complnum = 1 ) { return Opm::Connection { i, j, k, - complnum, - k*1.0, - Opm::WellCompletion::AUTO, - Opm::Value("ConnectionTransmissibilityFactor",99.88), - Opm::Value("D",22.33), - Opm::Value("SKIN",33.22), - Opm::Value("Kh",17.29), - 0, - Opm::WellCompletion::DirectionEnum::Z }; + complnum, + k*1.0, + Opm::WellCompletion::AUTO, + 99.88, + 17.29, + 0.25, + 0, + Opm::WellCompletion::DirectionEnum::Z }; } diff --git a/tests/parser/integration/ParseKEYWORD.cpp b/tests/parser/integration/ParseKEYWORD.cpp index 620c51415..c0e864c5a 100644 --- a/tests/parser/integration/ParseKEYWORD.cpp +++ b/tests/parser/integration/ParseKEYWORD.cpp @@ -577,26 +577,26 @@ BOOST_AUTO_TEST_CASE( MULTISEGMENT_ABS ) { BOOST_CHECK_EQUAL(7U, connections.size()); const Connection& connection5 = connections.get(4); - const int seg_number_connection5 = connection5.segment_number; - const double connection5_depth = connection5.center_depth; + const int seg_number_connection5 = connection5.segment(); + const double connection5_depth = connection5.depth(); BOOST_CHECK_EQUAL(seg_number_connection5, 6); BOOST_CHECK_CLOSE(connection5_depth, 2538.83, 0.001); const Connection& connection6 = connections.get(5); - const int seg_number_connection6 = connection6.segment_number; - const double connection6_depth = connection6.center_depth; + const int seg_number_connection6 = connection6.segment(); + const double connection6_depth = connection6.depth(); BOOST_CHECK_EQUAL(seg_number_connection6, 6); BOOST_CHECK_CLOSE(connection6_depth, 2537.83, 0.001); const Connection& connection1 = connections.get(0); - const int seg_number_connection1 = connection1.segment_number; - const double connection1_depth = connection1.center_depth; + const int seg_number_connection1 = connection1.segment(); + const double connection1_depth = connection1.depth(); BOOST_CHECK_EQUAL(seg_number_connection1, 1); BOOST_CHECK_EQUAL(connection1_depth, 2512.5); const Connection& connection3 = connections.get(2); - const int seg_number_connection3 = connection3.segment_number; - const double connection3_depth = connection3.center_depth; + const int seg_number_connection3 = connection3.segment(); + const double connection3_depth = connection3.depth(); BOOST_CHECK_EQUAL(seg_number_connection3, 3); BOOST_CHECK_EQUAL(connection3_depth, 2562.5); } diff --git a/tests/parser/integration/ScheduleCreateFromDeck.cpp b/tests/parser/integration/ScheduleCreateFromDeck.cpp index 71d34666b..c5a24021b 100644 --- a/tests/parser/integration/ScheduleCreateFromDeck.cpp +++ b/tests/parser/integration/ScheduleCreateFromDeck.cpp @@ -349,13 +349,11 @@ BOOST_AUTO_TEST_CASE(WellTestCOMPDAT) { const auto& connections = well1->getConnections(3); BOOST_CHECK_EQUAL(4U, connections.size()); - BOOST_CHECK_EQUAL(WellCompletion::OPEN, connections.get(3).state); - BOOST_CHECK_EQUAL(2.2836805555555556e-12 , connections.get(3).getConnectionTransmissibilityFactor()); - BOOST_CHECK_EQUAL(0.311/Metric::Length, connections.get(3).getDiameter()); - BOOST_CHECK_EQUAL(3.3, connections.get(3).getSkinFactor()); + BOOST_CHECK_EQUAL(WellCompletion::OPEN, connections.get(3).state()); + BOOST_CHECK_EQUAL(2.2836805555555556e-12 , connections.get(3).CF()); BOOST_CHECK_EQUAL(4U, well1->getConnections( 7 ).size() ); - BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).state ); + BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).state() ); } } diff --git a/tests/test_serialize_ICON.cpp b/tests/test_serialize_ICON.cpp index 639ca885e..5e0e0d2f8 100644 --- a/tests/test_serialize_ICON.cpp +++ b/tests/test_serialize_ICON.cpp @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test ) const size_t offset = w_offset + c_offset; BOOST_CHECK_EQUAL(icondata[offset + ICON_IC_INDEX], - c.complnum); + c.complnum()); BOOST_CHECK_EQUAL(icondata[offset + ICON_I_INDEX], c.getI() + 1); BOOST_CHECK_EQUAL(icondata[offset + ICON_J_INDEX], @@ -64,9 +64,9 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test ) BOOST_CHECK_EQUAL(icondata[offset + ICON_K_INDEX], c.getK() + 1); BOOST_CHECK_EQUAL(icondata[offset + ICON_DIRECTION_INDEX], - c.dir); + c.dir()); - if (c.state == Opm::WellCompletion::StateEnum::OPEN) + if (c.state() == Opm::WellCompletion::StateEnum::OPEN) BOOST_CHECK_EQUAL(icondata[offset + ICON_STATUS_INDEX], 1); else @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test ) if (c.attachedToSegment()) BOOST_CHECK_EQUAL(icondata[offset + ICON_SEGMENT_INDEX], - c.segment_number); + c.segment()); else BOOST_CHECK_EQUAL(icondata[offset + ICON_SEGMENT_INDEX], 0); diff --git a/tests/test_serialize_SCON.cpp b/tests/test_serialize_SCON.cpp index e380ad40d..d1b0c031f 100644 --- a/tests/test_serialize_SCON.cpp +++ b/tests/test_serialize_SCON.cpp @@ -56,15 +56,12 @@ BOOST_AUTO_TEST_CASE( serialize_scon_test ) for (const auto c : w->getConnections(tstep)) { const size_t offset = w_offset + c_offset; - const auto ctf = c.getConnectionTransmissibilityFactorAsValueObject(); - const double expected = - ctf.hasValue() - ? units.from_si(Opm::UnitSystem::measure::transmissibility, ctf.getValue()) - : Opm::RestartIO::Helpers::UNIMPLEMENTED_VALUE; + const double expected_cf = units.from_si(Opm::UnitSystem::measure::transmissibility, c.CF()); + const double expected_kh = units.from_si(Opm::UnitSystem::measure::effective_Kh, c.Kh()); BOOST_CHECK_EQUAL(scondata[offset + SCON_CF_INDEX], - expected); + expected_cf); BOOST_CHECK_EQUAL(scondata[offset + SCON_KH_INDEX], - Opm::RestartIO::Helpers::UNIMPLEMENTED_VALUE); + expected_kh); c_offset += SCONZ; }