One tower. One earthquake. Four different grounds underneath it.
The site that shook least at the surface — 0.89 g where another reached 1.62 g — is the one that destroyed the tower, and it did it at the lowest bedrock intensity of the four. Nothing about the tower changed between runs.
python -m pip install -r requirements.txt
python reproduce.py # ~2 minutes
python reproduce.py --no-plot # numbers only
python reproduce.py --convergence # also re-run every site at dt/2
The intuitive model is that soft ground is dangerous because it amplifies more. That model is wrong in an interesting way, and the disagreement is the whole point.
The ground is not a spring under the building. It is a filter in front of
it. A soil column of depth H over bedrock, with shear-wave velocity Vs,
has its own period
Ts = 4 H / Vs
and for vertically propagating SH waves through one damped layer with damping
ratio xi (Kramer, Geotechnical Earthquake Engineering, eq. 7.14):
|H(f)| = 1 / sqrt( cos²(k) + (xi·k)² ), k = 2π f H / Vs
The bedrock record is passed through that filter, and the tower is shaken with whatever comes out. A site does not simply turn the earthquake up — it decides which frequencies get turned up.
A first version of this study put compliant springs under the base instead (Gazetas / ASCE 41 surface-footing stiffnesses). It validated cleanly and it was useless: the largest period change across all four site classes was 4%, because a 40 m building on a 10 m footprint is tens of times more flexible than the soil under it. Four grounds, one answer, no result. That model was also the wrong physics for the story — Mexico City 1985 is not a footing problem.
Everything except Vs.
| tower | 8 storeys × 5 m, 10 m wide, X-braced steel frame |
| steel | 2.00 m³ exactly, thin-walled circular tube, D/t = 20 |
| mass | 20 t per floor + self weight, identical every run |
| damping | 3% Rayleigh, two-point calibrated |
| input | one seeded bedrock record, 0.2–10 Hz, identical every run |
| ground | 30 m of soil over bedrock — Vs is the only variable |
Rock is the reference and gets no soil column at all. Giving it a 30 m
column was a real bug in this file's history: at Vs = 1200 m/s that puts the
column's resonance at 10 Hz, inside the excitation band, and rock came out as
the most amplifying of the four sites.
One intensity proves nothing — it only tells you what happened at the intensity you picked. So the same record is turned up step by step and run as one continuous motion (incremental dynamic analysis):
0.05 g → 0.10 g → 0.18 g → 0.30 g → 0.45 g at the bedrock, 4 s each
Frequency content is identical at every rung. The only thing climbing the staircase is intensity, so "it fell at 0.18 g" is a threshold, not an anecdote.
| ground | Vs |
Ts |
Ts/T |
amplification | surface PGA | broke at |
|---|---|---|---|---|---|---|
| ROCK | 1200 m/s | — | — | 1.00× | 0.45 g | held |
| FIRM SOIL | 500 m/s | 0.24 s | 0.24 | 3.61× | 1.62 g | 0.30 g |
| SOFT SOIL | 250 m/s | 0.48 s | 0.48 | 3.17× | 1.43 g | 0.45 g |
| SOFT CLAY | 120 m/s | 1.00 s | 1.01 | 1.98× | 0.89 g | 0.18 g |
Read the last two columns against each other. Soft clay amplified the least of the three soil sites and delivered the weakest surface shaking — and it broke the tower at a bedrock intensity where every other site was still untouched, at less than half the level firm soil needed.
The tower's sway period is 0.994 s. The clay's is 1.00 s. The ground and the building agree on the beat, so every cycle arrives in step with the last one and the motion accumulates instead of averaging out. Firm soil hit the tower nearly twice as hard and the tower did not care, because 0.24 s is not a period it responds to.
Peak ground acceleration is the wrong number to rank sites by. It says nothing about which frequencies the ground carries, and that is what decides whether a particular building is in trouble.
This is the mechanism behind the 1985 Michoacán earthquake, 400 km from Mexico City: the lake-bed clay under the city has a period near 2 s, and it emptied the mid-rise buildings whose periods matched, while shorter and taller ones nearby stood.
results/ground_transfer.png plots the four filters with the tower's frequency
marked. The clay curve is not the tallest one. It is the one with a peak under
the marker.
Closed forms and a code formula — never the previous run's numbers.
| check | how |
|---|---|
| transfer function peak | at Ts the cosine term vanishes, so |H| = 1/(xi·π/2) = 12.732 exactly |
| rock is the reference | its output must equal the bedrock record bit for bit |
| one earthquake | the same record array reaches all four sites |
| sway period | vs ASCE 7-16 eq. 12.8-7, Ta = 0.0731·H^0.75 = 1.163 s |
| the headline | the first to break must also be the gentlest at the surface |
| the mechanism | and it must be the one whose Ts is nearest the tower's T |
The last two gates exist so the file cannot quietly stop supporting its own conclusion. If a change made "harder shaking breaks things" true again, they fail.
The reported period is the sway mode, not eigenvalue #1. A braced frame has repeated local panel modes that can sit below the sway mode and carry almost no mass; quoting one of those as "the building's period" is a real and easy mistake. The mode is selected by modal mass participation — the one reported here carries 65%.
--convergence re-runs every site at dt/2. The record is interpolated,
not regenerated: regenerating at dt/2 with the same seed produces a different
realisation of the noise, and the resulting disagreement is a different
earthquake, not a discretisation error. (That mistake produced a "41% error"
here once; interpolating the same record turned it into 0.03%.)
ground dt dt/2 drift dt drift dt/2
ROCK held held 0.00475 0.00473
FIRM SOIL 0.30 g 0.45 g 0.02500 0.02506
SOFT SOIL 0.45 g 0.45 g 0.02599 0.02548
SOFT CLAY 0.18 g 0.18 g 0.02503 0.02501
Survivors converge on drift. Firm soil moves one rung, 0.30 g → 0.45 g. It has to be reported that way: the collapse level is a discrete rung, so a case sitting near a threshold lands on either side of it, and peak drift cannot smooth that over because the collapse criterion caps it at 0.025 by construction. What does not move is the order — soft clay first at both timesteps, at the same level. The conclusion depends only on the order.
- 1D SH-wave amplification, linear. Real soft clay softens and damps more as
strain grows, which lowers
Tsand reduces amplification during strong shaking. Equivalent-linear or nonlinear site response would change the numbers. It would not remove the resonance — it moves where it sits. - One 30 m column depth for every site.
TsandVsare therefore not independent here. A shallower clay basin has a shorter site period and would target a different building. - Synthetic band-limited record, not a recorded accelerogram. One record, one seed. Real IDA uses a suite, and the collapse levels would come out as a distribution rather than a single rung.
- 2D frame, linear elastic members removed at first yield or Euler buckling. No plastic hinging, no strain hardening, no P-Δ. Members leave the model when utilisation reaches 1.0.
- Collapse is declared at 2.5% storey drift or loss of half the members — a criterion, not a simulation of the collapse itself.
reproduce.py everything, one file, no classes
requirements.txt
results/ written on run: results.json, ground_transfer.png
If something in here is wrong, please open an issue — that is the most useful thing you can send back.