Merge pull request #2044 from joakim-hove/include-udq-summary

Include udq summary
This commit is contained in:
Joakim Hove 2020-10-26 11:18:56 +01:00 committed by GitHub
commit cab2e29724
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 141 additions and 7 deletions

View File

@ -36,6 +36,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
@ -2522,6 +2523,7 @@ private:
SummaryOutputParameters outputParameters_{};
std::vector<EvalPtr> requiredRestartParameters_{};
std::vector<EvalPtr> udq_parameters;
std::vector<std::string> valueKeys_{};
std::vector<MiniStep> unwritten_{};
@ -2538,6 +2540,8 @@ private:
void configureRequiredRestartParameters(const SummaryConfig& sumcfg,
const Schedule& sched);
void configureUDQ(const SummaryConfig& summary_config, const Schedule& sched);
MiniStep& getNextMiniStep(const int report_step);
const MiniStep& lastUnwritten() const;
@ -2563,6 +2567,7 @@ SummaryImplementation(const EclipseState& es,
this->configureTimeVectors(es, sumcfg);
this->configureSummaryInput(es, sumcfg, grid, sched);
this->configureRequiredRestartParameters(sumcfg, sched);
this->configureUDQ(sumcfg, sched);
}
void Opm::out::Summary::SummaryImplementation::
@ -2611,6 +2616,9 @@ eval(const EclipseState& es,
for (auto& evalPtr : this->requiredRestartParameters_) {
evalPtr->update(sim_step, duration, input, simRes, st);
}
for (auto& eval_ptr : this->udq_parameters)
eval_ptr->update(sim_step, duration, input, simRes, st);
}
void Opm::out::Summary::SummaryImplementation::write()
@ -2759,6 +2767,105 @@ configureSummaryInput(const EclipseState& es,
reportUnsupportedKeywords(std::move(unsuppkw));
}
/*
These nodes are added to the summary evaluation list because they are
requested by the UDQ system. In the case of well and group variables the code
will all nodes for all wells / groups - irrespective of what has been
requested in the UDQ code.
*/
std::vector<Opm::EclIO::SummaryNode> make_default_nodes(const std::string& keyword, const Opm::Schedule& sched) {
auto nodes = std::vector<Opm::EclIO::SummaryNode> {};
auto category = Opm::parseKeywordCategory(keyword);
auto type = Opm::parseKeywordType(keyword);
switch (category) {
case Opm::EclIO::SummaryNode::Category::Field:
{
Opm::EclIO::SummaryNode node;
node.keyword = keyword;
node.category = category;
node.type = type;
nodes.push_back(node);
}
break;
case Opm::EclIO::SummaryNode::Category::Miscellaneous:
{
Opm::EclIO::SummaryNode node;
node.keyword = keyword;
node.category = category;
node.type = type;
nodes.push_back(node);
}
break;
case Opm::EclIO::SummaryNode::Category::Well:
{
for (const auto& well : sched.wellNames()) {
Opm::EclIO::SummaryNode node;
node.keyword = keyword;
node.category = category;
node.type = type;
node.wgname = well;
nodes.push_back(node);
}
}
break;
case Opm::EclIO::SummaryNode::Category::Group:
{
for (const auto& group : sched.groupNames()) {
Opm::EclIO::SummaryNode node;
node.keyword = keyword;
node.category = category;
node.type = type;
node.wgname = group;
nodes.push_back(node);
}
}
break;
default:
throw std::logic_error(fmt::format("make_default_nodes does not yet support: {}", keyword));
}
return nodes;
}
void Opm::out::Summary::SummaryImplementation::configureUDQ(const SummaryConfig& summary_config, const Schedule& sched) {
auto nodes = std::vector<Opm::EclIO::SummaryNode> {};
std::unordered_set<std::string> summary_keys;
for (const auto& udq_ptr : sched.udqConfigList())
udq_ptr->required_summary(summary_keys);
for (const auto& key : summary_keys) {
const auto& default_nodes = make_default_nodes(key, sched);
for (const auto& def_node : default_nodes)
nodes.push_back(def_node);
}
for (const auto& node: nodes) {
if (summary_config.hasSummaryKey(node.unique_key()))
// Handler already exists. Don't add second evaluation.
continue;
auto fun_pos = funs.find(node.keyword);
if (fun_pos != funs.end())
this->udq_parameters.push_back( std::make_unique<Evaluator::FunctionRelation>(node, fun_pos->second) );
else {
auto unit = single_values_units.find(node.keyword);
if (unit == single_values_units.end())
throw std::logic_error(fmt::format("Evaluation function for: {} not found ", node.keyword));
this->udq_parameters.push_back( std::make_unique<Evaluator::GlobalProcessValue>(node, unit->second));
}
}
}
void
Opm::out::Summary::SummaryImplementation::
configureRequiredRestartParameters(const SummaryConfig& sumcfg,
@ -2771,8 +2878,8 @@ configureRequiredRestartParameters(const SummaryConfig& sumcfg,
return;
auto fcnPos = funs.find(node.keyword);
assert ((fcnPos != funs.end()) &&
"Internal error creating required restart vectors");
if (fcnPos == funs.end())
throw std::logic_error(fmt::format("Evaluation function for:{} not found", node.keyword));
auto eval = std::make_unique<
Evaluator::FunctionRelation>(node, fcnPos->second);

View File

@ -83,6 +83,12 @@ double prod_opr(const EclipseState& es, const Schedule& /* sched */, const Summ
return -units.to_si(UnitSystem::measure::rate, oil_rate);
}
double prod_gpr(const EclipseState& es, const Schedule& /* sched */, const SummaryState&, const data::Solution& /* sol */, size_t /* report_step */, double /* seconds_elapsed */) {
const auto& units = es.getUnits();
double gas_rate = 20.0;
return -units.to_si(UnitSystem::measure::rate, gas_rate);
}
double prod_opr_low(const EclipseState& es, const Schedule& /* sched */, const SummaryState&, const data::Solution& /* sol */, size_t /* report_step */, double /* seconds_elapsed */) {
const auto& units = es.getUnits();
double oil_rate = 0.5;
@ -357,6 +363,11 @@ BOOST_AUTO_TEST_CASE(UDQ_IN_ACTIONX) {
sim.well_rate("P3", data::Rates::opt::wat, prod_wpr_P3);
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
sim.well_rate("P1", data::Rates::opt::gas, prod_gpr);
sim.well_rate("P2", data::Rates::opt::gas, prod_gpr);
sim.well_rate("P3", data::Rates::opt::gas, prod_gpr);
sim.well_rate("P4", data::Rates::opt::gas, prod_gpr);
{
const auto& w1 = td.schedule.getWell("P1", 15);
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
@ -381,8 +392,15 @@ BOOST_AUTO_TEST_CASE(UDQ_IN_ACTIONX) {
BOOST_CHECK(udq2.has_keyword("FUPROD"));
BOOST_CHECK(udq2.has_keyword("FUNEW"));
}
}
const auto& base_name = td.state.getIOConfig().getBaseName();
const EclIO::ESmry ecl_sum(base_name + ".SMSPEC");
BOOST_CHECK( !ecl_sum.hasKey("FLPR") );
BOOST_CHECK( ecl_sum.hasKey("FUGPR") );
BOOST_CHECK( !ecl_sum.hasKey("FGLIR") );
BOOST_CHECK( ecl_sum.hasKey("FUGPR") );
}
}
BOOST_AUTO_TEST_CASE(UDA) {

View File

@ -330,9 +330,6 @@ WGIT
'INJ'
/
WGPR
/
WGPT
/
@ -360,7 +357,8 @@ WUWCT
FOPR
FUOPR
FUGPR
FU_VAR2
SCHEDULE
-- -------------------------------------------------------------------------
@ -382,6 +380,7 @@ UDQ
UNITS WUWCT '1' /
DEFINE FUOPR SUM(WOPR) /
UNITS FUOPR 'SM3/DAY' /
DEFINE FUGPR FLPR /
/
@ -473,6 +472,12 @@ DATES -- 3
1 'MAR' 2015 /
/
UDQ
DEFINE FU_VAR2 FGLIR /
/
DATES -- 4
1 'APR' 2015 /
/
@ -481,6 +486,10 @@ DATES -- 5
1 'MAI' 2015 /
/
UDQ
DEFINE FU_VAR3 WGPR P1 /
/
DATES
1 'JUN' 2015 /
/