Examples:
 

 

Example - Traffic

* The "\" symbol has been used at the end of lines to indicate that the line was too long for the display and has been
wrapped to the line below in order to fit within the width of the web page. These lines would need to be joined in the normal
program editor.


I. Introduction

This program demonstrates how traffic jams occur on a road due to weight of traffic when there is little apparent cause. Given certain values of traffic flow, a small variation in one driver's speed can eventually result in near-stationary traffic. The program uses a finite element array to perform the simulation.



II. Mathematics Involved

1) Equation

The model used considers the equation of motion for each of the N cars, and supposes that the acceleration/deceleration of a car depends on the distance from the car in front.

where (car 1 is at the back of the line of cars; car N is at the front).

The x i represents the distance travelled by each of the cars


2) V( D x) Function Used

The function is used, as it has desirable properties:

  • When the separation is small, V is nearly zero.
  • As the separation increases, V increases to a maximum value, given by the constant of proportionality used.

The car in front is given an initial velocity higher than the others, so the behaviour of the system when a perturbation is applied can be observed.


3) Phases

It turns out that three distinct phases emerge:

  • N<=10: Stable, uncongested phase. All vehicles travel at high speed and with a large separation.
  • N>=26: Stable, congested phase. All vehicles travel at low speed with a small separation.
  • 11<=N<=25: Unstable phase. Several small congested areas (jams) develop on the loop, which later merge into one big jam moving in the opposite direction to the cars.

(The phase boundaries are determined by the ratio of the length of the loop to the number of cars)



III. How the Program Works

1) Initialisation of the Finite Element Array

When the form has been set up, the program then waits for input – clicking More or Fewer changes the number of cars. A click on Start will initiate the simulation by calling startproc(). In this procedure the finite element array is set up. The attribute of interest is the distance x travelled by each car, but because the cars are travelling on a loop, the forward distance between the first car and the last car has to be adjusted by the length of the loop in order that the first car behaves in the same way as the others. This is why two SetFormula() statements are required:

   'set up finite element array
   fea.Name = "fea"
   fea.Dimensions(1) = N%%
   
   IF fea.Exists("x") THEN SET fa = fea.x ELSE SET fa = fea.Add("x")
   'distance along the loop 
   fa.Order = 2
   fa.AllowableErrorFactor = 0.05
   fa.AllowableErrorMin = 0.25
   
   formula$ = LTRIM$ ( STR$ (a%,"-99999.00"))
   formula$ = formula$ + "*(15*(2/(1+EXP(-2*(x(0,CurrentX+1)-x(0,Current\
   X)-2)))-1+"
   formula$ = formula$ + tanh2$ + ")-x(1,CurrentX))"
   fa.SetFormula(formula$,2,1,N%% - 1)
   formula$ = LTRIM$ ( STR$ (a%,"-99999.00")) + "*(15*(2/(1+EXP(-2*(x(0,\
   1)-x(0,N%%)+"
   formula$ = formula$ + LTRIM$ ( STR$ (lengthofloop%)) + "-2)))-1 + " +\
   tanh2$ + ")-x(1,N%%))"
   fa.SetFormula(formula$,2,N%%,N%%)
   
   'set velocities of cars
   fa.SetInitialValue(velocity%,1,1,N%% - 1)
   'add a small perturbation to the last car
   fa.SetInitialValue(velocity% + perturb%,1,N%%,N%%)
   
   'set positions of cars
   FOR i%% = 1 TO N%%
     fa.SetInitialValue((i%% - 1) * spacing%,0,i%%,i%%)
   NEXT i%%

2) The TrafficRun() Procedure

Once the array has been set up, the program simply runs through the following loop in the TrafficRun() procedure (clicking Stop or Quit will change the form's tag to “stop” or “quit” respectively):

SUB TrafficRun()
   DIM deltat%,spacing%
   deltat% = 0.01
   
   
   '*****************main loop************
   WHILE Traffic.Tag <> "quit"
     Process()
     IF Traffic.Tag = "start" THEN 
       CALL FeaAdvance(deltat%)
       CALL PlotCars(Traffic)
       WAIT FOR 0.02
     END IF 
     IF Traffic.tag = "increase" AND N%% < 99 THEN 
       N%% = N%% + 1:Traffic.tag = "":spacing% = lengthofloop% / N%%
       Traffic("numberdisplay").caption = STR$ (N%%,"99"):Traffic.refresh()
     END IF
     IF Traffic.tag = "decrease" AND N%% > 2 THEN 
       N%% = N%% - 1:Traffic.tag = "":spacing% = lengthofloop% / N%%
       Traffic("numberdisplay").caption = STR$ (N%%,"99"):Traffic.refresh()
     END IF
   WEND 
   '*****************end of loop**********
 END SUB 

3) Output

The following screenshot shows an example of the first phase (stable, uncongested motion):

If the number of cars is increased, unstable congestion occurs (the traffic is slow-moving in the areas where it is close together):

However, if the number of cars is increased still further, the traffic is all slow-moving but stable: