Add More Segment Level Summary Vectors
In particular, add support for
SxFT - Cumulative flow of phase 'x'
SxFV - Free flow velocity of phase 'x'
SxHF - Free flow holdup fraction of phase 'x'
SxVIS - Phase viscosity of phase 'x'
The last three of these were added to the RFT file in 802a401a8
,
but are also useful in the summary output file. In the interest of
avoiding duplicate logic, refactor the existing segment-related
quantity calculation/extraction in terms of callbacks.
This commit is contained in:
parent
4fb2a3557b
commit
5b6f064804
@ -1146,9 +1146,9 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto kw_whitelist = std::vector<const char*> {
|
const auto kw_whitelist = std::vector<const char*> {
|
||||||
"SOFR" , "SOFRF", "SOFRS",
|
"SOFR" , "SOFRF", "SOFRS", "SOFT", "SOFV", "SOHF", "SOVIS",
|
||||||
"SGFR" , "SGFRF", "SGFRS",
|
"SGFR" , "SGFRF", "SGFRS", "SGFT", "SGFV", "SGHF", "SGVIS",
|
||||||
"SWFR" ,
|
"SWFR" , "SWFT", "SWFV", "SWHF", "SWVIS",
|
||||||
"SGOR" , "SOGR" , "SWCT" , "SWGR" ,
|
"SGOR" , "SOGR" , "SWCT" , "SWGR" ,
|
||||||
"SPR" , "SPRD" , "SPRDH", "SPRDF", "SPRDA",
|
"SPR" , "SPRD" , "SPRDH", "SPRDF", "SPRDA",
|
||||||
};
|
};
|
||||||
|
@ -7,19 +7,31 @@
|
|||||||
"SGFR",
|
"SGFR",
|
||||||
"SGFRF",
|
"SGFRF",
|
||||||
"SGFRS",
|
"SGFRS",
|
||||||
|
"SGFT",
|
||||||
|
"SGFV",
|
||||||
|
"SGHF",
|
||||||
"SGOR",
|
"SGOR",
|
||||||
|
"SGVIS",
|
||||||
"SOFR",
|
"SOFR",
|
||||||
"SOFRF",
|
"SOFRF",
|
||||||
"SOFRS",
|
"SOFRS",
|
||||||
|
"SOFT",
|
||||||
|
"SOFV",
|
||||||
"SOGR",
|
"SOGR",
|
||||||
|
"SOHF",
|
||||||
|
"SOVIS",
|
||||||
"SPR",
|
"SPR",
|
||||||
"SWFR",
|
|
||||||
"SWCT",
|
|
||||||
"SWGR",
|
|
||||||
"SPRD",
|
"SPRD",
|
||||||
|
"SPRDA",
|
||||||
"SPRDF",
|
"SPRDF",
|
||||||
"SPRDH",
|
"SPRDH",
|
||||||
"SPRDA"
|
"SWCT",
|
||||||
|
"SWFR",
|
||||||
|
"SWFT",
|
||||||
|
"SWFV",
|
||||||
|
"SWGR",
|
||||||
|
"SWHF",
|
||||||
|
"SWVIS"
|
||||||
],
|
],
|
||||||
"comment": "This list is incomplete",
|
"comment": "This list is incomplete",
|
||||||
"items": [
|
"items": [
|
||||||
|
@ -1003,10 +1003,12 @@ quantity crate_resv( const fn_args& args ) {
|
|||||||
return { v, rate_unit<rt::reservoir_oil>() };
|
return { v, rate_unit<rt::reservoir_oil>() };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <rt phase>
|
template <typename GetValue>
|
||||||
inline quantity srate(const fn_args& args)
|
quantity segment_quantity(const fn_args& args,
|
||||||
|
const measure m,
|
||||||
|
GetValue&& getValue)
|
||||||
{
|
{
|
||||||
const quantity zero = { 0, rate_unit<phase>() };
|
const auto zero = quantity { 0.0, m };
|
||||||
if (args.schedule_wells.empty()) {
|
if (args.schedule_wells.empty()) {
|
||||||
return zero;
|
return zero;
|
||||||
}
|
}
|
||||||
@ -1027,16 +1029,70 @@ inline quantity srate(const fn_args& args)
|
|||||||
return zero;
|
return zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto eff_fac = efac(args.eff_factors, name);
|
return { getValue(segPos->second), m };
|
||||||
|
}
|
||||||
|
|
||||||
// Switch sign of rate--opposite convention in Flow vs ECLIPSE.
|
template <Opm::data::SegmentPressures::Value ix>
|
||||||
const auto v = -segPos->second.rates.get(phase, 0.0) * eff_fac;
|
inline quantity segpress(const fn_args& args)
|
||||||
|
{
|
||||||
|
return segment_quantity(args, measure::pressure,
|
||||||
|
[](const Opm::data::Segment& segment)
|
||||||
|
{
|
||||||
|
return segment.pressures[ix];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if ((phase == rt::polymer) || (phase == rt::brine)) {
|
template <rt phase>
|
||||||
return { v, measure::mass_rate };
|
inline quantity srate(const fn_args& args)
|
||||||
}
|
{
|
||||||
|
const auto m = ((phase == rt::polymer) || (phase == rt::brine))
|
||||||
|
? measure::mass_rate
|
||||||
|
: rate_unit<phase>();
|
||||||
|
|
||||||
return { v, rate_unit<phase>() };
|
return segment_quantity(args, m,
|
||||||
|
[&args](const Opm::data::Segment& segment)
|
||||||
|
{
|
||||||
|
// Note: Opposite flow rate sign conventions in Flow vs. ECLIPSE.
|
||||||
|
return - segment.rates.get(phase, 0.0)
|
||||||
|
* efac(args.eff_factors, args.schedule_wells.front()->name());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Opm::data::SegmentPhaseQuantity::Item p>
|
||||||
|
double segment_phase_quantity_value(const Opm::data::SegmentPhaseQuantity& q)
|
||||||
|
{
|
||||||
|
return q.has(p) ? q.get(p) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Opm::data::SegmentPhaseQuantity::Item p>
|
||||||
|
quantity segment_flow_velocity(const fn_args& args)
|
||||||
|
{
|
||||||
|
return segment_quantity(args, measure::pipeflow_velocity,
|
||||||
|
[](const Opm::data::Segment& segment)
|
||||||
|
{
|
||||||
|
// Note: Opposite velocity sign conventions in Flow vs. ECLIPSE.
|
||||||
|
return - segment_phase_quantity_value<p>(segment.velocity);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Opm::data::SegmentPhaseQuantity::Item p>
|
||||||
|
quantity segment_holdup_fraction(const fn_args& args)
|
||||||
|
{
|
||||||
|
return segment_quantity(args, measure::identity,
|
||||||
|
[](const Opm::data::Segment& segment)
|
||||||
|
{
|
||||||
|
return segment_phase_quantity_value<p>(segment.holdup);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Opm::data::SegmentPhaseQuantity::Item p>
|
||||||
|
quantity segment_viscosity(const fn_args& args)
|
||||||
|
{
|
||||||
|
return segment_quantity(args, measure::viscosity,
|
||||||
|
[](const Opm::data::Segment& segment)
|
||||||
|
{
|
||||||
|
return segment_phase_quantity_value<p>(segment.viscosity);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline quantity trans_factors ( const fn_args& args ) {
|
inline quantity trans_factors ( const fn_args& args ) {
|
||||||
@ -1068,35 +1124,6 @@ inline quantity trans_factors ( const fn_args& args ) {
|
|||||||
return { connPos->trans_factor, measure::transmissibility };
|
return { connPos->trans_factor, measure::transmissibility };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Opm::data::SegmentPressures::Value ix>
|
|
||||||
inline quantity segpress ( const fn_args& args )
|
|
||||||
{
|
|
||||||
const quantity zero = { 0, measure::pressure };
|
|
||||||
|
|
||||||
if (args.schedule_wells.empty())
|
|
||||||
return zero;
|
|
||||||
|
|
||||||
const auto* well = args.schedule_wells.front();
|
|
||||||
auto xwPos = args.wells.find(well->name());
|
|
||||||
if ((xwPos == args.wells.end()) ||
|
|
||||||
(xwPos->second.dynamicStatus == Opm::Well::Status::SHUT))
|
|
||||||
{
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like connection rate we need to look up a connection with offset 0.
|
|
||||||
const size_t segNumber = args.num;
|
|
||||||
|
|
||||||
const auto& well_data = xwPos->second;
|
|
||||||
const auto& segment = well_data.segments.find(segNumber);
|
|
||||||
|
|
||||||
if (segment == well_data.segments.end()) {
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { segment->second.pressures[ix], measure::pressure };
|
|
||||||
}
|
|
||||||
|
|
||||||
inline quantity wstat( const fn_args& args ) {
|
inline quantity wstat( const fn_args& args ) {
|
||||||
const quantity zero = { Opm::WStat::numeric::UNKNOWN, measure::identity};
|
const quantity zero = { Opm::WStat::numeric::UNKNOWN, measure::identity};
|
||||||
if (args.schedule_wells.empty())
|
if (args.schedule_wells.empty())
|
||||||
@ -2185,12 +2212,24 @@ static const std::unordered_map< std::string, ofun > funs = {
|
|||||||
|
|
||||||
// Segment summary vectors for multi-segmented wells.
|
// Segment summary vectors for multi-segmented wells.
|
||||||
{ "SOFR" , srate<rt::oil> },
|
{ "SOFR" , srate<rt::oil> },
|
||||||
|
{ "SOFT" , mul(srate<rt::oil>, duration) },
|
||||||
{ "SOFRF", sub(srate<rt::oil>, srate<rt::vaporized_oil>) }, // Free oil flow
|
{ "SOFRF", sub(srate<rt::oil>, srate<rt::vaporized_oil>) }, // Free oil flow
|
||||||
{ "SOFRS", srate<rt::vaporized_oil> }, // Solution oil flow
|
{ "SOFRS", srate<rt::vaporized_oil> }, // Solution oil flow
|
||||||
|
{ "SOFV" , segment_flow_velocity<Opm::data::SegmentPhaseQuantity::Item::Oil> },
|
||||||
|
{ "SOHF" , segment_holdup_fraction<Opm::data::SegmentPhaseQuantity::Item::Oil> },
|
||||||
|
{ "SOVIS", segment_viscosity<Opm::data::SegmentPhaseQuantity::Item::Oil> },
|
||||||
{ "SGFR" , srate<rt::gas> },
|
{ "SGFR" , srate<rt::gas> },
|
||||||
|
{ "SGFT" , mul(srate<rt::gas>, duration) },
|
||||||
{ "SGFRF", sub(srate<rt::gas>, srate<rt::dissolved_gas>) }, // Free gas flow
|
{ "SGFRF", sub(srate<rt::gas>, srate<rt::dissolved_gas>) }, // Free gas flow
|
||||||
{ "SGFRS", srate<rt::dissolved_gas> }, // Solution gas flow
|
{ "SGFRS", srate<rt::dissolved_gas> }, // Solution gas flow
|
||||||
|
{ "SGFV" , segment_flow_velocity<Opm::data::SegmentPhaseQuantity::Item::Gas> },
|
||||||
|
{ "SGHF" , segment_holdup_fraction<Opm::data::SegmentPhaseQuantity::Item::Gas> },
|
||||||
|
{ "SGVIS", segment_viscosity<Opm::data::SegmentPhaseQuantity::Item::Gas> },
|
||||||
{ "SWFR" , srate<rt::wat> },
|
{ "SWFR" , srate<rt::wat> },
|
||||||
|
{ "SWFT" , mul(srate<rt::wat>, duration) },
|
||||||
|
{ "SWFV" , segment_flow_velocity<Opm::data::SegmentPhaseQuantity::Item::Water> },
|
||||||
|
{ "SWHF" , segment_holdup_fraction<Opm::data::SegmentPhaseQuantity::Item::Water> },
|
||||||
|
{ "SWVIS", segment_viscosity<Opm::data::SegmentPhaseQuantity::Item::Water> },
|
||||||
{ "SGOR" , div(srate<rt::gas>, srate<rt::oil>) },
|
{ "SGOR" , div(srate<rt::gas>, srate<rt::oil>) },
|
||||||
{ "SOGR" , div(srate<rt::oil>, srate<rt::gas>) },
|
{ "SOGR" , div(srate<rt::oil>, srate<rt::gas>) },
|
||||||
{ "SWCT" , div(srate<rt::wat>, sum(srate<rt::wat>, srate<rt::oil>)) },
|
{ "SWCT" , div(srate<rt::wat>, sum(srate<rt::wat>, srate<rt::oil>)) },
|
||||||
|
@ -111,6 +111,30 @@ SOFR
|
|||||||
'PROD01' 21 /
|
'PROD01' 21 /
|
||||||
/
|
/
|
||||||
|
|
||||||
|
SOFT
|
||||||
|
'PROD01' 1 /
|
||||||
|
'PROD01' 10 /
|
||||||
|
'PROD01' 21 /
|
||||||
|
/
|
||||||
|
|
||||||
|
SOHF
|
||||||
|
'PROD01' 1 /
|
||||||
|
'PROD01' 10 /
|
||||||
|
'PROD01' 21 /
|
||||||
|
/
|
||||||
|
|
||||||
|
SOFV
|
||||||
|
'PROD01' 1 /
|
||||||
|
'PROD01' 10 /
|
||||||
|
'PROD01' 21 /
|
||||||
|
/
|
||||||
|
|
||||||
|
SOVIS
|
||||||
|
'PROD01' 1 /
|
||||||
|
'PROD01' 10 /
|
||||||
|
'PROD01' 21 /
|
||||||
|
/
|
||||||
|
|
||||||
SOFRF
|
SOFRF
|
||||||
'PROD01' 1 /
|
'PROD01' 1 /
|
||||||
'PROD01' 10 /
|
'PROD01' 10 /
|
||||||
@ -132,6 +156,22 @@ SGFR
|
|||||||
'PROD01' /
|
'PROD01' /
|
||||||
/
|
/
|
||||||
|
|
||||||
|
SGFT
|
||||||
|
'PROD01' /
|
||||||
|
/
|
||||||
|
|
||||||
|
SGHF
|
||||||
|
'PROD01' /
|
||||||
|
/
|
||||||
|
|
||||||
|
SGFV
|
||||||
|
'PROD01' /
|
||||||
|
/
|
||||||
|
|
||||||
|
SGVIS
|
||||||
|
'PROD01' /
|
||||||
|
/
|
||||||
|
|
||||||
SGFRF
|
SGFRF
|
||||||
'PROD01' 2 /
|
'PROD01' 2 /
|
||||||
/
|
/
|
||||||
@ -151,6 +191,18 @@ SPR
|
|||||||
SWFR
|
SWFR
|
||||||
/
|
/
|
||||||
|
|
||||||
|
SWFT
|
||||||
|
/
|
||||||
|
|
||||||
|
SWHF
|
||||||
|
/
|
||||||
|
|
||||||
|
SWFV
|
||||||
|
/
|
||||||
|
|
||||||
|
SWVIS
|
||||||
|
/
|
||||||
|
|
||||||
SWGR
|
SWGR
|
||||||
1* 3 /
|
1* 3 /
|
||||||
/
|
/
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user