Extending a Visual Language for Simulation

Peter uses Turbo Pascal for Windows to extend VisSim, an off-the-shelf simulation package that provides a visual design environment for Microsoft Windows and UNIX/X.


June 01, 1993
URL:http://www.drdobbs.com/windows/extending-a-visual-language-for-simulati/184409015

Figure 1


Figure 1


Copyright © 1993, Dr. Dobb's Journal

Figure 2


Copyright © 1993, Dr. Dobb's Journal

JUN93: EXTENDING A VISUAL LANGUAGE FOR SIMULATION

EXTENDING A VISUAL LANGUAGE FOR SIMULATION

Discrete-event simulation made possible via DLLs

Peter D. Varhol

Peter is an assistant professor of computer science and mathematics at Rivier College in Nashua, New Hampshire.


As a college teacher, I'm constantly on the lookout for ways to supplement a purely mathematical treatment of system simulation and modeling. My mostly adult professional students are usually more interested in answering the questions "how and where is this useful" rather than "how or why is this done," necessitating a practitioner's approach to the subject.

The standard languages for system simulation, such as GPSS and Simscript, are old and don't take full advantage of many of the PC's capabilities. The alternative is to learn a new programming language to do simulation, and the simulation system itself must be expressed in terms of that language. Further, even with educational discounts, these packages are priced beyond the reach of the students I serve. Thus, I was understandably optimistic when introduced to VisSim, a simulation package based on a visual programming language.

With VisSim, the user constructs simulations by manipulating graphical blocks representing different high-level functions useful in simulation. These blocks are then connected to create the flow of data through the simulation. These characteristics make the software easy to learn and highly visual, giving students better insight into the simulation process. VisSim currently runs in Microsoft Windows and on several UNIX/X platforms. According to the vendor, Visual Solutions, the UNIX port was done by emulating the Windows API on top of X, making simulations portable between the platforms.

For most of my needs, however, VisSim has one major drawback--it lacks the ability to perform discrete-event simulation, which is in far more common use than continuous simulation. Discrete-event simulation models systems in which "customers" enter the system, receive "service," and leave. While this may seem more appropriate for modeling business-oriented systems, I've used this approach to successfully model systems such as job scheduling on multiuser computers, failure prediction on system components, and reliability analysis of automated processes. "Customers" can readily refer to people, computer processes, automobiles on a highway, failed electrical components, or hundreds of other discrete tasks.

In addition to being enormously useful, discrete-event simulation is both conceptually and computationally easier than continuous simulation, and requires little math beyond algebra. These characteristics make it easier for students to understand, and more useful in many of their professions.

Customizing VisSim Using DLLs

Fortunately, the VisSim menus include what is called a "user-defined block," a gateway to user-written dynamic link libraries (DLLs). These DLLs can be written for practically any purpose, and Visual Solutions supports C, Pascal, and Fortran. (The use of Fortran requires C calling conventions.) The ability to use Fortran is a nice feature for those who have existing Fortran code that can be included as part of a VisSim simulation.

Calling a user-defined function (in C) or procedure (in Pascal) in a DLL is simple. Selecting the userFunction from the menu and clicking in the window creates a rectangular block similar to predefined function blocks. The user can press the right mouse button to open a window to name both the DLL and the function. The DLL is loaded at that time, so it has to be in place before you create the block on the screen. The block can now be treated like any predefined block in VisSim, enabling it to be used as an operation in a larger simulation.

There are certain limitations in the DLL gateway that make the development of discrete-event procedures somewhat challenging. VisSim is designed so that the gateway between the application and the DLL consists of a three-element array of double-precision reals. While this data type may be useful for continuous simulations, discrete-event procedures rely more heavily on integer operations. This means that many type conversions have to be performed in the DLL. It also means that no more than three values can be passed to a DLL at one time.

Choosing a Development Environment

I decided to work in Turbo Pascal for Windows, for several reasons. First, I already had experience writing DLLs in Turbo C++, and I wanted to be able to compare the techniques used there with another language. Specifically, I thought that C DLLs were unnecessarily complex (what purpose does the WEP function really serve?) and was looking for an easier way. Second, I wanted my students to be able to examine and modify the DLLs, and Pascal is still a more universally accepted academic language.

Writing DLLs is easier in Pascal than in C, although Pascal's stricter type checking meant that I had to be creative in my type conversions. Turbo Pascal requires only that the program be declared as a library, that the appropriate Windows "user" files be included, and that the procedures be exported at the end of the file. As in writing DLLs using C, there's no main program as such.

Designing the DLLs

The discrete-event DLLs I needed can be divided into two categories. First, I had to design a set of procedures that would calculate the appropriate statistics resulting from the discrete-event processes. These statistics included expected time spent in the system, expected number of customers in the system, and the probability of a given number of customers in the system. These are relatively straightforward, with simple equations involving math no more difficult than algebra. They are computations that summarize the results of a simulation, and will likely be used just prior to a VisSim output block.

The second and more complex part of the problem was that I had to generate random events according to distributions that are most often associated with discrete processes. VisSim gives me random numbers that follow the uniform and normal distributions, which were useful, but I really needed the Poisson and exponential distributions. These values would represent the arrival rates and service times of the system.

There are two ways of doing this. First, I could use VisSim's uniform distribution generator, pass it to a DLL, filter the values so that the resulting random numbers followed the Poisson distribution, and finally return the filtered values back to VisSim. On the other hand, I could use the random-number generator in Turbo Pascal.

As Listing One (page 95) shows, I opted for the latter approach. Though I was not sure if there was a performance penalty in passing large amounts of random numbers to my DLL for filtering, it seemed more efficient to both create and parameterize my customer arrival rates and service rates from Pascal. The input to this event-generation DLL will be the mean of the desired probability distribution, and the output will be the random values generated by that distribution.

I ended up with three DLLs. The first created random numbers and filtered them so that they followed the Poisson distribution, and returned these values back to VisSim. The second did the same thing for the exponential distribution. The third calculated system statistics based on the interaction between the two series of random numbers, and returned these statistics to VisSim.

A Template for Queueing Models

Figure 1 shows an application of my discrete-event DLLs. I've kept it general, so that it can be used both as a template for simulating more specific systems and as a part of a more-complex simulation model.

The queueing system itself has three inputs: the mean customer-arrival rate, the mean service time, and the number of servers. The mean customer-arrival rate is used as input to my Poisson random-number filter DLL, designated by the step-distribution icon. This returns customer interarrival times that follow the Poisson distribution, which are the customer inputs to the queueing system.

The mean service time, which follows the exponential distribution, is set by the slider block and filtered through my exponential random-number generator DLL to produce individual customer-service times. This DLL is designated by the negative exponential curve icon. These service times for individual customers are passed into the queueing system.

The last input is the number of servers, which comes from a variable block. Note that the number of servers can easily be changed between simulation runs by changing the input variable to the "Number of servers" block. Likewise, the arrival rate and service time can be adjusted by moving the sliders that contain the respective values. Currently, the sliders for both the arrival rate and service time can be adjusted at 0.2 intervals between 0 and 20, but that range is also easily changed.

The block labeled "Queueing system" is a compound block that contains several different operations. It simulates customers being served and calculates several different statistics on the queueing process. The aforementioned statistics are calculated through values passed into another DLL. The actual values of three of the statistics are displayed in the final blocks at the far right of the model.

I've used this basic template to model problems from real life, such as jobs being run on a multitasking computer or cars crossing a bridge. Any system that follows a Markovian process can use these types of discrete operations.

For greater applicability, this template can be enhanced still further. The current approach assumes that each of the servers in a multiserver system has the same average service time. This is adequate for most purposes, but would make it difficult to model a distributed computing system where the CPUs had different clock speeds, for example. Another enhancement would be to display some of the statistics, such as the average number of customers in the system, in a meter or plot so that users can view the activity of the system as it occurs.

A Little About VisSim

The time I put into customizing VisSim is in no way a reflection on any failings in the product itself. VisSim comes with several dozen predefined, high-level operations, divided into 11 categories. These categories include arithmetic, Boolean operations, integration, transcendental functions, and nonlinear operations. This toolbox makes it possible to create a wide variety of simulations useful to both engineers and scientists. Its extensive collection of example simulations cover a number of different practical applications.

The visual modeling approach is well thought out and easily learned by anyone interested in simulating processes. A particularly nice feature is the ability to construct hierarchical block diagrams, representing hierarchical levels of a simulation. Like my DLLs, hierarchical function blocks are highly reusable between simulations.

Practitioners will appreciate VisSim (as opposed to traditional simulation languages) because they can visualize the simulation as it progresses. This can be done with one or more output blocks, which include simple value displays along with more graphical meters and plots. This allows the user to change parameter values on-the-fly and observe the results of the changes without having to save the data and display it in a spreadsheet.

VisSim also supports the use of bit-mapped graphic icons in place of the simple rectangular blocks for user-defined functions. The tool includes examples with graphical icons of DC motors and digital controls, which represent fully functional models of those devices. The icons themselves serve no functional purpose, but serve to better communicate the layout of the simulation. With my limited artistic ability, I used Windows Paintbrush to create my own set of icons, three of which are used in my queueing system in Figure 1.

Other Approaches to Discrete-event Simulation

It's possible to perform discrete-event simulation using VisSim without adding DLLs. In its extensive collection of examples, Visual Solutions includes a simulation of a "widget distribution system," shown in Figure 2. In this example, widgets are produced, distributed from a central location to regional warehouses, and sold from there. VisSim incorporates a time delay into a reservoir model to emulate the flow of widgets between distribution locations.

However, this is not the way most professionals are used to thinking about discrete-event simulation, and it adds an unnecessary layer of complexity onto a relatively simple process. My approach, using DLLs for generating the necessary random events, provides simpler and more understandable tools for this category of simulation problem.

Extending and Enhancing Commercial Software: The Time has Come

In general, the user-defined DLL is probably one of the most important features in a Windows application. An increasing number of commercial applications provide this capability, which both provides a thriving market for add-ons and lets technical users customize the products for their specific needs. While the interface between VisSim and the DLL is restrictive, many DLLs can still be written to make the product useful to more professionals.

VisSim also supports a DDE block, so that a simulation block can act as a data server or client for another application. This means that a simulation can be used to draw data from a spreadsheet, for example, and can also update the spreadsheet with the results of a simulation run. Developing simulations using this hot link to other applications and data sources is next on my list of simulation projects.

What advantage does the visual approach to simulation have over a traditional simulation language? VisSim has a learning curve, but since the simulation is a closer conceptual representation of the system being modeled, the learning curve is not as great as with a simulation language. Second, a properly constructed simulation, complete with bitmapped icons representing components, can be more instructive, since the relationships between components are more explicit. These features can benefit not only the student, but also the practitioner who seeks a greater understanding of any complex system.


_EXTENDING A VISUAL LANGUAGE FOR SIMULATION_
by Peter D. Varhol


[LISTING ONE]


{*****************************************************}
{ Borland Turbo Pascal                                }
{ VisSim DLL for Windows                              }
{ Poisson distribution random number generator        }
{ This procedure of the DLL generates a random number }
{ using the Turbo Pascal random number generator,     }
{ then filters the values to pass only those that     }
{ follow the Poisson distribution.                    }
{*****************************************************}

library Queue;     {rather than program}
uses WinTypes, WinProcs;
type
VisSimArg = array[0..2] of double;

Function fact(X:integer) : integer;

var
i, total : integer;

begin
if X <= 0 then fact := 0
else
    if X = 0 then fact := 1
        else
            begin
                    total := 1;
                for i := 1 to X do
                        total := total * i;
                    fact := total
                end
end;

Procedure poisson(var param, X,result:VisSimArg);
export;
const
e = 2.718;

var
n, testX_int, testY_int : integer;
testX, testY, poissonX : double;

begin
   {n := X[0];      contains Poisson mean  }
   Randomize;              {set random seed}
   testX := Random;     {uniform random number}
   testY := Random;          {second random number}
   testX_int := trunc(testX * X[0] * 2);
                                    {scale random numbers and make an integer}
   testY_int := trunc(testY * X[0] * 2);
   poissonX := (Exp(testX) * testX*Ln(-X[0])) / fact(testX_int);
                                                       {generate distribution}
   if poissonX > testX_int then
    result[0] := testX_int
 end;

exports
poisson index 1;      {export by name and index number}

begin     {procedure not called in main program}
end.













Copyright © 1993, Dr. Dobb's Journal

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.