Overview

Brief Introduction to SyDEVS

Concept

Using SyDEVS, simulation code is organized into nodes, which can be linked together to form dataflow and simulation networks. There are four main types of nodes, illustrated below.

SyDEVS Nodes

The atomic node provides a general structure for representing behavior that unfolds over simulated time. The modeler must implement four event handers that are invoked by the simulator. The initialization event hander is invoked first. The unplanned and planned event handlers are then called any number of times over the course of the simulation in response to incoming messages (unplanned events) or internally scheduled events (planned events). The finalization event handler is invoked at the end.

The function node represents a single function that reads a set of input values and calculates a set of output values.

The composite node integrates other nodes by linking their ports. There are initialization and finalization links, which form a dataflow programming graph. There are also simulation links, which direct messages and support discrete event simulation.

The collection node contains an arbtrary number of instances of the same type of node, supporting agent-based modeling.

Example

Here’s an example of a SyDEVS atomic node declared in C++. Observe that the four types of ports and four types of event handlers match the atomic node diagram above. The code is taken from the queueing demonstration project, which features an example of each of the four main types of nodes.

/**
 * This node processes jobs one at a time. The time required to process a job
 * is determined by the service duration flow input. Any job that arrives while
 * another is being processed is placed in a queue and processed later. The
 * total time spend in an idle state, with no jobs to be processed, is tracked
 * and reported as a flow output.
 */
class queueing_node : public atomic_node
{
public:
    // Constructor/Destructor:
    queueing_node(const std::string& node_name, const node_context& external_context);
    virtual ~queueing_node() = default;

    // Attributes:
    virtual scale time_precision() const { return micro; }

    // Ports:
    port<flow, input, duration> serv_dt_input;    // service duration
    port<message, input, int64> job_id_input;     // job ID (input)
    port<message, output, int64> job_id_output;   // job ID (output)
    port<flow, output, duration> idle_dt_output;  // idle duration

protected:
    // State Variables:
    duration serv_dt;      // service duration (constant)
    std::vector<int64> Q;  // queue of IDs of jobs waiting to be processed
    duration idle_dt;      // idle duration (accumulating)
    duration planned_dt;   // planned duration

    // Event Handlers:
    virtual duration initialization_event();
    virtual duration unplanned_event(duration elapsed_dt);
    virtual duration planned_event(duration elapsed_dt);
    virtual void finalization_event(duration elapsed_dt);
};

For the complete implementation of this atomic node, see queueing_node.h.

Also see an example of a function node (plus_node.h), a composite node (two_stage_queueing_node), and a collection node (parallel_queueing_node.h).

Notable Features

Theoretical Basis

SyDEVS is heavily influenced by the Discrete Event System Specification (DEVS), a set of conventions developed in the 1970s that allow essentially any simulation model to be specified using a common set of mathematical elements. The atomic and composite nodes of SyDEVS, which support discrete event simulation, are similar to the atomic and coupled models of the classic version of DEVS. The function nodes of SyDEVS extend the original theory to accommodate dataflow programming. The collection nodes improve support for agent-based modeling.

Other DEVS Frameworks