Core
The dissmodel.core module provides the simulation clock and execution lifecycle,
built on top of Salabim's discrete event engine.
All models and visualization components must be instantiated after the
Environment — they register themselves automatically on creation.
Environment → Model → Visualization → env.run()
↑ ↑ ↑ ↑
first second third fourth
Usage
from dissmodel.core import Environment, Model
env = Environment(start_time=1, end_time=10)
class MyModel(Model):
def setup(self):
pass
def execute(self):
print(f"step {self.env.now()}")
MyModel()
env.run()
Object-Oriented Modeling
Object-oriented modeling is a core feature of DisSModel, inherited directly from Python's class system. Just as TerraME defines agents as objects with encapsulated attributes and behaviours, DisSModel uses class inheritance to build structured, reusable, and modular models.
Every model is a subclass of Model, which guarantees automatic registration with
the active Environment. This means the simulation clock, the execution lifecycle,
and any visualization components are wired together without any boilerplate.
from dissmodel.core import Model, Environment
class SIR(Model):
def setup(self, susceptible=9998, infected=2, recovered=0,
duration=2, contacts=6, probability=0.25):
self.susceptible = susceptible
self.infected = infected
self.recovered = recovered
self.duration = duration
self.contacts = contacts
self.probability = probability
def execute(self):
total = self.susceptible + self.infected + self.recovered
alpha = self.contacts * self.probability
new_inf = self.infected * alpha * (self.susceptible / total)
new_rec = self.infected / self.duration
self.susceptible -= new_inf
self.infected += new_inf - new_rec
self.recovered += new_rec
Instantiation is clean and parametric:
env = Environment(end_time=30)
SIR(susceptible=9998, infected=2, recovered=0,
duration=2, contacts=6, probability=0.25)
env.run()
!!! tip "Why subclass Model?"
- Automatic clock integration — self.env.now() is always available inside execute().
- Encapsulation — each model owns its state; multiple instances can run in the same environment independently.
- Extensibility — override setup() to add parameters, execute() to define the transition rule. Nothing else is required.
- Composability — models can read each other's state, enabling coupled CA + SysDyn simulations within a single env.run().
Each model can define its own start_time and end_time, independent of the
environment interval. This allows different parts of a simulation to be active
at different periods within the same run.
from dissmodel.core import Model, Environment
class ModelA(Model):
def execute(self):
print(f"[A] t={self.env.now()}")
class ModelB(Model):
def execute(self):
print(f"[B] t={self.env.now()}")
class ModelC(Model):
def execute(self):
print(f"[C] t={self.env.now()}")
env = Environment(start_time=2010, end_time=2016)
ModelA(start_time=2012) # active from 2012 to end
ModelB(end_time=2013) # active from start to 2013
ModelC() # active throughout
env.run()
Expected output:
Running from 2010 to 2016 (duration: 6)
[B] t=2010.0
[C] t=2010.0
[B] t=2011.0
[C] t=2011.0
[A] t=2012.0
[B] t=2012.0
[C] t=2012.0
[A] t=2013.0
[C] t=2013.0
[A] t=2014.0
[C] t=2014.0
[A] t=2015.0
[C] t=2015.0
[A] t=2016.0
[C] t=2016.0
!!! note
Models with no start_time / end_time inherit the environment's interval.
Models are synchronised — all active models execute at each time step before
the clock advances.
API Reference
dissmodel.core.Environment
Bases: Environment
Simulation environment with support for a custom time window.
Extends :class:salabim.Environment with start_time and end_time
to define the simulation boundaries explicitly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
float
|
Simulation start time, by default 0. |
0
|
end_time
|
float
|
Simulation end time. Can also be set via |
None
|
*args
|
Any
|
Extra positional arguments forwarded to :class: |
()
|
**kwargs
|
Any
|
Extra keyword arguments forwarded to :class: |
{}
|
Examples:
>>> env = Environment(start_time=0, end_time=10)
>>> env.start_time
0
>>> env.end_time
10
Source code in dissmodel/core/environment.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
now()
Return the current simulation time adjusted by start_time.
Returns:
| Type | Description |
|---|---|
float
|
Current time as |
Examples:
>>> env = Environment(start_time=5)
>>> env.now()
5.0
Source code in dissmodel/core/environment.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
reset()
Clear accumulated plot data.
This method is called automatically at the start of :meth:run to
ensure charts start fresh on each simulation run.
Examples:
>>> env = Environment()
>>> env._plot_metadata = {"x": {"data": [1, 2, 3]}}
>>> env.reset()
>>> env._plot_metadata["x"]["data"]
[]
Source code in dissmodel/core/environment.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | |
run(till=None)
Run the simulation over the configured time window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
till
|
float
|
Duration to run from |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither |
Examples:
>>> env = Environment(start_time=0, end_time=10)
>>> env.run()
Running from 0 to 10 (duration: 10)
Source code in dissmodel/core/environment.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
dissmodel.core.Model
Bases: Component
Base class for simulation models backed by a salabim Component.
Provides a time-stepped execution loop and automatic tracking of
attributes marked for plotting via the :func:~dissmodel.visualization.track_plot
decorator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
step
|
float
|
Time increment between successive :meth: |
1
|
start_time
|
float
|
Time at which the model starts executing, by default 0. |
0
|
end_time
|
float
|
Time at which the model stops executing, by default |
inf
|
name
|
str
|
Component name, by default |
''
|
*args
|
Any
|
Extra positional arguments forwarded to :class: |
()
|
**kwargs
|
Any
|
Extra keyword arguments forwarded to :class: |
{}
|
Examples:
>>> class MyModel(Model):
... def execute(self):
... print (self.env.now())
>>> env = Environment()
>>> model = MyModel(step=1, start_time=0, end_time=5)
>>> env.run(5)
Running from 0 to 5 (duration: 5)
0.0
1.0
2.0
3.0
4.0
Source code in dissmodel/core/model.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
__setattr__(name, value)
Intercept attribute assignment to record values marked for plotting.
If the class defines _plot_info (via the
:func:~dissmodel.visualization.track_plot decorator) and name
matches a tracked attribute, the value is appended to the plot data
buffer and registered in env._plot_metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Attribute name being set. |
required |
value
|
Any
|
Value being assigned. |
required |
Source code in dissmodel/core/model.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
execute()
Called once per time step.
Override in subclasses to define model behaviour.
Source code in dissmodel/core/model.py
76 77 78 79 80 81 82 | |
process()
salabim process loop.
Waits until start_time, then calls :meth:execute every
step time units until end_time.
Source code in dissmodel/core/model.py
62 63 64 65 66 67 68 69 70 71 72 73 74 | |