Merge pull request #2760 from joakim-hove/handle-nextstep

Internalize NEXTSTEP keyword and interact with TUNING.TSINIT
This commit is contained in:
Bård Skaflestad 2021-10-18 18:34:14 +02:00 committed by GitHub
commit 726a0589ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 110 additions and 4 deletions

View File

@ -615,6 +615,7 @@ namespace Opm
void handleMULTFLT (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMXUNSUPP (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNETBALAN (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNEXTSTEP (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNODEPROP (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNUPCOL (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLY (const HandlerContext&, const ParseContext&, ErrorGuard&);

View File

@ -300,6 +300,7 @@ namespace Opm {
void update_tuning(Tuning tuning);
Tuning& tuning();
const Tuning& tuning() const;
double max_next_tstep() const;
void init_nupcol(Nupcol nupcol);
void update_nupcol(int nupcol);
@ -468,6 +469,7 @@ namespace Opm {
map_member<std::string, Group> groups;
map_member<std::string, Well> wells;
std::unordered_map<std::string, double> target_wellpi;
std::optional<NextStep> next_tstep;
using WellPIMapType = std::unordered_map<std::string, double>;
@ -483,6 +485,7 @@ namespace Opm {
serializer(m_save_step);
serializer(m_sumthin);
serializer(this->m_rptonly);
serializer(this->next_tstep);
m_tuning.serializeOp(serializer);
m_nupcol.serializeOp(serializer);
m_oilvap.serializeOp(serializer);

View File

@ -21,6 +21,28 @@
#define OPM_TUNING_HPP
namespace Opm {
class NextStep {
public:
NextStep() = default;
NextStep(double value, bool every_report);
double value() const;
bool every_report() const;
bool operator==(const NextStep& other) const;
static NextStep serializeObject();
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(this->next_tstep);
serializer(this->persist);
}
private:
double next_tstep;
bool persist;
};
struct Tuning {
Tuning();

View File

@ -744,6 +744,16 @@ namespace {
this->snapshots.back().network_balance.update( std::move(new_balance) );
}
void Schedule::handleNEXTSTEP(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
const auto& record = handlerContext.keyword[0];
auto next_tstep = record.getItem<ParserKeywords::NEXTSTEP::MAX_STEP>().getSIDouble(0);
auto apply_to_all = DeckItem::to_bool( record.getItem<ParserKeywords::NEXTSTEP::APPLY_TO_ALL>().get<std::string>(0) );
this->snapshots.back().next_tstep = NextStep{next_tstep, apply_to_all};
this->snapshots.back().events().addEvent(ScheduleEvents::TUNING_CHANGE);
}
void Schedule::handleNODEPROP(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
auto ext_network = this->snapshots.back().network.get();
@ -2052,6 +2062,7 @@ namespace {
{ "MULTZ" , &Schedule::handleMXUNSUPP },
{ "MULTZ-" , &Schedule::handleMXUNSUPP },
{ "NETBALAN", &Schedule::handleNETBALAN },
{ "NEXTSTEP", &Schedule::handleNEXTSTEP },
{ "NODEPROP", &Schedule::handleNODEPROP },
{ "NUPCOL" , &Schedule::handleNUPCOL },
{ "RPTONLY" , &Schedule::handleRPTONLY },

View File

@ -114,6 +114,13 @@ ScheduleState::ScheduleState(const ScheduleState& src, const time_point& start_t
new_rst.save = false;
this->rst_config.update( std::move(new_rst) );
}
if (this->next_tstep.has_value()) {
if (!this->next_tstep->every_report()) {
this->next_tstep = std::nullopt;
this->events().addEvent(ScheduleEvents::TUNING_CHANGE);
}
}
}
@ -267,6 +274,7 @@ bool ScheduleState::operator==(const ScheduleState& other) const {
this->vfpprod == other.vfpprod &&
this->vfpinj == other.vfpinj &&
this->m_sumthin == other.m_sumthin &&
this->next_tstep == other.next_tstep &&
this->m_rptonly == other.m_rptonly;
}
@ -325,6 +333,15 @@ Tuning& ScheduleState::tuning() {
return this->m_tuning;
}
double ScheduleState::max_next_tstep() const {
auto tuning_value = this->m_tuning.TSINIT;
if (!this->next_tstep.has_value())
return tuning_value;
auto next_value = this->next_tstep->value();
return std::max(next_value, tuning_value);
}
void ScheduleState::update_events(Events events) {
this->m_events = events;
}

View File

@ -25,6 +25,29 @@
namespace Opm {
NextStep::NextStep(double value, bool every_report)
: next_tstep(value)
, persist(every_report)
{}
bool NextStep::operator==(const NextStep& other) const {
return this->next_tstep == other.next_tstep &&
this->persist == other.persist;
}
double NextStep::value() const {
return this->next_tstep;
}
bool NextStep::every_report() const {
return this->persist;
}
Tuning::Tuning() {
using TuningKw = ParserKeywords::TUNING;
using WsegIterKW = ParserKeywords::WSEGITER;

View File

@ -41,6 +41,9 @@ START
21 MAY 1981 /
SCHEDULE
NEXTSTEP
5 YES /
TSTEP
1 2 3 4 5 /
@ -49,10 +52,14 @@ TUNING
0.2 0.002 2E-7 0.0002 11 0.02 2.0E-6 0.002 0.002 0.035 66 0.02 2/
13 2 26 2 9 9 4.0E6 4.0E6 4.0E6 1/
DATES
1 JAN 1982 /
1 JAN 1982 13:55:44 /
3 JAN 1982 14:56:45.123 /
1 JAN 1982 / -- 6
1 JAN 1982 13:55:44 / --7
3 JAN 1982 14:56:45.123 / -- 8
/
NEXTSTEP
10 /
TSTEP
9 10 /
@ -95,6 +102,7 @@ BOOST_AUTO_TEST_CASE(TuningTest) {
const auto& tuning = schedule[4].tuning();
double TSINIT_default = tuning.TSINIT;
BOOST_CHECK_CLOSE(TSINIT_default, 1 * Metric::Time, diff);
BOOST_CHECK_CLOSE(schedule[timestep].max_next_tstep(), 5*Metric::Time, diff);
double TSMAXZ_default = tuning.TSMAXZ;
BOOST_CHECK_CLOSE(TSMAXZ_default, 365 * Metric::Time, diff);
@ -215,6 +223,7 @@ BOOST_AUTO_TEST_CASE(TuningTest) {
BOOST_CHECK(event.hasEvent(ScheduleEvents::TUNING_CHANGE));
double TSINIT = tuning.TSINIT;
BOOST_CHECK_CLOSE(TSINIT, 2 * Metric::Time, diff);
BOOST_CHECK_CLOSE(schedule[timeStep].max_next_tstep(), 5*Metric::Time, diff);
double TSMAXZ = tuning.TSMAXZ;
BOOST_CHECK_CLOSE(TSMAXZ, 300 * Metric::Time, diff);
@ -322,11 +331,31 @@ BOOST_AUTO_TEST_CASE(TuningTest) {
BOOST_CHECK(!event.hasEvent(ScheduleEvents::TUNING_CHANGE));
}
/*** TIMESTEP 8 ***/
{
std::size_t timestep = 8;
const auto& event = schedule[timestep].events();
const auto& tuning = schedule[timestep].tuning();
BOOST_CHECK(event.hasEvent(ScheduleEvents::TUNING_CHANGE));
BOOST_CHECK_CLOSE(schedule[timestep].max_next_tstep(), 10*Metric::Time, diff);
}
/*** TIMESTEP 9 ***/
{
std::size_t timestep = 9;
const auto& event = schedule[timestep].events();
const auto& tuning = schedule[timestep].tuning();
BOOST_CHECK(event.hasEvent(ScheduleEvents::TUNING_CHANGE));
BOOST_CHECK_CLOSE(schedule[timestep].max_next_tstep(), 2*Metric::Time, diff);
}
/*** TIMESTEP 10 ***/
{
/********* Record 1 ***********/
std::size_t timestep = 10;
const auto& tuning = schedule[10].tuning();
const auto& tuning = schedule[timestep].tuning();
const auto& event = schedule[timestep].events();
BOOST_CHECK(event.hasEvent(ScheduleEvents::TUNING_CHANGE));
BOOST_CHECK_EQUAL(true, tuning.TMAXWC_has_value);