commit
981e977da4
@ -591,11 +591,13 @@ namespace {
|
||||
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
|
||||
|
||||
if (pc.alq_value != 0.0) {
|
||||
auto vfpTable = sched[sim_step].vfpprod(pc.vfp_table_number);
|
||||
if (vfpTable.getALQType() == Opm::VFPProdTable::ALQ_TYPE::ALQ_GRAT) {
|
||||
const auto alqType = sched[sim_step].vfpprod(pc.vfp_table_number).getALQType();
|
||||
if (alqType == Opm::VFPProdTable::ALQ_TYPE::ALQ_GRAT) {
|
||||
sWell[Ix::Alq_value] = static_cast<float>(units.from_si(M::gas_surface_rate, pc.alq_value));
|
||||
}
|
||||
else if ((vfpTable.getALQType() == Opm::VFPProdTable::ALQ_TYPE::ALQ_IGLR) || (vfpTable.getALQType() == Opm::VFPProdTable::ALQ_TYPE::ALQ_TGLR)) {
|
||||
else if ((alqType == Opm::VFPProdTable::ALQ_TYPE::ALQ_IGLR) ||
|
||||
(alqType == Opm::VFPProdTable::ALQ_TYPE::ALQ_TGLR))
|
||||
{
|
||||
sWell[Ix::Alq_value] = static_cast<float>(units.from_si(M::gas_oil_ratio, pc.alq_value));
|
||||
}
|
||||
else {
|
||||
|
@ -34,10 +34,12 @@
|
||||
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
|
||||
@ -461,6 +463,7 @@ struct fn_args
|
||||
const Opm::data::GroupAndNetworkValues& grp_nwrk;
|
||||
const Opm::out::RegionCache& regionCache;
|
||||
const Opm::EclipseGrid& grid;
|
||||
const Opm::Schedule& schedule;
|
||||
const std::vector< std::pair< std::string, double > > eff_factors;
|
||||
const Opm::Inplace& initial_inplace;
|
||||
const Opm::Inplace& inplace;
|
||||
@ -532,14 +535,55 @@ double efac( const std::vector<std::pair<std::string,double>>& eff_factors, cons
|
||||
return (it != eff_factors.end()) ? it->second : 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
This is bit dangerous, exactly how the ALQ value should be interpreted varies
|
||||
between the different VFP tables. The code here assumes - without checking -
|
||||
that it represents gas lift rate.
|
||||
*/
|
||||
inline quantity glir( const fn_args& args ) {
|
||||
double alq_rate = 0;
|
||||
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 alq = quantity { 0.0, measure::identity };
|
||||
|
||||
if (args.schedule_wells.empty()) {
|
||||
return alq;
|
||||
}
|
||||
|
||||
const auto* well = args.schedule_wells.front();
|
||||
if (well->isInjector()) {
|
||||
return alq;
|
||||
}
|
||||
|
||||
auto xwPos = args.wells.find(well->name());
|
||||
if ((xwPos == args.wells.end()) ||
|
||||
(xwPos->second.dynamicStatus == Opm::Well::Status::SHUT))
|
||||
{
|
||||
return alq;
|
||||
}
|
||||
|
||||
alq.value = well->productionControls(args.st).alq_value;
|
||||
|
||||
return alq;
|
||||
}
|
||||
|
||||
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()) {
|
||||
return { 0.0, measure::gas_surface_rate };
|
||||
}
|
||||
|
||||
const auto& sched_state = args.schedule[args.sim_step];
|
||||
|
||||
double alq_rate = 0.0;
|
||||
for (const auto* well : args.schedule_wells) {
|
||||
if (well->isInjector()) {
|
||||
continue;
|
||||
@ -552,8 +596,17 @@ inline quantity glir( const fn_args& args ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const double eff_fac = efac(args.eff_factors, well->name());
|
||||
const auto& production = well->productionControls(args.st);
|
||||
if (! has_alq_type(sched_state, production)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto thisAlqType = alq_type(sched_state, production);
|
||||
if (thisAlqType != Opm::VFPProdTable::ALQ_TYPE::ALQ_GRAT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const double eff_fac = efac(args.eff_factors, well->name());
|
||||
alq_rate += eff_fac * xwPos->second.rates.get(rt::alq, production.alq_value);
|
||||
}
|
||||
|
||||
@ -1526,6 +1579,7 @@ static const std::unordered_map< std::string, ofun > funs = {
|
||||
{ "WEPR", rate< rt::energy, producer > },
|
||||
{ "WTPRHEA", rate< rt::energy, producer > },
|
||||
{ "WGLIR", glir},
|
||||
{ "WALQ", artificial_lift_quantity },
|
||||
{ "WNPR", rate< rt::solvent, producer > },
|
||||
{ "WCPR", rate< rt::polymer, producer > },
|
||||
{ "WSPR", rate< rt::brine, producer > },
|
||||
@ -2373,8 +2427,10 @@ namespace Evaluator {
|
||||
wells, this->group_name(), this->node_.keyword, stepSize, static_cast<int>(sim_step),
|
||||
std::max(0, this->node_.number),
|
||||
this->node_.fip_region,
|
||||
st, simRes.wellSol, simRes.grpNwrkSol, input.reg, input.grid,
|
||||
std::move(efac.factors), input.initial_inplace, simRes.inplace, input.sched.getUnits()
|
||||
st, simRes.wellSol, simRes.grpNwrkSol,
|
||||
input.reg, input.grid, input.sched,
|
||||
std::move(efac.factors), input.initial_inplace, simRes.inplace,
|
||||
input.sched.getUnits()
|
||||
};
|
||||
|
||||
const auto& usys = input.es.getUnits();
|
||||
@ -2435,7 +2491,6 @@ namespace Evaluator {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AquiferValue: public Base
|
||||
{
|
||||
public:
|
||||
@ -2674,9 +2729,10 @@ namespace Evaluator {
|
||||
|
||||
explicit Factory(const Opm::EclipseState& es,
|
||||
const Opm::EclipseGrid& grid,
|
||||
const Opm::Schedule& sched,
|
||||
const Opm::SummaryState& st,
|
||||
const Opm::UDQConfig& udq)
|
||||
: es_(es), grid_(grid), st_(st), udq_(udq)
|
||||
: es_(es), sched_(sched), grid_(grid), st_(st), udq_(udq)
|
||||
{}
|
||||
|
||||
~Factory() = default;
|
||||
@ -2690,6 +2746,7 @@ namespace Evaluator {
|
||||
|
||||
private:
|
||||
const Opm::EclipseState& es_;
|
||||
const Opm::Schedule& sched_;
|
||||
const Opm::EclipseGrid& grid_;
|
||||
const Opm::SummaryState& st_;
|
||||
const Opm::UDQConfig& udq_;
|
||||
@ -2943,7 +3000,7 @@ namespace Evaluator {
|
||||
const fn_args args {
|
||||
{}, "", this->node_->keyword, 0.0, 0, std::max(0, this->node_->number),
|
||||
this->node_->fip_region,
|
||||
this->st_, {}, {}, reg, this->grid_,
|
||||
this->st_, {}, {}, reg, this->grid_, this->sched_,
|
||||
{}, {}, {}, Opm::UnitSystem(Opm::UnitSystem::UnitType::UNIT_TYPE_METRIC)
|
||||
};
|
||||
|
||||
@ -3296,7 +3353,7 @@ SummaryImplementation(const EclipseState& es,
|
||||
};
|
||||
|
||||
Evaluator::Factory evaluatorFactory {
|
||||
es, grid, st, sched.getUDQConfig(sched.size() - 1)
|
||||
es, grid, sched, st, sched.getUDQConfig(sched.size() - 1)
|
||||
};
|
||||
|
||||
this->configureTimeVectors(es, sumcfg);
|
||||
|
@ -193,7 +193,6 @@
|
||||
"WGPRFP",
|
||||
"WTHPFP",
|
||||
"WBHPFP",
|
||||
"WGLIR",
|
||||
"WOGLR",
|
||||
"WGCV",
|
||||
"WGQ",
|
||||
|
@ -10291,6 +10291,9 @@ WWPRH
|
||||
WGLIR
|
||||
'B-*' 'C-*' /
|
||||
|
||||
WALQ
|
||||
'B-*' /
|
||||
|
||||
-- Production cumulatives
|
||||
WOPT
|
||||
'B-*' 'C-*' /
|
||||
|
@ -1155,7 +1155,63 @@ BOOST_AUTO_TEST_CASE(group_group) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
data::Wells glir_alq_data()
|
||||
{
|
||||
auto wells = data::Wells{};
|
||||
|
||||
using opt = data::Rates::opt;
|
||||
auto& b1h = wells["B-1H"];
|
||||
auto& b2h = wells["B-2H"];
|
||||
auto& b3h = wells["B-3H"];
|
||||
|
||||
b1h.rates.set(opt::alq, 1234.56*unit::cubic(unit::meter)/unit::day);
|
||||
b2h.rates.set(opt::alq, 2345.67*unit::cubic(unit::meter)/unit::day);
|
||||
b3h.rates.set(opt::alq, 3456.78*unit::cubic(unit::meter)/unit::day);
|
||||
|
||||
return wells;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GLIR_and_ALQ)
|
||||
{
|
||||
const auto deck = Parser{}.parseFile("2_WLIFT_MODEL5_NOINC.DATA");
|
||||
const auto es = EclipseState { deck };
|
||||
const auto sched = Schedule { deck, es, std::make_shared<Python>() };
|
||||
const auto cfg = SummaryConfig { deck, sched, es.fieldProps(), es.aquifer() };
|
||||
const auto name = "glir_and_alq";
|
||||
|
||||
WorkArea ta{ "summary_test" };
|
||||
ta.makeSubDir(name);
|
||||
|
||||
const auto wellData = glir_alq_data();
|
||||
|
||||
auto st = SummaryState { TimeService::now() };
|
||||
auto writer = out::Summary{ es, cfg, es.getInputGrid(), sched, name };
|
||||
writer.eval(st, 0, 0*day, wellData, {}, {}, {}, {}, {});
|
||||
writer.add_timestep(st, 0, false);
|
||||
|
||||
writer.eval(st, 1, 1*day, wellData, {}, {}, {}, {}, {});
|
||||
writer.add_timestep(st, 1, false);
|
||||
|
||||
writer.eval(st, 2, 2*day, wellData, {}, {}, {}, {}, {});
|
||||
writer.add_timestep(st, 2, false);
|
||||
writer.write();
|
||||
|
||||
auto res = readsum(name);
|
||||
const auto* resp = res.get();
|
||||
|
||||
BOOST_CHECK_CLOSE(1234.56, ecl_sum_get_well_var(resp, 1, "B-1H", "WGLIR"), 1.0e-5);
|
||||
BOOST_CHECK_CLOSE(2345.67, ecl_sum_get_well_var(resp, 1, "B-2H", "WGLIR"), 1.0e-5);
|
||||
BOOST_CHECK_CLOSE(3456.78, ecl_sum_get_well_var(resp, 1, "B-3H", "WGLIR"), 1.0e-5);
|
||||
|
||||
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_AUTO_TEST_CASE(connection_kewords) {
|
||||
setup cfg( "test_summary_connection" );
|
||||
|
Loading…
Reference in New Issue
Block a user