///|
/// Helper for the built-in school example.
fn example_place(
id : String,
label : String,
kind : PlaceKind,
floor : Int,
x : Double,
y : Double,
capacity : Int,
) -> Place {
Place::new(id, label, kind, floor, x, y, capacity)
}
///|
/// Helper for a bidirectional example passage.
fn example_passage(
id : String,
from_id : String,
to_id : String,
kind : PassageKind,
length_m : Double,
width_m : Double,
) -> Passage {
Passage::new(id, from_id, to_id, kind, length_m, width_m)
}
///|
/// A compact two-exit classroom useful for unit tests and tutorials.
pub fn compact_demo_plan() -> EvacuationPlan {
let plan = EvacuationPlan::new("Compact classroom")
plan.places.push(
example_place("classroom", "Classroom", Room, 1, 80.0, 80.0, 40),
)
plan.places.push(
example_place("hall-center", "Central Hall", Corridor, 1, 200.0, 80.0, 100),
)
plan.places.push(
example_place("exit-west", "West Exit", Exit, 1, 20.0, 80.0, 200),
)
plan.places.push(
example_place("exit-east", "East Exit", Exit, 1, 360.0, 80.0, 200),
)
plan.passages.push(
example_passage(
"door-classroom",
"classroom",
"hall-center",
Door,
6.0,
1.2,
),
)
plan.passages.push(
example_passage("hall-west", "hall-center", "exit-west", Hallway, 18.0, 1.8),
)
plan.passages.push(
example_passage("hall-east", "hall-center", "exit-east", Hallway, 20.0, 1.8),
)
plan.populations.push(
PopulationGroup::new("class-a", "classroom", 32, Standard),
)
plan
}
///|
/// Build a realistic two-floor school wing with redundant exits.
pub fn school_demo_plan() -> EvacuationPlan {
let plan = EvacuationPlan::new("Riverside School Wing A")
plan.timestep_seconds = 1.0
// Ground floor teaching spaces.
plan.places.push(
example_place("f1-class-101", "Classroom 101", Room, 1, 70.0, 100.0, 45),
)
plan.places.push(
example_place("f1-class-102", "Classroom 102", Room, 1, 70.0, 220.0, 45),
)
plan.places.push(
example_place("f1-lab", "Science Laboratory", Room, 1, 70.0, 340.0, 36),
)
plan.places.push(
example_place(
"f1-office",
"Administration Office",
Room,
1,
70.0,
460.0,
20,
),
)
plan.places.push(
example_place(
"f1-corridor-west",
"Ground West Corridor",
Corridor,
1,
190.0,
180.0,
180,
),
)
plan.places.push(
example_place(
"f1-corridor-east",
"Ground East Corridor",
Corridor,
1,
310.0,
360.0,
180,
),
)
plan.places.push(
example_place("f1-lobby", "Ground Lobby", Assembly, 1, 250.0, 270.0, 250),
)
plan.places.push(
example_place(
"f1-stair-west",
"West Stair Landing",
Stair,
1,
180.0,
70.0,
60,
),
)
plan.places.push(
example_place(
"f1-stair-east",
"East Stair Landing",
Stair,
1,
330.0,
470.0,
60,
),
)
plan.places.push(
example_place("exit-main", "Main South Exit", Exit, 1, 250.0, 560.0, 500),
)
plan.places.push(
example_place("exit-west", "West Yard Exit", Exit, 1, 20.0, 180.0, 300),
)
plan.places.push(
example_place("exit-east", "East Service Exit", Exit, 1, 480.0, 360.0, 300),
)
// Upper floor teaching spaces.
plan.places.push(
example_place("f2-class-201", "Classroom 201", Room, 2, 70.0, 100.0, 45),
)
plan.places.push(
example_place("f2-class-202", "Classroom 202", Room, 2, 70.0, 220.0, 45),
)
plan.places.push(
example_place("f2-library", "Library", Room, 2, 70.0, 340.0, 80),
)
plan.places.push(
example_place("f2-music", "Music Room", Room, 2, 70.0, 460.0, 35),
)
plan.places.push(
example_place(
"f2-corridor-west",
"Upper West Corridor",
Corridor,
2,
190.0,
180.0,
180,
),
)
plan.places.push(
example_place(
"f2-corridor-east",
"Upper East Corridor",
Corridor,
2,
310.0,
360.0,
180,
),
)
plan.places.push(
example_place("f2-lobby", "Upper Lobby", Assembly, 2, 250.0, 270.0, 220),
)
plan.places.push(
example_place(
"f2-stair-west",
"Upper West Stair",
Stair,
2,
180.0,
70.0,
60,
),
)
plan.places.push(
example_place(
"f2-stair-east",
"Upper East Stair",
Stair,
2,
330.0,
470.0,
60,
),
)
plan.places.push(
example_place(
"f2-refuge",
"Accessible Refuge",
Assembly,
2,
390.0,
470.0,
20,
),
)
// Ground floor room doors and corridor spine.
plan.passages.push(
example_passage(
"door-101",
"f1-class-101",
"f1-corridor-west",
Door,
5.0,
1.2,
),
)
plan.passages.push(
example_passage(
"door-102",
"f1-class-102",
"f1-corridor-west",
Door,
5.0,
1.2,
),
)
plan.passages.push(
example_passage("door-lab", "f1-lab", "f1-corridor-east", Door, 6.0, 1.4),
)
plan.passages.push(
example_passage(
"door-office",
"f1-office",
"f1-corridor-east",
Door,
4.0,
1.0,
),
)
plan.passages.push(
example_passage(
"f1-west-lobby",
"f1-corridor-west",
"f1-lobby",
Hallway,
16.0,
2.4,
),
)
plan.passages.push(
example_passage(
"f1-east-lobby",
"f1-corridor-east",
"f1-lobby",
Hallway,
16.0,
2.4,
),
)
plan.passages.push(
example_passage(
"f1-cross-corridor",
"f1-corridor-west",
"f1-corridor-east",
Hallway,
28.0,
1.8,
),
)
plan.passages.push(
example_passage(
"f1-west-stair-link",
"f1-corridor-west",
"f1-stair-west",
Hallway,
8.0,
1.6,
),
)
plan.passages.push(
example_passage(
"f1-east-stair-link",
"f1-corridor-east",
"f1-stair-east",
Hallway,
8.0,
1.6,
),
)
plan.passages.push(
example_passage("lobby-main-exit", "f1-lobby", "exit-main", Door, 12.0, 3.2),
)
plan.passages.push(
example_passage(
"west-yard-exit",
"f1-corridor-west",
"exit-west",
Door,
10.0,
1.8,
),
)
plan.passages.push(
example_passage(
"east-service-exit",
"f1-corridor-east",
"exit-east",
Door,
12.0,
1.6,
),
)
// Upper floor room doors and corridor spine.
plan.passages.push(
example_passage(
"door-201",
"f2-class-201",
"f2-corridor-west",
Door,
5.0,
1.2,
),
)
plan.passages.push(
example_passage(
"door-202",
"f2-class-202",
"f2-corridor-west",
Door,
5.0,
1.2,
),
)
plan.passages.push(
example_passage(
"door-library",
"f2-library",
"f2-corridor-east",
Door,
7.0,
1.6,
),
)
plan.passages.push(
example_passage(
"door-music",
"f2-music",
"f2-corridor-east",
Door,
5.0,
1.2,
),
)
plan.passages.push(
example_passage(
"f2-west-lobby",
"f2-corridor-west",
"f2-lobby",
Hallway,
16.0,
2.4,
),
)
plan.passages.push(
example_passage(
"f2-east-lobby",
"f2-corridor-east",
"f2-lobby",
Hallway,
16.0,
2.4,
),
)
plan.passages.push(
example_passage(
"f2-cross-corridor",
"f2-corridor-west",
"f2-corridor-east",
Hallway,
28.0,
1.8,
),
)
plan.passages.push(
example_passage(
"f2-west-stair-link",
"f2-corridor-west",
"f2-stair-west",
Hallway,
8.0,
1.6,
),
)
plan.passages.push(
example_passage(
"f2-east-stair-link",
"f2-corridor-east",
"f2-stair-east",
Hallway,
8.0,
1.6,
),
)
plan.passages.push(
example_passage(
"refuge-link",
"f2-corridor-east",
"f2-refuge",
Ramp,
6.0,
1.5,
),
)
plan.passages.push(
example_passage(
"accessible-egress-ramp",
"f2-refuge",
"exit-east",
Ramp,
48.0,
1.5,
),
)
plan.passages.push(
example_passage(
"stair-west",
"f2-stair-west",
"f1-stair-west",
Stairway,
18.0,
1.4,
),
)
plan.passages.push(
example_passage(
"stair-east",
"f2-stair-east",
"f1-stair-east",
Stairway,
18.0,
1.4,
),
)
// Ground floor occupants.
plan.populations.push(
PopulationGroup::new("class-101-students", "f1-class-101", 32, Standard),
)
plan.populations.push(
PopulationGroup::new("class-102-students", "f1-class-102", 30, Standard),
)
plan.populations.push(
PopulationGroup::new("laboratory-group", "f1-lab", 24, Slow),
)
plan.populations.push(
PopulationGroup::new("office-staff", "f1-office", 12, Fast),
)
// Upper floor occupants including an assisted cohort.
plan.populations.push(
PopulationGroup::new("class-201-students", "f2-class-201", 31, Standard),
)
plan.populations.push(
PopulationGroup::new("class-202-students", "f2-class-202", 29, Standard),
)
plan.populations.push(
PopulationGroup::new("library-visitors", "f2-library", 40, Slow),
)
plan.populations.push(
PopulationGroup::new("music-class", "f2-music", 22, Standard),
)
plan.populations.push(
PopulationGroup::new("assisted-pair", "f2-refuge", 2, Assisted),
)
plan
}
///|
/// Add a delayed laboratory fire to the school example.
pub fn school_fire_scenario() -> EvacuationPlan {
let plan = school_demo_plan()
plan.events.push(Ignite("f1-lab", 4, 0.55))
plan.events.push(ClosePassage("east-service-exit", 18))
plan.events.push(OpenPassage("east-service-exit", 90))
plan
}
///|
/// Add an early main-exit closure without a hazard source.
pub fn school_exit_closure_scenario() -> EvacuationPlan {
let plan = school_demo_plan()
plan.events.push(ClosePassage("lobby-main-exit", 2))
plan.events.push(OpenPassage("lobby-main-exit", 120))
plan
}
///|
/// Create a deliberately invalid example for validation demonstrations.
pub fn invalid_demo_plan() -> EvacuationPlan {
let plan = EvacuationPlan::new("Invalid isolated room")
plan.places.push(
example_place("isolated", "Isolated Room", Room, 1, 50.0, 50.0, 20),
)
plan.places.push(example_place("exit", "Exit", Exit, 1, 250.0, 50.0, 100))
plan.populations.push(
PopulationGroup::new("isolated-group", "isolated", 18, Standard),
)
plan
}