Add class Action::State to keep track of ACTIONX count

This commit is contained in:
Joakim Hove
2020-06-18 16:45:39 +02:00
parent 7d856b4933
commit f54245f1ca
6 changed files with 158 additions and 12 deletions
+2
View File
@@ -96,6 +96,7 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Action/Condition.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Action/State.cpp
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
src/opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.cpp
@@ -671,6 +672,7 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/EclipseState/Schedule/Action/Condition.hpp
opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.hpp
opm/parser/eclipse/EclipseState/Schedule/Action/PyAction.hpp
opm/parser/eclipse/EclipseState/Schedule/Action/State.hpp
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp
opm/parser/eclipse/EclipseState/Schedule/Network/Branch.hpp
@@ -0,0 +1,59 @@
/*
Copyright 2020 Equinor 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 ACTION_STATE_HPP
#define ACTION_STATE_HPP
#include <ctime>
#include <map>
namespace Opm {
namespace Action {
class ActionX;
class State {
struct RunState {
RunState(std::time_t sim_time) :
run_count(1),
last_run(sim_time)
{}
void add_run(std::time_t sim_time) {
this->last_run = sim_time;
this->run_count += 1;
}
std::size_t run_count;
std::time_t last_run;
};
public:
void add_run(const ActionX& action, std::time_t sim_time);
std::size_t run_count(const ActionX& action) const;
std::time_t run_time(const ActionX& action) const;
private:
std::map<std::pair<std::string, std::size_t>, RunState> run_state;
};
}
}
#endif
@@ -124,8 +124,9 @@ Action::Result ActionX::eval(std::time_t sim_time, const Action::Context& contex
}
bool ActionX::ready(std::time_t sim_time) const {
if (this->run_count >= this->max_run())
bool ActionX::ready(const State& state, std::time_t sim_time) const {
auto run_count = state.run_count(*this);
if (run_count >= this->max_run())
return false;
if (sim_time < this->start_time())
@@ -137,7 +138,8 @@ bool ActionX::ready(std::time_t sim_time) const {
if (this->min_wait() <= 0)
return true;
return std::difftime(sim_time, this->last_run) > this->min_wait();
auto last_run = state.run_time(*this);
return std::difftime(sim_time, last_run) > this->min_wait();
}
@@ -55,8 +55,11 @@ void Actions::add(const ActionX& action) {
auto iter = std::find_if( this->actions.begin(), this->actions.end(), [&action](const ActionX& arg) { return arg.name() == action.name(); });
if (iter == this->actions.end())
this->actions.push_back(action);
else
else {
auto id = iter->id() + 1;
*iter = action;
iter->update_id(id);
}
}
void Actions::add(const PyAction& pyaction) {
@@ -0,0 +1,61 @@
/*
Copyright 2020 Equinor 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 <vector>
#include <algorithm>
#include <stdexcept>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/State.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
namespace Opm {
namespace Action {
namespace {
std::pair<std::string, std::size_t> action_id(const ActionX& action) {
return std::make_pair(action.name(), action.id());
}
}
std::size_t State::run_count(const ActionX& action) const {
auto count_iter = this->run_state.find(action_id(action));
if (count_iter == this->run_state.end())
return 0;
return count_iter->second.run_count;
}
std::time_t State::run_time(const ActionX& action) const {
auto state = this->run_state.at(action_id(action));
return state.last_run;
}
void State::add_run(const ActionX& action, std::time_t run_time) {
const auto& id = action_id(action);
auto count_iter = this->run_state.find(id);
if (count_iter == this->run_state.end())
this->run_state.insert( std::make_pair(id, run_time) );
else
count_iter->second.add_run(run_time);
}
}
}
+27 -8
View File
@@ -37,6 +37,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/State.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@@ -801,17 +802,30 @@ BOOST_AUTO_TEST_CASE(ACTIONRESULT_COPY_WELLS) {
BOOST_AUTO_TEST_CASE(ActionState) {
Action::State st;
Action::ActionX action1("NAME", 100, 100, 100); action1.update_id(100);
Action::ActionX action2("NAME", 100, 100, 100); action1.update_id(200);
BOOST_CHECK_EQUAL(0, st.run_count("NO_SUCH_ACTION"));
BOOST_CHECK_THROW( st.run_time("NO_SUCH_ACTION"), std::out_of_range);
BOOST_CHECK_EQUAL(0, st.run_count(action1));
BOOST_CHECK_THROW( st.run_time(action1), std::out_of_range);
st.add_run("ACT02", 100);
BOOST_CHECK_EQUAL(1, st.run_count("ACT02"));
BOOST_CHECK_EQUAL(100, st.run_time("ACT02"));
st.add_run(action1, 100);
BOOST_CHECK_EQUAL(1, st.run_count(action1));
BOOST_CHECK_EQUAL(100, st.run_time(action1));
st.add_run("ACT02", 1000);
BOOST_CHECK_EQUAL(2, st.run_count("ACT02"));
BOOST_CHECK_EQUAL(1000, st.run_time("ACT02"));
st.add_run(action1, 1000);
BOOST_CHECK_EQUAL(2, st.run_count(action1));
BOOST_CHECK_EQUAL(1000, st.run_time(action1));
BOOST_CHECK_EQUAL(0, st.run_count(action2));
BOOST_CHECK_THROW( st.run_time(action2), std::out_of_range);
st.add_run(action2, 100);
BOOST_CHECK_EQUAL(1, st.run_count(action2));
BOOST_CHECK_EQUAL(100, st.run_time(action2));
st.add_run(action2, 1000);
BOOST_CHECK_EQUAL(2, st.run_count(action2));
BOOST_CHECK_EQUAL(1000, st.run_time(action2));
}
BOOST_AUTO_TEST_CASE(ActionID) {
@@ -859,4 +873,9 @@ ENDACTIO
const auto& action2 = sched.actions(2).get("A");
BOOST_CHECK(action1.id() != action2.id());
Action::State st;
st.add_run(action1, 1000);
BOOST_CHECK_EQUAL( st.run_count(action1), 1);
BOOST_CHECK_EQUAL( st.run_count(action2), 0);
}