Match timestep for well info

Decrement timestep where necessary to avoid well post-configuration.

Consider the following:

.
.
.

WELLSPECS
 'W1'  'G1' ... /

TSTEP
 2*1 /

WELLSPECS
 'W1'  'G2' .../

TSTEP
 2*1 /

In that case the parent group of W1 is changed after two timesteps. At timestep
two the Group parent will indicate G2, while the GOPT:G2 at timestep two should
be reported for what has progressed up until timestep two.
This commit is contained in:
Lars Petter Øren Hauge
2018-03-07 08:57:58 +01:00
parent 35ebab0b69
commit bbf2ae26f1
3 changed files with 46 additions and 48 deletions

View File

@@ -151,7 +151,8 @@ struct quantity {
struct fn_args {
const std::vector< const Well* >& schedule_wells;
double duration;
size_t timestep;
const int report_step;
const int sim_step;
int num;
const data::Wells& wells;
const out::RegionCache& regionCache;
@@ -218,7 +219,7 @@ inline quantity rate( const fn_args& args ) {
template< bool injection >
inline quantity flowing( const fn_args& args ) {
const auto& wells = args.wells;
const auto ts = args.timestep;
const auto ts = args.report_step;
auto pred = [&wells,ts]( const Well* w ) {
const auto& name = w->name();
return w->isInjector( ts ) == injection
@@ -284,31 +285,29 @@ inline quantity thp( const fn_args& args ) {
}
inline quantity bhp_history( const fn_args& args ) {
if( args.timestep == 0 ) return { 0.0, measure::pressure };
if( args.schedule_wells.empty() ) return { 0.0, measure::pressure };
const auto timestep = args.timestep - 1;
const Well* sched_well = args.schedule_wells.front();
double bhp_hist;
if ( sched_well->isProducer( timestep ) )
bhp_hist = sched_well->getProductionProperties( timestep ).BHPH;
if ( sched_well->isProducer( args.sim_step ) )
bhp_hist = sched_well->getProductionProperties( args.sim_step ).BHPH;
else
bhp_hist = sched_well->getInjectionProperties( timestep ).BHPH;
bhp_hist = sched_well->getInjectionProperties( args.sim_step ).BHPH;
return { bhp_hist, measure::pressure };
}
inline quantity thp_history( const fn_args& args ) {
if( args.timestep == 0 ) return { 0.0, measure::pressure };
if( args.schedule_wells.empty() ) return { 0.0, measure::pressure };
const auto timestep = args.timestep - 1;
const Well* sched_well = args.schedule_wells.front();
double thp_hist;
if ( sched_well->isProducer( timestep ) )
thp_hist = sched_well->getProductionProperties( timestep ).THPH;
if ( sched_well->isProducer( args.sim_step ) )
thp_hist = sched_well->getProductionProperties( args.sim_step ).THPH;
else
thp_hist = sched_well->getInjectionProperties( timestep ).THPH;
thp_hist = sched_well->getInjectionProperties( args.sim_step ).THPH;
return { thp_hist, measure::pressure };
}
@@ -329,40 +328,30 @@ inline quantity production_history( const fn_args& args ) {
* special-case timestep N == 0, and for all other timesteps look up the
* value *reported* at N-1 which applies to timestep N.
*/
if( args.timestep == 0 ) return { 0.0, rate_unit< phase >() };
const auto timestep = args.timestep - 1;
double sum = 0.0;
for( const Well* sched_well : args.schedule_wells )
sum += sched_well->production_rate( phase, timestep );
sum += sched_well->production_rate( phase, args.sim_step );
return { sum, rate_unit< phase >() };
}
template< Phase phase >
inline quantity injection_history( const fn_args& args ) {
if( args.timestep == 0 ) return { 0.0, rate_unit< phase >() };
const auto timestep = args.timestep - 1;
double sum = 0.0;
for( const Well* sched_well : args.schedule_wells )
sum += sched_well->injection_rate( phase, timestep );
sum += sched_well->injection_rate( phase, args.sim_step );
return { sum, rate_unit< phase >() };
}
inline quantity res_vol_production_target( const fn_args& args ) {
if( args.timestep == 0 ) return { 0.0, measure::rate };
const auto timestep = args.timestep - 1;
double sum = 0.0;
for( const Well* sched_well : args.schedule_wells )
if (sched_well->getProductionProperties(timestep).predictionMode)
sum += sched_well->getProductionProperties( timestep ).ResVRate;
if (sched_well->getProductionProperties(args.sim_step).predictionMode)
sum += sched_well->getProductionProperties( args.sim_step ).ResVRate;
return { sum, measure::rate };
}
@@ -761,7 +750,7 @@ static const std::unordered_map< std::string, UnitSystem::measure> block_units =
inline std::vector< const Well* > find_wells( const Schedule& schedule,
const smspec_node_type* node,
size_t timestep,
const int sim_step,
const out::RegionCache& regionCache ) {
const auto* name = smspec_node_get_wgname( node );
@@ -776,7 +765,7 @@ inline std::vector< const Well* > find_wells( const Schedule& schedule,
if( type == ECL_SMSPEC_GROUP_VAR ) {
if( !schedule.hasGroup( name ) ) return {};
return schedule.getWells( name, timestep );
return schedule.getWells( name, sim_step );
}
if( type == ECL_SMSPEC_FIELD_VAR )
@@ -941,7 +930,8 @@ Summary::Summary( const EclipseState& st,
const fn_args no_args { dummy_wells, // Wells from Schedule object
0, // Duration of time step
0, // Timestep number
0, // Report step
0, // Simulation step
node.num(), // NUMS value for the summary output.
{}, // Well results - data::Wells
{}, // Region <-> cell mappings.
@@ -986,7 +976,7 @@ std::vector< std::pair< std::string, double > >
well_efficiency_factors( const smspec_node_type* type,
const Schedule& schedule,
const std::vector< const Well* >& schedule_wells,
size_t timestep ) {
const int sim_step ) {
std::vector< std::pair< std::string, double > > efac;
if( smspec_node_get_var_type(type) != ECL_SMSPEC_GROUP_VAR
@@ -998,22 +988,22 @@ well_efficiency_factors( const smspec_node_type* type,
const bool is_group = smspec_node_get_var_type(type) == ECL_SMSPEC_GROUP_VAR;
const bool is_rate = !smspec_node_is_total( type );
const auto &groupTree = schedule.getGroupTree(timestep);
const auto &groupTree = schedule.getGroupTree(sim_step);
for( const auto* well : schedule_wells ) {
double eff_factor = well->getEfficiencyFactor(timestep);
double eff_factor = well->getEfficiencyFactor(sim_step);
if ( !well->hasBeenDefined( timestep ) )
if ( !well->hasBeenDefined( sim_step ) )
continue;
const auto* node = &schedule.getGroup(well->getGroupName(timestep));
const auto* node = &schedule.getGroup(well->getGroupName(sim_step));
while(true){
if(( is_group
&& is_rate
&& node->name() == smspec_node_get_wgname(type) ))
break;
eff_factor *= node->getGroupEfficiencyFactor( timestep );
eff_factor *= node->getGroupEfficiencyFactor( sim_step );
const auto& parent = groupTree.parent( node->name() );
if( !schedule.hasGroup( parent ) )
@@ -1037,18 +1027,24 @@ void Summary::add_timestep( int report_step,
auto* tstep = ecl_sum_add_tstep( this->ecl_sum.get(), report_step, secs_elapsed );
const double duration = secs_elapsed - this->prev_time_elapsed;
const size_t timestep = report_step;
/* report_step is the number of the file we are about to write - i.e. for instance CASE.S$report_step
* for the data in a non-unified summary file.
* sim_step is the timestep which has been effective in the simulator, and as such is the value
* necessary to use when consulting the Schedule object. */
const auto sim_step = std::max( 0, report_step - 1 );
for( auto& f : this->handlers->handlers ) {
const int num = smspec_node_get_num( f.first );
const auto* genkey = smspec_node_get_gen_key1( f.first );
const auto schedule_wells = find_wells( schedule, f.first, timestep, this->regionCache );
auto eff_factors = well_efficiency_factors( f.first, schedule, schedule_wells, timestep );
const auto schedule_wells = find_wells( schedule, f.first, sim_step, this->regionCache );
auto eff_factors = well_efficiency_factors( f.first, schedule, schedule_wells, sim_step );
const auto val = f.second( { schedule_wells,
duration,
timestep,
report_step,
sim_step,
num,
wells,
this->regionCache,