-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfuture_sim.py
More file actions
140 lines (116 loc) · 4.75 KB
/
future_sim.py
File metadata and controls
140 lines (116 loc) · 4.75 KB
1
2
3
4
5
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
"""
BreezePath AI — Future Simulation
Urban growth model that predicts how the city evolves over time.
"""
import copy
import random
from model import compute_heat
from simulation import simulate_wind
from metrics import compute_metrics
def simulate_future(grid, growth_level, seed=None):
"""
Simulate urban growth at a given level (0-100).
As growth_level increases:
- Building density increases
- Building heights slightly increase
- Vegetation is replaced by buildings
- Some empty cells become buildings
Returns a new grid representing the future state.
"""
rng = random.Random(seed if seed is not None else growth_level)
future = copy.deepcopy(grid)
rows, cols = len(future), len(future[0])
# Growth factor 0.0 → 1.0
gf = growth_level / 100.0
# How many cells to urbanize
target_new_buildings = int(gf * rows * cols * 0.25) # up to 25% of grid
height_boost = int(gf * 2) # 0-2 extra floors
# Collect candidate cells (empty + vegetation)
candidates = []
for r in range(rows):
for c in range(cols):
t = future[r][c]["type"]
if t == "empty":
candidates.append((r, c, 1.0)) # high priority
elif t == "vegetation":
candidates.append((r, c, 0.4 + gf * 0.4)) # increasing priority
rng.shuffle(candidates)
placed = 0
for r, c, prob in candidates:
if placed >= target_new_buildings:
break
if rng.random() < prob:
base_h = rng.randint(1, 3) + height_boost
future[r][c] = {
"type": "building",
"height": min(5, base_h),
"heat": 0.0,
"wind_block": 0.0,
}
placed += 1
# Existing buildings: slight height increase
for r in range(rows):
for c in range(cols):
if future[r][c]["type"] == "building":
if rng.random() < gf * 0.3:
future[r][c]["height"] = min(5, future[r][c]["height"] + 1)
return future
def predict_future_state(grid, growth_level):
"""
Run full future simulation: growth → heat → wind → metrics.
Returns (future_grid, future_wind, future_metrics).
"""
future_grid = simulate_future(grid, growth_level)
future_grid = compute_heat(future_grid)
future_wind = simulate_wind(future_grid)
future_mets = compute_metrics(future_grid, future_wind)
return future_grid, future_wind, future_mets
def detect_risk_zones(grid, wind_field):
"""
Classify each cell into risk levels based on heat and wind.
Returns a 2D list of risk levels: 'critical', 'moderate', 'safe'.
"""
rows, cols = len(grid), len(grid[0])
risks = []
for r in range(rows):
row_risks = []
for c in range(cols):
heat = grid[r][c]["heat"]
wind = float(wind_field[r, c])
# Score: high heat + low wind = high risk
if heat > 38 and wind < 0.3:
row_risks.append("critical")
elif heat > 35 or wind < 0.2:
row_risks.append("moderate")
else:
row_risks.append("safe")
risks.append(row_risks)
return risks
def generate_future_story(current_mets, future_mets, growth_level):
"""Generate narrative about future projections."""
stories = []
dt = future_mets["avg_temp"] - current_mets["avg_temp"]
dw = future_mets["wind_efficiency"] - current_mets["wind_efficiency"]
dc = future_mets["cooling_score"] - current_mets["cooling_score"]
stories.append(f"📊 At **{growth_level}% urban growth**, projections show:")
if dt > 2:
stories.append(f"🔴 **Critical:** Average temperature rises by **{dt:.1f}°C** — immediate cooling intervention needed.")
elif dt > 1:
stories.append(f"⚠️ Temperature increases by **{dt:.1f}°C** — green corridors recommended.")
elif dt > 0.1:
stories.append(f"🌡️ Minor temperature rise of **{dt:.1f}°C** projected.")
else:
stories.append(f"✅ Temperature remains stable ({dt:+.1f}°C).")
if dw < -10:
stories.append(f"🔴 Wind efficiency drops by **{abs(dw):.1f}%** — severe airflow blockage expected.")
elif dw < -3:
stories.append(f"⚠️ Wind flow reduces by **{abs(dw):.1f}%** — breeze corridors at risk.")
if dc < -15:
stories.append(f"🔴 Cooling score plummets by **{abs(dc):.1f}** points — city resilience at risk.")
elif dc < -5:
stories.append(f"⚠️ Cooling capacity drops by **{abs(dc):.1f}** points.")
# Energy impact
if dt > 0.5:
extra_energy = min(40, dt * 8)
stories.append(f"⚡ Projected **{extra_energy:.0f}% increase** in cooling energy demand.")
return stories