diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index e650bb71c..6baf5602e 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -91,6 +91,7 @@ if(ENABLE_ECL_INPUT) src/opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.cpp src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp src/opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.cpp + src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp src/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp src/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp src/opm/parser/eclipse/EclipseState/Schedule/Well.cpp @@ -157,7 +158,6 @@ if(ENABLE_ECL_OUTPUT) src/opm/output/eclipse/LogiHEAD.cpp src/opm/output/eclipse/RestartIO.cpp src/opm/output/eclipse/Summary.cpp - src/opm/output/eclipse/SummaryState.cpp src/opm/output/eclipse/Tables.cpp src/opm/output/eclipse/RegionCache.cpp src/opm/output/eclipse/RestartValue.cpp @@ -451,6 +451,7 @@ if(ENABLE_ECL_INPUT) opm/parser/eclipse/EclipseState/Schedule/Well.hpp opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp + opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.hpp @@ -516,7 +517,6 @@ if(ENABLE_ECL_OUTPUT) opm/output/eclipse/RestartIO.hpp opm/output/eclipse/RestartValue.hpp opm/output/eclipse/Summary.hpp - opm/output/eclipse/SummaryState.hpp opm/output/eclipse/Tables.hpp opm/output/eclipse/WindowedArray.hpp opm/output/eclipse/WriteRestartHelpers.hpp diff --git a/opm/output/eclipse/AggregateMSWData.hpp b/opm/output/eclipse/AggregateMSWData.hpp index 1b76d058e..7ccbdb823 100644 --- a/opm/output/eclipse/AggregateMSWData.hpp +++ b/opm/output/eclipse/AggregateMSWData.hpp @@ -21,8 +21,6 @@ #define OPM_AGGREGATE_MSW_DATA_HPP #include -#include - #include #include diff --git a/opm/output/eclipse/EclipseIO.hpp b/opm/output/eclipse/EclipseIO.hpp index f601a0d94..a347f88a8 100644 --- a/opm/output/eclipse/EclipseIO.hpp +++ b/opm/output/eclipse/EclipseIO.hpp @@ -35,7 +35,6 @@ #include #include #include -#include namespace Opm { diff --git a/opm/output/eclipse/Summary.hpp b/opm/output/eclipse/Summary.hpp index 29baa4649..5709e2bc4 100644 --- a/opm/output/eclipse/Summary.hpp +++ b/opm/output/eclipse/Summary.hpp @@ -27,10 +27,9 @@ #include #include +#include #include - -#include #include namespace Opm { diff --git a/opm/output/eclipse/SummaryState.hpp b/opm/output/eclipse/SummaryState.hpp deleted file mode 100644 index 27cd028c6..000000000 --- a/opm/output/eclipse/SummaryState.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright 2016 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 . -*/ - -#ifndef SUMMARY_STATE_H -#define SUMMARY_STATE_H - -#include -#include - -namespace Opm{ - - -/* - The purpose of this class is to serve as a small container object for - computed, ready to use summary values. The values will typically be used by - the UDQ, WTEST and ACTIONX calculations. Observe that all value *have been - converted to the correct output units*. -*/ -class SummaryState { -public: - typedef std::unordered_map::const_iterator const_iterator; - - void add(const std::string& key, double value); - double get(const std::string&) const; - bool has(const std::string& key) const; - - const_iterator begin() const; - const_iterator end() const; -private: - std::unordered_map values; -}; - -} -#endif diff --git a/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp b/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp new file mode 100644 index 000000000..4c3614dbf --- /dev/null +++ b/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp @@ -0,0 +1,84 @@ +/* + Copyright 2016 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 . +*/ + +#ifndef SUMMARY_STATE_H +#define SUMMARY_STATE_H + +#include +#include + +#include + +namespace Opm{ + + +/* + The purpose of this class is to serve as a small container object for + computed, ready to use summary values. The values will typically be used by + the UDQ, WTEST and ACTIONX calculations. Observe that all value *have been + converted to the correct output units*. + + The main key used to access the content of this container is the eclipse style + colon separated string - i.e. 'WWCT:OPX' to get the watercut in well 'OPX'. + The main usage of the SummaryState class is a temporary holding ground while + assembling data for the summary output, but it is also used as a context + object when evaulating the condition in ACTIONX keywords. For that reason some + of the data is duplicated both in the general structure and a specialized + structure: + + SummaryState st; + + st.add_well_var("OPX", "WWCT", 0.75); + st.add("WGOR:OPY", 120); + + // The WWCT:OPX key has been added with the specialized add_well_var() + // method and this data is available both with the general + // st.has("WWCT:OPX") and the specialized st.has_well_var("OPX", "WWCT"); + st.has("WWCT:OPX") => True + st.has_well_var("OPX", "WWCT") => True + + + // The WGOR:OPY key is added with the general add("WGOR:OPY") and is *not* + // accessible through the specialized st.has_well_var("OPY", "WGOR"). + st.has("WGOR:OPY") => True + st.has_well_var("OPY", "WGOR") => False +*/ + +class SummaryState { +public: + typedef std::unordered_map::const_iterator const_iterator; + + double get(const std::string&) const; + bool has(const std::string& key) const; + void add(const std::string& key, double value); + void add(const smspec_node_type * node_ptr, double value); + + void add_well_var(const std::string& well, const std::string& var, double value); + bool has_well_var(const std::string& well, const std::string& var) const; + double get_well_var(const std::string& well, const std::string& var) const; + + const_iterator begin() const; + const_iterator end() const; +private: + std::unordered_map values; + std::unordered_map> well_values; +}; + +} +#endif diff --git a/src/opm/output/eclipse/AggregateGroupData.cpp b/src/opm/output/eclipse/AggregateGroupData.cpp index 6ccd0deee..373e1b57d 100644 --- a/src/opm/output/eclipse/AggregateGroupData.cpp +++ b/src/opm/output/eclipse/AggregateGroupData.cpp @@ -18,12 +18,11 @@ */ #include - -#include #include #include #include +#include #include #include #include diff --git a/src/opm/output/eclipse/AggregateMSWData.cpp b/src/opm/output/eclipse/AggregateMSWData.cpp index 021fcb815..0f78846b2 100644 --- a/src/opm/output/eclipse/AggregateMSWData.cpp +++ b/src/opm/output/eclipse/AggregateMSWData.cpp @@ -20,9 +20,9 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/opm/output/eclipse/AggregateWellData.cpp b/src/opm/output/eclipse/AggregateWellData.cpp index 3dd29de9c..27d73ba39 100644 --- a/src/opm/output/eclipse/AggregateWellData.cpp +++ b/src/opm/output/eclipse/AggregateWellData.cpp @@ -24,10 +24,9 @@ #include -#include - #include #include +#include #include #include #include diff --git a/src/opm/output/eclipse/EclipseIO.cpp b/src/opm/output/eclipse/EclipseIO.cpp index ca1d9f58c..c904face7 100644 --- a/src/opm/output/eclipse/EclipseIO.cpp +++ b/src/opm/output/eclipse/EclipseIO.cpp @@ -39,7 +39,6 @@ #include #include -#include #include #include diff --git a/src/opm/output/eclipse/RestartIO.cpp b/src/opm/output/eclipse/RestartIO.cpp index 7d1b91bb5..a7c4bfd76 100644 --- a/src/opm/output/eclipse/RestartIO.cpp +++ b/src/opm/output/eclipse/RestartIO.cpp @@ -28,11 +28,11 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 584277d67..f0db39859 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -38,8 +38,8 @@ #include #include #include +#include -#include #include #include @@ -1331,7 +1331,7 @@ Summary::Summary( const EclipseState& st, for (const auto& pair : this->handlers->handlers) { const auto * nodeptr = pair.first; if (smspec_node_is_total(nodeptr)) - this->prev_state.add(smspec_node_get_gen_key1(nodeptr), 0); + this->prev_state.add(nodeptr, 0); } } @@ -1431,7 +1431,6 @@ void Summary::add_timestep( int report_step, 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, sim_step, this->regionCache ); auto eff_factors = well_efficiency_factors( f.first, schedule, schedule_wells, sim_step ); @@ -1446,22 +1445,22 @@ void Summary::add_timestep( int report_step, eff_factors}); double unit_applied_val = es.getUnits().from_si( val.unit, val.value ); - if (smspec_node_is_total(f.first)) + if (smspec_node_is_total(f.first)) { + const auto* genkey = smspec_node_get_gen_key1( f.first ); unit_applied_val += this->prev_state.get(genkey); + } - st.add(genkey, unit_applied_val); + st.add(f.first, unit_applied_val); } for( const auto& value_pair : single_values ) { const std::string key = value_pair.first; const auto node_pair = this->handlers->single_value_nodes.find( key ); if (node_pair != this->handlers->single_value_nodes.end()) { - const auto * nodeptr = node_pair->second; - const auto * genkey = smspec_node_get_gen_key1( nodeptr ); const auto unit = single_values_units.at( key ); double si_value = value_pair.second; double output_value = es.getUnits().from_si(unit , si_value ); - st.add(genkey, output_value); + st.add(node_pair->second, output_value); } } @@ -1471,13 +1470,12 @@ void Summary::add_timestep( int report_step, const auto node_pair = this->handlers->region_nodes.find( std::make_pair(key, reg+1) ); if (node_pair != this->handlers->region_nodes.end()) { const auto * nodeptr = node_pair->second; - const auto* genkey = smspec_node_get_gen_key1( nodeptr ); const auto unit = region_units.at( key ); assert (smspec_node_get_num( nodeptr ) - 1 == static_cast(reg)); double si_value = value_pair.second[reg]; double output_value = es.getUnits().from_si(unit , si_value ); - st.add(genkey, output_value); + st.add(nodeptr, output_value); } } } @@ -1487,11 +1485,10 @@ void Summary::add_timestep( int report_step, const auto node_pair = this->handlers->block_nodes.find( key ); if (node_pair != this->handlers->block_nodes.end()) { const auto * nodeptr = node_pair->second; - const auto * genkey = smspec_node_get_gen_key1( nodeptr ); const auto unit = block_units.at( key.first ); double si_value = value_pair.second; double output_value = es.getUnits().from_si(unit , si_value ); - st.add(genkey, output_value); + st.add(nodeptr, output_value); } } diff --git a/src/opm/output/eclipse/SummaryState.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp similarity index 53% rename from src/opm/output/eclipse/SummaryState.cpp rename to src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp index c83b851e0..7deefac3a 100644 --- a/src/opm/output/eclipse/SummaryState.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp @@ -18,9 +18,17 @@ */ -#include +#include namespace Opm{ + void SummaryState::add(const smspec_node_type * node_ptr, double value) { + if (smspec_node_get_var_type(node_ptr) == ECL_SMSPEC_WELL_VAR) + this->add_well_var(smspec_node_get_wgname(node_ptr), + smspec_node_get_keyword(node_ptr), + value); + else + this->add(smspec_node_get_gen_key1(node_ptr), value); + } void SummaryState::add(const std::string& key, double value) { this->values[key] = value; @@ -40,6 +48,28 @@ namespace Opm{ return iter->second; } + void SummaryState::add_well_var(const std::string& well, const std::string& var, double value) { + this->add(var + ":" + well, value); + this->well_values[well][var] = value; + } + + bool SummaryState::has_well_var(const std::string& well, const std::string& var) const { + const auto& well_iter = this->well_values.find(well); + if (well_iter == this->well_values.end()) + return false; + + const auto& var_iter = well_iter->second.find(var); + if (var_iter == well_iter->second.end()) + return false; + + return true; + } + + double SummaryState::get_well_var(const std::string& well, const std::string& var) const { + return this->well_values.at(well).at(var); + } + + SummaryState::const_iterator SummaryState::begin() const { return this->values.begin(); } diff --git a/tests/test_AggregateWellData.cpp b/tests/test_AggregateWellData.cpp index a26b5f3cf..bdcfabb19 100644 --- a/tests/test_AggregateWellData.cpp +++ b/tests/test_AggregateWellData.cpp @@ -23,8 +23,7 @@ #include -#include - +#include #include #include diff --git a/tests/test_Restart.cpp b/tests/test_Restart.cpp index fa84adfe1..d1f928c02 100644 --- a/tests/test_Restart.cpp +++ b/tests/test_Restart.cpp @@ -38,6 +38,8 @@ #include #include #include +#include + // ERT stuff #include diff --git a/tests/test_Summary.cpp b/tests/test_Summary.cpp index 91766ec26..6597b4df2 100644 --- a/tests/test_Summary.cpp +++ b/tests/test_Summary.cpp @@ -35,8 +35,8 @@ #include #include -#include +#include #include #include #include @@ -1324,6 +1324,12 @@ BOOST_AUTO_TEST_CASE(Test_SummaryState) { BOOST_CHECK_THROW(st.get("NO_SUCH_KEY"), std::invalid_argument); BOOST_CHECK(st.has("WWCT:OP_2")); BOOST_CHECK(!st.has("NO_SUCH_KEY")); + + + st.add_well_var("OP1", "WWCT", 0.75); + BOOST_CHECK( st.has_well_var("OP1", "WWCT")); + BOOST_CHECK_EQUAL( st.get_well_var("OP1", "WWCT"), 0.75); + BOOST_CHECK_EQUAL( st.get_well_var("OP1", "WWCT"), st.get("WWCT:OP1")); } BOOST_AUTO_TEST_SUITE_END()