commit
7f8578ea96
@ -565,7 +565,9 @@ public:
|
||||
bool segmented_density_calculation() const { return true; }
|
||||
double alq_value() const;
|
||||
double temperature() const;
|
||||
bool hasInjected( ) const;
|
||||
bool hasProduced( ) const;
|
||||
bool updateHasInjected( );
|
||||
bool updateHasProduced();
|
||||
bool cmp_structure(const Well& other) const;
|
||||
bool operator==(const Well& data) const;
|
||||
@ -595,6 +597,7 @@ public:
|
||||
serializer(efficiency_factor);
|
||||
serializer(solvent_fraction);
|
||||
serializer(has_produced);
|
||||
serializer(has_injected);
|
||||
serializer(prediction_mode);
|
||||
serializer(productivity_index);
|
||||
serializer(econ_limits);
|
||||
@ -632,6 +635,7 @@ private:
|
||||
double efficiency_factor;
|
||||
double solvent_fraction;
|
||||
bool has_produced = false;
|
||||
bool has_injected = false;
|
||||
bool prediction_mode = true;
|
||||
std::optional<double> productivity_index{ std::nullopt };
|
||||
|
||||
|
@ -738,7 +738,24 @@ inline quantity injection_history( const fn_args& args ) {
|
||||
return { sum, rate_unit< phase >() };
|
||||
}
|
||||
|
||||
inline quantity abondoned_wells( const fn_args& args ) {
|
||||
inline quantity abondoned_injectors( const fn_args& args ) {
|
||||
std::size_t count = 0;
|
||||
|
||||
for (const auto& sched_well : args.schedule_wells) {
|
||||
if (sched_well.hasInjected()) {
|
||||
const auto& well_name = sched_well.name();
|
||||
auto well_iter = args.wells.find( well_name );
|
||||
if (well_iter == args.wells.end())
|
||||
continue;
|
||||
|
||||
count += !well_iter->second.flowing();
|
||||
}
|
||||
}
|
||||
|
||||
return { 1.0 * count, measure::identity };
|
||||
}
|
||||
|
||||
inline quantity abondoned_producers( const fn_args& args ) {
|
||||
std::size_t count = 0;
|
||||
|
||||
for (const auto& sched_well : args.schedule_wells) {
|
||||
@ -1362,7 +1379,8 @@ static const std::unordered_map< std::string, ofun > funs = {
|
||||
{ "FMWIN", flowing< injector > },
|
||||
{ "FMWPR", flowing< producer > },
|
||||
{ "FVPRT", res_vol_production_target },
|
||||
{ "FMWPA", abondoned_wells },
|
||||
{ "FMWPA", abondoned_producers },
|
||||
{ "FMWIA", abondoned_injectors },
|
||||
|
||||
//Field control mode
|
||||
{ "FMCTP", group_control< false, true, false, false >},
|
||||
|
@ -951,6 +951,9 @@ namespace {
|
||||
if (well2->updatePrediction(true))
|
||||
update_well = true;
|
||||
|
||||
if (well2->updateHasInjected())
|
||||
update_well = true;
|
||||
|
||||
if (update_well) {
|
||||
this->updateWell(well2, handlerContext.currentStep);
|
||||
m_events.addEvent( ScheduleEvents::INJECTION_UPDATE , handlerContext.currentStep );
|
||||
@ -1010,6 +1013,9 @@ namespace {
|
||||
if (well2->updatePrediction(false))
|
||||
update_well = true;
|
||||
|
||||
if (well2->updateHasInjected())
|
||||
update_well = true;
|
||||
|
||||
if (update_well) {
|
||||
this->updateWell(well2, handlerContext.currentStep);
|
||||
m_events.addEvent( ScheduleEvents::INJECTION_UPDATE , handlerContext.currentStep );
|
||||
|
@ -510,6 +510,17 @@ bool Well::updateHasProduced() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Well::updateHasInjected() {
|
||||
if (this->wtype.injector() && this->status == Status::OPEN) {
|
||||
if (this->has_injected)
|
||||
return false;
|
||||
|
||||
this->has_injected= true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Well::updateProduction(std::shared_ptr<WellProductionProperties> production_arg) {
|
||||
if (!this->wtype.producer())
|
||||
this->switchToProducer( );
|
||||
@ -1142,6 +1153,10 @@ bool Well::hasProduced( ) const {
|
||||
return this->has_produced;
|
||||
}
|
||||
|
||||
bool Well::hasInjected( ) const {
|
||||
return this->has_injected;
|
||||
}
|
||||
|
||||
|
||||
bool Well::updatePrediction(bool prediction_mode_arg) {
|
||||
if (this->prediction_mode != prediction_mode_arg) {
|
||||
@ -1513,6 +1528,7 @@ bool Well::operator==(const Well& data) const {
|
||||
this->guide_rate == data.guide_rate &&
|
||||
this->solvent_fraction == data.solvent_fraction &&
|
||||
this->hasProduced() == data.hasProduced() &&
|
||||
this->hasInjected() == data.hasInjected() &&
|
||||
this->predictionMode() == data.predictionMode() &&
|
||||
this->productivity_index == data.productivity_index &&
|
||||
this->getTracerProperties() == data.getTracerProperties() &&
|
||||
|
@ -288,6 +288,7 @@ RPR__NUM
|
||||
|
||||
RUNSUM
|
||||
FMWPA
|
||||
FMWIA
|
||||
|
||||
-- 1a) Oil rate vs time
|
||||
FOPR
|
||||
@ -392,8 +393,10 @@ WELSPECS
|
||||
-- Item #: 1 2 3 4 5 6
|
||||
'PROD' 'G1' 10 10 8400 'OIL' /
|
||||
'INJ' 'G1' 1 1 8335 'GAS' /
|
||||
'RFT' 'G1' 10 10 8400 'OIL' /
|
||||
'RFTP' 'G1' 10 10 8400 'OIL' /
|
||||
'RFTI' 'G1' 9 9 8400 'WATER' /
|
||||
/
|
||||
|
||||
-- Coordinates in item 3-4 are retrieved from Odeh's figure 1 and 2
|
||||
-- Note that the depth at the midpoint of the well grid blocks
|
||||
-- has been used as reference depth for bottom hole pressure in item 5
|
||||
@ -401,7 +404,8 @@ WELSPECS
|
||||
COMPDAT
|
||||
-- Item #: 1 2 3 4 5 6 7 8 9
|
||||
'PROD' 10 10 3 3 'OPEN' 1* 1* 0.5 /
|
||||
'RFT' 10 10 3 3 'OPEN' 1* 1* 0.5 /
|
||||
'RFTP' 10 10 3 3 'OPEN' 1* 1* 0.5 /
|
||||
'RFTI' 9 9 3 3 'OPEN' 1* 1* 0.5 /
|
||||
'INJ' 1 1 1 1 'OPEN' 1* 1* 0.5 /
|
||||
/
|
||||
-- Coordinates in item 2-5 are retreived from Odeh's figure 1 and 2
|
||||
@ -412,7 +416,7 @@ COMPDAT
|
||||
WCONPROD
|
||||
-- Item #:1 2 3 4 5 9
|
||||
'PROD' 'OPEN' 'ORAT' 20000 4* 1000 /
|
||||
'RFT' 'SHUT' 'ORAT' 20000 4* 1000 /
|
||||
'RFTP' 'SHUT' 'ORAT' 20000 4* 1000 /
|
||||
/
|
||||
-- It is stated in Odeh's paper that the maximum oil prod. rate
|
||||
-- is 20 000stb per day which explains the choice of value in item 4.
|
||||
@ -422,7 +426,9 @@ WCONPROD
|
||||
WCONINJE
|
||||
-- Item #:1 2 3 4 5 6 7
|
||||
'INJ' 'GAS' 'OPEN' 'RATE' 100000 1* 9014 /
|
||||
'RFTI' 'GAS' 'SHUT' 'RATE' 0 /
|
||||
/
|
||||
|
||||
-- Stated in Odeh that gas inj. rate (item 5) is 100MMscf per day
|
||||
-- BHP upper limit (item 7) should not be exceeding the highest
|
||||
-- pressure in the PVT table=9014.7psia (default is 100 000psia)
|
||||
@ -432,18 +438,24 @@ TSTEP
|
||||
31 28 31 30 31 30 31 31 30 31 30 31 /
|
||||
|
||||
WELOPEN
|
||||
'RFT' OPEN /
|
||||
'RFTP' OPEN /
|
||||
'RFTI' OPEN /
|
||||
/
|
||||
|
||||
WCONHIST
|
||||
'RFT' 'OPEN' 'RESV' 0 /
|
||||
'RFTP' 'OPEN' 'RESV' 0 /
|
||||
/
|
||||
|
||||
WCONINJE
|
||||
'RFTI' 'GAS' 'OPEN' 'RATE' 0 /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
31 /
|
||||
|
||||
WELOPEN
|
||||
'RFT' 'SHUT' /
|
||||
'RFTP' 'SHUT' /
|
||||
'RFTI' 'SHUT' /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
|
@ -56,6 +56,11 @@ double prod_rft(const EclipseState& es, const Schedule& /* sched */, const Summ
|
||||
return -units.to_si(UnitSystem::measure::rate, 0.0);
|
||||
}
|
||||
|
||||
double inj_rft(const EclipseState& es, const Schedule& /* sched */, const SummaryState&, const data::Solution& /* sol */, size_t /* report_step */, double /* seconds_elapsed */) {
|
||||
const auto& units = es.getUnits();
|
||||
return units.to_si(UnitSystem::measure::rate, 0.0);
|
||||
}
|
||||
|
||||
void pressure(const EclipseState& es, const Schedule& /* sched */, data::Solution& sol, size_t /* report_step */, double seconds_elapsed) {
|
||||
const auto& grid = es.getInputGrid();
|
||||
const auto& units = es.getUnits();
|
||||
@ -84,7 +89,8 @@ BOOST_AUTO_TEST_CASE(RUN) {
|
||||
msim msim(state);
|
||||
|
||||
msim.well_rate("PROD", data::Rates::opt::oil, prod_opr);
|
||||
msim.well_rate("RFT", data::Rates::opt::oil, prod_rft);
|
||||
msim.well_rate("RFTP", data::Rates::opt::oil, prod_rft);
|
||||
msim.well_rate("RFTI", data::Rates::opt::wat, inj_rft);
|
||||
msim.solution("PRESSURE", pressure);
|
||||
{
|
||||
const WorkArea work_area("test_msim");
|
||||
@ -107,6 +113,7 @@ BOOST_AUTO_TEST_CASE(RUN) {
|
||||
}
|
||||
|
||||
const auto& fmwpa = smry.get("FMWPA");
|
||||
const auto& fmwia = smry.get("FMWIA");
|
||||
const auto& dates = smry.dates();
|
||||
const auto& day = smry.get("DAY");
|
||||
const auto& month = smry.get("MONTH");
|
||||
@ -120,8 +127,10 @@ BOOST_AUTO_TEST_CASE(RUN) {
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL( fmwpa[0], 0.0 );
|
||||
// The RFT well will appear as an abondoned well.
|
||||
BOOST_CHECK_EQUAL( fmwia[0], 0.0 );
|
||||
// The RFTP /RFTI wells will appear as an abondoned well.
|
||||
BOOST_CHECK_EQUAL( fmwpa[dates.size() - 1], 1.0 );
|
||||
BOOST_CHECK_EQUAL( fmwia[dates.size() - 1], 1.0 );
|
||||
|
||||
const auto rsm = EclIO::ERsm("SPE1CASE1.RSM");
|
||||
BOOST_CHECK( EclIO::cmp( smry, rsm ));
|
||||
@ -141,8 +150,10 @@ BOOST_AUTO_TEST_CASE(RUN) {
|
||||
const int report_step = 50;
|
||||
const auto& rst_state = Opm::RestartIO::RstState::load(rst, report_step);
|
||||
Schedule sched_rst(deck, state, python, &rst_state);
|
||||
const auto& rft_well = sched_rst.getWell("RFT", report_step);
|
||||
BOOST_CHECK(rft_well.getStatus() == Well::Status::SHUT);
|
||||
const auto& rfti_well = sched_rst.getWell("RFTI", report_step);
|
||||
const auto& rftp_well = sched_rst.getWell("RFTP", report_step);
|
||||
BOOST_CHECK(rftp_well.getStatus() == Well::Status::SHUT);
|
||||
BOOST_CHECK(rfti_well.getStatus() == Well::Status::SHUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user