@@ -125,6 +125,7 @@ if(ENABLE_ECL_INPUT)
|
|||||||
src/opm/parser/eclipse/EclipseState/Tables/Tables.cpp
|
src/opm/parser/eclipse/EclipseState/Tables/Tables.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/UDQParams.cpp
|
src/opm/parser/eclipse/EclipseState/UDQParams.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/UDQ.cpp
|
||||||
|
src/opm/parser/eclipse/EclipseState/Schedule/UDQContext.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQExpression.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/UDQExpression.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp
|
||||||
@@ -504,8 +505,10 @@ if(ENABLE_ECL_INPUT)
|
|||||||
opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp
|
opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp
|
||||||
opm/parser/eclipse/EclipseState/checkDeck.hpp
|
opm/parser/eclipse/EclipseState/checkDeck.hpp
|
||||||
opm/parser/eclipse/EclipseState/Runspec.hpp
|
opm/parser/eclipse/EclipseState/Runspec.hpp
|
||||||
|
opm/parser/eclipse/EclipseState/Schedule/UDQContext.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp
|
opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp
|
||||||
opm/parser/eclipse/EclipseState/UDQParams.hpp
|
opm/parser/eclipse/EclipseState/UDQParams.hpp
|
||||||
|
opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp
|
opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp
|
||||||
opm/parser/eclipse/Deck/DeckItem.hpp
|
opm/parser/eclipse/Deck/DeckItem.hpp
|
||||||
opm/parser/eclipse/Deck/Deck.hpp
|
opm/parser/eclipse/Deck/Deck.hpp
|
||||||
|
|||||||
43
opm/parser/eclipse/EclipseState/Schedule/UDQContext.hpp
Normal file
43
opm/parser/eclipse/EclipseState/Schedule/UDQContext.hpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 Statoil ASA.
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UDQ_CONTEXT_HPP
|
||||||
|
#define UDQ_CONTEXT_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
class SummaryState;
|
||||||
|
|
||||||
|
class UDQContext{
|
||||||
|
public:
|
||||||
|
explicit UDQContext(const SummaryState& summary_state);
|
||||||
|
double get(const std::string& key) const;
|
||||||
|
void add(const std::string& key, double value);
|
||||||
|
private:
|
||||||
|
const SummaryState& summary_state;
|
||||||
|
std::unordered_map<std::string, double> values;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
|
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQContext.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||||
@@ -1110,6 +1112,16 @@ inline std::vector< const Well* > find_wells( const Schedule& schedule,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool is_udq(const std::string& keyword) {
|
||||||
|
return (keyword.size() > 1 && keyword[1] == 'U');
|
||||||
|
}
|
||||||
|
|
||||||
|
void eval_udq(const UDQ& udq, const UDQContext& context, SummaryState& st)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace out {
|
namespace out {
|
||||||
@@ -1152,6 +1164,7 @@ Summary::Summary( const EclipseState& st,
|
|||||||
handlers( new keyword_handlers() )
|
handlers( new keyword_handlers() )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const auto& udq = schedule.getUDQConfig(schedule.size() - 1);
|
||||||
const auto& init_config = st.getInitConfig();
|
const auto& init_config = st.getInitConfig();
|
||||||
const char * restart_case = nullptr;
|
const char * restart_case = nullptr;
|
||||||
int restart_step = -1;
|
int restart_step = -1;
|
||||||
@@ -1244,6 +1257,10 @@ Summary::Summary( const EclipseState& st,
|
|||||||
|
|
||||||
auto * nodeptr = ecl_smspec_add_node( smspec, keyword.c_str(), node.wgname().c_str(), node.num(), st.getUnits().name( val.unit ), 0 );
|
auto * nodeptr = ecl_smspec_add_node( smspec, keyword.c_str(), node.wgname().c_str(), node.num(), st.getUnits().name( val.unit ), 0 );
|
||||||
this->handlers->handlers.emplace_back( nodeptr, handle );
|
this->handlers->handlers.emplace_back( nodeptr, handle );
|
||||||
|
} else if (is_udq(keyword)) {
|
||||||
|
const auto& unit = udq.unit(keyword);
|
||||||
|
const auto& udq_params = st.runspec().udqParams();
|
||||||
|
ecl_smspec_add_node(smspec, keyword.c_str(), node.wgname().c_str(), node.num(), unit.c_str(), udq_params.undefinedValue());
|
||||||
} else {
|
} else {
|
||||||
unsupported_keywords.insert(keyword);
|
unsupported_keywords.insert(keyword);
|
||||||
}
|
}
|
||||||
@@ -1468,6 +1485,11 @@ void Summary::add_timestep( int report_step,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UDQContext udq_context(st);
|
||||||
|
const UDQ& udq = schedule.getUDQConfig(sim_step);
|
||||||
|
eval_udq(udq, udq_context, st);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
const ecl_sum_type * ecl_sum = this->ecl_sum.get();
|
const ecl_sum_type * ecl_sum = this->ecl_sum.get();
|
||||||
const ecl_smspec_type * smspec = ecl_sum_get_smspec(ecl_sum);
|
const ecl_smspec_type * smspec = ecl_sum_get_smspec(ecl_sum);
|
||||||
|
|||||||
60
src/opm/parser/eclipse/EclipseState/Schedule/UDQContext.cpp
Normal file
60
src/opm/parser/eclipse/EclipseState/Schedule/UDQContext.cpp
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 Statoil ASA.
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQContext.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
UDQContext::UDQContext(const SummaryState& summary_state) :
|
||||||
|
summary_state(summary_state)
|
||||||
|
{
|
||||||
|
for (const auto& pair : TimeMap::eclipseMonthIndices())
|
||||||
|
this->add(pair.first, pair.second);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Simulator performance keywords which are expected to be available for
|
||||||
|
UDQ keywords; probably better to guarantee that they are present in
|
||||||
|
the underlying summary state object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
this->add("ELAPSED", 0.0);
|
||||||
|
this->add("MSUMLINS", 0.0);
|
||||||
|
this->add("MSUMNEWT", 0.0);
|
||||||
|
this->add("NEWTON", 0.0);
|
||||||
|
this->add("TCPU", 0.0);
|
||||||
|
this->add("TIME", 0.0);
|
||||||
|
this->add("TIMESTEP", 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UDQContext::add(const std::string& key, double value) {
|
||||||
|
this->values[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double UDQContext::get(const std::string& key) const {
|
||||||
|
const auto& pair_ptr = this->values.find(key);
|
||||||
|
if (pair_ptr == this->values.end())
|
||||||
|
return this->summary_state.get(key);
|
||||||
|
|
||||||
|
return pair_ptr->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQExpression.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQContext.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||||
|
|
||||||
using namespace Opm;
|
using namespace Opm;
|
||||||
|
|
||||||
@@ -99,6 +101,11 @@ UDQ
|
|||||||
|
|
||||||
BOOST_CHECK_THROW( udq.unit("NO_SUCH_KEY"), std::invalid_argument );
|
BOOST_CHECK_THROW( udq.unit("NO_SUCH_KEY"), std::invalid_argument );
|
||||||
BOOST_CHECK_EQUAL( udq.unit("WUBHP"), "BARSA");
|
BOOST_CHECK_EQUAL( udq.unit("WUBHP"), "BARSA");
|
||||||
|
|
||||||
|
Parser parser;
|
||||||
|
auto deck = parser.parseString(input);
|
||||||
|
auto udq_params = UDQParams(deck);
|
||||||
|
BOOST_CHECK_EQUAL(0.25, udq_params.cmpEpsilon());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(UDQ_CHANGE_UNITS_ILLEGAL) {
|
BOOST_AUTO_TEST_CASE(UDQ_CHANGE_UNITS_ILLEGAL) {
|
||||||
@@ -180,3 +187,17 @@ DEFINE WUMW1 WBHP 'P*1*' UMAX WBHP 'P*4*' /
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(UDQ_CONTEXT) {
|
||||||
|
SummaryState st;
|
||||||
|
UDQContext ctx(st);
|
||||||
|
BOOST_CHECK_EQUAL(ctx.get("JAN"), 1.0);
|
||||||
|
|
||||||
|
BOOST_REQUIRE_THROW(ctx.get("NO_SUCH_KEY"), std::out_of_range);
|
||||||
|
|
||||||
|
for (std::string& key : std::vector<std::string>({"ELAPSED", "MSUMLINS", "MSUMNEWT", "NEWTON", "TCPU", "TIME", "TIMESTEP"}))
|
||||||
|
BOOST_CHECK_NO_THROW( ctx.get(key) );
|
||||||
|
|
||||||
|
st.add("SUMMARY:KEY", 1.0);
|
||||||
|
BOOST_CHECK_EQUAL(ctx.get("SUMMARY:KEY") , 1.0 );
|
||||||
|
}
|
||||||
|
|||||||
@@ -632,8 +632,16 @@ CTFAC
|
|||||||
----'E-2H' /
|
----'E-2H' /
|
||||||
----/
|
----/
|
||||||
|
|
||||||
|
WUBHP
|
||||||
|
/
|
||||||
|
|
||||||
|
|
||||||
SCHEDULE
|
SCHEDULE
|
||||||
|
|
||||||
|
UDQ
|
||||||
|
UNITS WUBHP 'BARSA' /
|
||||||
|
/
|
||||||
|
|
||||||
-- Three wells, two producers (so that we can form a group) and one injector
|
-- Three wells, two producers (so that we can form a group) and one injector
|
||||||
WELSPECS
|
WELSPECS
|
||||||
'W_1' 'G_1' 1 1 3.33 'OIL' 7* /
|
'W_1' 'G_1' 1 1 3.33 'OIL' 7* /
|
||||||
|
|||||||
@@ -501,6 +501,24 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
|
|||||||
BOOST_CHECK_CLOSE( 2.2, ecl_sum_get_well_var( resp, 1, "W_3", "WTHPH" ), 1e-5 );
|
BOOST_CHECK_CLOSE( 2.2, ecl_sum_get_well_var( resp, 1, "W_3", "WTHPH" ), 1e-5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(udq_keywords) {
|
||||||
|
setup cfg( "test_summary_udq" );
|
||||||
|
|
||||||
|
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
|
||||||
|
writer.add_timestep( 0, 0 * day, cfg.es, cfg.schedule, cfg.wells , {});
|
||||||
|
writer.add_timestep( 1, 1 * 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();
|
||||||
|
|
||||||
|
const auto& udq_params = cfg.es.runspec().udqParams();
|
||||||
|
BOOST_CHECK_CLOSE( ecl_sum_get_well_var(resp, 1, "W_1", "WUBHP"), udq_params.undefinedValue(), 1e-5 );
|
||||||
|
BOOST_CHECK_CLOSE( ecl_sum_get_well_var(resp, 1, "W_3", "WUBHP"), udq_params.undefinedValue(), 1e-5 );
|
||||||
|
BOOST_CHECK_EQUAL( std::string(ecl_sum_get_unit(resp, "WUBHP:W_1")), "BARSA");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(group_keywords) {
|
BOOST_AUTO_TEST_CASE(group_keywords) {
|
||||||
setup cfg( "test_summary_group" );
|
setup cfg( "test_summary_group" );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user