Merge pull request #2950 from joakim-hove/pyaction-handle-return
Pyaction handle return
This commit is contained in:
@@ -551,6 +551,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/msim/action1.py
|
||||
tests/msim/action2.py
|
||||
tests/msim/action3.py
|
||||
tests/msim/action_count.py
|
||||
tests/VFP_CASE.DATA)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ int main(int /* argc */, char** argv) {
|
||||
error_guard.terminate();
|
||||
}
|
||||
|
||||
Opm::msim msim(state);
|
||||
Opm::msim msim(state, schedule);
|
||||
Opm::EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
msim.run(schedule, io, false);
|
||||
msim.run(io, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
@@ -36,27 +37,30 @@ public:
|
||||
using well_rate_function = double(const EclipseState&, const Schedule&, const SummaryState& st, const data::Solution&, size_t report_step, double seconds_elapsed);
|
||||
using solution_function = void(const EclipseState&, const Schedule&, data::Solution&, size_t report_step, double seconds_elapsed);
|
||||
|
||||
msim(const EclipseState& state);
|
||||
msim(const EclipseState& state, const Schedule& schedule_arg);
|
||||
|
||||
Opm::UDAValue uda_val();
|
||||
|
||||
void well_rate(const std::string& well, data::Rates::opt rate, std::function<well_rate_function> func);
|
||||
void solution(const std::string& field, std::function<solution_function> func);
|
||||
void run(Schedule& schedule, EclipseIO& io, bool report_only);
|
||||
void post_step(Schedule& schedule, SummaryState& st, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, const time_point& sim_time);
|
||||
|
||||
Action::State action_state;
|
||||
void run(EclipseIO& io, bool report_only);
|
||||
void post_step(data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, const time_point& sim_time);
|
||||
|
||||
private:
|
||||
|
||||
void run_step(const Schedule& schedule, WellTestState& wtest_state, SummaryState& st, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, EclipseIO& io) const;
|
||||
void run_step(const Schedule& schedule, WellTestState& wtest_state, SummaryState& st, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double dt, EclipseIO& io) const;
|
||||
void output(WellTestState& wtest_state, SummaryState& st, const UDQState& udq_state, size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, const data::GroupAndNetworkValues& group_data, EclipseIO& io) const;
|
||||
void simulate(const Schedule& schedule, const SummaryState& st, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double seconds_elapsed, double time_step) const;
|
||||
void run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, EclipseIO& io);
|
||||
void run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double dt, EclipseIO& io);
|
||||
void output(WellTestState& wtest_state, const UDQState& udq_state, size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, const data::GroupAndNetworkValues& group_data, EclipseIO& io);
|
||||
void simulate(data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double seconds_elapsed, double time_step);
|
||||
|
||||
EclipseState state;
|
||||
std::map<std::string, std::map<data::Rates::opt, std::function<well_rate_function>>> well_rates;
|
||||
std::map<std::string, std::function<solution_function>> solutions;
|
||||
|
||||
public:
|
||||
Schedule schedule;
|
||||
Action::State action_state;
|
||||
SummaryState st;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <opm/output/data/Groups.hpp>
|
||||
#include <opm/input/eclipse/Python/Python.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/ActionContext.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
|
||||
@@ -41,15 +40,16 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
msim::msim(const EclipseState& state_arg) :
|
||||
state(state_arg)
|
||||
msim::msim(const EclipseState& state_arg, const Schedule& schedule_arg)
|
||||
: state(state_arg)
|
||||
, schedule(schedule_arg)
|
||||
, st(TimeService::from_time_t(this->schedule.getStartTime()))
|
||||
{}
|
||||
|
||||
void msim::run(Schedule& schedule, EclipseIO& io, bool report_only) {
|
||||
void msim::run(EclipseIO& io, bool report_only) {
|
||||
const double week = 7 * 86400;
|
||||
data::Solution sol;
|
||||
SummaryState st(TimeService::from_time_t(schedule.getStartTime()));
|
||||
UDQState udq_state(schedule.getUDQConfig(0).params().undefinedValue());
|
||||
UDQState udq_state(this->schedule.getUDQConfig(0).params().undefinedValue());
|
||||
WellTestState wtest_state;
|
||||
Python python;
|
||||
|
||||
@@ -58,13 +58,13 @@ void msim::run(Schedule& schedule, EclipseIO& io, bool report_only) {
|
||||
data::Wells well_data;
|
||||
data::GroupAndNetworkValues group_nwrk_data;
|
||||
if (report_only)
|
||||
run_step(schedule, wtest_state, st, udq_state, sol, well_data, group_nwrk_data, report_step, io);
|
||||
run_step(wtest_state, udq_state, sol, well_data, group_nwrk_data, report_step, io);
|
||||
else {
|
||||
double time_step = std::min(week, 0.5*schedule.stepLength(report_step - 1));
|
||||
run_step(schedule, wtest_state, st, udq_state, sol, well_data, group_nwrk_data, report_step, time_step, io);
|
||||
run_step(wtest_state, udq_state, sol, well_data, group_nwrk_data, report_step, time_step, io);
|
||||
}
|
||||
auto sim_time = TimeService::from_time_t( schedule.simTime(report_step) );
|
||||
post_step(schedule, st, sol, well_data, group_nwrk_data, report_step, sim_time);
|
||||
post_step(sol, well_data, group_nwrk_data, report_step, sim_time);
|
||||
const auto& exit_status = schedule.exitStatus();
|
||||
if (exit_status.has_value())
|
||||
return;
|
||||
@@ -76,33 +76,33 @@ UDAValue msim::uda_val() {
|
||||
}
|
||||
|
||||
|
||||
void msim::post_step(Schedule& schedule, SummaryState& st, data::Solution& /* sol */, data::Wells& /* well_data */, data::GroupAndNetworkValues& /* grp_nwrk_data */, size_t report_step, const time_point& sim_time) {
|
||||
const auto& actions = schedule[report_step].actions.get();
|
||||
void msim::post_step(data::Solution& /* sol */, data::Wells& /* well_data */, data::GroupAndNetworkValues& /* grp_nwrk_data */, size_t report_step, const time_point& sim_time) {
|
||||
const auto& actions = this->schedule[report_step].actions.get();
|
||||
if (actions.empty())
|
||||
return;
|
||||
|
||||
Action::Context context( st , schedule[report_step].wlist_manager.get());
|
||||
Action::Context context( this->st , this->schedule[report_step].wlist_manager.get());
|
||||
|
||||
for (const auto& action : actions.pending(this->action_state, std::chrono::system_clock::to_time_t(sim_time))) {
|
||||
auto result = action->eval(context);
|
||||
if (result)
|
||||
schedule.applyAction(report_step, *action, result.wells(), {});
|
||||
this->schedule.applyAction(report_step, *action, result.wells(), {});
|
||||
}
|
||||
|
||||
for (const auto& pyaction : actions.pending_python())
|
||||
schedule.runPyAction(report_step, *pyaction, this->state, st);
|
||||
for (const auto& pyaction : actions.pending_python(this->action_state))
|
||||
this->schedule.runPyAction(report_step, *pyaction, this->action_state, this->state, this->st);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void msim::run_step(const Schedule& schedule, WellTestState& wtest_state, SummaryState& st, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& grp_nwrk_data, size_t report_step, EclipseIO& io) const {
|
||||
this->run_step(schedule, wtest_state, st, udq_state, sol, well_data, grp_nwrk_data, report_step, schedule.stepLength(report_step - 1), io);
|
||||
void msim::run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& grp_nwrk_data, size_t report_step, EclipseIO& io) {
|
||||
this->run_step(wtest_state, udq_state, sol, well_data, grp_nwrk_data, report_step, schedule.stepLength(report_step - 1), io);
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(const Schedule& schedule, WellTestState& wtest_state, SummaryState& st, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double dt, EclipseIO& io) const {
|
||||
double start_time = schedule.seconds(report_step - 1);
|
||||
double end_time = schedule.seconds(report_step);
|
||||
void msim::run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double dt, EclipseIO& io) {
|
||||
double start_time = this->schedule.seconds(report_step - 1);
|
||||
double end_time = this->schedule.seconds(report_step);
|
||||
double seconds_elapsed = start_time;
|
||||
|
||||
while (seconds_elapsed < end_time) {
|
||||
@@ -110,11 +110,11 @@ void msim::run_step(const Schedule& schedule, WellTestState& wtest_state, Summar
|
||||
if ((seconds_elapsed + time_step) > end_time)
|
||||
time_step = end_time - seconds_elapsed;
|
||||
|
||||
this->simulate(schedule, st, sol, well_data, group_nwrk_data, report_step, seconds_elapsed, time_step);
|
||||
this->simulate(sol, well_data, group_nwrk_data, report_step, seconds_elapsed, time_step);
|
||||
|
||||
seconds_elapsed += time_step;
|
||||
|
||||
io.summary().eval(st,
|
||||
io.summary().eval(this->st,
|
||||
report_step,
|
||||
seconds_elapsed,
|
||||
well_data,
|
||||
@@ -124,10 +124,9 @@ void msim::run_step(const Schedule& schedule, WellTestState& wtest_state, Summar
|
||||
{},
|
||||
{});
|
||||
|
||||
schedule.getUDQConfig( report_step ).eval(report_step, schedule.wellMatcher(report_step), st, udq_state);
|
||||
this->schedule.getUDQConfig( report_step ).eval(report_step, schedule.wellMatcher(report_step), this->st, udq_state);
|
||||
|
||||
this->output(wtest_state,
|
||||
st,
|
||||
udq_state,
|
||||
report_step,
|
||||
(seconds_elapsed < end_time),
|
||||
@@ -141,11 +140,11 @@ void msim::run_step(const Schedule& schedule, WellTestState& wtest_state, Summar
|
||||
|
||||
|
||||
|
||||
void msim::output(WellTestState& wtest_state, SummaryState& st, const UDQState& udq_state, size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, const data::GroupAndNetworkValues& group_nwrk_data, EclipseIO& io) const {
|
||||
void msim::output(WellTestState& wtest_state, const UDQState& udq_state, size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, const data::GroupAndNetworkValues& group_nwrk_data, EclipseIO& io) {
|
||||
RestartValue value(sol, well_data, group_nwrk_data, {});
|
||||
io.writeTimeStep(this->action_state,
|
||||
wtest_state,
|
||||
st,
|
||||
this->st,
|
||||
udq_state,
|
||||
report_step,
|
||||
substep,
|
||||
@@ -154,15 +153,15 @@ void msim::output(WellTestState& wtest_state, SummaryState& st, const UDQState&
|
||||
}
|
||||
|
||||
|
||||
void msim::simulate(const Schedule& schedule, const SummaryState& st, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& /* group_nwrk_data */, size_t report_step, double seconds_elapsed, double time_step) const {
|
||||
void msim::simulate(data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& /* group_nwrk_data */, size_t report_step, double seconds_elapsed, double time_step) {
|
||||
for (const auto& sol_pair : this->solutions) {
|
||||
auto func = sol_pair.second;
|
||||
func(this->state, schedule, sol, report_step, seconds_elapsed + time_step);
|
||||
func(this->state, this->schedule, sol, report_step, seconds_elapsed + time_step);
|
||||
}
|
||||
|
||||
for (const auto& well_pair : this->well_rates) {
|
||||
const std::string& well_name = well_pair.first;
|
||||
const auto& sched_well = schedule.getWell(well_name, report_step);
|
||||
const auto& sched_well = this->schedule.getWell(well_name, report_step);
|
||||
bool well_open = (sched_well.getStatus() == Well::Status::OPEN);
|
||||
|
||||
data::Well& well = well_data[well_name];
|
||||
@@ -171,7 +170,7 @@ void msim::simulate(const Schedule& schedule, const SummaryState& st, data::Solu
|
||||
auto func = rate_pair.second;
|
||||
|
||||
if (well_open)
|
||||
well.rates.set(rate, func(this->state, schedule, st, sol, report_step, seconds_elapsed + time_step));
|
||||
well.rates.set(rate, func(this->state, this->schedule, this->st, sol, report_step, seconds_elapsed + time_step));
|
||||
else
|
||||
well.rates.set(rate, 0.0);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
const ActionX& operator[](const std::string& name) const;
|
||||
const ActionX& operator[](std::size_t index) const;
|
||||
std::vector<const ActionX *> pending(const State& state, std::time_t sim_time) const;
|
||||
std::vector<const PyAction *> pending_python() const;
|
||||
std::vector<const PyAction *> pending_python(const State& state) const;
|
||||
|
||||
bool has(const std::string& name) const;
|
||||
std::vector<ActionX>::const_iterator begin() const;
|
||||
|
||||
@@ -36,6 +36,7 @@ class SummaryState;
|
||||
class PyRunModule;
|
||||
|
||||
namespace Action {
|
||||
class State;
|
||||
|
||||
class PyAction {
|
||||
public:
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
bool run(EclipseState& ecl_state, Schedule& schedule, std::size_t report_step, SummaryState& st,
|
||||
const std::function<void(const std::string&, const std::vector<std::string>&)>& actionx_callback) const;
|
||||
const std::string& name() const;
|
||||
bool active() const;
|
||||
bool ready(const State& state) const;
|
||||
bool operator==(const PyAction& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace Action {
|
||||
|
||||
class ActionX;
|
||||
class Actions;
|
||||
class PyAction;
|
||||
|
||||
class State {
|
||||
|
||||
struct RunState {
|
||||
@@ -79,9 +81,11 @@ struct RunState {
|
||||
|
||||
public:
|
||||
void add_run(const ActionX& action, std::time_t sim_time, Result result);
|
||||
void add_run(const PyAction& action, bool result);
|
||||
std::size_t run_count(const ActionX& action) const;
|
||||
std::time_t run_time(const ActionX& action) const;
|
||||
std::optional<Result> result(const std::string& action) const;
|
||||
std::optional<bool> python_result(const std::string& action) const;
|
||||
void load_rst(const Actions& action_config, const RestartIO::RstState& rst_state);
|
||||
|
||||
template<class Serializer>
|
||||
@@ -89,6 +93,7 @@ public:
|
||||
{
|
||||
serializer.map(this->run_state);
|
||||
serializer.map(this->last_result);
|
||||
serializer.template map<std::map<std::string,bool>, false>(this->m_python_result);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +105,7 @@ private:
|
||||
static action_id make_id(const ActionX& action);
|
||||
std::map<action_id, RunState> run_state;
|
||||
std::map<std::string, Result> last_result;
|
||||
std::map<std::string, bool> m_python_result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ namespace Opm
|
||||
Python code. he return value from runPyAction() comes from such a
|
||||
internal ACTIONX.
|
||||
*/
|
||||
SimulatorUpdate runPyAction(std::size_t reportStep, const Action::PyAction& pyaction, EclipseState& ecl_state, SummaryState& summary_state);
|
||||
SimulatorUpdate runPyAction(std::size_t reportStep, const Action::PyAction& pyaction, Action::State& action_state, EclipseState& ecl_state, SummaryState& summary_state);
|
||||
|
||||
|
||||
const GasLiftOpt& glo(std::size_t report_step) const;
|
||||
|
||||
@@ -75,8 +75,10 @@ public:
|
||||
explicit SummaryState(std::time_t sim_start_arg);
|
||||
|
||||
/*
|
||||
The set() function has to be retained temporarily to support updating of
|
||||
cumulatives from restart files.
|
||||
The canonical way to update the SummaryState is through the update_xxx()
|
||||
methods which will inspect the variable and either accumulate or just
|
||||
assign, depending on whether it represents a total or not. The set()
|
||||
method is low level and unconditionally do an assignment.
|
||||
*/
|
||||
void set(const std::string& key, double value);
|
||||
|
||||
|
||||
@@ -55,5 +55,6 @@ void python::common::export_SummaryState(py::module& module) {
|
||||
.def("__contains__", &SummaryState::has)
|
||||
.def("has_well_var", py::overload_cast<const std::string&, const std::string&>(&SummaryState::has_well_var, py::const_))
|
||||
.def("has_group_var", py::overload_cast<const std::string&, const std::string&>(&SummaryState::has_group_var, py::const_))
|
||||
.def("__setitem__", &SummaryState::set)
|
||||
.def("__getitem__", py::overload_cast<const std::string&>(&SummaryState::get, py::const_));
|
||||
}
|
||||
|
||||
@@ -109,10 +109,10 @@ bool Actions::ready(const State& state, std::time_t sim_time) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const PyAction *> Actions::pending_python() const {
|
||||
std::vector<const PyAction *> Actions::pending_python(const State& state) const {
|
||||
std::vector<const PyAction *> pyaction_vector;
|
||||
for (const auto& pyaction : this->pyactions) {
|
||||
if (pyaction.active())
|
||||
if (pyaction.ready(state))
|
||||
pyaction_vector.push_back( &pyaction );
|
||||
}
|
||||
return pyaction_vector;
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace py = pybind11;
|
||||
#include <opm/input/eclipse/Python/Python.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/PyAction.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/State.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||
|
||||
|
||||
@@ -64,8 +65,18 @@ PyAction PyAction::serializeObject()
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PyAction::active() const {
|
||||
return this->m_active;
|
||||
bool PyAction::ready(const State& state) const {
|
||||
if (this->m_run_count == RunCount::unlimited)
|
||||
return true;
|
||||
|
||||
auto last_result = state.python_result(this->m_name);
|
||||
if (!last_result.has_value())
|
||||
return true;
|
||||
|
||||
if (this->m_run_count == RunCount::first_true && last_result.value() == false)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,13 +84,6 @@ const std::string& PyAction::name() const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
void PyAction::update(bool result) const {
|
||||
if (this->m_run_count == RunCount::single)
|
||||
this->m_active = false;
|
||||
|
||||
if (this->m_run_count == RunCount::first_true && result)
|
||||
this->m_active = false;
|
||||
}
|
||||
|
||||
bool PyAction::operator==(const PyAction& other) const {
|
||||
return this->m_name == other.m_name &&
|
||||
|
||||
@@ -59,6 +59,10 @@ void State::add_run(const ActionX& action, std::time_t run_time, Result result)
|
||||
this->last_result.insert_or_assign(action.name(), std::move(result));
|
||||
}
|
||||
|
||||
void State::add_run(const PyAction& action, bool result) {
|
||||
this->m_python_result.insert_or_assign( action.name(), result );
|
||||
}
|
||||
|
||||
|
||||
std::optional<Result> State::result(const std::string& action) const {
|
||||
auto iter = this->last_result.find(action);
|
||||
@@ -69,6 +73,16 @@ std::optional<Result> State::result(const std::string& action) const {
|
||||
}
|
||||
|
||||
|
||||
std::optional<bool> State::python_result(const std::string& action) const {
|
||||
auto iter = this->m_python_result.find(action);
|
||||
if (iter == this->m_python_result.end())
|
||||
return std::nullopt;
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
When restoring from restart file we initialize the number of times it has run
|
||||
and the last run time. From the evaluation only the 'true' evaluation is
|
||||
@@ -86,7 +100,8 @@ void State::load_rst(const Actions& action_config, const RestartIO::RstState& rs
|
||||
|
||||
bool State::operator==(const State& other) const {
|
||||
return this->run_state == other.run_state &&
|
||||
this->last_result == other.last_result;
|
||||
this->last_result == other.last_result &&
|
||||
this->m_python_result == other.m_python_result;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +109,7 @@ State State::serializeObject() {
|
||||
State st;
|
||||
st.run_state.insert(std::make_pair( std::make_pair("ACTION", 100), RunState::serializeObject()));
|
||||
st.last_result.insert( std::make_pair("ACTION", Result::serializeObject()));
|
||||
st.m_python_result.insert( std::make_pair("PYACTION", false) );
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/TracerConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/State.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/ActionX.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/ActionResult.hpp>
|
||||
#include <opm/input/eclipse/Schedule/MSW/SICD.hpp>
|
||||
@@ -1428,14 +1429,15 @@ File {} line {}.)", pattern, location.keyword, location.filename, location.linen
|
||||
*/
|
||||
|
||||
|
||||
SimulatorUpdate Schedule::runPyAction(std::size_t reportStep, const Action::PyAction& pyaction, EclipseState& ecl_state, SummaryState& summary_state) {
|
||||
SimulatorUpdate Schedule::runPyAction(std::size_t reportStep, const Action::PyAction& pyaction, Action::State& action_state, EclipseState& ecl_state, SummaryState& summary_state) {
|
||||
SimulatorUpdate sim_update;
|
||||
|
||||
auto apply_action_callback = [&sim_update, &reportStep, this](const std::string& action_name, const std::vector<std::string>& matching_wells) {
|
||||
sim_update = this->applyAction(reportStep, action_name, matching_wells);
|
||||
};
|
||||
|
||||
pyaction.run(ecl_state, *this, reportStep, summary_state, apply_action_callback);
|
||||
auto result = pyaction.run(ecl_state, *this, reportStep, summary_state, apply_action_callback);
|
||||
action_state.add_run(pyaction, result);
|
||||
return sim_update;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,18 @@ PYACTION
|
||||
WCLOSE UNLIMITED /
|
||||
'wclose.py' /
|
||||
|
||||
PYACTION
|
||||
UNLIMITED UNLIMITED /
|
||||
'wclose.py' /
|
||||
|
||||
PYACTION
|
||||
SINGLE SINGLE /
|
||||
'wclose.py' /
|
||||
|
||||
PYACTION
|
||||
FIRST_TRUE FIRST_TRUE /
|
||||
'wclose.py' /
|
||||
|
||||
WELSPECS
|
||||
'PROD1' 'G1' 10 10 8400 'OIL' /
|
||||
'PROD2' 'G1' 5 5 8400 'OIL' /
|
||||
|
||||
@@ -447,7 +447,7 @@ PYACTION
|
||||
|
||||
PYACTION
|
||||
ACTION3 FIRST_TRUE /
|
||||
'action2.py' /
|
||||
'action_count.py' /
|
||||
|
||||
DATES
|
||||
1 'JAN' 2015 /
|
||||
|
||||
11
tests/msim/action_count.py
Normal file
11
tests/msim/action_count.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import math
|
||||
|
||||
def run(ecl_state, schedule, report_step, summary_state, actionx_callback):
|
||||
if not "run_count" in summary_state:
|
||||
summary_state["run_count"] = 0
|
||||
summary_state["run_count"] += 1
|
||||
|
||||
if summary_state.elapsed() > (365 + 15)*24*3600:
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(RUN) {
|
||||
EclipseState state(deck);
|
||||
Schedule schedule(deck, state, python);
|
||||
SummaryConfig summary_config(deck, schedule, state.fieldProps(), state.aquifer());
|
||||
msim msim(state);
|
||||
msim msim(state, schedule);
|
||||
|
||||
msim.well_rate("PROD", data::Rates::opt::oil, prod_opr);
|
||||
msim.well_rate("RFTP", data::Rates::opt::oil, prod_rft);
|
||||
@@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(RUN) {
|
||||
const WorkArea work_area("test_msim");
|
||||
EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
|
||||
msim.run(schedule, io, false);
|
||||
msim.run(io, false);
|
||||
|
||||
for (const auto& fname : {"SPE1CASE1.INIT", "SPE1CASE1.UNRST", "SPE1CASE1.EGRID", "SPE1CASE1.SMSPEC", "SPE1CASE1.UNSMRY", "SPE1CASE1.RSM"})
|
||||
BOOST_CHECK( is_file( fname ));
|
||||
@@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(RUN_SUMTHIN) {
|
||||
EclipseState state(deck);
|
||||
Schedule schedule(deck, state, python);
|
||||
SummaryConfig summary_config(deck, schedule, state.fieldProps(), state.aquifer());
|
||||
msim msim(state);
|
||||
msim msim(state, schedule);
|
||||
|
||||
msim.well_rate("PROD", data::Rates::opt::oil, prod_opr);
|
||||
msim.well_rate("RFTP", data::Rates::opt::oil, prod_rft);
|
||||
@@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(RUN_SUMTHIN) {
|
||||
EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
|
||||
// TSTEP = N*7
|
||||
msim.run(schedule, io, false);
|
||||
msim.run(io, false);
|
||||
|
||||
// clang-format off
|
||||
const auto expect_smry_time = std::vector<double> {
|
||||
@@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(RUN_RPTONLY) {
|
||||
Schedule schedule(deck, state, std::make_shared<Python>());
|
||||
const SummaryConfig summary_config(deck, schedule, state.fieldProps(), state.aquifer());
|
||||
|
||||
msim msim(state);
|
||||
msim msim(state, schedule);
|
||||
|
||||
msim.well_rate("PROD", data::Rates::opt::oil, prod_opr);
|
||||
msim.well_rate("RFTP", data::Rates::opt::oil, prod_rft);
|
||||
@@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(RUN_RPTONLY) {
|
||||
EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
|
||||
// TSTEP = N*7
|
||||
msim.run(schedule, io, false);
|
||||
msim.run(io, false);
|
||||
|
||||
// clang-format off
|
||||
const auto expect_smry_time = std::vector<double> {
|
||||
|
||||
@@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) {
|
||||
#include "actionx2.include"
|
||||
|
||||
test_data td( actionx );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
@@ -184,16 +184,16 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) {
|
||||
sim.well_rate("P3", data::Rates::opt::oil, prod_opr);
|
||||
sim.well_rate("P4", data::Rates::opt::oil, prod_opr_low);
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 1);
|
||||
const auto& w4 = td.schedule.getWell("P4", 1);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 1);
|
||||
const auto& w4 = sim.schedule.getWell("P4", 1);
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w4.getStatus() == Well::Status::OPEN );
|
||||
}
|
||||
{
|
||||
const auto& w1 = td.schedule.getWellatEnd("P1");
|
||||
const auto& w4 = td.schedule.getWellatEnd("P4");
|
||||
const auto& w1 = sim.schedule.getWellatEnd("P1");
|
||||
const auto& w4 = sim.schedule.getWellatEnd("P4");
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w4.getStatus() == Well::Status::SHUT );
|
||||
}
|
||||
@@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) {
|
||||
#include "actionx1.include"
|
||||
|
||||
test_data td( actionx1 );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
@@ -221,10 +221,10 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) {
|
||||
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
|
||||
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 15);
|
||||
const auto& w2 = td.schedule.getWell("P2", 15);
|
||||
const auto& w3 = td.schedule.getWell("P3", 15);
|
||||
const auto& w4 = td.schedule.getWell("P4", 15);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 15);
|
||||
const auto& w2 = sim.schedule.getWell("P2", 15);
|
||||
const auto& w3 = sim.schedule.getWell("P3", 15);
|
||||
const auto& w4 = sim.schedule.getWell("P4", 15);
|
||||
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w2.getStatus() == Well::Status::OPEN );
|
||||
@@ -233,19 +233,19 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) {
|
||||
}
|
||||
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 15);
|
||||
const auto& w3 = td.schedule.getWell("P3", 15);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 15);
|
||||
const auto& w3 = sim.schedule.getWell("P3", 15);
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w3.getStatus() == Well::Status::OPEN );
|
||||
}
|
||||
{
|
||||
const auto& w2_6 = td.schedule.getWell("P2", 6);
|
||||
const auto& w2_6 = sim.schedule.getWell("P2", 6);
|
||||
BOOST_CHECK(w2_6.getStatus() == Well::Status::SHUT );
|
||||
}
|
||||
{
|
||||
const auto& w4_11 = td.schedule.getWell("P4", 11);
|
||||
const auto& w4_11 = sim.schedule.getWell("P4", 11);
|
||||
BOOST_CHECK(w4_11.getStatus() == Well::Status::SHUT );
|
||||
}
|
||||
}
|
||||
@@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) {
|
||||
#include "actionx1.include"
|
||||
|
||||
test_data td( actionx1 );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
@@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) {
|
||||
sim.well_rate("P3", data::Rates::opt::wat, prod_wpr_P3);
|
||||
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
|
||||
const auto& base_name = td.state.getIOConfig().getBaseName();
|
||||
|
||||
@@ -303,7 +303,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
|
||||
#include "actionx1.include"
|
||||
|
||||
test_data td( actionx1 );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
@@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
|
||||
sim.well_rate("P3", data::Rates::opt::wat, prod_wpr_P3);
|
||||
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
|
||||
const auto& base_name = td.state.getIOConfig().getBaseName();
|
||||
const EclIO::ESmry ecl_sum(base_name + ".SMSPEC");
|
||||
@@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
|
||||
BOOST_AUTO_TEST_CASE(UDQ_IN_ACTIONX) {
|
||||
#include "udq_in_actionx.include"
|
||||
test_data td( actionx1 );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
@@ -384,26 +384,26 @@ BOOST_AUTO_TEST_CASE(UDQ_IN_ACTIONX) {
|
||||
sim.well_rate("P4", data::Rates::opt::gas, prod_gpr);
|
||||
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 15);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 15);
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
|
||||
const auto& udq1 = td.schedule.getUDQConfig(15);
|
||||
const auto& udq1 = sim.schedule.getUDQConfig(15);
|
||||
BOOST_CHECK(!udq1.has_keyword("FUNEW"));
|
||||
|
||||
const auto& udq2 = td.schedule.getUDQConfig(25);
|
||||
const auto& udq2 = sim.schedule.getUDQConfig(25);
|
||||
BOOST_CHECK(udq2.has_keyword("FUPROD"));
|
||||
}
|
||||
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 15);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 15);
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
|
||||
const auto& udq1 = td.schedule.getUDQConfig(15);
|
||||
const auto& udq1 = sim.schedule.getUDQConfig(15);
|
||||
BOOST_CHECK(udq1.has_keyword("FUNEW"));
|
||||
|
||||
const auto& udq2 = td.schedule.getUDQConfig(25);
|
||||
const auto& udq2 = sim.schedule.getUDQConfig(25);
|
||||
BOOST_CHECK(udq2.has_keyword("FUPROD"));
|
||||
BOOST_CHECK(udq2.has_keyword("FUNEW"));
|
||||
}
|
||||
@@ -421,7 +421,7 @@ BOOST_AUTO_TEST_CASE(UDQ_IN_ACTIONX) {
|
||||
BOOST_AUTO_TEST_CASE(UDA) {
|
||||
#include "uda.include"
|
||||
test_data td( uda_deck );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
auto eps_lim = sim.uda_val().epsilonLimit();
|
||||
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
@@ -434,7 +434,7 @@ BOOST_AUTO_TEST_CASE(UDA) {
|
||||
{
|
||||
WorkArea work_area("uda_sim");
|
||||
|
||||
sim.run(td.schedule, io, true);
|
||||
sim.run(io, true);
|
||||
|
||||
const auto& base_name = td.state.getIOConfig().getBaseName();
|
||||
const EclIO::ESmry ecl_sum(base_name + ".SMSPEC");
|
||||
@@ -460,7 +460,7 @@ BOOST_AUTO_TEST_CASE(UDA) {
|
||||
BOOST_AUTO_TEST_CASE(COMPDAT) {
|
||||
#include "compdat.include"
|
||||
test_data td( compdat_deck );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
|
||||
sim.well_rate("P1", data::Rates::opt::wat, prod_wpr_P1);
|
||||
@@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(COMPDAT) {
|
||||
{
|
||||
WorkArea work_area("compdat_sim");
|
||||
|
||||
BOOST_CHECK_NO_THROW(sim.run(td.schedule, io, true));
|
||||
BOOST_CHECK_NO_THROW(sim.run(io, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,10 +480,10 @@ BOOST_AUTO_TEST_CASE(COMPDAT) {
|
||||
BOOST_AUTO_TEST_CASE(PYTHON_WELL_CLOSE_EXAMPLE) {
|
||||
const auto& deck = Parser().parseFile("msim/MSIM_PYACTION.DATA");
|
||||
test_data td( deck );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), sim.schedule, td.summary_config);
|
||||
|
||||
sim.well_rate("P1", data::Rates::opt::oil, prod_opr);
|
||||
sim.well_rate("P2", data::Rates::opt::oil, prod_opr);
|
||||
@@ -496,10 +496,10 @@ BOOST_AUTO_TEST_CASE(PYTHON_WELL_CLOSE_EXAMPLE) {
|
||||
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
|
||||
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 15);
|
||||
const auto& w2 = td.schedule.getWell("P2", 15);
|
||||
const auto& w3 = td.schedule.getWell("P3", 15);
|
||||
const auto& w4 = td.schedule.getWell("P4", 15);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 15);
|
||||
const auto& w2 = sim.schedule.getWell("P2", 15);
|
||||
const auto& w3 = sim.schedule.getWell("P3", 15);
|
||||
const auto& w4 = sim.schedule.getWell("P4", 15);
|
||||
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w2.getStatus() == Well::Status::OPEN );
|
||||
@@ -508,31 +508,32 @@ BOOST_AUTO_TEST_CASE(PYTHON_WELL_CLOSE_EXAMPLE) {
|
||||
}
|
||||
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 15);
|
||||
const auto& w3 = td.schedule.getWell("P3", 15);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 15);
|
||||
const auto& w3 = sim.schedule.getWell("P3", 15);
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w3.getStatus() == Well::Status::OPEN );
|
||||
}
|
||||
{
|
||||
const auto& w2_6 = td.schedule.getWell("P2", 6);
|
||||
const auto& w2_6 = sim.schedule.getWell("P2", 6);
|
||||
BOOST_CHECK(w2_6.getStatus() == Well::Status::SHUT );
|
||||
}
|
||||
{
|
||||
const auto& w4_11 = td.schedule.getWell("P4", 11);
|
||||
const auto& w4_11 = sim.schedule.getWell("P4", 11);
|
||||
BOOST_CHECK(w4_11.getStatus() == Well::Status::SHUT );
|
||||
}
|
||||
}
|
||||
BOOST_CHECK_EQUAL( sim.st.get("run_count"), 13);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PYTHON_ACTIONX) {
|
||||
const auto& deck = Parser().parseFile("msim/MSIM_PYACTION_ACTIONX.DATA");
|
||||
test_data td( deck );
|
||||
msim sim(td.state);
|
||||
msim sim(td.state, td.schedule);
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
|
||||
EclipseIO io(td.state, td.state.getInputGrid(), sim.schedule, td.summary_config);
|
||||
|
||||
sim.well_rate("P1", data::Rates::opt::oil, prod_opr);
|
||||
sim.well_rate("P2", data::Rates::opt::oil, prod_opr);
|
||||
@@ -545,10 +546,10 @@ BOOST_AUTO_TEST_CASE(PYTHON_ACTIONX) {
|
||||
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
|
||||
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 0);
|
||||
const auto& w2 = td.schedule.getWell("P2", 0);
|
||||
const auto& w3 = td.schedule.getWell("P3", 0);
|
||||
const auto& w4 = td.schedule.getWell("P4", 0);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 0);
|
||||
const auto& w2 = sim.schedule.getWell("P2", 0);
|
||||
const auto& w3 = sim.schedule.getWell("P3", 0);
|
||||
const auto& w4 = sim.schedule.getWell("P4", 0);
|
||||
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK(w2.getStatus() == Well::Status::OPEN );
|
||||
@@ -557,13 +558,13 @@ BOOST_AUTO_TEST_CASE(PYTHON_ACTIONX) {
|
||||
}
|
||||
|
||||
|
||||
sim.run(td.schedule, io, false);
|
||||
sim.run(io, false);
|
||||
|
||||
{
|
||||
const auto& w1 = td.schedule.getWell("P1", 1);
|
||||
const auto& w2 = td.schedule.getWell("P2", 2);
|
||||
const auto& w3 = td.schedule.getWell("P3", 3);
|
||||
const auto& w4 = td.schedule.getWell("P4", 4);
|
||||
const auto& w1 = sim.schedule.getWell("P1", 1);
|
||||
const auto& w2 = sim.schedule.getWell("P2", 2);
|
||||
const auto& w3 = sim.schedule.getWell("P3", 3);
|
||||
const auto& w4 = sim.schedule.getWell("P4", 4);
|
||||
BOOST_CHECK(w1.getStatus() == Well::Status::SHUT );
|
||||
BOOST_CHECK(w2.getStatus() == Well::Status::SHUT );
|
||||
BOOST_CHECK(w3.getStatus() == Well::Status::SHUT );
|
||||
|
||||
@@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(MSIM_EXIT_TEST) {
|
||||
|
||||
{
|
||||
WorkArea work_area("test_msim");
|
||||
Opm::msim msim(state);
|
||||
Opm::msim msim(state, schedule);
|
||||
Opm::EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
|
||||
msim.well_rate("P1", Opm::data::Rates::opt::oil, Opm::prod_opr);
|
||||
msim.well_rate("P2", Opm::data::Rates::opt::oil, Opm::prod_opr);
|
||||
@@ -99,9 +99,10 @@ BOOST_AUTO_TEST_CASE(MSIM_EXIT_TEST) {
|
||||
msim.well_rate("P2", Opm::data::Rates::opt::wat, Opm::prod_wpr_P2);
|
||||
msim.well_rate("P3", Opm::data::Rates::opt::wat, Opm::prod_wpr_P3);
|
||||
msim.well_rate("P4", Opm::data::Rates::opt::wat, Opm::prod_wpr_P4);
|
||||
msim.run(schedule, io, false);
|
||||
msim.run(io, false);
|
||||
|
||||
auto exit_status = msim.schedule.exitStatus();
|
||||
BOOST_CHECK( exit_status.has_value() );
|
||||
BOOST_CHECK_EQUAL(exit_status.value(), 99);
|
||||
}
|
||||
auto exit_status = schedule.exitStatus();
|
||||
BOOST_CHECK( exit_status.has_value() );
|
||||
BOOST_CHECK_EQUAL(exit_status.value(), 99);
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ BOOST_AUTO_TEST_CASE(TestActions) {
|
||||
BOOST_CHECK(!action2.eval(context));
|
||||
|
||||
|
||||
const auto& python_actions = config.pending_python();
|
||||
const auto& python_actions = config.pending_python(action_state);
|
||||
BOOST_CHECK_EQUAL(python_actions.size(), 2U);
|
||||
}
|
||||
|
||||
@@ -977,6 +977,7 @@ BOOST_AUTO_TEST_CASE(ActionState) {
|
||||
|
||||
auto res = st.result("NAME-HIDDEN");
|
||||
BOOST_CHECK(!res.has_value());
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MANUAL4_QUOTE) {
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Action/State.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
@@ -124,7 +125,7 @@ BOOST_AUTO_TEST_CASE(PYACTION) {
|
||||
const std::string& fname = pyaction_kw.getRecord(1).getItem(0).get<std::string>(0);
|
||||
Action::PyAction py_action(python, "WCLOSE", Action::PyAction::RunCount::unlimited, deck.makeDeckPath(fname));
|
||||
auto actionx_callback = [] (const std::string&, const std::vector<std::string>&) { ;};
|
||||
|
||||
Action::State action_state;
|
||||
|
||||
st.update_well_var("PROD1", "WWCT", 0);
|
||||
py_action.run(ecl_state, schedule, 10, st, actionx_callback);
|
||||
@@ -141,6 +142,32 @@ BOOST_AUTO_TEST_CASE(PYACTION) {
|
||||
BOOST_CHECK( well1.getStatus() == Well::Status::SHUT );
|
||||
BOOST_CHECK( well2.getStatus() == Well::Status::OPEN );
|
||||
BOOST_CHECK( st.has("RUN_COUNT") );
|
||||
|
||||
std::map<std::string, Action::PyAction> action_map;
|
||||
for (const auto * p : schedule[0].actions().pending_python(action_state))
|
||||
action_map.emplace( p->name(), *p );
|
||||
|
||||
const auto& pyaction_unlimited = action_map.at("UNLIMITED");
|
||||
const auto& pyaction_single = action_map.at("SINGLE");
|
||||
const auto& pyaction_first_true = action_map.at("FIRST_TRUE");
|
||||
|
||||
auto actions = schedule[0].actions();
|
||||
BOOST_CHECK( actions.pending_python(action_state).size() == 4);
|
||||
|
||||
action_state.add_run( py_action, true);
|
||||
BOOST_CHECK( actions.pending_python(action_state).size() == 4);
|
||||
|
||||
action_state.add_run( pyaction_unlimited, true);
|
||||
BOOST_CHECK( actions.pending_python(action_state).size() == 4);
|
||||
|
||||
action_state.add_run( pyaction_single, false);
|
||||
BOOST_CHECK( actions.pending_python(action_state).size() == 3);
|
||||
|
||||
action_state.add_run( pyaction_first_true, false);
|
||||
BOOST_CHECK( actions.pending_python(action_state).size() == 3);
|
||||
|
||||
action_state.add_run( pyaction_first_true, true);
|
||||
BOOST_CHECK( actions.pending_python(action_state).size() == 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user