'' @(#) law106.sim 2/25/86
''Port operations model
''An Introduction to Simulation Using SIMSCRIPT II.5, Chapter 6
PREAMBLE
								      
   PROCESSES INCLUDE ARRIVAL.GENERATOR, END.WARMUP, REPORT, STORM,
      AND TUG.TRANSIT

      EVERY HARBOR.MASTER HAS A HM.STATE
      DEFINE HM.STATE AS A TEXT VARIABLE

      EVERY TANKER MAY BELONG TO THE HARBOR.QUEUE AND MAY BELONG TO 
         THE DEBERTHING.QUEUE

   RESOURCES INCLUDE BERTH

      EVERY TUG HAS A TG.DESTINATION, A TG.IDLE, AND A TG.TRANSIT
      DEFINE TG.IDLE AND TG.TRANSIT AS INTEGER VARIABLES
      DEFINE TG.DESTINATION AS A TEXT VARIABLE

   PERMANENT ENTITIES

      EVERY TANKER.TYPE HAS A MIN.LOADING.TIME, A MAX.LOADING.TIME,
         AND A TIME.IN.PORT
      DEFINE MAX.LOADING.TIME, MIN.LOADING.TIME, AND TIME.IN.PORT 
         AS REAL VARIABLES

   DEFINE DEBERTHING.QUEUE AS A FIFO SET
   DEFINE HARBOR.QUEUE AS A FIFO SET
   THE SYSTEM OWNS THE DEBERTHING.QUEUE AND THE HARBOR.QUEUE

   DEFINE MAX.INTERARRIVAL.TIME, MAX.STORM.DURATION, MEAN.TIME.BET.STORMS,
      MIN.INTERARRIVAL.TIME, MIN.STORM.DURATION, SIM.LENGTH, TOW.TIME,
      TRANSIT.TIME, AND WARMUP.TIME AS REAL VARIABLES

   DEFINE NUM.BERTHS, NUM.LOADING.BERTHS, NUM.REPLICATIONS, AND 
      REP.NUMBER AS INTEGER VARIABLES

   DEFINE WEATHER AS A TEXT VARIABLE

   DEFINE .HOURS TO MEAN UNITS

   DEFINE .IDLE TO MEAN 1
   DEFINE .BUSY TO MEAN 0
   DEFINE .IN.TRANSIT TO MEAN 1
   DEFINE .NOT.IN.TRANSIT TO MEAN 0

   THE SYSTEM HAS A TYPE.DISTRIBUTION RANDOM STEP VARIABLE
   DEFINE TYPE.DISTRIBUTION AS AN INTEGER, STREAM 2 VARIABLE

   TALLY MEAN.TIME.IN.PORT AS THE MEAN OF TIME.IN.PORT

   ACCUMULATE PROP.TUG.IDLE AS THE AVERAGE OF TG.IDLE

   ACCUMULATE PROP.TUG.TRANSIT AS THE AVERAGE OF TG.TRANSIT

   ACCUMULATE AVG.NUM.IN.DEBERTHING.Q AS THE AVERAGE OF N.DEBERTHING.QUEUE     

   ACCUMULATE AVG.NUM.IN.HARBOR.Q AS THE AVERAGE OF N.HARBOR.QUEUE

   ACCUMULATE AVG.NUM.IN.BERTH.Q AS THE AVERAGE OF N.Q.BERTH

   ACCUMULATE AVG.NUM.LOADING.BERTHS AS THE AVERAGE OF NUM.LOADING.BERTHS

END ''PREAMBLE
MAIN    use 1 for input
   
   write as  /, "Test LAW106 - Port Operations model", /
   CALL READ.DATA
  
   FOR REP.NUMBER = 1 TO NUM.REPLICATIONS 
   DO
      CALL INITIALIZE
      START SIMULATION
   LOOP
   write as  /, /, "End of Test LAW106", /

END ''MAIN
ROUTINE READ.DATA

   DEFINE I AS AN INTEGER VARIABLE
   
   READ NUM.BERTHS
   CREATE EVERY BERTH(1)
   LET U.BERTH(1) = NUM.BERTHS
   
   CREATE EVERY TUG(1)
   LET U.TUG(1) = 1   

   READ TYPE.DISTRIBUTION AND N.TANKER.TYPE
   CREATE EVERY TANKER.TYPE
   FOR EACH TANKER.TYPE
   DO
      READ MIN.LOADING.TIME(TANKER.TYPE) AND MAX.LOADING.TIME(TANKER.TYPE)
   LOOP
   READ MIN.INTERARRIVAL.TIME AND MAX.INTERARRIVAL.TIME

   READ TOW.TIME, TRANSIT.TIME, MIN.STORM.DURATION, MAX.STORM.DURATION, 
      MEAN.TIME.BET.STORMS, WARMUP.TIME, SIM.LENGTH, AND NUM.REPLICATIONS

   PRINT 6 LINES THUS



AFRICAN PORT PROBLEM -- INPUT PARAMETERS
----------------------------------------

   SKIP 3 LINES

   PRINT 19 LINES WITH NUM.BERTHS, NUM.REPLICATIONS, SIM.LENGTH, 
      TOW.TIME, TRANSIT.TIME, WARMUP.TIME, MEAN.TIME.BET.STORMS,
      MIN.STORM.DURATION, MAX.STORM.DURATION, MIN.INTERARRIVAL.TIME,
      AND MAX.INTERARRIVAL.TIME THUS

NUMBER OF BERTHS         ***

NUMBER OF REPLICATIONS   ***

REPLICATION LENGTH            *****.** HOURS

TUG TRAVEL TIME WITH TANKER   *****.** HOURS

TUG TRAVEL TIME ALONE         *****.** HOURS

WARMUP TIME                   *****.** HOURS

INTER-STORM TIMES ARE EXPONENTIAL WITH MEAN ***.* HOURS

STORM DURATIONS ARE UNIFORM ON THE INTERVAL              (***.*,***.*) HOURS
 
INTERARRIVAL TIMES ARE UNIFORM ON THE INTERVAL           (***.*,***.*) HOURS

   FOR EACH RANDOM.E IN TYPE.DISTRIBUTION
   DO
      LET I = IVALUE.A(RANDOM.E)
      PRINT 2 LINES WITH I, MIN.LOADING.TIME(I), AND MAX.LOADING.TIME(I) 
         THUS
TYPE * TANKERS LOADING TIMES ARE UNIFORM ON THE INTERVAL (***.*,***.*) HOURS 

   LOOP

   SKIP 3 LINES

   PRINT 9 LINES THUS

DISTRIBUTION FUNCTION OF TANKER TYPES:
--------------------------------------



TYPE     CUMULATIVE PROBABILITY
----     ----------------------

   FOR EACH RANDOM.E IN TYPE.DISTRIBUTION
      PRINT 3 LINES WITH IVALUE.A(RANDOM.E) AND PROB.A(RANDOM.E) THUS

  **                       *.**
  
   START NEW PAGE

   PRINT 6 LINES THUS



SIMULATION RESULTS (ALL TIMES ARE IN HOURS)
-------------------------------------------

   SKIP 3 LINES

   PRINT 6 LINES THUS

     -------TANKER-------  AVG IN  AVG IN  -------TUG-------  ------BERTHS-----
     ----TIME IN PORT----  DOCK    HARBOR  IDLE  TOW   OTHER  EMPTY LOAD  OTHER
RUN  TYPE 1 TYPE 2 TYPE 3  QUEUE   QUEUE   TIME  TIME  TIME   TIME  TIME  TIME
---  ------ ------ ------  ------  ------  ----- ----- -----  ----- ----- -----

END ''READ.DATA
ROUTINE INITIALIZE

   LET TG.IDLE(1) = .IDLE
   LET TG.TRANSIT(1) = .NOT.IN.TRANSIT

   LET TIME.V = 0
   LET NUM.LOADING.BERTHS = 0
   LET WEATHER = "CALM"
 
   ACTIVATE AN ARRIVAL.GENERATOR NOW
   ACTIVATE A STORM NOW
   ACTIVATE AN END.WARMUP IN WARMUP.TIME .HOURS
   ACTIVATE A REPORT IN SIM.LENGTH .HOURS

END ''INITIALIZE
PROCESS ARRIVAL.GENERATOR
   
   WHILE TIME.V < SIM.LENGTH
   DO
      WAIT UNIFORM.F(MIN.INTERARRIVAL.TIME,MAX.INTERARRIVAL.TIME,1)
         .HOURS 
      ACTIVATE A TANKER NOW
   LOOP

END ''ARRIVAL.GENERATOR
PROCESS END.WARMUP

   RESET TOTALS OF TG.IDLE(1), TG.TRANSIT(1), N.DEBERTHING.QUEUE,
      N.HARBOR.QUEUE, N.Q.BERTH(1), AND NUM.LOADING.BERTHS
   FOR EACH TANKER.TYPE
      RESET TOTALS OF TIME.IN.PORT(TANKER.TYPE)

END ''END.WARMUP
PROCESS TANKER

   DEFINE LOADING.TIME AND TIME.OF.ARRIVAL AS REAL VARIABLES
   DEFINE TYPE AS AN INTEGER VARIABLE

   LET TIME.OF.ARRIVAL = TIME.V
   LET TYPE = TYPE.DISTRIBUTION
   LET LOADING.TIME = UNIFORM.F(MIN.LOADING.TIME(TYPE),
      MAX.LOADING.TIME(TYPE),3) 

   REQUEST 1 BERTH(1)
   FILE THIS TANKER IN THE HARBOR.QUEUE
   ACTIVATE A HARBOR.MASTER GIVING "ARRIVE AT HARBOR" NOW
   SUSPEND

   REQUEST 1 TUG(1)
   WORK TOW.TIME .HOURS
   RELINQUISH 1 TUG(1)
   ACTIVATE A HARBOR.MASTER GIVING "TUG AT BERTHS" NOW

   ADD 1 TO NUM.LOADING.BERTHS
   WORK LOADING.TIME .HOURS
   SUBTRACT 1 FROM NUM.LOADING.BERTHS
   FILE THIS TANKER IN THE DEBERTHING.QUEUE
   ACTIVATE A HARBOR.MASTER GIVING "DEPART THE BERTHS" NOW
   SUSPEND

   REQUEST 1 TUG(1)
   RELINQUISH 1 BERTH(1)
   WORK TOW.TIME .HOURS
   RELINQUISH 1 TUG(1)
   ACTIVATE A HARBOR.MASTER GIVING "TUG AT HARBOR" NOW
   LET TIME.IN.PORT(TYPE) = TIME.V - TIME.OF.ARRIVAL

END ''TANKER
PROCESS HARBOR.MASTER GIVEN STATE

   DEFINE STATE AS A TEXT VARIABLE

   IF STATE = "TUG AT HARBOR"

      IF (N.HARBOR.QUEUE > 0) AND (WEATHER = "CALM")

         REMOVE THE FIRST TANKER FROM THE HARBOR.QUEUE
         REACTIVATE THIS TANKER NOW

      ELSE 

         LET TG.DESTINATION(1) = "TUG AT BERTHS"
         ACTIVATE A TUG.TRANSIT NOW

      ALWAYS

   ELSE IF STATE = "TUG AT BERTHS"

      IF (N.DEBERTHING.QUEUE > 0) AND (WEATHER = "CALM")

         REMOVE THE FIRST TANKER FROM DEBERTHING.QUEUE
         LET TG.IDLE(1) = .BUSY 
         REACTIVATE THIS TANKER NOW

      ELSE

         IF (N.HARBOR.QUEUE > 0) AND (WEATHER = "CALM")

            LET TG.IDLE(1) = .BUSY
            LET TG.DESTINATION(1) = "TUG AT HARBOR"
            ACTIVATE A TUG.TRANSIT NOW

         ELSE

            LET TG.IDLE(1) = .IDLE

         ALWAYS

      ALWAYS

   ELSE IF STATE = "ARRIVE AT HARBOR"

      IF (TG.IDLE(1) = .IDLE) AND (WEATHER = "CALM")

         LET TG.IDLE(1) = .BUSY
         LET TG.DESTINATION(1) = "TUG AT HARBOR"
         ACTIVATE A TUG.TRANSIT NOW

      ALWAYS

   ELSE IF STATE = "DEPART THE BERTHS"

      IF (TG.IDLE(1) = .IDLE) AND (WEATHER = "CALM")

         REMOVE THE FIRST TANKER FROM DEBERTHING.QUEUE
         LET TG.IDLE(1) = .BUSY
         REACTIVATE THIS TANKER NOW

      ALWAYS

   ALWAYS
   ALWAYS
   ALWAYS
   ALWAYS

END ''HARBOR.MASTER
PROCESS TUG.TRANSIT

   LET TG.TRANSIT(1) = .IN.TRANSIT
   WORK TRANSIT.TIME .HOURS
   LET TG.TRANSIT(1) = .NOT.IN.TRANSIT
   ACTIVATE A HARBOR.MASTER GIVING TG.DESTINATION(1) NOW

END ''TUG.TRANSIT
PROCESS STORM

   WHILE TIME.V < SIM.LENGTH
   DO
      WAIT EXPONENTIAL.F(MEAN.TIME.BET.STORMS,4) .HOURS

      LET WEATHER = "STORMY"
      IF (TG.TRANSIT(1) = .IN.TRANSIT) AND  
         (TG.DESTINATION(1) = "TUG AT HARBOR")
         INTERRUPT TUG.TRANSIT
         LET TG.DESTINATION(1) = "TUG AT BERTHS"
         LET TIME.A(TUG.TRANSIT) = TRANSIT.TIME - TIME.A(TUG.TRANSIT)
         RESUME TUG.TRANSIT
      ALWAYS
      WORK UNIFORM.F(MIN.STORM.DURATION,MAX.STORM.DURATION,5) .HOURS
									
      LET WEATHER = "CALM"
      IF TG.IDLE(1) = .IDLE
         ACTIVATE A HARBOR.MASTER GIVING "TUG AT BERTHS" NOW
      ALWAYS
   LOOP

END ''STORM
PROCESS REPORT

   DEFINE AVG.NUM.IN.ARRIVAL.Q, PROP.BLOCKED, PROP.EMPTY, PROP.LOADING,
      AND PROP.TUG.TOWING AS REAL VARIABLES

   LET AVG.NUM.IN.ARRIVAL.Q = AVG.NUM.IN.HARBOR.Q + AVG.NUM.IN.BERTH.Q(1)   

   LET PROP.TUG.TOWING = 1.0 - PROP.TUG.IDLE(1) - PROP.TUG.TRANSIT(1)

   LET PROP.BLOCKED = AVG.NUM.IN.DEBERTHING.Q/NUM.BERTHS

   LET PROP.LOADING = AVG.NUM.LOADING.BERTHS/NUM.BERTHS

   LET PROP.EMPTY = 1.0 - PROP.BLOCKED - PROP.LOADING

   PRINT 2 LINES WITH REP.NUMBER, MEAN.TIME.IN.PORT(1), MEAN.TIME.IN.PORT(2),
      MEAN.TIME.IN.PORT(3), AVG.NUM.IN.DEBERTHING.Q, AVG.NUM.IN.ARRIVAL.Q,
      PROP.TUG.IDLE(1), PROP.TUG.TOWING, PROP.TUG.TRANSIT(1), PROP.EMPTY, 
      PROP.LOADING, AND PROP.BLOCKED THUS
 **  ****.* ****.* ****.*  ***.**  ***.**  *.*** *.*** *.***  *.*** *.*** *.***

END ''REPORT
