process synchronization#
Next to the synchronization of activities using control structures like SequentialActivity, WhileActivity, RepeatActivity and ParallelActivity used within a single process, OpenCLSim allows to synchronize different processes using start_events. Start_events can be specified using the expression language as documented to delay the execution of a process. Control structures do not delay the execution but explicitly start the execution when possible. The difference is very well visible when you compare the activity log in this demo with the one from the sequence demo.
0. Import libraries#
import datetime, time
import simpy
import shapely.geometry
import pandas as pd
import openclsim.core as core
import openclsim.model as model
import openclsim.plot as plot
1. Initialise simpy environment#
# setup environment
simulation_start = 0
my_env = simpy.Environment(initial_time=simulation_start)
2. Define object classes#
In this example we won’t use object classes
3. Create objects#
3.1. Create site object(s)#
No site objects are created
3.2. Create vessel object(s)#
No vessel objects are created
3.3 Create activity/activities#
The two activities are started in parallel, but the execution of Activity2 is delayed until Activity1 has been completed. To easier see how the two activities are interrelated a reporting activity is added.
# initialise registry
registry = {}
# create a reporting activity
reporting_activity = model.BasicActivity(
env=my_env,
name="Reporting activity",
registry=registry,
duration=0,
)
# create two basic activities
activity1 = model.BasicActivity(
env=my_env,
name="Activity1",
registry=registry,
additional_logs=[reporting_activity],
duration=20,
)
activity2 = model.BasicActivity(
env=my_env,
name="Activity2",
registry=registry,
additional_logs=[reporting_activity],
duration=40,
start_event=[
{
"name": "Activity1",
"type": "activity",
"state": "done"
}
],
)
4. Register processes and run simpy#
# initate the simpy processes defined in activity1 and activity2 and run simpy
model.register_processes([reporting_activity, activity1, activity2])
my_env.run()
5. Inspect results#
5.1 Inspect logs#
display(plot.get_log_dataframe(reporting_activity, [reporting_activity, activity1, activity2]))
Activity | Timestamp | ActivityState | type | ref | |
---|---|---|---|---|---|
0 | Reporting activity | 1970-01-01 00:00:00 | START | NaN | NaN |
1 | Activity1 | 1970-01-01 00:00:00 | START | additional log | aff9a031-2237-448b-8051-05b617c7744b |
2 | Reporting activity | 1970-01-01 00:00:00 | STOP | NaN | NaN |
4 | Activity2 | 1970-01-01 00:00:00 | WAIT_START | additional log | 5d4b6fc5-6fd7-4bf8-82e1-8253be6eaee3 |
3 | Activity1 | 1970-01-01 00:00:20 | STOP | additional log | aff9a031-2237-448b-8051-05b617c7744b |
5 | Activity2 | 1970-01-01 00:00:20 | WAIT_STOP | additional log | 5d4b6fc5-6fd7-4bf8-82e1-8253be6eaee3 |
6 | Activity2 | 1970-01-01 00:00:20 | START | additional log | 5d4b6fc5-6fd7-4bf8-82e1-8253be6eaee3 |
7 | Activity2 | 1970-01-01 00:01:00 | STOP | additional log | 5d4b6fc5-6fd7-4bf8-82e1-8253be6eaee3 |
Both activities start at the same time. Activity2 gets into a waiting state, which ends, when Activity1 ends. Then Activity2 is executed.
5.2 Visualise gantt charts#
plot.get_gantt_chart([reporting_activity, activity1, activity2])