Add WellType class for ecl interop
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#define OPM_SCHEDULE_TYPES_HPP
|
||||
|
||||
#include <string>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@@ -33,6 +34,48 @@ enum class InjectorType {
|
||||
const std::string InjectorType2String( InjectorType enumValue );
|
||||
InjectorType InjectorTypeFromString( const std::string& stringValue );
|
||||
|
||||
|
||||
class WellType {
|
||||
public:
|
||||
WellType(int ecl_wtype, int welspecs_phase);
|
||||
WellType(bool producer, Phase welspecs_phase);
|
||||
explicit WellType(Phase welspecs_phase);
|
||||
WellType() = default;
|
||||
|
||||
bool injector() const;
|
||||
bool producer() const;
|
||||
bool update(InjectorType injector_type);
|
||||
bool update(bool producer);
|
||||
|
||||
static bool oil_injector(int ecl_wtype);
|
||||
static bool gas_injector(int ecl_wtype);
|
||||
static bool water_injector(int ecl_wtype);
|
||||
static bool producer(int ecl_wtype);
|
||||
|
||||
int ecl_wtype() const;
|
||||
int ecl_phase() const;
|
||||
Phase preferred_phase() const;
|
||||
InjectorType injector_type() const;
|
||||
bool operator==(const WellType& other) const;
|
||||
private:
|
||||
bool m_producer;
|
||||
/*
|
||||
The injection_phase member is updated during the course of the simulation;
|
||||
following each WCONINJE keyword the injection phase is updated. If an
|
||||
producer is specified in the constructor the injection_phase is
|
||||
initialzied to the welspecs phase. This is not wildly random - but the
|
||||
injection_phase will not be meaningfull before an update(Phase) call has been
|
||||
issued.
|
||||
|
||||
The welspecs_phase is the preferred phase specified when the well is
|
||||
defined with the WELSPECS keyword. This member is immutable, and it is only
|
||||
used when initializing the well equations for a producer.
|
||||
*/
|
||||
|
||||
Phase injection_phase;
|
||||
Phase m_welspecs_phase;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,204 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace ecl {
|
||||
|
||||
static constexpr int producer = 1;
|
||||
static constexpr int oil_injector = 2;
|
||||
static constexpr int water_injector = 3;
|
||||
static constexpr int gas_injector = 4;
|
||||
|
||||
|
||||
static constexpr int oil_phase = 1;
|
||||
static constexpr int water_phase = 2;
|
||||
static constexpr int gas_phase = 3;
|
||||
static constexpr int liquid_phase = 4;
|
||||
|
||||
|
||||
Phase from_ecl_phase(int ecl_phase) {
|
||||
switch(ecl_phase) {
|
||||
case ecl::oil_phase:
|
||||
return Phase::OIL;
|
||||
case ecl::water_phase:
|
||||
return Phase::WATER;
|
||||
case ecl::gas_phase:
|
||||
return Phase::GAS;
|
||||
case ecl::liquid_phase:
|
||||
throw std::logic_error("Sorry wells with preferred phase:LIQUID is not supported");
|
||||
default:
|
||||
throw std::invalid_argument("Invalid integer well phase");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
Phase from_injector_type(InjectorType injector_type) {
|
||||
switch (injector_type) {
|
||||
case InjectorType::WATER:
|
||||
return Phase::WATER;
|
||||
case InjectorType::GAS:
|
||||
return Phase::GAS;
|
||||
case InjectorType::OIL:
|
||||
return Phase::OIL;
|
||||
default:
|
||||
throw std::logic_error("Unhandled injector type");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool WellType::producer(int ecl_wtype) {
|
||||
return ecl_wtype == ecl::producer;
|
||||
}
|
||||
|
||||
bool WellType::oil_injector(int ecl_wtype) {
|
||||
return ecl_wtype == ecl::oil_injector;
|
||||
}
|
||||
|
||||
bool WellType::water_injector(int ecl_wtype) {
|
||||
return ecl_wtype == ecl::water_injector;
|
||||
}
|
||||
|
||||
bool WellType::gas_injector(int ecl_wtype) {
|
||||
return ecl_wtype == ecl::gas_injector;
|
||||
}
|
||||
|
||||
|
||||
WellType::WellType(int ecl_wtype, int ecl_phase) :
|
||||
injection_phase(ecl::from_ecl_phase(ecl_phase)),
|
||||
m_welspecs_phase(ecl::from_ecl_phase(ecl_phase))
|
||||
{
|
||||
this->m_producer = false;
|
||||
switch (ecl_wtype) {
|
||||
case ecl::producer:
|
||||
this->m_producer = true;
|
||||
break;
|
||||
case ecl::oil_injector:
|
||||
this->injection_phase = Phase::OIL;
|
||||
break;
|
||||
case ecl::water_injector:
|
||||
this->injection_phase = Phase::WATER;
|
||||
break;
|
||||
case ecl::gas_injector:
|
||||
this->injection_phase = Phase::GAS;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid integer well type ID");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WellType::WellType(bool producer, Phase phase) :
|
||||
m_producer(producer),
|
||||
injection_phase(phase),
|
||||
m_welspecs_phase(phase)
|
||||
{}
|
||||
|
||||
WellType::WellType(Phase phase) :
|
||||
WellType(true, phase)
|
||||
{}
|
||||
|
||||
bool WellType::update(bool producer_arg) {
|
||||
if (this->m_producer != producer_arg) {
|
||||
this->m_producer = producer_arg;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WellType::update(InjectorType injector_type) {
|
||||
bool ret_value = false;
|
||||
if (this->m_producer) {
|
||||
this->m_producer = false;
|
||||
ret_value = true;
|
||||
}
|
||||
|
||||
auto inj_phase = from_injector_type(injector_type);
|
||||
if (this->injection_phase != inj_phase) {
|
||||
this->injection_phase = inj_phase;
|
||||
ret_value = true;
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
bool WellType::producer() const {
|
||||
return this->m_producer;
|
||||
}
|
||||
|
||||
bool WellType::injector() const {
|
||||
return !this->m_producer;
|
||||
}
|
||||
|
||||
int WellType::ecl_wtype() const {
|
||||
if (this->m_producer)
|
||||
return ecl::producer;
|
||||
|
||||
switch (this->injection_phase) {
|
||||
case Phase::OIL:
|
||||
return ecl::oil_injector;
|
||||
case Phase::WATER:
|
||||
return ecl::water_injector;
|
||||
case Phase::GAS:
|
||||
return ecl::gas_injector;
|
||||
default:
|
||||
throw std::logic_error("Internal error - should not be here");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The enum Runspec::Phase is maybe not very well suited; it has lots of 'extra'
|
||||
phases like ENERGY and BRINE, and at the same time it is missing the phase
|
||||
LIQUID which should map to ecl value 4.
|
||||
*/
|
||||
|
||||
int WellType::ecl_phase() const {
|
||||
switch (this->m_welspecs_phase) {
|
||||
case Phase::OIL:
|
||||
return ecl::oil_phase;
|
||||
case Phase::WATER:
|
||||
return ecl::water_phase;
|
||||
case Phase::GAS:
|
||||
return ecl::gas_phase;
|
||||
default:
|
||||
throw std::logic_error("Member has invalid phase");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Phase WellType::preferred_phase() const {
|
||||
return this->m_welspecs_phase;
|
||||
}
|
||||
|
||||
|
||||
bool WellType::operator==(const WellType& other) const {
|
||||
return this->m_welspecs_phase == other.m_welspecs_phase &&
|
||||
this->injection_phase == other.injection_phase &&
|
||||
this->m_producer == other.m_producer;
|
||||
}
|
||||
|
||||
|
||||
InjectorType WellType::injector_type() const {
|
||||
if (this->producer())
|
||||
throw std::invalid_argument("Asked for injector type for a well which is a producer");
|
||||
|
||||
switch (this->injection_phase) {
|
||||
case Phase::OIL:
|
||||
return InjectorType::OIL;
|
||||
case Phase::WATER:
|
||||
return InjectorType::WATER;
|
||||
case Phase::GAS:
|
||||
return InjectorType::GAS;
|
||||
default:
|
||||
throw std::logic_error("Member has invalid phase");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
const std::string InjectorType2String( InjectorType enumValue ) {
|
||||
switch( enumValue ) {
|
||||
case InjectorType::OIL:
|
||||
|
||||
@@ -863,3 +863,47 @@ BOOST_AUTO_TEST_CASE(WELOPEN) {
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WellTypeTest) {
|
||||
BOOST_CHECK_THROW(Opm::WellType(0, 3), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(Opm::WellType(5, 3), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(Opm::WellType(3, 0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(Opm::WellType(3, 5), std::invalid_argument);
|
||||
|
||||
Opm::WellType wt1(1,1);
|
||||
BOOST_CHECK(wt1.producer());
|
||||
BOOST_CHECK(!wt1.injector());
|
||||
BOOST_CHECK_EQUAL(wt1.ecl_wtype(), 1);
|
||||
BOOST_CHECK_EQUAL(wt1.ecl_phase(), 1);
|
||||
BOOST_CHECK(wt1.preferred_phase() == Phase::OIL);
|
||||
BOOST_CHECK_THROW(wt1.injector_type(), std::invalid_argument);
|
||||
|
||||
Opm::WellType wt4(4,3);
|
||||
BOOST_CHECK(!wt4.producer());
|
||||
BOOST_CHECK(wt4.injector());
|
||||
BOOST_CHECK_EQUAL(wt4.ecl_wtype(), 4);
|
||||
BOOST_CHECK_EQUAL(wt4.ecl_phase(), 3);
|
||||
BOOST_CHECK(wt4.preferred_phase() == Phase::GAS);
|
||||
BOOST_CHECK(wt4.injector_type() == InjectorType::GAS);
|
||||
|
||||
BOOST_CHECK(wt4.update(true));
|
||||
BOOST_CHECK(!wt4.update(true));
|
||||
BOOST_CHECK(wt4.producer());
|
||||
BOOST_CHECK(!wt4.injector());
|
||||
BOOST_CHECK_EQUAL(wt4.ecl_wtype(), 1);
|
||||
BOOST_CHECK_EQUAL(wt4.ecl_phase(), 3);
|
||||
BOOST_CHECK(wt4.preferred_phase() == Phase::GAS);
|
||||
|
||||
Opm::WellType wtp(false, Phase::WATER);
|
||||
BOOST_CHECK(!wtp.producer());
|
||||
BOOST_CHECK(wtp.injector());
|
||||
BOOST_CHECK_EQUAL(wtp.ecl_wtype(), 3);
|
||||
BOOST_CHECK_EQUAL(wtp.ecl_phase(), 2);
|
||||
BOOST_CHECK(wtp.preferred_phase() == Phase::WATER);
|
||||
BOOST_CHECK(wtp.injector_type() == InjectorType::WATER);
|
||||
|
||||
wtp.update( InjectorType::GAS );
|
||||
BOOST_CHECK_EQUAL(wtp.ecl_wtype(), 4);
|
||||
BOOST_CHECK_EQUAL(wtp.ecl_phase(), 2);
|
||||
BOOST_CHECK(wtp.preferred_phase() == Phase::WATER);
|
||||
BOOST_CHECK(wtp.injector_type() == InjectorType::GAS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user