next up previous
Next: Models with Many Input/Output Up: A Discrete EVent system Previous: Continuous Models

The Simulator Class

The functionality of the Simulator class is broken into three pieces: determining the model's next event time, extracting output from the model, injecting external input into the model, and advancing the simulation clock. The first piece of functionality is provided by the nextEventTime method with which we are already familiar. I'll address the three remaining pieces in turn.

There are two essential steps for extracting output from your model. The first step is to register an EventListener with the simulator. The EventListener's outputEvent method is used to intercept output originating from Atomic and Network models; this first step is already familiar to us. The second step is to invoke the Simulator's computeNextOutput method, which performs the output calculations and provides the results to registered EventListeners.

The computeNextOutput method is probably not familiar; we have not had cause to discuss it until now. The method signature is

void computeNextOutput()
and it computes the model output at the next event 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 that has been registered with the Simulator. This method anticipates the outcome of your model from its current state assuming that no input events will intervene between now and the nextEventTime.

The computeNextState method is used to inject intervening events 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 Devs$ <$ X$ >$ (i.e., a Network or Atomic model) and a value of type X.

The computeNextState method applies a bag of input Events 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; 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, the workhorse of most simulation programs, actually defers its job to two these two methods which do the real work. The implementation takes only two lines; the Bag bogus_input is empty.

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

The Simulator's computeNextOutput, computeNextState, and execNextEvent methods throw an exception if a model violates either of two constraints: the time advance is negative or the coupling constraints described in section [*] and illustrated in Figure [*], are violated. The Adevs exception class is derived from the standard C++ exception class; the method what returns a string that describes the exception condition and the method who returns a pointer to the model that caused the exception to be generated. The Adevs exception class is intended to assist with model debugging. 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 be friendly by identifying a problem before it becomes an obscure and difficult to find bug.


next up previous
Next: Models with Many Input/Output Up: A Discrete EVent system Previous: Continuous Models
2008-01-13