Seismic Response Spectrum Calculator Back
Interactive Tool — Seismic Engineering

Seismic Response Spectrum Calculator

Interactively compute design response spectra (simplified model based on Japan Building Code / ASCE/SEI 7). Adjust damping ratio and site class to compare Sa, Sv, and Sd spectra in real time.

Ground Motion & Site Conditions
Damping Ratio ζ
Primary Damping Ratio
%
Steel: 2%, RC: 5%, Isolated: 20%
Spectrum Type
Structure Natural Period
Natural Period T
s
Low-rise RC: 0.1–0.3 s / High-rise: 3–5 s
Sa = — m/s²
Results
Natural Period T [s]
Sa [m/s²]
Sv [m/s]
Sd [m]
Response Spectrum (Multiple Damping Ratios) Acceleration Spectrum Sa [m/s²]
Spec
Building Vibration Animation — Seismic Response Visualization

Theory Notes — How to Read a Response Spectrum

A response spectrum plots the maximum response of single-degree-of-freedom (SDOF) systems with varying natural periods, all subjected to the same ground motion. Engineers read the spectral value at their structure's natural period T and compute the equivalent static force as $F = S_a \times m$.

$$S_a(T) \xrightarrow{\div \omega^2}S_d(T) = \frac{T^2}{4\pi^2}S_a(T), \quad S_v(T) = \frac{T}{2\pi}S_a(T)$$

Higher damping reduces spectral values. Standard design damping ratios are 2% for steel structures and 5% for reinforced concrete. Seismically isolated structures use an equivalent damping ratio of 20–30% to substantially reduce the seismic response.

The design spectrum in this tool is a simplified model based on Japan's standard acceleration response spectrum (use code-specified or site-specific spectra for actual design).

What is a Seismic Response Spectrum?

🙋
What exactly is a "response spectrum"? I see it's used in earthquake engineering, but I'm not sure what the graph is actually telling me.
🎓
Basically, it's a graph that predicts how hard an earthquake will shake structures of different stiffnesses. Think of it as a cheat sheet for engineers. Instead of simulating every single building for every quake, we use this. For instance, the vertical axis (Spectral Acceleration, Sa) tells you the maximum force a simple, one-story building will feel if its natural period (on the horizontal axis) matches the earthquake's shaking rhythm. Try moving the "Natural Period" slider above—you'll see the predicted force change dramatically.
🙋
Wait, really? So the "Natural Period" is like the building's natural sway speed? And what does the "Damping Ratio" slider do?
🎓
Exactly! A short, stiff building (like a concrete tower) has a short period (e.g., 0.3 seconds), while a tall, flexible one (like a steel skyscraper) has a long period (e.g., 3 seconds). The damping ratio is like the building's built-in shock absorbers. A common case is 5% for standard buildings. When you increase damping in the simulator, you'll see the spectral values drop because more energy is dissipated, just like better shocks in a car give a smoother ride over bumps.
🙋
Okay, that makes sense. But the simulator shows three curves: Sa, Sv, and Sd. Why do we need three, and how are they connected?
🎓
Great question! They're just different views of the same seismic demand, tailored for different design calculations. Sa (acceleration) is for calculating inertial forces. Sv (velocity) relates to energy input. Sd (displacement) tells you how much the building needs to flex to survive. They are mathematically linked through the natural period. The simulator calculates them in real time from the Sa spectrum using the formulas you see. A key insight: for very long periods, the force (Sa) might be low, but the required sway (Sd) can be huge, which is critical for designing expansion joints!

Physical Model & Key Equations

The core model is a Single-Degree-of-Freedom (SDOF) system—a mass on a spring with a damper—subjected to a base acceleration from an earthquake. The maximum response of this system, for a given natural period and damping, defines a point on the spectrum. Building codes provide a smoothed, simplified design spectrum based on many real earthquake records.

$$ S_a(T, \zeta) = \text{Design Spectrum Function (from JBC or ASCE 7)}$$

Where $S_a$ is the Spectral Acceleration (m/s² or g), $T$ is the Natural Period (seconds), and $\zeta$ is the Damping Ratio (e.g., 0.05 for 5%). This is the primary output from the code model, which you control with the sliders.

Once Sa is known, the associated Spectral Velocity (Sv) and Spectral Displacement (Sd) are derived using the relationships for a simple oscillator. These conversions assume the response is dominated by the fundamental mode, which is a standard simplification for design.

$$ S_d(T) = \frac{T^2}{4\pi^2}S_a(T), \quad S_v(T) = \frac{T}{2\pi} S_a(T) $$

Here, $S_d$ is Spectral Displacement (meters) and $S_v$ is Spectral Velocity (m/s). Notice how Sd grows with the square of the period—this is why long-period structures need large gaps to avoid pounding during an earthquake.

Real-World Applications

Building Code Compliance: This is the direct application. Structural engineers use spectra from national codes (like the Japan Building Code or ASCE 7 shown here) as the minimum seismic demand. They calculate their building's period, read the Sa value, and use it to determine the total lateral force the structure must resist.

Seismic Isolation Design: For base-isolated buildings or bridges, engineers aim to shift the structure's period into a region of low spectral acceleration. The response spectrum visually shows the "valley" of lower forces at longer periods, allowing designers to target and verify this beneficial shift.

Equipment and Component Qualification: It's not just for buildings. The spectra are used to specify the shaking test requirements for critical non-structural components like emergency generators, piping systems, or data center servers to ensure they remain operational after a quake.

Performance-Based Earthquake Engineering (PBEE): Advanced analysis uses site-specific spectra to evaluate if a building will meet performance objectives like "Immediate Occupancy" or "Collapse Prevention." Engineers compare the structure's capacity curve against the demand spectrum to predict damage.

Common Misconceptions and Points to Note

When you start using this tool, there are a few points you should be aware of. First, understand that "the design spectrum is not an absolute answer." The smooth curve produced by the tool is a "representative value" derived from statistical processing of numerous earthquake records. For instance, if you input an actual seismic wave for calculation, it's not uncommon to see peaks that significantly exceed this design curve. Therefore, in practice, you design by adding safety factors, such as the "required horizontal load-bearing capacity," on top of this design value.

Next, understand the limitations of the "single-degree-of-freedom" model. This tool models a building as a single mass and spring, but actual buildings are multi-degree-of-freedom systems where second and third higher-order modes also affect the response. For example, in slender tower-like structures, the response of the second mode (swaying in an inverted S-shape) cannot be ignored, not just the first mode (the slowest sway). Use the tool's results strictly as a guideline for the primary mode.

Finally, beware of pitfalls in parameter settings. Particularly, the "damping ratio" is highly sensitive. While 5% is common for reinforced concrete structures, it changes to 2% for steel structures and 10-20% for seismic isolation structures. If you carelessly leave this at the default value, you might end up with a response evaluation completely different from what you intended. Make it a habit to always set a value appropriate for the type of structure you're analyzing.

// Seismic building animation (function() { const el = document.getElementById('seismicAnimCanvas'); const ctx = el.getContext('2d'); let simT = 0; const NFLOORS = 5; function getParams() { const T = parseFloat(document.getElementById('sl-T').value) || 0.5; const z = (parseFloat(document.getElementById('sl-z').value) || 5) / 100; const omega = 2 * Math.PI / T; return { T, z, omega }; } // Generate pseudo-random ground motion signal function groundAccel(t) { // Superposition of several frequency components to mimic earthquake return ( 0.5 * Math.sin(2 * Math.PI * 1.2 * t) + 0.3 * Math.sin(2 * Math.PI * 2.5 * t + 1.1) + 0.4 * Math.sin(2 * Math.PI * 0.7 * t + 2.3) + 0.2 * Math.sin(2 * Math.PI * 3.1 * t + 0.5) + 0.15 * Math.sin(2 * Math.PI * 4.5 * t + 1.8) ) * 0.5; } // Simple Duhamel response state (velocity, displacement) let respV = 0, respD = 0; let prevAccel = 0; const dt = 1/60; function resize() { const dpr = window.devicePixelRatio || 1; const w = el.parentElement.clientWidth - 48; const H = Math.round(Math.min(w * 0.5, 320)); if (Math.abs(el.width - w * dpr) > 2 || el.height !== H * dpr) { el.width = w * dpr; el.height = H * dpr; el.style.height = H + 'px'; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); } return { W: w, H }; } function frame() { const { W, H } = resize(); const { T, z, omega } = getParams(); simT += dt; // Compute ground acceleration const ag = groundAccel(simT); // Newmark-beta integration (beta=0.25, gamma=0.5 — avg. accel.) const c = 2 * z * omega; const k = omega * omega; const force = -ag - c * respV - k * respD; const newA = force; respD = respD + dt * respV + dt * dt * (0.25 * newA + 0.25 * prevAccel); respV = respV + dt * (0.5 * newA + 0.5 * prevAccel); prevAccel = newA; ctx.clearRect(0, 0, W, H); ctx.fillStyle = '#f8f9fa'; ctx.fillRect(0, 0, W, H); const groundY = H - 30; const bldW = Math.min(W * 0.25, 100); const floorH = Math.min((groundY - 40) / NFLOORS, 45); const bldH = floorH * NFLOORS; const bldX = W / 2 - bldW / 2; // Ground strip const groundShake = ag * 18; ctx.fillStyle = '#001F3F'; ctx.fillRect(0, groundY, W, H - groundY); // Ground motion indicator ctx.strokeStyle = '#e17055'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(W - 100, groundY - 4); ctx.lineTo(W - 100 + groundShake * 8, groundY - 4); ctx.stroke(); ctx.fillStyle = '#6c757d'; ctx.font = '9px Roboto Mono'; ctx.textAlign = 'right'; ctx.fillText(`Ground acceleration: ${(ag * 9.8).toFixed(2)} m/s²`, W - 10, groundY - 8); // Cap visual displacement const maxVisDisp = bldH * 0.15; const disp0 = Math.max(-maxVisDisp, Math.min(maxVisDisp, respD * 80)); // Draw building floors with linear drift (larger sway at top) for (let f = 0; f < NFLOORS; f++) { const frac = (f + 1) / NFLOORS; // 0 at base, 1 at top const floorDisp = disp0 * frac + groundShake; const fy = groundY - (f + 1) * floorH; const fx = bldX + floorDisp; // Floor slab const g = Math.round(60 + (1 - frac) * 60); ctx.fillStyle = `rgb(0,${g},127)`; ctx.fillRect(fx, fy, bldW, 6); // Column (connecting to next floor) if (f < NFLOORS - 1) { const nextFrac = (f + 2) / NFLOORS; const nextDisp = disp0 * nextFrac + groundShake; const nextFy = groundY - (f + 2) * floorH; ctx.strokeStyle = `rgba(0,123,255,0.7)`; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(fx + 8, fy + 6); ctx.lineTo(bldX + nextDisp + 8, nextFy + 6); ctx.moveTo(fx + bldW - 8, fy + 6); ctx.lineTo(bldX + nextDisp + bldW - 8, nextFy + 6); ctx.stroke(); } // Floor label ctx.fillStyle = 'rgba(255,255,255,0.7)'; ctx.font = '9px Roboto Mono'; ctx.textAlign = 'left'; ctx.fillText(`F${f+1}`, fx + bldW + 4, fy + 10); } // Base (ground floor connection) ctx.fillStyle = '#007BFF'; ctx.fillRect(bldX + groundShake - 2, groundY - floorH, bldW + 4, 6); // Roof marker and displacement label const roofDisp = disp0 + groundShake; const roofY = groundY - bldH; ctx.fillStyle = '#e17055'; ctx.beginPath(); ctx.arc(bldX + bldW/2 + roofDisp, roofY - 8, 4, 0, Math.PI * 2); ctx.fill(); // Response labels ctx.fillStyle = '#001F3F'; ctx.font = 'bold 11px Roboto Mono, monospace'; ctx.textAlign = 'left'; ctx.fillText(`T = ${T.toFixed(2)} s`, 10, 22); ctx.fillText(`ζ = ${(z*100).toFixed(0)}%`, 10, 36); ctx.fillStyle = Math.abs(respD) > 0.2 ? '#d63031' : '#007BFF'; ctx.fillText(`u = ${(respD * 100).toFixed(1)} cm`, 10, 50); requestAnimationFrame(frame); } frame(); })();