Fetch ALQ value from simulator if WLIFTOPT is enabled for well

This commit is contained in:
Joakim Hove 2021-10-27 16:40:49 +02:00
parent 03f440d064
commit 8fb66ef908
2 changed files with 44 additions and 19 deletions

View File

@ -545,12 +545,40 @@ double efac( const std::vector<std::pair<std::string,double>>& eff_factors, cons
return (it != eff_factors.end()) ? it->second : 1.0;
}
inline bool
has_vfp_table(const Opm::ScheduleState& sched_state,
int vfp_table_number)
{
return sched_state.vfpprod.has(pc.vfp_table_number);
}
inline Opm::VFPProdTable::ALQ_TYPE
alq_type(const Opm::ScheduleState& sched_state,
const Opm::Well::ProductionControls& pc)
{
return sched_state.vfpprod(pc.vfp_table_number).getALQType();
}
inline quantity artificial_lift_quantity( const fn_args& args ) {
// Note: This function is intentionally supported only at the well level
// (meaning there's no loop over args.schedule_wells by intention). Its
// purpose is to calculate WALQ only.
auto zero = quantity { 0.0, measure::identity };
// Note: in order to determine the correct dimension to use the Summary code
// calls the various evaluator functions with a default constructed fn_args
// instance. In the case of the WALQ function this does not really work,
// because the correct output dimension depends on exactly what physical
// quantity is represented by the ALQ - and that again requires quite some
// context to determine correctly. The current hack is that if WLIFTOPT is
// configured for at least one well we use dimension
// measure::gas_surface_rate - otherwise we use measure::identity.
auto dimension = measure::identity;
const auto& glo = args.schedule[args.sim_step].glo();
if (glo.num_wells() != 0)
dimension = measure::gas_surface_rate;
auto zero = quantity{0, dimension};
if (args.schedule_wells.empty()) {
return zero;
}
@ -567,22 +595,19 @@ inline quantity artificial_lift_quantity( const fn_args& args ) {
return zero;
}
return { well->productionControls(args.st).alq_value, measure::identity};
const auto& production = well->productionControls(args.st);
if (!glo.has_well(well->name()))
return { production.alq_value, dimension};
const auto& sched_state = args.schedule[args.sim_step];
if (alq_type(sched_state, production.vfp_table_number) != Opm::VFPProdTable::ALQ_TYPE::ALQ_GRAT)
return zero;
const double eff_fac = efac(args.eff_factors, well->name());
auto alq_rate = eff_fac * xwPos->second.rates.get(rt::alq, production.alq_value);
return { alq_rate, dimension };
}
inline bool
has_alq_type(const Opm::ScheduleState& sched_state,
const Opm::Well::ProductionControls& pc)
{
return sched_state.vfpprod.has(pc.vfp_table_number);
}
inline Opm::VFPProdTable::ALQ_TYPE
alq_type(const Opm::ScheduleState& sched_state,
const Opm::Well::ProductionControls& pc)
{
return sched_state.vfpprod(pc.vfp_table_number).getALQType();
}
inline quantity glir( const fn_args& args ) {
if (args.schedule_wells.empty()) {
@ -605,7 +630,7 @@ inline quantity glir( const fn_args& args ) {
}
const auto& production = well->productionControls(args.st);
if (! has_alq_type(sched_state, production)) {
if (! has_alq_vfp_table(sched_state, production.vfp_table_number)) {
continue;
}

View File

@ -1208,9 +1208,9 @@ BOOST_AUTO_TEST_CASE(GLIR_and_ALQ)
BOOST_CHECK_CLOSE(1234.56 + 2345.67 + 3456.78,
ecl_sum_get_group_var(resp, 1, "B1", "GGLIR"), 1.0e-5);
BOOST_CHECK_CLOSE(0.0, ecl_sum_get_well_var(resp, 1, "B-1H", "WALQ"), 1.0e-5);
BOOST_CHECK_CLOSE(0.0, ecl_sum_get_well_var(resp, 1, "B-2H", "WALQ"), 1.0e-5);
BOOST_CHECK_CLOSE(0.0, ecl_sum_get_well_var(resp, 1, "B-3H", "WALQ"), 1.0e-5);
BOOST_CHECK_EQUAL(ecl_sum_get_well_var(resp, 1, "B-1H", "WGLIR"), ecl_sum_get_well_var(resp, 1, "B-1H", "WALQ"));
BOOST_CHECK_EQUAL(ecl_sum_get_well_var(resp, 1, "B-2H", "WGLIR"), ecl_sum_get_well_var(resp, 1, "B-2H", "WALQ"));
BOOST_CHECK_EQUAL(ecl_sum_get_well_var(resp, 1, "B-3H", "WGLIR"), ecl_sum_get_well_var(resp, 1, "B-3H", "WALQ"));
}
BOOST_AUTO_TEST_CASE(connection_kewords) {