New implementation of WELOPEN

This commit is contained in:
Joakim Hove 2018-06-25 18:45:01 +02:00
parent 1f1ecebec5
commit 9d16cc8ec4
12 changed files with 80 additions and 96 deletions

View File

@ -62,7 +62,6 @@ namespace Opm {
int getI() const;
int getJ() const;
int getK() const;
WellCompletion::StateEnum getState() const;
double getConnectionTransmissibilityFactor() const;
double getWellPi() const;
const Value<double>& getConnectionTransmissibilityFactorAsValueObject() const;
@ -84,6 +83,7 @@ namespace Opm {
int m_segment_number = -1;
double m_center_depth;
int complnum;
WellCompletion::StateEnum state;
private:
int m_i, m_j, m_k;
@ -92,7 +92,6 @@ namespace Opm {
double m_wellPi;
Value<double> m_skinFactor;
int m_satTableId;
WellCompletion::StateEnum m_state;
WellCompletion::DirectionEnum m_direction;
Value<double> getDiameterAsValueObject() const;
Value<double> getSkinFactorAsValueObject() const;

View File

@ -168,6 +168,7 @@ namespace Opm {
void handleCOMPLUMP(const DeckRecord& record, size_t time_step);
void handleCOMPDAT(size_t time_step, const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
void handleCOMPSEGS(const DeckKeyword& keyword, size_t time_step);
void handleWELOPEN(const DeckRecord& record, size_t time_step, WellCompletion::StateEnum status);
/*
Will remove all completions which are attached to inactive cells. Will

View File

@ -194,7 +194,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.getState() == WellCompletion::SHUT ) {
if( !grid.cellActive( i, j, k ) || sc.state == WellCompletion::SHUT ) {
opm_xwel_data += data::Connection::restart_size + phases.size();
continue;
}
@ -301,7 +301,7 @@ std::vector<int> serialize_ICON( int sim_step,
data[ offset + ICON_DIRECTION_INDEX ] = connection.getDirection();
{
const auto open = WellCompletion::StateEnum::OPEN;
data[ offset + ICON_STATUS_INDEX ] = connection.getState() == open
data[ offset + ICON_STATUS_INDEX ] = connection.state == open
? 1
: 0;
}
@ -396,7 +396,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.getState() == WellCompletion::SHUT ) {
if( !grid.cellActive( i, j, k ) || sc.state == WellCompletion::SHUT ) {
xwel.insert( xwel.end(), rs_size, 0.0 );
continue;
}

View File

@ -100,7 +100,7 @@ serialize_ICON(int lookup_step,
data[ offset + ICON_K_INDEX ] = connection.getK() + 1;
data[ offset + ICON_DIRECTION_INDEX ] = connection.getDirection();
data[ offset + ICON_STATUS_INDEX ] =
(connection.getState() == WellCompletion::StateEnum::OPEN) ?
(connection.state == WellCompletion::StateEnum::OPEN) ?
1 : -1000;
data[ offset + ICON_SEGMENT_INDEX ] =
connection.attachedToSegment() ?

View File

@ -52,7 +52,7 @@ namespace Opm {
m_wellPi(1.0),
m_skinFactor(skinFactor),
m_satTableId(satTableId),
m_state(state),
state(state),
m_direction(direction),
m_center_depth( depth )
{}
@ -60,7 +60,7 @@ namespace Opm {
Connection::Connection(const Connection& oldConnection, WellCompletion::StateEnum newStatus ) :
Connection( oldConnection )
{
this->m_state = newStatus;
this->state = newStatus;
}
Connection::Connection(const Connection& oldConnection, double wellPi) :
@ -130,10 +130,6 @@ namespace Opm {
}
WellCompletion::StateEnum Connection::getState() const {
return m_state;
}
double Connection::getConnectionTransmissibilityFactor() const {
return m_connectionTransmissibilityFactor.getValue();
}
@ -196,7 +192,7 @@ namespace Opm {
&& this->m_wellPi == rhs.m_wellPi
&& this->m_skinFactor == rhs.m_skinFactor
&& this->m_satTableId == rhs.m_satTableId
&& this->m_state == rhs.m_state
&& this->state == rhs.state
&& this->m_direction == rhs.m_direction
&& this->m_segment_number == rhs.m_segment_number
&& this->m_center_depth == rhs.m_center_depth;

View File

@ -956,10 +956,9 @@ namespace Opm {
* well status is updated
*/
if( all_defaulted( record ) ) {
const auto status = WellCommon::StatusFromString( status_str );
const auto well_status = WellCommon::StatusFromString( status_str );
for( auto* well : wells ) {
if( status == open && !well->canOpen(currentStep) ) {
if( well_status == open && !well->canOpen(currentStep) ) {
auto days = m_timeMap.getTimePassedUntil( currentStep ) / (60 * 60 * 24);
std::string msg = "Well " + well->name()
+ " where crossflow is banned has zero total rate."
@ -967,53 +966,16 @@ namespace Opm {
+ std::to_string( days ) + " days";
OpmLog::note(msg);
} else {
this->updateWellStatus( *well, currentStep, status );
this->updateWellStatus( *well, currentStep, well_status );
}
}
continue;
}
const int I = maybe( record, "I" );
const int J = maybe( record, "J" );
const int K = maybe( record, "K" );
const int C1 = maybe( record, "C1" );
const int C2 = maybe( record, "C2" );
const auto status = WellCompletion::StateEnumFromString( status_str );
/*
* Construct the updated completion with the possible status change
* applied. Status is changed when a completion matches all the IJK
* criteria *and* the completion number. A defaulted field always
* matches the property in question.
*/
auto new_completion = [=]( const Connection& completion ) -> Connection {
if( !defaulted( I ) && completion.getI() != I ) return completion;
if( !defaulted( J ) && completion.getJ() != J ) return completion;
if( !defaulted( K ) && completion.getK() != K ) return completion;
// assuming CM can be defaulted, even in the presence of
// CN, e.g. it's a match for c >= C1 when C2 is defaulted
// and vice versa.
// complnum starts at 1, but we temp. adjust it for zero to
// generalise the negative default value
const auto complnum = completion.complnum - 1;
if( !defaulted( C1 ) && complnum < C1 ) return completion;
if( !defaulted( C2 ) && complnum > C2 ) return completion;
if( !defaulted( C1 ) && !defaulted( C2 )
&& ( C1 > complnum || complnum > C2 ) ) return completion;
// completion matched - update it's status
return { completion, status };
};
for( auto* well : wells ) {
WellConnections * new_completions = well->newWellConnections(currentStep);
for( const auto& c : well->getConnections( currentStep ) )
new_completions->add( new_completion( c ) );
well->updateWellConnections( currentStep, new_completions );
const auto comp_status = WellCompletion::StateEnumFromString( status_str );
well->handleWELOPEN(record, currentStep, comp_status);
m_events.addEvent( ScheduleEvents::COMPLETION_CHANGE, currentStep );
}
}

View File

@ -659,6 +659,32 @@ namespace Opm {
this->updateWellConnections(time_step, new_connections);
}
void Well::handleWELOPEN(const DeckRecord& record, size_t time_step, WellCompletion::StateEnum status) {
auto match = [=]( const Connection &c) -> bool {
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;
return true;
};
WellConnections * new_connections = this->newWellConnections(time_step);
for (auto c : this->getConnections(time_step)) {
if (match(c))
c.state = status;
new_connections->add(c);
}
this->updateWellConnections(time_step, new_connections);
}
void Well::handleCOMPDAT(size_t time_step, const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) {
WellConnections * connections = new WellConnections(this->getConnections(time_step));
connections->loadCOMPDAT(record, grid, eclipseProperties);

View File

@ -216,7 +216,7 @@ namespace Opm {
bool WellConnections::allConnectionsShut( ) const {
auto shut = []( const Connection& c ) {
return c.getState() == WellCompletion::StateEnum::SHUT;
return c.state == WellCompletion::StateEnum::SHUT;
};
return std::all_of( this->m_connections.begin(),

View File

@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(testGetFunctions) {
BOOST_CHECK_EQUAL( 11 , completion.getJ() );
BOOST_CHECK_EQUAL( 12 , completion.getK() );
BOOST_CHECK_EQUAL( Opm::WellCompletion::OPEN , completion.getState());
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());

View File

@ -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 ).getState());
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 3 ).getState());
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 4 ).getState());
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 7, 2 ).getState());
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 ).getState());
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 3 ).getState());
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 4 ).getState());
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 7, 2 ).getState());
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 ).getState());
BOOST_CHECK_EQUAL(shut, cs3.get( 0 ).state);
const auto& cs4 = well->getConnections( 4 );
BOOST_CHECK_EQUAL(open, cs4.get( 0 ).getState());
BOOST_CHECK_EQUAL(open, cs4.get( 0 ).state);
well = schedule.getWell("OP_1");
BOOST_CHECK_EQUAL(WellCommon::StatusEnum::SHUT, well->getStatus( 3 ));
@ -1848,15 +1848,15 @@ BOOST_AUTO_TEST_CASE( complump ) {
//BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 2 ).complnum );
//BOOST_CHECK_EQUAL( 4, sc0.getFromIJK( 2, 2, 3 ).complnum );
//BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 0 ).getState() );
//BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 1 ).getState() );
//BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 2 ).getState() );
//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 ).getState() );
//BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 1 ).getState() );
//BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 2 ).getState() );
//BOOST_CHECK_EQUAL( shut, sc1.getFromIJK( 2, 2, 3 ).getState() );
//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_AUTO_TEST_CASE( COMPLUMP_specific_coordinates ) {
@ -1918,25 +1918,25 @@ BOOST_AUTO_TEST_CASE( COMPLUMP_specific_coordinates ) {
const auto& cs2 = well.getConnections( 2 );
BOOST_CHECK_EQUAL( 9U, cs1.size() );
//BOOST_CHECK_EQUAL( open, cs1.getFromIJK( 0, 0, 0 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 0, 0, 1 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 0 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 1 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 2 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 0 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 3 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 4 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 5 ).getState() );
//BOOST_CHECK_EQUAL( open, cs1.getFromIJK( 0, 0, 0 ).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, 0 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 1 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 2, 2, 0 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 1 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 2 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 0 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 3 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 4 ).getState() );
//BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 1, 1, 5 ).getState() );
//BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 0 ).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) {

View File

@ -349,13 +349,13 @@ 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).getState());
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(4U, well1->getConnections( 7 ).size() );
BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).getState() );
BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).state );
}
}

View File

@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test )
BOOST_CHECK_EQUAL(icondata[offset + ICON_DIRECTION_INDEX],
c.getDirection());
if (c.getState() == Opm::WellCompletion::StateEnum::OPEN)
if (c.state == Opm::WellCompletion::StateEnum::OPEN)
BOOST_CHECK_EQUAL(icondata[offset + ICON_STATUS_INDEX],
1);
else