** Next:** Simulation on multi-core computers
** Up:** A Discrete EVent system
** Previous:** Continuous Models
** Contents**

The **Simulator** class has four functions: to determining the model's time of next event, to extract output from the model, to inject input into the model, and to advance the simulation clock. The first function is implemented by the *nextEventTime* method with which we are already familiar. I'll address the other three functions in turn.
There are two essential steps for extracting output from your model. The first step is to register an **EventListener** with the simulator. This is done by creating a subclass of the **EventListener** and then passing this object to the **Simulator**'s *addEventListener* method. When the **EventListener** is registered with the simulator, its *outputEvent* method intercepts output originating from **Atomic** and **Network** models.

The second step is to invoke the **Simulator**'s *computeNextOutput* method, which performs the output calculations and provides the results to registered **EventListener**s. The signature of *computeNextOutput* is

void computeNextOutput()

and it computes the model output at the time given by the *nextEventTime* method. The *computeNextOutput* method invokes the *output_func* method of every imminent **Atomic** model, maps outputs to inputs by calling the *route* method of **Network** models, and calls the *outputEvent* method of every **EventListener** registered with the **Simulator**. The *computeNextOutput* method anticipates the output of your model from its current state assuming that no input events will intervene between now and the time returned by *nextEventTime*.
The *computeNextState* method is used to inject events into a model and advance the simulation clock. The method signature is

void computeNextState(Bag<Event<X> >& input, double t)

where the **Event** class is the same one that the **EventListener** accepts to its *outputEvent* method. The **Event** class has two fields: a pointer to a model of type **DevsX** (i.e., a **Network** or **Atomic** model) and a value of type X.
The *computeNextState* method applies a bag of **Event** objects to the model at time t. If the input bag is empty and t is equal to the next event time, then this method has the same effect as *execNextEvent*: it calculates the output values at time t using the *computeNextOutput* method, computes the next state of all models undergoing internal and external events, computes structure changes, and advances the simulation clock.

If the input bag is not empty then the value of each **Event** is applied as an input to the model pointed to by that **Event**. If, in this case, t is equal to the next event time then the method also follows the usual steps of invoking the *computeNextOutput* method and calculating state and structure changes. However, if t is less than the **Simulator**'s next event time, then the procedure is nearly identical excepting that the *computeNextOutput* method is not invoked. In this case, the only input events for any model are those provided in the input bag.

The **Simulator**'s *execNextEvent* method does its job using *computeNextOutput* and *computeNextState*. The implementation of *execNextEvent* has only two lines; the **Bag** bogus_input is empty.

void execNextEvent() {
computeNextOutput();
computeNextState(bogus_input,nextEventTime());
}

The *computeNextOutput*, *computeNextState*, and *execNextEvent* methods throw an exception if a model violates either of two constraints: i) the time advance is negative and ii) the coupling constraints described in section and illustrated in Figure are violated. The Adevs **exception** class is derived from the standard C++ **exception** class. Its method *what* returns a string that describes the exception condition and the method *who* returns a pointer to the model that caused the exception.

The Adevs **exception** class is intended to assist with debugging simulations. There isn't much you can do at run-time to fix a time advance method or reorganize a model's structure (or fix the structure change logic), but the simulator tries to identify problems before they become obscure and difficult to find bugs.

** Next:** Simulation on multi-core computers
** Up:** A Discrete EVent system
** Previous:** Continuous Models
** Contents**
James J. Nutaro
2017-03-07