Skip to content

Commit

Permalink
Merge pull request #4374 from atgeirr/fix-subsecond-timesteps
Browse files Browse the repository at this point in the history
Fix subsecond timesteps
  • Loading branch information
atgeirr authored Dec 13, 2024
2 parents 734ce76 + 5ea7cb7 commit 7916398
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 29 deletions.
11 changes: 5 additions & 6 deletions opm/common/utility/MemPacker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,22 @@ unpack(std::string& data, const std::vector<char>& buffer, std::size_t& position
std::size_t Packing<false,time_point>::
packSize(const time_point&)
{
return Packing<true,std::time_t>::packSize(std::time_t());
return Packing<true, time_point::duration::rep>::packSize(time_point::duration::rep());
}

void Packing<false,time_point>::
pack(const time_point& data,
std::vector<char>& buffer, std::size_t& position)
{
Packing<true,std::time_t>::pack(TimeService::to_time_t(data),
buffer, position);
Packing<true, time_point::duration::rep>::pack(data.time_since_epoch().count(), buffer, position);
}

void Packing<false,time_point>::
unpack(time_point& data, const std::vector<char>& buffer, std::size_t& position)
{
std::time_t res;
Packing<true,std::time_t>::unpack(res, buffer, position);
data = TimeService::from_time_t(res);
time_point::duration::rep res;
Packing<true, time_point::duration::rep>::unpack(res, buffer, position);
data = time_point(time_point::duration(res));
}

template struct Packing<false,std::bitset<3>>;
Expand Down
9 changes: 5 additions & 4 deletions opm/input/eclipse/Schedule/Schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1531,8 +1531,7 @@ File {} line {}.)", pattern, location.keyword, location.filename, location.linen
const auto& well = this->getWell(wname, timeStep);
const auto& connections = well.getConnections();
if (connections.allConnectionsShut() && well.getStatus() != Well::Status::SHUT) {
auto elapsed = this->snapshots[timeStep].start_time() - this->snapshots[0].start_time();
auto days = std::chrono::duration_cast<std::chrono::hours>(elapsed).count() / 24.0;
auto days = unit::convert::to(seconds(timeStep), unit::day);
auto msg = fmt::format("All completions in well {} is shut at {} days\n"
"The well is therefore also shut", well.name(), days);
OpmLog::note(msg);
Expand Down Expand Up @@ -1576,7 +1575,8 @@ File {} line {}.)", pattern, location.keyword, location.filename, location.linen
throw std::logic_error(fmt::format("seconds({}) - invalid timeStep. Valid range [0,{}>", timeStep, this->snapshots.size()));

auto elapsed = this->snapshots[timeStep].start_time() - this->snapshots[0].start_time();
return std::chrono::duration_cast<std::chrono::seconds>(elapsed).count();
using DurationInSeconds = std::chrono::duration<double>; // Tick is 1 second, stored in double.
return DurationInSeconds(elapsed).count();
}

std::time_t Schedule::simTime(std::size_t timeStep) const {
Expand All @@ -1596,7 +1596,8 @@ File {} line {}.)", pattern, location.keyword, location.filename, location.linen
fmt::gmtime(TimeService::to_time_t(start_time)),
fmt::gmtime(TimeService::to_time_t(end_time))) };
}
return std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count();
using DurationInSeconds = std::chrono::duration<double>; // Tick is 1 second, stored in double.
return DurationInSeconds(end_time - start_time).count();
}

void Schedule::applyKeywords(std::vector<std::unique_ptr<DeckKeyword>>& keywords)
Expand Down
2 changes: 1 addition & 1 deletion opm/input/eclipse/Schedule/ScheduleBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void ScheduleBlock::writeTStep(const UnitSystem& usys,
time_point current_time,
DeckOutput& output) const
{
const auto seconds = std::chrono::duration_cast<std::chrono::seconds>
const auto seconds = std::chrono::duration<double>
(this->start_time() - current_time);

const auto tstep_string = fmt::format(R"(
Expand Down
8 changes: 7 additions & 1 deletion opm/input/eclipse/Schedule/ScheduleDeck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ void ScheduleDeck::add_TSTEP(const DeckKeyword& TSTEPKeyword, ScheduleDeckContex
throw OpmInputError(msg, TSTEPKeyword.location());
}
}
// The duration_cast on the next line is converting to
// millisecond accuracy, which is what is used for storing
// times internally. This should be sufficient also for lab
// scale simulations, so the duration_cast is left in the code
// (converting from float to integer representation generally
// required such a cast).
auto next_time = context.last_time + std::chrono::duration_cast<time_point::duration>(std::chrono::duration<double>(item.getSIDouble(itemIndex)));
this->add_block(ScheduleTimeType::TSTEP, next_time, context, TSTEPKeyword.location());
}
Expand All @@ -231,7 +237,7 @@ double ScheduleDeck::seconds(std::size_t timeStep) const {
throw std::logic_error(fmt::format("seconds({}) - invalid timeStep. Valid range [0,{}>", timeStep, this->m_blocks.size()));

std::chrono::duration<double> elapsed = this->m_blocks[timeStep].start_time() - this->m_blocks[0].start_time();
return std::chrono::duration_cast<std::chrono::seconds>(elapsed).count();
return elapsed.count();
}


Expand Down
16 changes: 3 additions & 13 deletions opm/input/eclipse/Schedule/ScheduleState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,6 @@

namespace {

// This is to ensure that only time_points which can be represented with
// std::time_t are used. The reason for clamping to std::time_t
// resolution is that the serialization code in
// opm-simulators:opm/simulators/utils/ParallelRestart.cpp goes via
// std::time_t.
Opm::time_point clamp_time(Opm::time_point t)
{
return Opm::TimeService::from_time_t(Opm::TimeService::to_time_t(t));
}

std::pair<std::size_t, std::size_t>
date_diff(const Opm::time_point& t2, const Opm::time_point& t1)
{
Expand All @@ -89,7 +79,7 @@ bool ScheduleState::save() const {
}

ScheduleState::ScheduleState(const time_point& t1)
: m_start_time(clamp_time(t1))
: m_start_time(t1)
, m_first_in_month(true)
, m_first_in_year(true)
{
Expand All @@ -100,7 +90,7 @@ ScheduleState::ScheduleState(const time_point& t1)
ScheduleState::ScheduleState(const time_point& start_time, const time_point& end_time)
: ScheduleState(start_time)
{
this->m_end_time = clamp_time(end_time);
this->m_end_time = end_time;
}

void ScheduleState::update_date(const time_point& prev_time)
Expand All @@ -117,7 +107,7 @@ void ScheduleState::update_date(const time_point& prev_time)
ScheduleState::ScheduleState(const ScheduleState& src, const time_point& start_time)
: ScheduleState { src } // Copy constructor
{
this->m_start_time = clamp_time(start_time);
this->m_start_time = start_time;
this->m_end_time = std::nullopt;
this->m_sim_step = src.sim_step() + 1;
this->m_events.reset();
Expand Down
2 changes: 1 addition & 1 deletion opm/io/eclipse/ERsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ bool cmp(const ESmry& smry, const ERsm& rsm) {
return false;

for (std::size_t time_index = 0; time_index < rsm_days.size(); time_index++) {
auto smry_days = std::chrono::duration_cast<std::chrono::seconds>(summary_dates[time_index] - smry.startdate()).count() / 86400.0 ;
auto smry_days = std::chrono::duration<double, std::ratio<86400>>(summary_dates[time_index] - smry.startdate()).count();

if (!cmp::scalar_equal(smry_days, rsm_days[time_index])) {
fmt::print(stderr, "time_index: {} summary.days: {} rsm.days: {}\n", time_index, smry_days, rsm_days[time_index]);
Expand Down
2 changes: 1 addition & 1 deletion opm/io/eclipse/ESmry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ std::vector<Opm::time_point> ESmry::dates() const
{
using Seconds = std::chrono::duration<double, std::chrono::seconds::period>;
return this->tp_startdat +
std::chrono::duration_cast<std::chrono::seconds>(Seconds{t * time_unit});
std::chrono::duration_cast<time_point::duration>(Seconds{t * time_unit});
});

return d;
Expand Down
2 changes: 1 addition & 1 deletion opm/io/eclipse/ExtESmry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ std::vector<Opm::time_point> ExtESmry::dates()
[this, time_unit](const auto& t)
{
using Seconds = std::chrono::duration<double, std::chrono::seconds::period>;
return this->m_startdat + std::chrono::duration_cast<std::chrono::seconds>(Seconds{t * time_unit});
return this->m_startdat + std::chrono::duration_cast<time_point::duration>(Seconds{t * time_unit});
});

return d;
Expand Down
2 changes: 1 addition & 1 deletion tests/test_ESmry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(TestESmry_1) {
const auto dates = smry1.dates();
for (std::size_t index = 0; index < dates.size(); index++) {
auto diff = dates[index]- smry1.startdate();
auto diff_seconds = std::chrono::duration_cast<std::chrono::seconds>(diff).count();
auto diff_seconds = std::chrono::duration<double>(diff).count();
BOOST_CHECK_CLOSE(diff_seconds, 24*3600 * smryVect[index], 1e-6);
}

Expand Down

0 comments on commit 7916398

Please sign in to comment.