Discrete Event Modeling

Physical modeling, in general, involves continuous variables and equations. In some cases, however, you can simplify the mathematical model of the system and improve simulation performance by treating certain changes in system behavior as discrete. Such an idealization assumes that system variables may only change values instantaneously and discontinuously at specific points in time.

An event is a conceptual notation that denotes a change of state in a system. Event modeling lets you perform discrete changes on continuous variables. The two most common applications of event modeling are:

• Trigger-and-hold mechanism, such as a triggered delay. For example, a component has two inputs: `u` and `x` (triggered signal), and one output `y`. When and only when the triggered signal `x` changes value from false to true, output `y` is reset to the value of `u` at current time. `y` remains unchanged all other times.

• Enabled component, acting on a principle similar to Simulink® enabled subsystem. That is, the component has a control signal as input. If the control signal has a positive value, then the component holds certain states to the most recent value, or resets them. When the control signal is negative, the states change according to component equations.

The following constructs in Simscape™ language let you perform event modeling: event variables, `events` section, `when` clause, and `edge` operator.

Event Variables

Event variables are piecewise constant, that is, they change values only at event instants, and keep their values constant between events. You can declare internal component variables of type integer or real as event variables by setting the `Event=true` attribute.

For example, the following code declares two event variables: `x` (type real) and `d` (type integer).

```variables (Event=true) x = 0; d = int32(0); end```

You can initialize event variables by using the `initialevent` operator. You can also initialize event variables the same way as continuous variables, by setting their target values and priorities in the member declaration block. For more information, see `initialevent`.

You update the values of the event variables in the `events` section of the component file, by using the `when` clause.

Event Data Type and `edge` Operator

The `edge` operator takes a scalar Boolean expression as input. It returns true, and triggers an event, when and only when the input argument changes value from false to true. The return type of `edge` is event type. Event data type is a special category of Boolean type, which returns true only instantaneously, and returns false otherwise.

The following graphic illustrates the difference between Boolean and event data types.

`edge(b)` returns true only when `b` changes from false to true.

To trigger an event on the falling edge of condition `b`, use `edge(~b)`.

The data derivation rules between Boolean and event data types are:

• `edge`(`boolean`) is `event`

• `~event` is `boolean`

• (`event` && `event`) is `event`

• (`event` && `boolean`) is `event`

• (`event` || `event`) is `event`

• (`event` || `boolean`) is `boolean`

You use the `edge` operator to define event predicates in `when` clauses.

Events Section and `when` Clause

The `events` section in a component file manages the event updates. The `events` section can contain only `when` clauses. The order of `when` clauses does not matter.

The `when` clause serves to update the values of the event variables. The syntax is

```when EventPredicate var1 = expr1; var2 = expr2; ... end ```

`EventPredicate` is an expression that defines when an event occurs. It must be an expression of event data type, as described in Event Data Type and edge Operator.

The variables in the body of the `when` clause must be declared as event variables. When the event predicate returns true, all the variables in the body of the `when` clause simultaneously get updated to the new values.

The order of the variable assignments in the body of the `when` clause does not matter, because all updates happen simultaneously. For example, if `d1` and `d2` are event variables initialized to 0,

```when edge(time>1.0) d1 = d2 + 1; d2 = d1 + 1; end ```

is equivalent to:

```when edge(time>1.0) d2 = d1 + 1; d1 = d2 + 1; end ```

After the event, both `d1` and `d2` have a new value of 1, because they were both simultaneously updated by adding 1 to the old value of 0.

A `when` clause cannot update an event variable more than once within the same assignments list. However, two independent `when` clauses also may not update the same event variable. You must use an `elsewhen` branch to do this.

Branching of the `elsewhen` Clauses

A `when` clause can optionally have one or more `elsewhen` branches:

```when EventPredicate var1 = expr1; var2 = expr2; ... elsewhen EventPredicate var1 = expr3; ... end ```

Note

The default `else` branch in a `when` clause is illegal.

A common usage of `elsewhen` branches is to prioritize events. If multiple predicates become true at the same point in time, only the branch with the highest precedence is activated. The precedence of the branches in a `when` clause is determined by their declaration order. That is, the `when` branch has the highest priority, the last `elsewhen` branch has the lowest priority.