Imagine you've got work to do. You are a bricklayer having to lay 1000 bricks until tomorrow. Loosely following an example from the VENSIM modeling guide, we will develop a model to help you understand the processes involved in getting this work done. In conceptualizing and creating this model, we will use an iterative approach. We will start with the simplest structure that is relevant to this problem, and continually refine it. This corresponds to a well known and important modeling principle which often is abreviated as KIS, keep it simple.

We start out with defining two stocks, one flow and one free variable with VENSIM's easy-to-use point-and-click graphical user interface.

Clicking on the menu button equations and then on one of the components of our model opens up a dialog like the one on the right side.

Put in the following parameters and set Model > Settings in the menu as shown below to the right.

Work
remaining = INTEG(-work flow, initial task definition)

Units: bricks laid

Work accomplished = INTEG(work flow, 0)

Units: bricks laid

initial task definitions = 1000

Units: bricks laid

work flow = 100

Units: bricks laid / hour

When done, use the Control Panel > Graphs > New... option to define a plot and use the I/O-Object button to place it into the model display.

Now if you push the the sim-setup-button
_{} followed by the simulate-button
_{} (after having told VENSIM where to save its
outputs), you should get something like the following:

Notice that VENSIM indicates developments on the rectangles representing stocks, and it endows variables with a small slider so that they can be altered while the model is running.

To refine this model we can add an indicator for when our work is done. This provides us with a chance to account for scheduling problems. For this we change the model as follows:

work
is done = IF THEN ELSE(Work accomplished >= initial task
definition, 1, 0)

Units: Dmnl (dimensionless)

Work accomplished = INTEG(work flow, 0)

Units: bricks laid

work flow = IF THEN ELSE(work is done, 0, 100)

Units: bricks laid / hour

which, after modifying the Y-min and Y-max-values in the Control Panel to 0 and 1000 respectively, yields the following result, indicating that we can finish our work after 10 hours (which is hardly surprising if we have 1000 bricks to lay and manage to do 100 per hour):

However, our work could be error-prone, with errors not detected immediately. The quality of our work output is 90%, and the control unit needs 3 hours to detect our sloppiness and to urge rework.

rework
discovery rate = Rework / time to detect errors

Units: bricks laid / hour

time to detect errors = 3

Units: hours

Rework = INTEG(work flow * (1 - work quality) - rework discovery
rate, 0)

Units: bricks laid

Work accomplished = INTEG(work flow - rework discovery rate, 0)

Units: bricks laid

work quality = 0.9

Units: Dmnl

Work remaining = INTEG(rework discovery rate - work flow,
initial task definition)

Units: bricks laid

It can be a bit tricky to create the shown stock-and-flow-model. The turns in the flows are done by holding down the shift key while mouse-clicking at the position where you want the turn to appear. The valve without name is done by simply pressing Esc when you are asked for an input, and the arrow-heads of a flow can be removed by right-clicking the arrowhead and unchecking Arrowhead in the appearing options window. In general you will have to experiment a little with these possibilities to get the diagram right.

From the above alterations we get the following results:

Looking at the green spikes in the work flow and at the rework plot to the right, we see that some residual work becomes due after the original 10 hours needed to fulfill our task. Obviously errors are discovered too late, so we have to do overtime. If detection would be more efficient, we should be able to finish in time. So we add another loop and make time to detect errors dependent on how far advanced our task is.

fraction
accomplished = INTEG(Work accomplished / initial task
definition, 0)

Units: Dmnl

work is done = IF THEN ELSE (fraction accomplished >= 1, 1,
0)

Units: Dmnl

time to detect errors = time to detect error lookup (fraction
accomplished)

Units: hours

time to detect error lookup =
[(0,0)-(1,10)],(0,5),(0.5,3),(1,0.5)

Units: hours

What we did here, was using a lookup function in order to ascribe a varying value to the variable time to detect errors. It now will start out with a higher value of 5 hours in the beginning, since there will be not much too check yet. Towards the middle of our workload time to detect errors is reduced to the original 3 hours, and towards the end error checking is intensified. It shall not take longer than half an hour. In VENSIM we can define this variation in the Equations input window by selecting the Type Lookup and pressing the button As Graph, which opens the following lookup input allowing us to define respective values one by one.

This yields the following output, where we can see that the spikes at the end of the work flow have been reduced to one (left plot below) and the peak of rework (right plot below) has shifted towards the middle of our workload.

So far we treated work flow as a constant flow. To further improve performance we could endow the work flow with an additional feed back from a scheduled completion time. For this we alter the model as follows.

required work flow = MIN(max work flow, XIDZ(Work remaining,
scheduled time remaining, max work flow))

Units: bricks laid / hour

scheduled time remaining = MAX(0, scheduled completion time -
Time)

Units: hours

scheduled completion time = 10

units: hours

max work flow = 500

Units: bricks laid / hour

work flow = IF THEN ELSE(work is done, 0, required work flow)

Units: bricks laid / hour

Running it generates the following result

As we can see work flow increases gradually during our scheduled working time, with a rather sudden steep ascend right at the end in order to finish the project on time.

In the parameter setting we used some commands that need explanation. MIN and MAX indicate the minimum, resp. maximum of the two options indicated in brackets after the term. So if scheduled completion time should be greater than 0 in the case of MAX(0, scheduled completion time - Time), then scheduled completion time - Time will be the calculated value, and vice versa. XIDZ means "X if Division by Zero" indicating that if the denominator should become zero, division is performed alternatively by the third term, max work flow in this case.

A max work flow of 500 as indicated in this model version, will not be achievable by one person alone. We have to hire extra workforce. In order to know how much workforce would be appropriate, we introduce several additional variables.

net hire rate = (required workforce - Workforce) / time to
adjust workforce

Units: person / hour

productivity = 100

Units: bricks laid / person / hour

required work flow = IF THEN ELSE(work is done,0, XIDZ(Work
remaining, scheduled time remaining, max work flow))

units: bricks laid / hour

required workforce = required workflow / productivity

Units: person

time to adjust workforce = 2

Units: hours

Workforce = INTEG(net hire rate, 0)

Units: person

From the output we see that our labor activity starts out without anyone working on it, but people are brought on relatively quickly to get the work done. Workforce shows a dramatic increase near the end of our task. Also there is a resurgence of project activity after the end of the project. Both developments seem rather unrealistic. Additional workers would not be hired towards the end of a work project, and we wouldn't want to burden them with excessive overtime.

Exercise: Think about alterations or extensions to the model that would account for this problem. Try to implement them into your model.