2.1. Basic Simulation of Daily Cycle

Your first working Simulation Code

Jeff Elpern


2.1.1. Introducing the event loop

In this section we will create the "backbone" of the Go West simulation - the daily event loop. We create a SimPy Process that uses the yield hold functionality to step thought a 24 hour cycle and fire event massages at key daily point such as sun up. The events fired by this daily loop drive all the other simulation processes and resources added in the following sections and chapters.

The console output shown in Figure 1, “Event Loop Trace Output” is the trace output generated by the daily event loop.

Figure 1. Event Loop Trace Output

Event Loop Trace Output

2.1.2. Objectives

List the objectives of this section

  • Simulation setup and initialization. ???

  • Simulation event loop. ???

  • Global variables. 

  • Trace and debug output control. ???

2.1.3. Simulation setup, global variables and trace output control

???

Figure 2. Code fragment: Simulation Initialization, Globals and trace control

# File: kese_gw_dailyCycle_v1.py  1
# Knowledge and Economics Simulation Engine
# RealTime driver "Go West" scenario

from SimPy.SimulationRT  import *    2

simDays = 5   3
simHours = simDays * 24

# Print feedback control   4
printDaylightCycle = True
      

1

This is an internal note of the file name.

2

Load of Real Time SimPy lib. See the SimulationRT Manual .

3

The number of simulation days and the total simulation hours are defined as global variables. They are global in scope by being created at the top level thus all Classes will be able to "see" them. Note: Global variables can make the code very hard to follow. Only stable, simulation wide variables are defined this way.

4

Being able to trace what is happening inside the simulation model is critical for debugging the code. However, too many messages are also a problem. We use global true/false variables to easy control the flow of internal messages. This printDaylightCycle variable controls console messages inside the Daylight class.

2.1.4. Simulation Initialization and Event Objects

???

Figure 3. Code fragment: Initialization and Event Objects

##########################################################################
#
# Module level code that initializes simulation
#
##########################################################################

initialize()  1

# create day and daylight event Process
daylightEvents = Daylight()  2
activate(daylightEvents, daylightEvents.sunEvents())

# Create Event Objects   3
externalityPhase = SimEvent(name='Externality Phase signal for Economic Cycle')
sunUp = SimEvent(name='Sun rise event')
sunDown = SimEvent(name='Sun set event')
newDay = SimEvent(name='Start of day event')
dayEnd = SimEvent(name='End of day event')

# simualtion starts here - 12 rel unit sim time = 2 sec clock per day
simulate(real_time=True, rel_speed=12, until=simHours)  4
      

1

This initializes the SimPy simulation code. In this kese_gw_dailyCycle_v1.py the RT version is initialized because that is the version imported (see Figure 2, “Code fragment: Simulation Initialization, Globals and trace control”). This command is covered in teh Simulation with SimPy section of the SimPy Manual

2

These two lines create an instance of the Daylight class and activates the instance bay calling the sunEvents() method. The event loop is discussed in detail in Section 2.1.6, “DailyCycle code”

3

This section of the code creates five event objects - externalityPhase, sunUp, sunDown, newDay, and dayEnd. These events are signaled as a day progresses by the Daylight event loop (see Section 2.1.1, “Introducing the event loop”). All other objects within the simulation - Processes, Resources, Levels, etc. - are programmed to take certain actions at specific phases with a day. SimEvents are described in detail in Creating and Signalling SimEvents in the SImPy Manual.

4

This starts the simulation, sets teh relative speed, and sets the duration. The rel_speed is the number of simulation time units per real second. Thus 12 makes each half day 1 second of real time. Or, each day is simulated in 2 real seconds. This is described in the Introduction section of A Manual for SimulationRT

2.1.5. Daily Event Loop

???

Figure 4. Code fragment: Daily Event Loop

#---------------------------------------------------------------------
# daylight massaging Process
#---------------------------------------------------------------------
'''
This is a simple 12 hour sun up to sun down time. However the process
could be extended to simulate seasons and/or latitude.

Note: this process also fires a new day event
'''

class Daylight(Process):

    def __init__(self):
        Process.__init__(self, name='Daylight')
        self.sunUpHour = 6
        self.sunDownHour = 18
    
    def sunEvents(self):

        # start 24 hour loop
        while True:
            # tick internal clock to first hour of next day
            yield hold, self, 1               

            # send start of new day event
            newDay.signal()
            if printDaylightCycle == True:
                print 'From Daylight Process: ', \
                'Start of day %d at simulation hour %d'\
                %( int(now()/24)+1, now() )
            
            # wait for daylight and them sed event
            yield hold, self, self.sunUpHour
            sunUp.signal()
            if printDaylightCycle == True:
                print 'From Daylight Process: sun up at %d' %now()

            # wait for nightfall and then send event
            #   subtract 1 to set at start of sundown
            yield hold, self, (self.sunDownHour-self.sunUpHour)-1
            sunDown.signal()
            if printDaylightCycle == True:
                print 'From Daylight Process: sundown at %d' %now()

            # wait for midnight
            yield hold, self, 24-self.sunDownHour
            dayEnd.signal()
            if printDaylightCycle == True:
             print 'From Daylight Process:  Day ended at %d' %now()
      

2.1.6. DailyCycle code

Below is a full and clean (no callouts) listing of the simulation code for this section.

Figure 5.  Full listing of Daily Cycle simulation code

    # File: kese_gw_dailyCycle_v1.py
# Knowledge and Economics Simulation Engine
# RealTime driver "Go West" scenario

from SimPy.SimulationRT  import *

simDays = 5
simHours = simDays * 24

# Print feedback control
printDaylightCycle = True

#---------------------------------------------------------------------
# daylight massaging Process
#---------------------------------------------------------------------
'''
This is a simple 12 hour sun up to sun down time. However the process
could be extended to simulate seasons and/or latitude.

Note: this process also fires a new day event
'''

class Daylight(Process):

    def __init__(self):
        Process.__init__(self, name='Daylight')
        self.sunUpHour = 6
        self.sunDownHour = 18
    
    def sunEvents(self):

        # start 24 hour loop
        while True:
            # tick internal clock to first hour of next day
            yield hold, self, 1               

            # send start of new day event
            newDay.signal()
            if printDaylightCycle == True:
                print 'From Daylight Process: ', \
                'Start of day %d at simulation hour %d'\
                %( int(now()/24)+1, now() )
            
            # wait for daylight and them sed event
            yield hold, self, self.sunUpHour
            sunUp.signal()
            if printDaylightCycle == True:
                print 'From Daylight Process: sun up at %d' %now()

            # wait for nightfall and then send event
            #   subtract 1 to set at start of sundown
            yield hold, self, (self.sunDownHour-self.sunUpHour)-1
            sunDown.signal()
            if printDaylightCycle == True:
                print 'From Daylight Process: sundown at %d' %now()

            # wait for midnight
            yield hold, self, 24-self.sunDownHour
            dayEnd.signal()
            if printDaylightCycle == True:
             print 'From Daylight Process:  Day ended at %d' %now()

##########################################################################
#
# Module level code that initializes simulation
#
##########################################################################

initialize()

# create day and daylight event Process
daylightEvents = Daylight()
activate(daylightEvents, daylightEvents.sunEvents())

# Create Event Objects
externalityPhase = SimEvent(name='Externality Phase signal for Economic Cycle')
sunUp = SimEvent(name='Sun rise event')
sunDown = SimEvent(name='Sun set event')
newDay = SimEvent(name='Start of day event')
dayEnd = SimEvent(name='End of day event')

# simualtion starts here - 12 rel unit sim time = 2 sec clock per day
simulate(real_time=True, rel_speed=12, until=simHours)
      

KESL/RandD/keseGoWest/ChapSunUp/DaylightCycle (last edited 2008-12-30 20:53:39 by jeff)