# tem_timeControl_module Module

This module provides functions to control explicit time stepping solvers.

It makes use of the tem_time_module with its definition of time in terms of various measurements, allowing the control of events based on these units. A time control is always active within a certain range, given by its min and max value, and emits actions to take based on the given interval. If multiple measurements are given for any of the measures, this time is always taken by that unit which occurs first. All three settings (min, max and interval) might use different time measures independently.

The time_control table takes the following form:

     time_control = {
min = {},
max = {},
interval = {},
check_iter = 123,
delay_check = false
}


Here min, max and interval are each time definitions, see tem_time_module. The time definition is providing, a measure of time in terms of simulation time, number of iterations and passed running time (clock): {sim = 1.0, iter = 1, clock = 60.0}.

max describes the end of the time span. If this time_control is for the overall simulation it defines the end of the run, after any of the time measures is reached, the simulation will stop.

min describes the beginning of the timespan for this control object. This may for example be used to start writing tracking data only after a certain point in time. Again, if multiple time definitions (sim, iter, clock) are defined, whichever first will be encountered will start the timespan of this control.

interval describes intervals within in the min and max points in time where something is to happen, for example that a restart file is to be written.

If a time definition is not provided as a table the given value is interpreted as specifying a time in terms of simulated time (sim). See tem_time_module for details on the time definition.

check_iter allows you to control, how often the trigger status of the time control is to be checked in terms of iterations. These checks involve communication and may have a performance impact if performed in every iteration and the iterations are very short. By setting the check_iter to some larger value the communications can be decreased as they will only be performed every check_iter iteration. Be aware that increasing the check_iter setting also decreases the accuracy for the time control. There might be performed multiple iterations beyond the intended specified trigger in this case. Typically it is not necessary to specify the check_iter setting. Without providing it a default of one will be used.

delay_check provides the option to delay the evaluation for the clock time trigger by one check interval by using a nonblocking allreduce. It relaxes the synchronization requirements, but introduces a delay in the actual triggering of the clock event. The default of this setting depends on the corresponding delay_check setting in simControl. Thus, if it is set in the simControl table itself, that setting will also be used here unless overwritten by explicitly providing it here.

## Variables

TypeVisibilityAttributesNameInitial
integer, private, parameter:: sim =1
integer, private, parameter:: iter =2
integer, private, parameter:: clock =3

## Derived Types

### type, public :: tem_timeControl_type

Definition of a time control.

#### Components

TypeVisibilityAttributesNameInitial
type(tem_time_type), private :: min

Minimal point in time, from where on, this control should be active. Whichever time definition happens first will be used.

type(tem_time_type), private :: max

Maximal point in time, after which the control should not be active anymore. Whichever time definition happens first will be used.

type(tem_time_type), private :: interval

A regular interval at which an action should be triggered between min and max.

type(tem_time_type), private :: trigger

Keep track of the next point in time, at which an action should be triggered by this control.

logical, private :: delay_check =.false.

Configuration flag, whether to use nonblocking allreduces to determine whether an event has triggered across all processes.

integer, private :: check_iter =1

Trigger checking can involve communication and is potentially hurting the performance.

integer, private :: check_request =MPI_REQUEST_NULL

IAllreduce request handle

logical, private :: globally_triggered

Flag to indicate whether trigger was globally activated

logical, private :: needs_reduce

Flag to indicate if this control object needs a MPI_reduce to determine trigger status.

logical, private :: min_reached =.false.

Flag that indicates whether the minimal point in time specified in min has already been reached.

## Functions

### public function tem_timeControl_triggered(me, now) result(hasTriggered)

Returns if the timeControl has triggered since last update.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control to check if it was triggered.

type(tem_time_type), intent(in) :: now

Current time that is to be used as comparison for the trigger check.

#### Return Value logical

Result indicating if the time control has triggered.

### public function tem_timeControl_globalTriggered(me, now, comm) result(hasTriggered)

This routine checks globally if the control has triggered.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control to check if it was triggered across all processes.

type(tem_time_type), intent(in) :: now

Current time to use for the comparison.

integer, intent(in) :: comm

Communicator to use for the global reduction.

#### Return Value logical

Result indicating if the time control has triggered.

### public pure function tem_timeControl_reached_max(me, now) result(at_max)

Returns for each of the time measurements, if the max specification was reached.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(in) :: me

Time control to compare agains its max settings.

type(tem_time_type), intent(in) :: now

Current time to compare the max settings to.

#### Return Value logical(tem_time_n_ids)

Resulting array indicating for each time definition, if its max setting was reached.

## Subroutines

### public subroutine tem_timeControl_load(me, conf, parent, key, delay_check)

Load a time control definition from a Lua script.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(out) :: me

Time control definition to load from a Lua config.

type(flu_state) :: conf

Handle for the Lua script.

integer, intent(in), optional :: parent

Parent table to read from.

character(len=*), intent(in), optional :: key

Name of the time control table. Default: 'time_control'

logical, intent(in), optional :: delay_check

Default setting for the delay_check.

If set to true the check will use a nonblocking iAllreduce and delay the evaluation by one check_iter block. This setting may be overwritten by the user in the timecontrol block.

### public subroutine tem_timeControl_align_trigger(me, conf, now, parent, key)

Align the trigger to intervals since min.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control definition to load from a Lua config.

type(flu_state) :: conf

Handle for the Lua script.

type(tem_time_type), intent(in) :: now

Current point in time to find alignement of trigger.

integer, intent(in), optional :: parent

Parent table to read from.

character(len=*), intent(in), optional :: key

Name of the time control table. Default: 'time_control'

### public subroutine tem_timeControl_out(me, conf, key)

Write a time control definition to a Lua script.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(in) :: me

Time control definition to write to a Lua config.

type(aot_out_type) :: conf

Handle for the Lua script.

character(len=*), intent(in), optional :: key

Name of the time control table. Default: 'time_control'

### public subroutine tem_timeControl_dump(me, outUnit)

Dump timecontrol information to the specified outUnit.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control to write on outUnit.

integer, intent(in) :: outUnit

The file unit to write the time control to.

### public subroutine tem_timeControl_start_at_sim(me, now)

Set the begin of the control interval in me to now.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control that should be started at now.

type(tem_time_type), intent(in) :: now

Time that should be used as starting point for the time control.

### public subroutine tem_timeControl_update(me, now, hasTriggered, localTriggered)

Update the given timeControl if it just triggered.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control object to update.

type(tem_time_type), intent(in) :: now

Current time to use for the update.

logical, intent(in), optional :: hasTriggered

Flag to indicate if the time control already has triggered.

If this argument is not present, the check for the trigger status of the time control will be done internally.

logical, intent(in), optional :: localTriggered

Flag to indicate if the local time control already has triggered.

This will be used in place of the hasTriggered, if delayCheck is true to avoid subsequent multiple checks of the same interval.

### public subroutine tem_timeControl_check(me, now, comm, triggered)

This routine checks if the control has triggered, and if so updates it.

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control settings to check.

type(tem_time_type), intent(in) :: now

Current time to check the control against.

integer, intent(in) :: comm

Communicator to use in the reduction.

logical, intent(out) :: triggered

Result of the check, indicating if the time control was triggered now.

### public subroutine tem_timeControl_reset_trigger(me)

This routine resets trigger to min and sets min_reached to false

#### Arguments

TypeIntentOptionalAttributesName
type(tem_timeControl_type), intent(inout) :: me

Time control settings to check.

#### Arguments

TypeIntentOptionalAttributesName
logical, intent(out) :: mask(3)

Time to be read from the Lua script

type(flu_state), intent(inout) :: conf

Handle to the Lua script.

character(len=*), intent(in) :: key

Name of the table containing the time definition. Default: 'time'.

integer, intent(in), optional :: parent

Handle to the parent table.