REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_DateClock.H File Reference
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <AMReX_Extension.H>
#include <AMReX_GpuQualifiers.H>
Include dependency graph for REMORA_DateClock.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int remora_yearday (int year, int month, int day) noexcept
 Day of the year for a calendar date. ROMS yearday.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double remora_datenum (double time_ref, int year, int month, int day, int hour=0, int minutes=0, double seconds=0.0) noexcept
 Fractional day number for a calendar date. ROMS datenum.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_ref_clock (double time_ref, int &year, int &month, int &day, int &hour, int &minute, int &second) noexcept
 Reference date the model clock counts from, implied by time_ref.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double remora_ref_datenum (double time_ref) noexcept
 Day number of the reference date implied by time_ref.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_datevec (double time_ref, double date_number, bool is_day_units, int &year, int &month, int &day) noexcept
 Calendar date for a day (or second) number. ROMS datevec.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_caldate (double time_ref, double current_time_days, int &year, int &month, int &day, double &yday) noexcept
 Model time in days to calendar date. ROMS caldate.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_caldate (double time_ref, double current_time_days, int &year, double &yday) noexcept
 remora_caldate for callers that only want the year and day of year.
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool remora_time_ref_is_valid (double time_ref) noexcept
 Whether time_ref names a calendar this header implements.
 
AMREX_FORCE_INLINE std::string remora_ref_calendar (double time_ref)
 CF calendar name for time_ref. ROMS ref_clock's Rclockcalendar.
 
AMREX_FORCE_INLINE std::string remora_ref_date_string (double time_ref)
 Reference date as YYYY-MM-DD hh:mm:ss. ROMS ref_clock's Rclockstring.
 

Variables

static constexpr int remora_gregorian_daynum = 2299161
 

Detailed Description

Model time to calendar date, ported from ROMS dateclock.F.

The model clock is elapsed time since a reference date, and remora.time_ref both sets that date and picks the calendar, exactly as ROMS TIME_REF does:

time_ref calendar epoch year length
yyyymmdd.dd proleptic Gregorian the date given 365.2425 d
0 proleptic Gregorian 0001-01-01 00:00:00 365.2425 d
-1 360_day 0000-12-30 00:00:00 360 d
-2 Gregorian, truncated 1968-05-23 00:00:00 365.25 d

Julian day (NASA)

time_ref is passed in rather than read from a global, so these stay pure functions; ROMS keeps the equivalent in Rclock in mod_scalars. The reference date number is recomputed per call, which is a handful of integer operations, rather than cached.

The arithmetic is deliberately a transcription rather than a tidier equivalent. Fortran INT and AINT truncate toward zero, as do a C++ cast to int and std::trunc, and C++ integer division truncates toward zero too, so each expression carries over term for term. Where ROMS uses FLOOR – and in the time_ref = -2 conversion it does, which rounds differently from INT on the negative side of the epoch – std::floor is used here.

Everything here is double regardless of the build's amrex::Real. A yyyymmdd.dd reference date carries eight significant integer digits, which a single-precision float (24-bit mantissa, exact only to 2^24 = 16777216) cannot hold, and a modern day number (about 737791 for 2020, 2440000 and up for the truncated Julian day) would keep only a fraction of a day of resolution.

The day fraction is available from remora_caldate's yday for a caller that needs it. The reference date does carry a time of day – remora.time_ref can name one – and remora_ref_clock returns it.

Two quirks of the time_ref = -2 calendar carry over, both ROMS's and both confirmed against the Fortran rather than inferred:

  • datenum splits the year as y01 = MyYear/100, which truncates toward zero, so it disagrees with the true Julian day number for years before 0. dateclock.F documents datenum(-4713,11,24) = 0; its own code returns 1, and so does this. From year 1 on it agrees with the standard Fliegel-Van Flandern day number exactly.
  • datevec treats any day number below the 15 October 1582 changeover as a truncated one and adds the reference offset back, so it does not invert datenum before that date. That is the heuristic ROMS uses to accept both full and truncated Julian days in the same argument.

Neither affects a model run in modern times, which is what this calendar is for, but both would bite anyone reaching further back with it.

Definition in file REMORA_DateClock.H.

Function Documentation

◆ remora_caldate() [1/2]

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_caldate ( double  time_ref,
double  current_time_days,
int &  year,
double &  yday 
)
noexcept

remora_caldate for callers that only want the year and day of year.

Definition at line 366 of file REMORA_DateClock.H.

Here is the call graph for this function:

◆ remora_caldate() [2/2]

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_caldate ( double  time_ref,
double  current_time_days,
int &  year,
int &  month,
int &  day,
double &  yday 
)
noexcept

Model time in days to calendar date. ROMS caldate.

Parameters
[in]time_refremora.time_ref; see the table at the top
[in]current_time_daysmodel time in days, as ROMS tdays
[out]yearyear including century
[out]monthmonth of the year, 1 = January
[out]dayday of the month
[out]ydayday of the year, including the day fraction, so 00:00 on the first day of the year is exactly 1.0

Definition at line 336 of file REMORA_DateClock.H.

Referenced by remora_caldate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_datenum()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double remora_datenum ( double  time_ref,
int  year,
int  month,
int  day,
int  hour = 0,
int  minutes = 0,
double  seconds = 0.0 
)
noexcept

Fractional day number for a calendar date. ROMS datenum.

Reference values, per calendar:

  • proleptic Gregorian: datenum(0000,01,01) = 1, datenum(0001,01,01) = 367. The origin is Matlab's datenum(0000,00,00) = 0, hence the 61-day offset.
  • 360_day: datenum(0000,01,01) = 0, datenum(0001,01,01) = 360.
  • truncated Julian: datenum(-4713,11,24) = 0, datenum(1968,05,23) = 2440000.

Definition at line 89 of file REMORA_DateClock.H.

Referenced by remora_ref_datenum().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_datevec()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_datevec ( double  time_ref,
double  date_number,
bool  is_day_units,
int &  year,
int &  month,
int &  day 
)
noexcept

Calendar date for a day (or second) number. ROMS datevec.

is_day_units selects fractional days over fractional seconds, as ROMS's IsDayUnits does.

ROMS's time_ref = -2 branch can also run a proleptic Julian conversion, but its ProlepticJulian switch is a local hardcoded to .FALSE., so that path is unreachable as shipped and is not ported.

Definition at line 227 of file REMORA_DateClock.H.

Referenced by remora_caldate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_ref_calendar()

AMREX_FORCE_INLINE std::string remora_ref_calendar ( double  time_ref)

CF calendar name for time_ref. ROMS ref_clock's Rclockcalendar.

Written next to every time stamp in NetCDF output, so a reader can tell which calendar the model clock is on.

Definition at line 393 of file REMORA_DateClock.H.

Referenced by REMORA::WriteNCPlotFile_which().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_ref_clock()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void remora_ref_clock ( double  time_ref,
int &  year,
int &  month,
int &  day,
int &  hour,
int &  minute,
int &  second 
)
noexcept

Reference date the model clock counts from, implied by time_ref.

ROMS ref_clock's date decode, the fields behind Rclockstring. The sentinel calendars carry ROMS's hardcoded dates: 0000-12-30 for 360_day, whose epoch is shifted back a day to undo a historical one-day offset, 1968-05-23 for the truncated Julian day, and 0001-01-01 for time_ref = 0.

Definition at line 156 of file REMORA_DateClock.H.

Referenced by remora_ref_date_string(), and remora_ref_datenum().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_ref_date_string()

AMREX_FORCE_INLINE std::string remora_ref_date_string ( double  time_ref)

Reference date as YYYY-MM-DD hh:mm:ss. ROMS ref_clock's Rclockstring.

The "since" half of a CF time-units attribute: prefix days since or seconds since to get the units of a time stamp on the model clock. Host only, since it builds a std::string.

Definition at line 414 of file REMORA_DateClock.H.

Referenced by REMORA::WriteNCPlotFile_which().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_ref_datenum()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double remora_ref_datenum ( double  time_ref)
noexcept

Day number of the reference date implied by time_ref.

ROMS ref_clock, reduced to the one field most of this header needs: RclockDateNumber(1). The two negative calendars carry hardcoded values in ROMS – 359 for 360_day, whose epoch is shifted to 0000-12-30 to undo a historical one-day offset, and 2440000 for the truncated Julian day.

Definition at line 197 of file REMORA_DateClock.H.

Referenced by remora_caldate(), and remora_datevec().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remora_time_ref_is_valid()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool remora_time_ref_is_valid ( double  time_ref)
noexcept

Whether time_ref names a calendar this header implements.

ROMS's CALENDAR if-chain has no final ELSE, so a value below -2 leaves the date undefined rather than failing. Callers should reject it up front.

Definition at line 381 of file REMORA_DateClock.H.

Referenced by SolverChoice::init_params().

Here is the caller graph for this function:

◆ remora_yearday()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int remora_yearday ( int  year,
int  month,
int  day 
)
noexcept

Day of the year for a calendar date. ROMS yearday.

Definition at line 72 of file REMORA_DateClock.H.

Referenced by remora_caldate().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ remora_gregorian_daynum

constexpr int remora_gregorian_daynum = 2299161
staticconstexpr

Reference day number of the 15 October 1582 Gregorian changeover, as ROMS spells it in datevec.

Definition at line 68 of file REMORA_DateClock.H.

Referenced by remora_datevec().