2. Stop Condition and Simulation Timer
This second step adds a stop condition to the model so that the simulation halts automatically. This is a necessary prerequisite before running any batch experiment — without it, each simulation run would continue indefinitely and the batch scheduler would never move to the next parameter configuration.
In particular, this step presents:
- Why
do haltmust be used instead ofdo pausein the context of batch experiments - How to combine two stopping criteria with
or - How the
until:facet of a batch experiment relates to the model's stop condition
The model file for this step can be found in:
msi.gama.models/models/Tutorials/SIR Analysis/models/SIR Model 02.gaml
do halt vs do pause​
GAMA provides two ways to stop a running simulation:
| Statement | Effect |
|---|---|
do pause | Freezes the entire experiment, including the batch scheduler. Subsequent runs never start. |
do halt | Terminates only the current simulation instance. The batch scheduler continues to the next run. |
For a GUI experiment used interactively, both work fine. But as soon as you introduce a
batch experiment, do pause breaks the exploration — every run stops at the first
simulation and the batch never completes. Always use do halt in models intended for
batch.
Adding the stop condition​
A single reflex added to the global block is sufficient. It fires when either of two
conditions is true: the epidemic is over (no infected agents remain) or the simulation
has run for the maximum number of cycles.
global {
// ... (unchanged from step 1)
int max_steps <- 1000;
reflex stop when: cycle >= max_steps or nb_infected = 0 {
do halt;
}
}
Note:
nb_infectedis already updated each step by theupdate_countsreflex defined in step 1. The two reflexes are independent — GAMA executes all reflexes whosewhen:condition is true at each step, in the order they are declared.
Complete model​
The only changes from step 1 are the addition of max_steps and the stop reflex.
Everything else is identical.
model SIR
global {
int nb_agents <- 200 min: 50 max: 500;
int nb_infected_init <- 5 min: 1 max: 50;
float infection_rate <- 0.5 min: 0.0 max: 1.0;
int infection_distance <- 5 min: 1 max: 20;
int recovery_time <- 50 min: 10 max: 200;
int max_steps <- 1000;
int nb_susceptible <- 0;
int nb_infected <- 0;
int nb_recovered <- 0;
init {
create person number: nb_agents;
ask nb_infected_init among (person as list) {
status <- "infected";
infection_timer <- recovery_time;
}
}
reflex update_counts {
nb_susceptible <- person count (each.status = "susceptible");
nb_infected <- person count (each.status = "infected");
nb_recovered <- person count (each.status = "recovered");
}
reflex stop when: cycle >= max_steps or nb_infected = 0 {
do halt;
}
}
species person skills: [moving] {
string status <- "susceptible";
int infection_timer <- 0;
float speed <- 1.0;
reflex move {
do wander();
}
reflex infect when: status = "infected" {
ask (person at_distance infection_distance) where (each.status = "susceptible") {
if flip(infection_rate) {
status <- "infected";
infection_timer <- recovery_time;
}
}
infection_timer <- infection_timer - 1;
if infection_timer <= 0 {
status <- "recovered";
}
}
aspect base {
draw circle(1) at: location color:
(status = "infected") ? #red : ((status = "recovered") ? #blue : #green);
}
}
experiment SIR_gui type: gui {
parameter "Number of agents" var: nb_agents;
parameter "Initially infected" var: nb_infected_init;
parameter "Infection rate" var: infection_rate;
parameter "Infection distance" var: infection_distance;
parameter "Recovery time" var: recovery_time;
output {
display "Population" type: java2D {
species person aspect: base;
}
display "SIR Chart" type: java2D {
chart "SIR dynamics" type: series {
data "Susceptible" value: nb_susceptible color: #green;
data "Infected" value: nb_infected color: #red;
data "Recovered" value: nb_recovered color: #blue;
}
}
monitor "Susceptible" value: nb_susceptible;
monitor "Infected" value: nb_infected;
monitor "Recovered" value: nb_recovered;
monitor "Cycle" value: cycle;
}
}
What's next?​
In Step 3, we add a batch experiment to the model and use Latin Hypercube Sampling to systematically explore the five-dimensional parameter space and save the results to a CSV file.