Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions components/omega/configs/Default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ Omega:
CalendarType: No Leap
TimeStepper: Forward-Backward
TimeStep: 0000_00:10:00
StartType: StartUp
StartTime: 0001-01-01_00:00:00
StopTime: 0001-01-01_02:00:00
RunDuration: none
StopType: AtTime
StopCriterion: 0001-01-01_02:00:00
Decomp:
HaloWidth: 3
DecompMethod: MetisKWay
Expand Down Expand Up @@ -119,9 +120,8 @@ Omega:
UseStartEnd: false
Contents:
- InitVertCoord
# InitialState should only be used when starting from scratch.
# For restart runs, the frequency units should be changed from
# "OnStartup" to "never" so that the initial state file is not read.
# InitialState is only read if the StartType is StartUp so this should
# reflect that case with FreqUnits "OnStartup"
InitialState:
UsePointerFile: false
Filename: OmegaMesh.nc
Expand All @@ -147,19 +147,16 @@ Omega:
Contents:
- Forcing
# Restarts are used to initialize for all job submissions after the very
# first startup job. We use UseStartEnd with a start time just after the
# simulation start time so that omega does not attempt to use a restart
# for the first startup job.
# first startup job. This is only read of the StartType requires a restart
# so the options here reflect only that case and are ignored otherwise
RestartRead:
UsePointerFile: true
PointerFilename: ocn.pointer
Mode: read
Precision: double
Freq: 1
FreqUnits: OnStartup
UseStartEnd: true
StartTime: 0001-01-01_00:00:01
EndTime: 99999-12-31_00:00:00
UseStartEnd: false
Contents:
- Restart
RestartWrite:
Expand Down
33 changes: 23 additions & 10 deletions components/omega/doc/devGuide/TimeStepping.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,8 @@ the configuration file. For coupled simulations the StartTime is provided by
the coupler, overriding the value defined in the configuration file.
In this case, the first phase of time stepper initialization would look like:
```c++
// coupled simulations have a start time but no stop time
TimeInitParams TimeParams{StartTime, std::nullopt};

// initialize TimeStepper with coupler provided start time
TimeStepper::init1(TimeParams);
// initialize TimeStepper with coupler provided start type and start time
TimeStepper::init1(StartType, StartTime);
```

#### Creation of non-default time steppers
Expand All @@ -88,12 +85,22 @@ A non-default time stepper can be created from a string `Name`, time stepper
type `Type`, `TimeStep`, `StartTime`, `EndTime`, tendencies `Tend`,
auxiliary state `AuxState`, horizontal mesh `Mesh`, and halo layer `MyHalo`
```c++
TimeStepper* NewTimeStepper = TimeStepper::create(Name, Type, TimeStep,
StartTime, EndTime, Tend, AuxState, Mesh, MyHalo);
TimeStepper* NewTimeStepper = TimeStepper::create(Name, Type,
Tend, AuxState, Mesh, MyHalo, TimeStep, StartType, StartTime,
StopType, EndTime, Duration);
```
For convenience, this returns a pointer to the newly created time stepper.
Given its name, a pointer to a named time stepper can be obtained at any time
by calling the static `get` method:
where the EndTime and Duration are optional arguments depending on StopType.

The TimeStepper constructors are filled initially with a StopTime based on
the simulation CurrentTime. In many cases (including the default time stepper),
the constructor is called before the CurrentTime is reset on restart. For the
StartType Continue option, the StopTime and EndAlarm must be reset by calling
the ``MyStepper->resetEndAlarm()`` function once the current simulation time
has been updated from the restart metadata.

For convenience, the create routine returns a pointer to the newly created
time stepper. Given its name, a pointer to a named time stepper can be obtained
at any time by calling the static `get` method:
```c++
TimeStepper* NewTimeStepper = TimeStepper::get(Name);
```
Expand All @@ -114,11 +121,17 @@ TimeStepperType Type = Stepper->getType();
int NTimeLevels = Stepper->getNTimeLevels();
std::string Name = Stepper->getName();
TimeInterval TimeStep = Stepper->getTimeStep();
TimeStepperStartType StartType = Stepper->getStartType();
TimeInstant StartTime = Stepper->getStartTime();
TimeStepperStopType StopType = Stepper->getStopType();
TimeInstant StopTime = Stepper->getStopTime();
TimeInterval Duration = Stepper->getDuration();
Clock *ModelClock = Stepper->getClock();
Alarm *EndAlarm = Stepper->getEndAlarm();
```
Note that StopTime, Duration and EndAlarm are set to appropriate values
no matter what the StopType is (though for the OnSignal option, they are
set far into the future).

#### Removal of time steppers
To erase a specific named time stepper use `erase`
Expand Down
35 changes: 23 additions & 12 deletions components/omega/doc/userGuide/TimeStepping.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ of the Omega configuration file:
CalendarType: No Leap
TimeStepper: Forward-Backward
TimeStep: 0000_00:10:00
StartType: StartUp
StartTime: 0001-01-01_00:00:00
StopTime: 0001-01-01_02:00:00
RunDuration: none
StopType: AtTime
StopCriterion: 0001-01-01_02:00:00
```
This configuration refers to the default time stepping used for the model
dynamics (momentum and continuity equations). Additional time steppers can
Expand Down Expand Up @@ -43,19 +44,29 @@ in any of the following forms:
Days, hours and minutes are optional but must be in order if included.
Fractional seconds are optional.

The StartTime refers to the starting time for the simulation. It is in the
The StartOption can be one of three choices. The StartUp option is for starting
a solution from scratch from an initial state file. The Continue option is for
continuing a simulation from a restart file. The Branch option will branch
from an existing simulation by reading from the restart file, but it will
reset the clock to the StartTime.

The StartTime refers to the starting time for the full simulation (not the
current leg of an ongoing simulation). It is in the
format ``yyyy-mm-day_hh:mm:ss`` for year, month, day, hour, minute, second.
This refers to the initial start time; for a longer simulation, the current
time will be modified by the restart file to update to the present time for
the current segment of the simulation.

The simulation will be stopped either at a fixed StopTime if provided or
by the RunDuration. For shorter simulations, the StopTime can be used to
specify a specific time to stop. For longer simulations with multiple
segments that are restarted, the RunDuration should used and should be set
to fit within the queue time. The format for StopTime is the same as StartTime.
The format for RunDuration is the same as the TimeStep.
A StopType determines (with the StopCriterion below) how the simulation will
be stopped. There are three options. The AtTime option will stop the simulation
at a specific time and the StopCriterion holds that specific time as described
below. The AfterDuration option runs the simulation for a fixed time interval
and the StopCriterion is used to define that interval. A final option called
OnSignal is primarily for coupled simulation where the simulation will stop
and a signal from the coupler.

Only one of the StopTime or RunDuration should be specified with the other
set to either an empty string or "none". If both are specified, the
RunDuration is used instead of the StopTime.
For the AtTime stop type, the StopCriterion must be a time instant in the
format ``yyyy-mm-dd_hh:mm:ss``. If the StopType is AfterDuration, the
StopCriterion is a time interval in the format described above for the time
step (but typically ``dddd_hh:mm:ss``). For the OnSignal option the
StopCriterion is ignored.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void omega_ocn_init1(
const int OcnID, // [in] mct comp id for ocn mode
const char *YamlConfigFile, // [in] yaml file name for ocean model
const char *OcnLogFile, // [in] log file name for ocean model
const int StartType, // [in] 0=startup, 1=continue, 2=branch
const int InStartType, // [in] 0=startup, 1=continue, 2=branch
const char *CalendarName, // [in] CIME calendar name
const int RunStartYMD, // [in] run start date in YYYYMMDD
const int RunStartTOD, // [in] run start time in seconds of day
Expand Down Expand Up @@ -97,14 +97,14 @@ void omega_ocn_init1(

Pacer::start("Init1", 0);

OMEGA::StartType StartTypeEnum = OMEGA::safeIntToStartType(StartType);
OMEGA::TimeInitParams TimeParams{StartTime, std::nullopt};
OMEGA::TimeStepperStartType StartTypeEnum =
OMEGA::getTimeStepperStartTypeFromE3SM(InStartType);
OMEGA::CouplingInitParams CouplingParams{
NCouplerImports, NCouplerExports, ImportIdxMap,
ExportIdxMap, CouplingInterval, OMEGA::CouplingLayout::MCT};

OMEGA::ocnInit1(Comm, OcnID, YamlConfigFile, OcnLogFile, StartTypeEnum,
TimeParams, CouplingParams);
StartTime, CouplingParams);

Pacer::stop("Init1", 0);

Expand Down
38 changes: 28 additions & 10 deletions components/omega/src/infra/TimeMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3914,6 +3914,15 @@ bool Alarm::isRinging(void) { return Ringing; }

// end Alarm::isRinging

//------------------------------------------------------------------------------
// Alarm::isPeriodic - Check whether an alarm is a recurring alarm
// This function checks to see if an alarm is a recurring alarm by simply
// returning the periodic flag

bool Alarm::isPeriodic(void) { return Periodic; }

// end Alarm::isPeriodic

//------------------------------------------------------------------------------
// Alarm::updateStatus - Changes the alarm status based on current time
// Checks whether the alarm should ring based on the current (or supplied)
Expand All @@ -3932,7 +3941,7 @@ void Alarm::updateStatus(const TimeInstant CurrentTime // [in] current time

//------------------------------------------------------------------------------
// Alarm::reset - Stops a ringing alarm and resets to a new alarm time
// Stops a ringing alarm and sets next a new ring time. If the alarm
// Stops a ringing alarm and sets a new ring time. If the alarm
// is a periodic/interval alarm, the next ring time is set to be the
// next interval boundary after the input time. If the alarm is a
// single instance, the input time is used as the next alarm time.
Expand All @@ -3943,17 +3952,20 @@ void Alarm::reset(const TimeInstant InTime // [in] new alarm time
// stop the ringing alarm
Ringing = false;

// if this is an interval alarm, find the next alarm time after
// the input time
// if this is an interval alarm, reset the alarm so it rings at the next
// interval after the input time
if (Periodic) {

// first check that the input time is valid
// if the new time is before the ring time, move the alarm backward
// until the new time is within a ring interval
if (InTime < RingTime) {
ABORT_ERROR("TimeMgr: Alarm::reset error - input time is less than the"
" current ring time");
while (InTime < RingTimePrev) {
RingTime -= RingInterval;
RingTimePrev -= RingInterval;
}
// if the new time is after the ring time, move alarm forward until
// the next interval is greater than input time
} else {
// now move forward in time until the next interval is greater
// than the input time
while (RingTime <= InTime) {
RingTimePrev = RingTime;
RingTime += RingInterval;
Expand Down Expand Up @@ -4075,6 +4087,8 @@ Clock::~Clock(void) { // Nothing to be done
// Clock::setCurrentTime - Sets the current time
// Sets the current time to an input value. Also must reset previous time and
// next time to be consistent. Check that new time does not precede start time.
// Updates all one-time alarms and resets all periodic alarms based on the new
// time.

void Clock::setCurrentTime(
const TimeInstant InCurrTime // new value for current time
Expand All @@ -4093,9 +4107,13 @@ void Clock::setCurrentTime(
NextTime = CurrTime + TimeStep;
}

// Update status of all attached alarms based on new time
// Reset periodic alarms and update the status of one-time alarms
for (I4 N = 0; N < NumAlarms; ++N) {
Alarms[N]->updateStatus(CurrTime);
if (Alarms[N]->isPeriodic()) {
Alarms[N]->reset(CurrTime);
} else {
Alarms[N]->updateStatus(CurrTime);
}
}

} // end Clock::setCurrentTime
Expand Down
6 changes: 5 additions & 1 deletion components/omega/src/infra/TimeMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -773,9 +773,13 @@ class Alarm {
~Alarm(void);

/// Check whether an alarm is ringing
/// \return true if alarm is ringing, false otherwise
/// Return true if alarm is ringing, false otherwise
bool isRinging(void);

/// Check whether an alarm is a recurring alarm
/// Return true if periodic, false otherwise
bool isPeriodic(void);

/// Checks whether the alarm should ring based on the current
/// (or supplied) time instant
void updateStatus(const TimeInstant CurrentTime ///< [in] current time
Expand Down
18 changes: 8 additions & 10 deletions components/omega/src/ocn/OceanDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@

namespace OMEGA {

/// enumeration for the different "start_type"s supported by the coupler
enum class StartType { StartUp, Continue, Branch };

/// Convienvence converter of an int to a StartType enum, with error checking
StartType safeIntToStartType(int val);

/// Should timing info be printed from all ranks
bool printTimingAllRanks();

Expand All @@ -40,8 +34,8 @@ int ocnInit1(
const int OcnId, ///< [in] mct comp id for ocean
const std::string &ConfigFile, ///< [in] path to yaml config file
const std::string &LogFile, ///< [in] path to log file
const StartType StartType, ///< [in] simulation start type
const TimeInitParams &TimeParams, ///< [in] time parameters
const TimeStepperStartType StartType, ///< [in] simulation start type
const TimeInstant &StartTime, ///< [in] simulation start time
const CouplingInitParams &CouplingParams ///< [in] coupling parameters
);

Expand All @@ -64,8 +58,12 @@ int ocnFinalize(const TimeInstant &CurrTime);
int initOmegaModules(MPI_Comm Comm);

/// Initialize Omega modules with coupler-provided time parameters
int initOmegaModules(MPI_Comm Comm, const TimeInitParams &TParams,
const CouplingInitParams &CParams);
int initOmegaModules(
MPI_Comm Comm, ///< [in] MPI communicator for ocn
TimeStepperStartType StartType, ///< [in] option for starting this leg
const TimeInstant &StartTime, ///< [in] start time for full simulation
const CouplingInitParams &CParams ///< [in] struct with coupling params
);

/// Update Halo/Host arrays with new state, auxiliary state, and tracer fields
int initUpdateHaloAndHostArrays();
Expand Down
Loading
Loading