Arena to SimPy Cheat Sheet for Discrete-Event Simulation

Arena to SimPy Cheat Sheet for Discrete-Event Simulation

Also In the Series

Simul8 vs SimPy

FlexSim vs SimPy

SimEvents vs SimPy

Siemens Plant Simulation vs SimPy

Simio vs SimPy

AnyLogic vs SimPy

Salabim vs SimPy

Introduction

For Arena users transitioning to SimPy

This cheat sheet provides a high-level mapping of common Arena simulation elements to their equivalents in SimPy, along with code snippets. The focus is on heavy-industry use cases (e.g. oil & gas, manufacturing) – think of entities as parts, products, or tasks moving through industrial processes. Arena uses a visual flowchart paradigm, while SimPy is code-based (Python). In SimPy, you will write process functions (generator functions) that yield events (like timeouts or resource requests) to model entity behavior over time. The table below summarises how Arena’s modules translate to SimPy concepts.

Arena vs. SimPy: Common Elements Mapping

Article content

SimPy Code Snippets for Common Arena Constructs

Below are code snippets illustrating how to implement the above Arena constructs in SimPy. The scenario is a simple manufacturing process where parts arrive, get processed by a machine (with a queue if busy), and then leave the system. We also show branching (Decide) and recording statistics like waiting time and count of scrapped parts.

Setup the SimPy Environment and Resources:

import simpy
import random

env = simpy.Environment()

 # One machine (Resource) with 1 capacity
machine = simpy.Resource(env, capacity=1)         

Here, we create a SimPy environment and define a Resource with capacity 1 (like a single machine or service unit). In a heavy industry setting, this could represent a single processing station, a drilling rig, or an operator.

CREATE – Entity Arrival Generator:

def source(env, interarrival_time, machine):
    """Generate entities (e.g., parts) periodically."""
    part_id = 0
    while True:
        # Delay between arrivals (SimPy equivalent of Arena CREATE schedule)
        yield env.timeout(interarrival_time)  # wait for next arrival
        part_id += 1

        # On each arrival, start a new part's process
        env.process(part_process(env, f"Part{part_id}", machine))
        # (In industry terms, think of this as a new job/part entering the system)        

  • Arena CREATE: In Arena, you would specify an interarrival distribution for entities.
  • SimPy: We use a source generator function. It loops forever, yielding a timeout for the interarrival delay, then spawns a new process by calling env.process() to start the entity’s simulation (here part_process for each new part). This models entities arriving over time.

PROCESS (with SEIZE, DELAY, RELEASE) – Handling an Entity’s lifecycle:

# Global data collection for RECORD stats
wait_times = []   # to record how long each part waits for the machine
scrap_count = 0   # to count how many parts are scrapped (for demonstration)

def part_process(env, name, machine):
    """Process an entity (e.g., a part going through a machine)."""
    global scrap_count  # allow modifying the global scrap counter
    # note in practice we would use objects to store data instead of global variables
    
    # ASSIGN: determine if this part is defective (for branching example)
    defective = random.random() < 0.1  # 10% chance of defect
    
    # DECIDE: branch based on defect status
    if defective:
        # This branch represents a scrapped part that skips processing
        scrap_count += 1  # RECORD: increment scrap counter
        # Maybe some delay for handling defective part (optional)
        yield env.timeout(1)  # small delay to represent inspection/disposal
        # (Entity will be disposed after this, process ends here)
    else:
        # Normal part processing branch
        arrive_time = env.now
        # SEIZE: request the machine resource
        with machine.request() as req:
            yield req  # wait until resource is acquired (queues if busy)
            wait = env.now - arrive_time
            wait_times.append(wait)   # RECORD: log waiting time before processing
            # DELAY: process the part on the machine for some time
            processing_time = random.expovariate(1/5.0)  # e.g., mean of 5 time units
            yield env.timeout(processing_time)
        # RELEASE: happens automatically at end of `with` block (machine freed)
        # After processing, the part leaves the system (DISPOSE)
    # (Process function ends here – in SimPy this means the entity is disposed)
        

In this code:

  • We used a with statement for machine.request() to seize the resource. The yield req inside the with waits until the machine is available. This is equivalent to Arena’s SEIZE of a Resource (and QUEUE is managed automatically if the machine is busy).
  • The wait_times.append(wait) line records how long the part waited in queue – this is a manual RECORD of a performance metric (Arena’s Record module would do this automatically when an entity passes through it).
  • We simulate the processing delay with yield env.timeout(processing_time) – this is the DELAY equivalent (Arena’s processing time). During this timeout, the resource is held by the entity.
  • Exiting the with block RELEASES the machine resource (no explicit release call needed in this pattern; if not using with, you would do req = machine.request() and later machine.release(req)).
  • The ASSIGN and DECIDE are shown by using a Python variable defective and an if statement. In Arena, you might use an Assign module to set an attribute (e.g., a “defect flag”) and a Decide module to branch flow; in SimPy, you just use normal Python logic.
  • If the part is defective, we increment a scrap_count (a global counter) and introduce a short delay to represent handling the scrap. Then the function ends, effectively disposing of the entity without using the machine.
  • If the part is not defective, it goes through the normal process of seizing the machine, waiting if necessary, being processed, and then leaving (function ends).

Running the Simulation and Viewing Results:

# Start the arrival process and run the simulation
env.process(source(env, interarrival_time=3, machine=machine))  # e.g., parts arrive every 3 time units on average
env.run(until=50)  # run simulation for 50 time units

# After simulation, analyze recorded stats (Record equivalent)
average_wait = sum(wait_times) / len(wait_times) if wait_times else 0
print(f"Average wait time: {average_wait:.2f}")
print(f"Number of scrapped parts: {scrap_count}")
        

In an actual SimPy model, after running env.run(), you would use the data collected to compute the desired statistics (here we calculate the average waiting time and total scrapped parts). This manual analysis replaces Arena’s automatic reporting. In Arena, the Record module and built-in statistics would handle this, but in SimPy you have the flexibility to calculate anything you need from the collected data.


Paradigm Difference Summary Between Arena and SimPy

Arena’s modules (Create, Process, Decide, etc.) provide a high-level, drag-and-drop framework specific to simulation modeling. SimPy, on the other hand, is a lower-level process-oriented simulation library. You manually code the logic of entity behavior and resource constraints. This gives you more flexibility (since it’s full Python) but requires thinking in terms of processes, events, and yields instead of connecting Arena blocks. For example, an Arena Process block might combine seize-delay-release for a machine, whereas in SimPy you write those steps out with resource requests and timeouts. Arena automatically tracks statistics for you, whereas in SimPy you instrument your model to collect the data you need (as shown with wait_times and scrap_count).

By understanding these equivalent concepts, Arena users can leverage their knowledge of simulation logic while harnessing the power of Python with SimPy. Use this cheat sheet as a quick reference while building your first SimPy models – it will help you “translate” your Arena modeling habits into Python code.

If you’re ready to explore SimPy further and want a deeper dive into best practices, examples, and tips for success, we’ve got something for you. Download my free guide to simulation in Python with SimPy for a comprehensive walkthrough of building DES models in Python - from basic queuing systems to complex supply chain networks. It’s packed with code samples and conversion tips for SimEvents users. Download the Free Guide Here and take your simulation skills to the next level in an open-source world!

George Nelson M.

Solution Architect | Mathematician

4mo

Very useful, I am trying to do the same

What about animation of the processes? You get easily with Arena. But SimPy?

Like
Reply
Cemalettin Öztürk

Lecturer || Funded Investigator || Logistics, Supply Chain and Smart Manufacturing

5mo

This is extremely useful, thanks for sharing 📊 Harry Munro 📊

To view or add a comment, sign in

Others also viewed

Explore topics