From ea5b2f072cdd811116aefd6838d63b18ecf83483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 15 Feb 2022 14:08:26 +0100 Subject: [PATCH] Clarify Underlying Issue When Missing RESTART DATE in SKIPREST When a restarted model uses SKIPREST, there must be DATES or TSTEP records/report times that correspond exactly to the restart time. The current diagnostic message is a little too brief and developer centric and does not offer sufficient hints to the user as to what the underlying issue might be. Try to expand the current message and provide more clues to the user by mentioning both the SKIPREST and RESTART keywords in addition to the expected and encountered time points. Example original message: Error: Problem with keyword DATES In PRED_FLOW.DATA line 223 At date: 2019-04-18 - scanned past restart data: 2019-04-12 Example message in this commit: Error: Problem with keyword DATES In PRED_FLOW.DATA line 223 In a restarted simulation using SKIPREST, the DATES keyword must have a record corresponding to the RESTART time 12-Apr-2019 00:00:00. Reached time 18-Apr-2019 00:00:00 without an intervening record. --- .../input/eclipse/Schedule/ScheduleDeck.cpp | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/src/opm/input/eclipse/Schedule/ScheduleDeck.cpp b/src/opm/input/eclipse/Schedule/ScheduleDeck.cpp index c2bd24d6a..3b2c76cab 100644 --- a/src/opm/input/eclipse/Schedule/ScheduleDeck.cpp +++ b/src/opm/input/eclipse/Schedule/ScheduleDeck.cpp @@ -17,21 +17,27 @@ along with OPM. If not, see . */ -#include -#include -#include - -#include -#include -#include #include + #include + #include #include #include + +#include +#include #include + #include +#include +#include +#include + +#include +#include + namespace Opm { ScheduleRestartInfo::ScheduleRestartInfo(const RestartIO::RstState * rst, const Deck& deck) { @@ -253,6 +259,50 @@ ScheduleDeck::ScheduleDeck(time_point start_time, const Deck& deck, const Schedu } } +namespace { + + std::string + format_skiprest_error(const ScheduleTimeType time_type, + const time_point& restart_time, + const time_point& t) + { + const auto rst = TimeStampUTC { + TimeService::to_time_t(restart_time) + }; + + const auto current = TimeStampUTC { + TimeService::to_time_t(t) + }; + + auto rst_tm = std::tm{}; + rst_tm.tm_year = rst.year() - 1900; + rst_tm.tm_mon = rst.month() - 1; + rst_tm.tm_mday = rst.day(); + + rst_tm.tm_hour = rst.hour(); + rst_tm.tm_min = rst.minutes(); + rst_tm.tm_sec = rst.seconds(); + + auto current_tm = std::tm{}; + current_tm.tm_year = current.year() - 1900; + current_tm.tm_mon = current.month() - 1; + current_tm.tm_mday = current.day(); + + current_tm.tm_hour = current.hour(); + current_tm.tm_min = current.minutes(); + current_tm.tm_sec = current.seconds(); + + const auto* keyword = (time_type == ScheduleTimeType::DATES) + ? "DATES" : "TSTEP"; + const auto* record = (time_type == ScheduleTimeType::DATES) + ? "record" : "report step"; + + return fmt::format("In a restarted simulation using SKIPREST, the {0} keyword must have\n" + "a {1} corresponding to the RESTART time {2:%d-%b-%Y %H:%M:%S}.\n" + "Reached time {3:%d-%b-%Y %H:%M:%S} without an intervening {1}.", + keyword, record, rst_tm, current_tm); + } +} void ScheduleDeck::add_block(ScheduleTimeType time_type, const time_point& t, ScheduleDeckContext& context, const KeywordLocation& location) { context.last_time = t; @@ -265,11 +315,9 @@ void ScheduleDeck::add_block(ScheduleTimeType time_type, const time_point& t, Sc if (t > this->m_restart_time) { if (this->skiprest) { - TimeStampUTC rst(TimeService::to_time_t(this->m_restart_time)); - TimeStampUTC current(TimeService::to_time_t(t)); - auto reason = fmt::format("At date: {:4d}-{:02d}-{:02d} - scanned past restart data: {:4d}-{:02d}-{:02d}", - current.year(), current.month(), current.day(), - rst.year(), rst.month(), rst.day()); + const auto reason = + format_skiprest_error(time_type, this->m_restart_time, t); + throw OpmInputError(reason, location); } context.rst_skip = false;