SimPy

Simulation in Python

Robert Ramsdell

Great Lakes Dredge & Dock Company

What is SimPy?

What is SimPy?

Extras

Basis of the Simulation

Basis of the Simulation - Processes

Basis of the Simulation - Resources

Basis of the Simulation - Monitors

Example 1 - Mismatched Dredges

  • Dredges load at a borrow area, then unload through a discharge pipe onto a beach.

Example 1 - Mismatched Dredges

  • Two Dredges share a single discharge point.
  • The Dredges are mismatched, they load at the same rate, but one has 50% more power for discharging, and 30% faster discharge time.

Example 1 - The Process

Example 1 - The Simulation

  • initialize() - create the event list and set time to 0
  • initialize()
    
  • Define the processes and resources
  • riser = Resource(1,monitored=True)
    Dredges=[TSHD('Dodge Island',250,100),
             TSHD('Manhattan Island',250,140)]
    

    Example 1 - The Simulation

  • activate() the processes so that they start generating events.
  • for d in Dredges:
        activate(d,d.go())
    
  • Run the simulation.
  • simulate(until=1440*2)  #Simulate for 2 days
    

    Example 1 - The Output

    Dodge Island 350
    Manhattan Island 390
    250 Dodge Island unloading, waited 0  min
    350 Manhattan Island unloading, waited 100  min
    ...
    2300 Manhattan Island unloading, waited 0  min
    2440 Dodge Island unloading, waited 40  min
    2690 Manhattan Island unloading, waited 0  min
    2830 Dodge Island unloading, waited 40  min
    Riser in use 60 %
    Dodge Island  waited  130  min, completed  7
    Manhattan Island  waited  100  min, completed  7
    Total Loads: 14
    
    The Manhattan wait is at the start. After that the Dodge does all the waiting. Each does the same number of loads.

    How SimPy Works

  • The initialize() function creates an event list
  • Events in the list are calls to the PEMs at a given time
  • PEMs do whatever, then post new events to the list using yield statements.
  • simulate() steps through the event list.
  • Time passes based on scheduled times for events in the list (i.e. there is no clock).
  • Advanced Process Control

  • Requesting resources with priority - jumping the queue
  • riser = Resource(1,monitored=True,qType=PriorityQ)
    ...
    yield request,self,riser,self.priority
    
  • Requesting resources with priority & preemption - taking resources away
  • riser = Resource(1,monitored=True,qType=PriorityQ,preemptable=1)
    ...
    yield request,self,riser,self.priority
    

    Advanced Process Control

  • Waiting on events
  • yield waitevent,self,someevent
    or
    yield queueevent,self,someevent
    

    someevent is a SimEvent object

  • Waiting on arbitrary conditions
  • yield waituntil,self,d.disconnecting
    

    d.disconnecting is a function that returns True or False

    Advanced Process Control

  • Interruptions - One process can interrupt another.
  • self.interrupt(victim)
    
  • The victim, which must be active, returns from it's yield hold prematurely. It can check to see if it has been interrupted.
  • if self.interrupted()==True:
        #Do something about the interruption
    

    Example 2 - Preemption

  • Same two dredges
  • Slower dredge will wait if the other is ready to pumpout
  •     #wait on any higher priority dredges
        for d in self.waiton:
            if d.status in ['SailLoaded','Turn']:
                #The other dredge is coming back, wait until it is
                #   done pumping out
                yield waituntil,self,d.disconnecting
    
  • The more powerful dredge can take the riser from the other
  •     #Request the riser - higher priority will pre-empt lower
        yield request,self,riser,self.priority
    
    Test the option of teh more productive Dredge taking priority at the riser.

    Example 2 - Other changes

  • More detailed cycle model
  • cycleorder = ['SailLight','Pump','Turn','SailLoaded','Connect','Discharge',
                  'Disconnect']
    
    Randomized cycle times and load sizes. Independent random streams and seeds for each dredge.
        self.rand=random.Random(seed)
    
  • Command-line options to allow changes to process parameters
  • More sophisticated and flexible simulation.

    Example 2 - Results

  • No waiting or preemption - first-come-first-served
  • >HopperSim3.py d 120
    Manhattan Island  Est cycle:  387.0
    Dodge Island  Est cycle:  354.0
    Manhattan Island:
    0 wait, 446 loads, 491523 CY total, 386 min Cycle
    Dodge Island :
    14443 wait, 446 loads, 575450 CY total, 354 min Cycle
    Total Loads: 892
    Total CY: 1066974 in 120 days
    
    This is essentially the same as Example 1. The more productive dredge does all the waiting.

    Example 2 - Results

  • Manhattan waits if Dodge is near
  • >HopperSim3.py d 120 wait
    Manhattan Island  Est cycle:  387.0
    Dodge Island  Est cycle:  354.0
    Manhattan Island :
    7536 wait, 427 loads, 470423 CY total, 386 min Cycle
    Dodge Island :
    6509 wait, 468 loads, 603545 CY total, 354 min Cycle
    Total Loads: 895
    Total CY: 1073969 in 120 days
    
    Here the Manhattan will wait if the Dodge is almost done loading, or nearing the riser. Wait time shifts to the Manhattan and 3 loads are gained over 120 days.

    Example 2 - Results

  • Dodge can interrupt the Manhattan at the riser
  • >HopperSim3.py d 120 wait p
    Manhattan Island  Est cycle:  387.0
    Dodge Island  Est cycle:  354.0
    Manhattan Island :
    14049 wait, 409 loads, 450914 CY total, 387 min Cycle
    Dodge Island :
     109 wait, 487 loads, 627973 CY total, 354 min Cycle
    Total Loads: 896
    Total CY: 1078888 in 120 days
    
    Here the Manhattan does all the waiting and 1 more load is gained.

    Abusing Processes

  • As constructors - spitting out other processes at intervals
  • class Customer(Process):
        ...
    
    class FrontDoor(Process):
        ...
        def DoorOpens():
            yield hold,self,now()+t
            c = Customer()
            activate(c,c.goinside())
            ...
    
  • As data loggers - Logging data at regular intervals