DEVSLib can be used to develop any new Atomic DEVS model. The user only has to define the behavior of this new model and implement it using the atomicDraft package included in the library.
The procedure to create a new atomic model can be divided in the following steps:
This step has to be performed by just duplicating the atomicDraft package into another package that will store the new atomic model.
The best way to duplicate a package is to use the Dymola menu option. Selecting the atomicDraft package and left clicking in it, the menu is displayed. The duplicate option corresponds to the Edit->Duplicate Class option in the menu. The following figure shows the menu and the duplicate option.
The new name for the atomic model has to be indicated, and the place to store the package selected among the Dymola's Packages tree structure.
Finally, the atomic model inside the atomicDraft package can be changed to match the new name of the atomic model.
Next step is to define the input and output ports of the new model. The number of input and output ports depend on the behavior of the new model.
New ports can be declared by just copy/paste one of the existing input/output port. If no ports are needed, the existing ones can also be deleted. Another way to introduce new ports is to drag and drop them from the DEVSLib.SRC.Interfaces package.
After declaring the new ports, some equations must be added and edited in the model. These equations correspond to the connection between the ports and the iQueue, iEvent, oQueue and oEvent arrays in the model.
Each input port in the model must have two equations connecting the event and queue variables of the connector, to the iEvent and iQueue variables in the model. The index of the iEvent/iQueue arrays assigned to each connector identifies it, and will also be used to identify the received messages.
Each output port in the model must have two equations connecting the event and queue variables of the connector, to the oEvent and oQueue variables in the model. The index of the oEvent/oQueue arrays assigned to each connector identifies it, and will also be used by the output function to identify the port for the output messages.
If the model has no input ports, the following equation has to be added iEvent[1] = 0;, since the minimum value for the number of input ports (numIn) is 1.
(see the Generator model for example)
If the model has no output ports, the following equiation has to be added oQueue[1] = 0;, since the minimum value for the number of output ports (numOut) is 1.
(see the Display model for example)
At the end, the numIn and numOut parameters of the model have also to be set, indicating the number of input and output ports in the model. An example of port definition and equation edition is shown in the next figure.
The state of a DEVS model is composed by two elements. First, the st record that stores all the variables that are stored in the state. Second, the initst function used to initialize the state of each model at the beginning of the simulation.
The user has to declare in the st record all the variables used to control the model behavior.
By default this record contains the phase variable, normally used to indicate the current phase of the model (active, passive, busy,...),
and the sigma variable, that usually indicates the time for the next internal transition.
Any other variable can be included in the record, using the usual Modelica types and notation.
Notice that if the model has any parameter, it must be stored in the state of the model in order to use it in the transition and output functions.
So each parameter must have a corresponding variable in the state of the model.
The second component of the state is the initialization function. This function is called at the beginning of
the simulation to initialize the state of each model.
The initst function has as inputs the parameters of the model, if any.
The output of the function is the initial state, as desired by the user.
The value set to the sigma variable will be used to generate the first internal transition.
As described in the Parallel DEVS section, every time a new message arrives to a model an external transition is executed. Simultaneous arrivals to the model can also occur when:
All the received messages are temporary stored in a bag. In both cases the external transition function is executed and manages the bag of messages.
The actions performed in each external transition have to be implemented in the ext function, inside the duplicated atomicDraft package. This function receives as inputs the current state, the elapsed time, the bag of received messages. It returns the new state after the external transition. The user has to read the message or messages received in each transition from the bag of messages. This can be done using the readEvent function. Also, the numEvents function can be used to know the number of messages received. After reading the messages, the new state has to be calculated depending on the behavior of the model.
Every time an internal transition has to be performed, an output can be sent from the DEVS model. No output is sent at external transitions. The DEVS model generates its output using the output fuction and the current state of the model, before executing the internal transition.
The generation of outputs can be configured in the DEVS model including the required code in the out function inside the duplicated atomicDraft package. The inputs of this function are the current state, the arrays of queues that represent the output ports and the number of queues in that array. Depending on the model state, an event can be generated using the protected variable y and sending it to the desired queue using the function sendEvent (i.e. sendEvent(queue[i],y);). Several messages can be sent using multiple calls to the sendEvent function.
In an internal transition, the model state has to be updated after generating the output. The internal transition function is used to update the state.
This function simply receives the current state of the model and returns the updated state, depending on the behavior of the model.
The implementation of the internal transition function is contained in the int function inside the atomicDraft package. This function has to be changed to represent the model behavior at internal transitions.
In Parallel DEVS a confluent transition is executed when an external transition and internal transition occur at the same instant and have to be simultaneously executed. The confluent transition function is used to update the state of the model in a confluent transition. This function is usually a combination of the internal and external transition functions, but it is not neccesary to use them to update the state.
The confluent transition function is implemented in the con function inside the atomicDraft package.
This function receives as inputs the current state, the elapsed time and the bag of received events.
Its output corresponds to the updated state of the model.
Since the confluent transition involves an internal transition, the output function will be executed before the confluent trasition function.
The default behavior for this function is to generate an output and execute the internal transition before executing the external transition. This behavior can be changed as required by the behavior of the model.