Factor out eval() method from Summary::add_timestep()

This commit is contained in:
Joakim Hove 2019-05-11 11:26:34 +02:00
parent d554334316
commit 07b02ed151
3 changed files with 125 additions and 56 deletions

View File

@ -43,37 +43,52 @@ namespace Opm {
namespace out {
class Summary {
public:
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule& );
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule&, const std::string& );
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule&, const char* basename );
public:
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule& );
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule&, const std::string& );
Summary( const EclipseState&, const SummaryConfig&, const EclipseGrid&, const Schedule&, const char* basename );
void add_timestep(int report_step,
double secs_elapsed,
const EclipseState& es,
const Schedule& schedule,
const data::Wells&,
const std::map<std::string, double>& single_values,
const std::map<std::string, std::vector<double>>& region_values = {},
const std::map<std::pair<std::string, int>, double>& block_values = {});
void add_timestep(int report_step,
double secs_elapsed,
const EclipseState& es,
const Schedule& schedule,
const data::Wells&,
const std::map<std::string, double>& single_values,
const std::map<std::string, std::vector<double>>& region_values = {},
const std::map<std::pair<std::string, int>, double>& block_values = {});
void write();
~Summary();
void eval(SummaryState& summary_state,
int report_step,
double secs_elapsed,
const EclipseState& es,
const Schedule& schedule,
const data::Wells&,
const std::map<std::string, double>& single_values,
const std::map<std::string, std::vector<double>>& region_values = {},
const std::map<std::pair<std::string, int>, double>& block_values = {}) const;
const SummaryState& get_restart_vectors() const;
void reset_cumulative_quantities(const SummaryState& rstrt);
private:
class keyword_handlers;
~Summary();
const EclipseGrid& grid;
out::RegionCache regionCache;
ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free > ecl_sum;
std::unique_ptr< keyword_handlers > handlers;
double prev_time_elapsed = 0;
SummaryState prev_state;
const SummaryState& get_restart_vectors() const;
void reset_cumulative_quantities(const SummaryState& rstrt);
void write() const;
private:
void internal_store(const SummaryState& summary_state, int report_step, double seconds_elapsed);
class keyword_handlers;
const EclipseGrid& grid;
out::RegionCache regionCache;
ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free > ecl_sum;
std::unique_ptr< keyword_handlers > handlers;
double prev_time_elapsed = 0;
SummaryState prev_state;
};
}

View File

@ -1446,14 +1446,15 @@ well_efficiency_factors( const ecl::smspec_node* node,
return efac;
}
void Summary::add_timestep( int report_step,
double secs_elapsed,
const EclipseState& es,
const Schedule& schedule,
const data::Wells& wells ,
const std::map<std::string, double>& single_values,
const std::map<std::string, std::vector<double>>& region_values,
const std::map<std::pair<std::string, int>, double>& block_values) {
void Summary::eval( SummaryState& st,
int report_step,
double secs_elapsed,
const EclipseState& es,
const Schedule& schedule,
const data::Wells& wells ,
const std::map<std::string, double>& single_values,
const std::map<std::string, std::vector<double>>& region_values,
const std::map<std::pair<std::string, int>, double>& block_values) const {
if (secs_elapsed < this->prev_time_elapsed) {
const auto& usys = es.getUnits();
@ -1470,9 +1471,7 @@ 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;
SummaryState st;
/* 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.
@ -1563,38 +1562,57 @@ void Summary::add_timestep( int report_step,
st.update(*nodeptr, output_value);
}
}
eval_udq(schedule, sim_step, st);
{
const ecl_sum_type * ecl_sum = this->ecl_sum.get();
const ecl_smspec_type * smspec = ecl_sum_get_smspec(ecl_sum);
auto num_nodes = ecl_smspec_num_nodes(smspec);
for (int node_index = 0; node_index < num_nodes; node_index++) {
const auto& smspec_node = ecl_smspec_iget_node(smspec, node_index);
// The TIME node is treated specially, it is created internally in
// the ecl_sum instance when the timestep is created - and
// furthermore it is not in st SummaryState instance.
if (smspec_node.get_params_index() == ecl_smspec_get_time_index(smspec))
continue;
}
const std::string key = smspec_node.get_gen_key1();
if (st.has(key))
ecl_sum_tstep_iset(tstep, smspec_node.get_params_index(), st.get(key));
/*
else
OpmLog::warning("Have configured summary variable " + key + " for summary output - but it has not been calculated");
*/
}
void Summary::internal_store(const SummaryState& st, int report_step, double secs_elapsed) {
auto* tstep = ecl_sum_add_tstep( this->ecl_sum.get(), report_step, secs_elapsed );
const ecl_sum_type * ecl_sum = this->ecl_sum.get();
const ecl_smspec_type * smspec = ecl_sum_get_smspec(ecl_sum);
auto num_nodes = ecl_smspec_num_nodes(smspec);
for (int node_index = 0; node_index < num_nodes; node_index++) {
const auto& smspec_node = ecl_smspec_iget_node(smspec, node_index);
// The TIME node is treated specially, it is created internally in
// the ecl_sum instance when the timestep is created - and
// furthermore it is not in st SummaryState instance.
if (smspec_node.get_params_index() == ecl_smspec_get_time_index(smspec))
continue;
const std::string key = smspec_node.get_gen_key1();
if (st.has(key))
ecl_sum_tstep_iset(tstep, smspec_node.get_params_index(), st.get(key));
/*
else
OpmLog::warning("Have configured summary variable " + key + " for summary output - but it has not been calculated");
*/
}
}
void Summary::add_timestep( int report_step,
double secs_elapsed,
const EclipseState& es,
const Schedule& schedule,
const data::Wells& wells ,
const std::map<std::string, double>& single_values,
const std::map<std::string, std::vector<double>>& region_values,
const std::map<std::pair<std::string, int>, double>& block_values) {
SummaryState st;
this->eval(st, report_step, secs_elapsed, es, schedule, wells, single_values, region_values, block_values);
this->internal_store(st, report_step, secs_elapsed);
this->prev_state = st;
this->prev_time_elapsed = secs_elapsed;
}
void Summary::write() {
void Summary::write() const {
ecl_sum_fwrite( this->ecl_sum.get() );
}
Summary::~Summary() {}
const SummaryState& Summary::get_restart_vectors() const

View File

@ -219,7 +219,7 @@ static data::Wells result_wells() {
data::Connection well2_comp1 { 1 , crates2, 1.10 , 123.4, 212.1, 0.78, 0.0, 12.34};
data::Connection well2_comp2 { 101, crates3, 1.11 , 123.4, 150.6, 0.001, 0.89, 100.0};
data::Connection well3_comp1 { 2 , crates3, 1.11 , 123.4, 456.78, 0.0, 0.15, 432.1};
data::Connection well6_comp1 { 5 , crates6, 6.11 , 623.4, 656.78, 0.0, 0.65, 632.1};
data::Connection well6_comp1 { 5 , crates6, 6.11 , 623.4, 656.78, 0.0, 0.65, 632.1};
/*
The completions
*/
@ -284,6 +284,20 @@ struct setup {
};
void compare(const SummaryState& st, const ecl_sum_type * ecl_sum, int tstep) {
for (const auto& key_value : st) {
const std::string& key = key_value.first;
double value = key_value.second;
if (ecl_sum_has_general_var(ecl_sum, key.c_str()))
// The ecl_sum value has been on disk where it has been stored as float
// - i.e. we must use BOOST_CHECK_CLOSE()
BOOST_CHECK_CLOSE(value, ecl_sum_get_general_var(ecl_sum, tstep, key.c_str()), 1e-5);
}
}
BOOST_AUTO_TEST_SUITE(Summary)
/*
@ -298,12 +312,30 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
util_make_path( "PATH" );
cfg.name = "PATH/CASE";
SummaryState st0;
SummaryState st1;
SummaryState st2;
/*
The state of the summary object is modified in the add_timestep() routine,
therefor the eval and add_timestep() calls must be carefully interleaved -
the perils of state!
*/
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
writer.eval(st0, 0, 0*day, cfg.es, cfg.schedule, cfg.wells, {});
writer.add_timestep( 0, 0 * day, cfg.es, cfg.schedule, cfg.wells , {});
writer.eval(st1, 1, 1*day, cfg.es, cfg.schedule, cfg.wells, {});
writer.add_timestep( 1, 1 * day, cfg.es, cfg.schedule, cfg.wells , {});
writer.eval(st2, 2, 2*day, cfg.es, cfg.schedule, cfg.wells, {});
writer.add_timestep( 2, 2 * day, cfg.es, cfg.schedule, cfg.wells , {});
writer.write();
auto res = readsum( cfg.name );
const auto* resp = res.get();
@ -499,6 +531,10 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
BOOST_CHECK_CLOSE( 0.2, ecl_sum_get_well_var( resp, 1, "W_1", "WTHPH" ), 1e-5 );
BOOST_CHECK_CLOSE( 1.2, ecl_sum_get_well_var( resp, 1, "W_2", "WTHPH" ), 1e-5 );
BOOST_CHECK_CLOSE( 2.2, ecl_sum_get_well_var( resp, 1, "W_3", "WTHPH" ), 1e-5 );
compare(st0, resp, 0);
compare(st1, resp, 1);
compare(st2, resp, 2);
}
BOOST_AUTO_TEST_CASE(udq_keywords) {