Core
The dissmodel.core module provides the simulation clock and execution lifecycle.
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
[C] t=2010
[B] t=2011
[C] t=2011
[A] t=2012
[B] t=2012
[C] t=2012
[A] t=2013
[C] t=2013
[A] t=2014
[C] t=2014
[A] t=2015
[C] t=2015
!!! 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
Simulation environment with support for a custom time window.
Manages the simulation clock and coordinates the execution of all
registered :class:~dissmodel.core.Model instances.
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
|
Examples:
>>> env = Environment(start_time=0, end_time=10)
>>> env.start_time
0
>>> env.end_time
10
Source code in dissmodel/core/environment.py
6 7 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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |
now()
Return the current simulation time.
Returns:
| Type | Description |
|---|---|
float
|
Current simulation time. |
Examples:
>>> env = Environment(start_time=5)
>>> env.now()
5
Source code in dissmodel/core/environment.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
reset()
Reset the clock and clear accumulated plot data.
Called automatically at the start of :meth:run to ensure the
environment starts fresh on each simulation run.
Examples:
>>> env = Environment(start_time=0, end_time=10)
>>> env._plot_metadata = {"x": {"data": [1, 2, 3]}}
>>> env.reset()
>>> env._plot_metadata["x"]["data"]
[]
Source code in dissmodel/core/environment.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |
run(till=None)
Run the simulation over the configured time window.
Executes all registered models in time-step order. On each tick,
every model whose next scheduled time is less than or equal to the
current simulation time has its :meth:~dissmodel.core.Model.execute
method called. The clock then advances to the nearest pending event.
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
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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | |
dissmodel.core.Model
Base class for simulation models.
Provides a time-stepped execution loop and automatic tracking of
attributes marked for plotting via the
:func:~dissmodel.visualization.track_plot decorator.
Every Model instance auto-registers with the currently active
:class:~dissmodel.core.Environment at construction time. An active
environment must exist before instantiating any model.
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
|
Human-readable model name, by default |
''
|
**kwargs
|
Any
|
Extra keyword arguments (ignored; kept for subclass compatibility). |
{}
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no active :class: |
Examples:
>>> class MyModel(Model):
... def execute(self):
... print(self.env.now())
>>> env = Environment(start_time=0, end_time=5)
>>> model = MyModel(step=1)
>>> env.run()
Running from 0 to 5 (duration: 5)
0
1
2
3
4
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
__setattr__(name, value)
Intercept attribute assignment to record values marked for plotting.
If the class defines _plot_info (populated by 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
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
execute()
Called once per time step.
Override in subclasses to define model behaviour.
Source code in dissmodel/core/model.py
102 103 104 105 106 107 108 | |
post_execute()
Called once after each :meth:execute.
Override in subclasses to perform per-step cleanup or snapshotting after the transition rule runs.
Source code in dissmodel/core/model.py
110 111 112 113 114 115 116 117 | |
pre_execute()
Called once before each :meth:execute.
Override in subclasses to perform per-step setup, such as snapshotting state arrays before the transition rule runs.
Source code in dissmodel/core/model.py
93 94 95 96 97 98 99 100 | |
setup(**kwargs)
Called once after instantiation, receiving any extra keyword
arguments not consumed by __init__.
Override in subclasses to perform one-time setup such as building neighborhoods or initializing visualization state.
Source code in dissmodel/core/model.py
83 84 85 86 87 88 89 90 91 | |