Skip to content

Commit

Permalink
Merge pull request #154 from philipwjones/omega/single-calendar
Browse files Browse the repository at this point in the history
allow only one calendar instance for a simulation
  • Loading branch information
philipwjones authored Oct 30, 2024
2 parents 8018287 + 91ab3bb commit 5d6af46
Show file tree
Hide file tree
Showing 11 changed files with 1,838 additions and 1,969 deletions.
48 changes: 37 additions & 11 deletions components/omega/doc/devGuide/TimeMgr.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,54 @@ enum CalendarKind {
CalendarUnknown ///< uninitialized or invalid
};
```
During a simulation, only one calendar can be defined and is set with the call:
```c++
Calendar::init("CalendarName");
```
that must be set early in the model initialization before other time quantities
are defined. CalendarName is a string associated with the defined calendars
above and found in the list CalendarKindName in ``TimeMgr.h``. Typically, they
are the same as the kinds above with a space for multi-word names
(eg "No Leap"). If a custom calendar is desired rather than the supported
calendars, a custom calendar can be defined with a different init
interface in which all the relevant quantities are provided:
```c++
Calendar::init(
std::vector<I4> &InDaysPerMonth, ///< [in] array of days per month
I4 InSecondsPerDay, ///< [in] seconds per day
I4 InSecondsPerYear, ///< [in] seconds per year
I4 InDaysPerYear ///< [in] days per year (dpy)
);
```
Time is generally tracked as the amount of time elapsed from a reference date
for a given calendar.
for a given calendar. A number of public functions exist to retrieve Calendar
information, convert between dates and elapsed time, check for leap years and
other checks. However, these are typically used by other TimeMgr classes and
not directly by the developer. Examples of their use can be found in the
TimeMgr unit test.

### 3. TimeInstant

The TimeInstant class represents a moment in time for a particular calendar. It
consists of a TimeFrac and a pointer to the Calendar in which the time is based.
The TimeInstant class represents a moment in time with the particular calendar
that has been defined for the simulation. It consists of a TimeFrac that
represents the time since a reference time associated with the defined calendar.
There are three constructors for initializing a TimeInstant. One method is with
a pointer to an initialized Calendar object, five 8-byte integers, and an 8-byte
real value:
five 8-byte integers, and an 8-byte real value:
```c++
OMEGA::TimeInstant TI1(&CalGreg, Year, Month, Day, Hour, Minute, RealSecond);
OMEGA::TimeInstant TI1(Year, Month, Day, Hour, Minute, RealSecond);
```
Alternatively, the TimeInstant can be initialized with a Calendar pointer and
eight 8-byte integers, with the seconds value represented by three 8-byte
integers:
Alternatively, the TimeInstant can be initialized with eight 8-byte integers,
with the seconds value represented by three 8-byte integers:
```c++
OMEGA::TimeInstant TI2(&CalGreg, Y, M, D, H, M, Whole, Numer, Denom);
OMEGA::TimeInstant TI2(Y, M, D, H, M, Whole, Numer, Denom);
```
A final constructor creates a time instant based on a time string that
conforms roughly to the ISO standard `"YYYYYY-MM-DD_HH:MM:SS.SSSS"` though
the constructor allows for any single-character non-numeric separator between
each of the numeric fields and the width of the YY and SS fields can be up
to the 8-byte standards for integer and floats, respectively.
```c++
OMEGA::TimeInstant TI3(&CalGreg, TimeString);
OMEGA::TimeInstant TI3(TimeString);
```
Among the methods defined in the TimeInstant class is `getString` which will
Expand Down Expand Up @@ -108,6 +130,10 @@ enum class TimeUnits {
Years, ///< time units in years
};
```
Finally, a time interval can be defined as the time between two time instants:
```c++
OMEGA::TimeInterval MyDeltaTime = MyTimeInstant2 - MyTimeInstant1;
```

### 5. Alarm

Expand Down
3 changes: 1 addition & 2 deletions components/omega/src/drivers/standalone/OceanDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ int main(int argc, char **argv) {
Kokkos::initialize(); // initialize Kokkos

// Time management objects
OMEGA::Calendar OmegaCal;
OMEGA::TimeInstant CurrTime;
OMEGA::Alarm EndAlarm;

ErrCurr = OMEGA::ocnInit(MPI_COMM_WORLD, OmegaCal, CurrTime, EndAlarm);
ErrCurr = OMEGA::ocnInit(MPI_COMM_WORLD, CurrTime, EndAlarm);
if (ErrCurr != 0)
LOG_ERROR("Error initializing OMEGA");

Expand Down
13 changes: 3 additions & 10 deletions components/omega/src/infra/IOStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,6 @@ int IOStream::create(const std::string &StreamName, //< [in] name of stream

// For alarms, need to retrieve clock start time
TimeInstant ClockStart = ModelClock.getStartTime();
Calendar *CalendarPtr;
Err = ClockStart.get(CalendarPtr);
if (Err != 0) {
LOG_ERROR("Unable to retrieve clock info while constructing stream {}",
StreamName);
return Err;
}

// Read frequency of input/output
int IOFreq;
Expand Down Expand Up @@ -518,7 +511,7 @@ int IOStream::create(const std::string &StreamName, //< [in] name of stream
std::string StrtTime;
Err = StreamConfig.get("StartTime", StrtTime);
if (Err == 0) {
TimeInstant AlarmTime(CalendarPtr, StrtTime);
TimeInstant AlarmTime(StrtTime);
NewStream->MyAlarm = Alarm(AlarmName, AlarmTime);
HasAlarm = true;
} else {
Expand Down Expand Up @@ -576,8 +569,8 @@ int IOStream::create(const std::string &StreamName, //< [in] name of stream
StreamName);
return Err;
}
TimeInstant Start(CalendarPtr, StartTimeStr);
TimeInstant End(CalendarPtr, EndTimeStr);
TimeInstant Start(StartTimeStr);
TimeInstant End(EndTimeStr);
std::string StartName = StreamName + "Start";
std::string EndName = StreamName + "End";
NewStream->StartAlarm = Alarm(StartName, Start);
Expand Down
Loading

0 comments on commit 5d6af46

Please sign in to comment.