SimulationLab — Master Plan
Ten modelling & simulation (M&S) projects for a Georgia Tech M&S student. They start with a grid automaton and end with a real-data 3D digital twin. Each level inherits the previous tech stack and adds to it, while jumping to a new field. The point is to be a reference Dan can come back to: to see which scientific and industry-standard tools exist, to learn how each one is used, and to get ideas.
The ladder
| # | Folder | Field | Core M&S paradigm | New tools added (cumulative stack) |
|---|---|---|---|---|
| 1 | L01_wildfire_percolation |
Statistical physics / ecology | Cellular automata, Monte Carlo, phase transitions | Python, NumPy, Matplotlib (animation→GIF) |
| 2 | L02_gene_circuit_noise |
Systems / synthetic biology | ODEs vs exact stochastic simulation (Gillespie SSA) | + SciPy (solve_ivp, optimize, FFT) |
| 3 | L03_atl_checkpoint |
Operations research | Discrete-event simulation, output analysis, sim-optimization | + SimPy, scipy.stats |
| 4 | L04_echo_chambers |
Computational social science | Agent-based modelling on adaptive networks | + Mesa 3, NetworkX, parallel parameter sweeps |
| 5 | L05_galactic_collision |
Astrophysics | N-body, symplectic integrators, HPC Python | + Numba (JIT, prange), MP4 via ffmpeg |
| 6 | L06_virtual_wind_tunnel |
Fluid dynamics / aero | Lattice Boltzmann CFD, verification & validation | + Numba stencils, scipy.fft, V&V workflow |
| 7 | L07_earths_thermostat |
Climate science | Bayesian calibration, UQ, global sensitivity on real data | + pandas, requests (live APIs), emcee, SALib |
| 8 | L08_generative_bracket |
Structural engineering | FEM + 3D topology optimization (generative design) | + scikit-fem, sparse solvers + pyamg, PyVista/VTK, STL |
| 9 | L09_orbital_traffic_control |
Astrodynamics / space safety | Real-catalog propagation, conjunction screening, debris Monte Carlo | + sgp4, KD-trees, Three.js WebGL + satellite.js |
| 10 | L10_solar_stinger_twin |
Energy + mobility + materials | Real-data multi-physics digital twin (DES + physics + GIS) | + pvlib, OSM/Overpass GIS, GT bus data, Materials Project, HTEM |
The stack only grows: L10 uses NumPy, SciPy, SimPy, pandas, Numba, and web 3D all together.
Conventions (every level)
- Environment: one shared uv env at the repo root (Python 3.12). Run with
uv run python LXX_name/sim.pyfromSimulationLab/. Do not runuv add,uv syncorpip install, because other agents share this env. Everything inpyproject.tomlis already installed and smoke-tested (numpy, scipy, matplotlib, pillow, simpy, mesa 3.5, networkx, numba 0.67, imageio-ffmpeg, pandas, pyarrow, requests, emcee, SALib, scikit-fem, pyamg, pyvista (offscreen works), sgp4, pvlib). If something is truly missing, stop and say so. - Layout per level:
LXX_name/hassim.py(split into ≤3 files only if it really helps),README.mdandoutput/(generated media, kept in the repo). Alsodata/for cached downloads when needed. Scripts write intoPath(__file__).parent / "output". - Headless:
matplotlib.use("Agg"), no GUI windows, PyVistaoff_screen=True. - Windows console: keep
print()output ASCII-only, or setPYTHONUTF8=1. cp1252 crashes on Greek letters. - Multiprocessing on Windows needs an
if __name__ == "__main__":guard. - CPU etiquette (8 cores / 16 threads, shared with other agents): cap at 4 threads/processes
(
os.environ.setdefault("NUMBA_NUM_THREADS","4")before importing numba;OMP_NUM_THREADS=4; pools ≤ 4). The default full run should finish in about ≤ 5 min. Size the problems to fit. - Media: GIF (Pillow) for levels 1–4, MP4 for 5+. MP4 is written with matplotlib's
FFMpegWriter, withplt.rcParams["animation.ffmpeg_path"] = imageio_ffmpeg.get_ffmpeg_exe()andextra_args=["-pix_fmt","yuv420p"]so browsers can play it. Budgets: GIF ≤ 8 MB, MP4 ≤ 20 MB, and ahero.pngstill per level for the gallery. Aim for publication-quality figures (dark theme is fine), with labelled axes and units. - Verification is part of the science. Each level asserts against at least one known
analytical, empirical or literature result, e.g.
verify()called bymain(). The printed numbers must be real, from actual runs. The README reports them honestly, including misses. - Code style (ponytail): minimal, boring, readable. Stdlib or already-installed libs first. No
frameworks, no classes-for-the-sake-of-it, no config systems. Mark deliberate simplifications
with
# ponytail: <ceiling>, <upgrade path>. - README.md is the teaching artifact, so write it in full. Sections:
1. Title, one-line hook, hero image or animation
2. The question the simulation answers
3. The model: equations and assumptions, compact
4. M&S concepts you'll learn here: bullets, 1–2 lines each
5. Tech stack: the cumulative stack, with this level's new tools marked ★ and why each one matters
6. Industry & scientific tools: a table of tool | what it is | who uses it | how this project maps to it
7. Results: figures, plus verification/validation numbers (actual values)
8. Run it: commands and expected runtime
9. Code tour: file/function → what it does
10. Simplifications & ceilings
11. Go further: 3–5 concrete extensions, including "rebuild it in
" 12. References: key papers and books
Level specs
Each spec gives the goal plus the must-haves. The implementer has creative latitude on everything else and should make it look impressive.
L01 — Wildfire Percolation (cellular automata)
- A. Percolation fire: L×L grid with tree density p. Ignite the left edge and spread to the 4-neighbourhood, vectorised in NumPy. Monte Carlo sweep of p over several L (e.g. 32…256), plotting P(fire crosses) and burned fraction. The transition sharpens with L (finite-size scaling). Verify: the estimated p_c is within ±0.02 of 0.5927 (square-lattice site percolation).
- B. Drossel–Schwabl forest-fire model (growth p, lightning f): self-organised criticality. Animated GIF, plus a fire-size distribution on log-log showing a power law.
- Tools to discuss: NetLogo, Golly, Cell-DEVS, and real wildfire sims (USFS FARSITE/FlamMap, Prometheus).
L02 — Noise in Gene Circuits (ODE vs exact stochastic simulation)
- Genetic toggle switch (Gardner/Cantor/Collins 2000). ODE with
solve_ivp, nullclines, bistability. Gillespie direct-method SSA shows noise-induced switching that the ODE can never produce. Mean switching time vs system size Ω grows exponentially. - Repressilator (Elowitz & Leibler 2000). ODE limit cycle vs SSA, with a period distribution via FFT/peaks.
- Compare stiff and non-stiff solvers (RK45 vs LSODA/BDF runtime).
- Verify: the SSA birth–death stationary distribution matches the analytical Poisson(k/γ).
- Tools: COPASI, Tellurium/libRoadRunner, SBML, GillesPy2/StochKit, BioNetGen.
L03 — ATL Checkpoint (discrete-event simulation)
- A Hartsfield–Jackson TSA checkpoint in SimPy. Non-homogeneous Poisson arrivals (thinning) follow a daily profile, with PreCheck and standard streams, document check → screening lanes, and secondary screening with probability q. Assumed rates are documented and loosely anchored to public figures.
- Verify: an M/M/c SimPy model reproduces Erlang-C Wq within its 95% CI.
- Output analysis: replications, t-based CIs, common random numbers for policy comparison, and a warm-up discussion (Welch). Simulation-optimisation: find the cheapest lane-staffing schedule with P95 wait ≤ 15 min.
- Visuals: queue length over the day with CI bands, wait distributions, policy comparison, and optionally an animated checkpoint GIF.
- Tools: Arena, Simio, AnyLogic, FlexSim, SimPy/salabim, queueing theory.
L04 — Echo Chambers (agent-based model on an adaptive network)
- Mesa 3 model on a NetworkX graph. Deffuant bounded-confidence opinion updates. A "recommender" rewires ties toward like-minded agents with probability r. Metrics: number of opinion clusters, polarisation/bimodality, modularity, assortativity.
- Parallel parameter sweep (
mesa.batch_run, ≤4 processes) over ε × r gives a phase diagram: consensus / polarisation / fragmentation. - Visuals: animated network with nodes coloured by opinion as echo chambers form, Deffuant "spaghetti" trajectories, and the phase-diagram heatmap.
- Verify: without rewiring, the cluster count ≈ ⌊1/(2ε)⌋ (Deffuant et al. 2000), roughly.
- Mesa 3.5 API differs from older tutorials. Read the installed package source
(
.venv/Lib/site-packages/mesa) for the current way to do agents, spaces and batch_run. - Tools: NetLogo, Mesa, Repast HPC, MASON, GAMA, AnyLogic.
L05 — Galactic Collision (N-body, high-performance Python)
- Two disk galaxies on a parabolic encounter (Toomre & Toomre 1972), producing tidal tails and bridges. Direct-sum gravity with Plummer softening and a kick-drift-kick leapfrog.
- Performance ladder: pure Python → NumPy broadcasting → Numba
@njit→ Numbaparallel+fastmath. Benchmark chart (interactions/s vs N on log-log, showing O(N²)) and a speedup table. - Verify: the two-body Kepler period matches analytics to <1%. Leapfrog energy error stays bounded while explicit Euler drifts (plot both).
- MP4: log-density rendering on black (looks like Hubble imagery), one colour per galaxy.
- Tools: GADGET-4, AREPO, SWIFT, REBOUND, AMUSE, galpy (plus LAMMPS/GROMACS as the MD cousins).
L06 — Virtual Wind Tunnel (lattice Boltzmann CFD)
- D2Q9 BGK LBM in Numba, with bounce-back solids and inlet/outlet BCs, and force by momentum exchange.
- Verification: Poiseuille channel vs the analytical parabola, and a grid-convergence study (≈2nd order).
- Validation: cylinder at Re≈100 should shed vortices with Strouhal ≈ 0.16–0.2 (FFT of lift), with C_D compared to the literature.
- Showcase: a NACA airfoil across angles of attack, giving a lift/drag polar and vorticity MP4.
- Tools: OpenFOAM, Ansys Fluent, STAR-CCM+, PowerFLOW (industrial LBM), Palabos, waLBerla, XFOIL.
L07 — Earth's Thermostat (Bayesian calibration + UQ on real data)
- Live data, cached in
data/: NASA GISTEMP global anomaly; IPCC AR6 effective radiative forcing (https://raw.githubusercontent.com/IPCC-WG1/Chapter-7/main/data_output/AR6_ERF_1750-2019.csv, look for SSP forcing files in the same repo); NOAA Mauna Loa CO₂. - Two-layer energy-balance model (Held 2010 / Geoffroy 2013) with an aerosol-forcing scale factor. emcee posterior over climate feedback, heat uptake, heat capacities, aerosol scale and noise. Derive ECS/TCR posteriors and compare them with the IPCC AR6 likely range.
- SALib Sobol indices for 2100 warming. Scenario projections (SSP-like) as posterior-predictive fan charts.
- Verify: synthetic-truth test (generate data from known parameters, check that MCMC recovers them).
- Tools: FaIR, MAGICC, CMIP6 ESMs (CESM, E3SM), PyMC/Stan, Dakota, UQLab, OpenTURNS.
L08 — Generative Bracket (3D FEM + topology optimisation)
- 3D linear-elasticity FEM on a voxel hex mesh (scikit-fem preferred, hand-assembled KE acceptable if faster). SIMP penalisation, density filter, optimality-criteria update, and pyamg-preconditioned CG.
- A visually striking load case, e.g. a 3D cantilever/bridge or a simplified GE jet-engine bracket (the GrabCAD 2013 challenge).
- Render with PyVista: isosurface of the density, smoothed, with a turntable MP4/GIF, an
optimisation-evolution animation, and von Mises stress on the final part. Export
.stl(3D printable). - Verify: cantilever tip deflection vs Euler–Bernoulli/Timoshenko within a few %, volume constraint met, and compliance history converging.
- Tools: Ansys Mechanical, Abaqus, COMSOL, Altair OptiStruct/Inspire, nTop, Fusion 360 generative design, FEniCS, deal.II, ParaView.
L09 — Orbital Traffic Control (real catalog + interactive 3D)
- Pull the real active-satellite catalog from CelesTrak and cache it. Python does the analytics:
vectorised
sgp4propagation, conjunction screening (coarse KD-tree sieve per time step, then refine the time of closest approach), a ranked conjunction list (TCA, miss distance, relative speed, and a Pc estimate with the covariance assumption stated). - Kessler Monte Carlo: a shell-based LEO debris source–sink model with the NASA standard breakup model for fragment counts, atmospheric-drag decay by altitude, and launch/disposal-compliance scenarios. 200-year projections with spread.
- Web 3D (
index.html, single file, opens by double-click): Three.js globe (Blue Marble texture via jsDelivrthree-globeexample img), with thousands of satellites as instanced points propagated live in the browser by satellite.js (CDN). Time controls, click a satellite for its info and orbit trail, and a conjunction panel that flies to each close approach. Data goes in a classic<script src="data.js">(not fetch), so it works fromfile://. - Verify: Python sgp4 vs satellite.js agree to <1 km on sample objects, and conjunction refinement is checked on a synthetic pair with a known minimum distance.
- Tools: Ansys STK, NASA GMAT, Orekit, poliastro, CesiumJS, Space-Track, LeoLabs, NASA ORDEM/LEGEND, ESA DELTA/MASTER.
L10 — Solar Stinger: a Georgia Tech digital twin (flagship, built by the orchestrator)
Question: Could the Stinger bus fleet run on sunshine harvested from campus rooftops, and
which semiconductor should the panels be made from?
- Campus: OSM buildings (Overpass) with heights, roads and green space, projected to local metres.
- Buses: real Stinger GPS/ETA polls (March 2026, from Stinger Proj). Route polylines and stops come
from the bus.gatech.edu API. The pipeline smooths trajectories into speed/acceleration drive cycles.
A longitudinal-dynamics energy model (rolling, aero, grade, inertia, regen, HVAC) gives kWh/mi per route.
- Sun: PVGIS TMY via pvlib.iotools, pvlib solar position and POA transposition. Building shading
uses per-roof-point horizon profiles ray-marched on a height raster (Numba), which also gives sky-view factor.
- Materials: Materials Project semiconductors from the Band Gap GNN dataset. The Shockley–Queisser
detailed-balance limit is computed from the ASTM G173 AM1.5G spectrum (bundled in pvlib), then
screened for earth-abundance and non-toxicity. HTEM sputtered-film thickness data gives a
thin-film absorption reality check.
- System: SimPy fleet-day simulation with SOC and charger queues, plus an 8760-h energy balance
with storage sizing.
- 3D twin UI: Three.js with extruded buildings coloured by PV yield, a live sun with shadow
mapping, buses replaying real GPS coloured by SOC, a material picker, a crystal viewer and charts.