Shock Response Spectrum (structures/loads/shock-response-spectrum)
Use when the task is computing the shock response spectrum (SRS) of a
transient base acceleration pulse for equipment shock qualification:
each SDOF oscillator on the frequency grid responds to the pulse at a
fixed damping, the peak pseudo acceleration of every oscillator forms
the spectrum, and the frequency of the maximum response shows which
structural or equipment mode the shock amplifies most. This leaf
implements the standard SRS model in pure Python, stdlib only, with
RK4 time integration of the oscillator equation. It pairs with
structures/loads/random-vibration-analysis, the steady-state counterpart
that covers the random PSD regime of the same SDOF equipment model, and
sits alongside structures/loads/gust-maneuver-loads in the loads pack.
The transient shock regime is this leaf's claim; the DO-160 test
condition planner for equipment lives in avionics/do160/
environmental-qualification and consumes these response levels.
Domain quick reference
- Quality factor and damping: zeta = 1/(2Q), Q_DEFAULT = 10.0.
- Base-excited SDOF oscillator (relative displacement x, natural
frequency wn = 2pifn in rad/s):
x_ddot + 2zetawnx_dot + wn^2x = -a_base(t).
- Peak pseudo acceleration: wn^2 * max|x(t)|, the SRS ordinate. For a
lightly damped oscillator this equals the peak absolute acceleration
of the oscillator mass within the Q-squared correction.
- Half-sine pulse: a(t) = Asin(pit/T) for 0 <= t < T, else 0.
- Decaying-sine pulse: a(t) = Asin(2pifdt)exp(-t/tau) for t >= 0
with fd = 1/T and tau default 3T.
- Integration: fixed-step RK4 from rest with dt = min(1/(fn50),
T/200) per oscillator. Each oscillator is integrated over its
excitation support: the pulse end T for the half-sine, and the time
the envelope Aexp(-t/tau) first falls below 1% of A (ENVELOPE_FLOOR)
for the decaying sine. The SRS ordinate is the peak of the forced
response over that support. The ideal half-sine leaves a residual
base velocity; the low-frequency free ring after the pulse is an
artifact of that idealization and is excluded, which keeps the
classical half-sine SRS shape (see the worked example anchors).
- Output: one dict per grid frequency {freq_hz, peak_ms2, peak_g}; the
curve maximum carries the amplifying frequency.
- Units: amplitude m/s2 (G = 9.80665), durations s, frequencies Hz,
ordinates m/s2 and g. SI throughout.
- FAR 25 frames the equipment and structure dynamic loads context; the
relations above are standard engineering methodology, summary-only.
Workflow
- State the shock input: pulse type (half-sine or decaying-sine),
amplitude A in m/s2 (or g times 9.80665), pulse duration T in s,
and the quality factor Q (default 10). For the decaying sine set
the decay time tau (default 3*T).
- Choose the SRS frequency grid: the natural frequencies of the
equipment modes under evaluation, typically a log-spaced band
around the pulse content, for example [5..1000] Hz for a 10 ms
pulse.
- Call srs_curve with the pulse and grid. The module computes
zeta = 1/(2Q), integrates each oscillator with RK4 at
dt = min(1/(fn*50), T/200) over the excitation support, and returns
the curve list of {freq_hz, peak_ms2, peak_g}.
- Call max_response on the curve for the peak pseudo acceleration and
its amplifying frequency, the shock qualification driver.
- Read individual ordinates off the curve: the low-frequency branch
(oscillators slow relative to the pulse) rises from near zero, the
amplification peak sits where the pulse spectrum meets the
resonance, and the high-frequency branch approaches the input
amplitude as the oscillator follows the base.
- Confirm the deterministic checks with the contract test
scripts/test_shock_response_spectrum.py.
Worked example
Half-sine pulse, amplitude 10 g (98.0665 m/s2), duration 10 ms, Q 10,
grid [5, 10, 20, 30, 40, 50, 60, 80, 100, 150, 200, 300, 500, 1000] Hz:
- At 5 Hz the oscillator is slow relative to the pulse: 0.309 g,
consistent with the anchor 0.31 g.
- The curve maximum sits at 80 Hz with 16.462 g, consistent with the
anchor 16.5 g near 80 Hz.
- At 1000 Hz the oscillator follows the base: 10.111 g, consistent
with the anchor 10.1 g high-frequency asymptote.
- Shape: 20 Hz gives 4.367 g and 500 Hz gives 10.427 g, both below the
80 Hz peak, so the amplification band is monotone up to and down
from the maximum.
Intermediate half-sine ordinates (g): 10 Hz 1.202, 30 Hz 8.459, 40 Hz
12.222, 50 Hz 14.557, 60 Hz 15.678, 100 Hz 16.201, 150 Hz 14.192,
200 Hz 12.110, 300 Hz 11.009.
Decaying-sine case, amplitude 10 g, T 10 ms, tau 30 ms, Q 10: the
pulse content sits at fd = 1/T = 100 Hz and the curve maximum is
35.780 g at exactly 100 Hz, the resonance of the decaying transient.
Pitfalls
- Reading the low-frequency branch as zero response: oscillators
slow relative to the pulse still respond (0.309 g at 5 Hz for the
worked 10 g pulse); the SRS rises from near zero only at very low
frequency.
- Expecting the maximum at the pulse's own frequency: for the
half-sine the amplification peak sits where the pulse spectrum
meets the resonance (80 Hz for a 10 ms pulse, not 1/T = 100 Hz);
the decaying-sine maximum, in contrast, sits at 1/T exactly.
- Trusting the free ring after a half-sine: the ideal pulse leaves a
residual base velocity whose low-frequency ring is an artifact of
the idealization and is excluded from the support, keeping the
classical SRS shape.
- Choosing a grid that skips the peak: the maximum and its
amplifying frequency only appear if a grid point lands in the
amplification band, so the grid must cover the equipment modes and
the pulse content.
- Confusing pseudo acceleration with peak absolute acceleration:
the SRS ordinate is wn^2 * max|x(t)|, which equals the peak
absolute acceleration only within the Q-squared correction for
light damping.
- Feeding non-physical pulse inputs: amplitude or duration at or
below zero, q <= 0.5, empty grids, frequencies at or below zero,
unknown pulse types and non-positive decay tau all raise
ValueError.
Verification
- Confirm the half-sine worked example values above: 0.309 g at 5 Hz
(within 10% and within 0.05 g of the 0.31 g anchor), maximum at
80 Hz at 16.462 g (frequency in [60, 100] Hz, peak within 10% of the
16.5 g anchor), 10.111 g at 1000 Hz (within 10% of the 10.1 g
anchor), and the monotonic checks peak(20 Hz) < peak(80 Hz) and
peak(500 Hz) < peak(80 Hz).
- Confirm the decaying-sine maximum is finite and sits at 100 Hz,
inside [70, 130] Hz.
- Confirm srs_curve output is deterministic: repeated calls return
identical curves (no RNG anywhere).
- Confirm ValueError rejection: amplitude <= 0, pulse duration <= 0,
quality factor q <= 0.5, empty frequency grid, any natural frequency
<= 0, unknown pulse type, non-positive decay tau for the decaying
sine, and non-positive wn, out-of-range zeta, non-positive total
time or time step in sdof_peak.
- Run the contract test offline: python3
scripts/test_shock_response_spectrum.py (32 tests, deterministic).
Related leaves
- structures/loads/random-vibration-analysis: the steady-state
counterpart for the random regime of the same SDOF equipment
response model; together the two leaves cover the shock and
vibration qualification regimes.
- structures/loads/gust-maneuver-loads: the loads pack context for
airframe limit loads from discrete gust and maneuver conditions.
- avionics/do160/environmental-qualification: test condition planning
for equipment environmental qualification, the consumer of these
response levels.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline):
python3 scripts/test_shock_response_spectrum.py
The test covers the analytic base acceleration histories (half-sine
support and decaying-sine envelope), the half-sine worked example
anchors (5 Hz 0.31 g, maximum near 80 Hz at 16.5 g, 1000 Hz 10.1 g,
monotonic shape), the exact deterministic module values, the decaying-
sine maximum near 1/T with its finite resonant peak, determinism of
repeated runs, the g to m/s2 unit consistency of the curve dicts, the
direct sdof_peak round trip, the effect of damping on the resonant
peak, and ValueError rejection of every non-physical input.
Compliance
- Standards referenced, not reproduced: FAR 25 frames the dynamic
loads and equipment context; the SDOF response relations above are
standard engineering methodology, summary-only per standards-map.yaml
(far-25 reference-only).
- compliance: STANDARDS-REF, gated: false.
1---2name: shock-response-spectrum3description: Use when you must compute the shock response spectrum (SRS) of a transient base acceleration pulse for shock qualification of equipment: single-degree-of-freedom oscillator peak response over a frequency grid at fixed damping, RK4 integration of the oscillator equation x_ddot + 2*zeta*wn*x_dot + wn^2*x = -a_base(t), half-sine pulse A*sin(pi*t/T) and decaying-sine pulse A*sin(2*pi*fd*t)*exp(-t/tau) support, peak pseudo acceleration wn^2 times peak relative displacement, the SRS curve as frequency to peak response in m/s2 and in g, and the maximum response with its amplifying frequency. Produces the SRS curve points, the peak response, and the frequency of the maximum that gate shock qualification assessment of equipment. Trigger: shock response spectrum, SRS, transient shock response, half sine pulse, base acceleration, pseudo acceleration, oscillator peak response, shock qualification, amplified frequency.4license: Apache-2.05---67# Shock Response Spectrum (structures/loads/shock-response-spectrum)89Use when the task is computing the shock response spectrum (SRS) of a10transient base acceleration pulse for equipment shock qualification:11each SDOF oscillator on the frequency grid responds to the pulse at a12fixed damping, the peak pseudo acceleration of every oscillator forms13the spectrum, and the frequency of the maximum response shows which14structural or equipment mode the shock amplifies most. This leaf15implements the standard SRS model in pure Python, stdlib only, with16RK4 time integration of the oscillator equation. It pairs with17structures/loads/random-vibration-analysis, the steady-state counterpart18that covers the random PSD regime of the same SDOF equipment model, and19sits alongside structures/loads/gust-maneuver-loads in the loads pack.20The transient shock regime is this leaf's claim; the DO-160 test21condition planner for equipment lives in avionics/do160/22environmental-qualification and consumes these response levels.2324## Domain quick reference2526- Quality factor and damping: zeta = 1/(2Q), Q_DEFAULT = 10.0.27- Base-excited SDOF oscillator (relative displacement x, natural28 frequency wn = 2*pi*fn in rad/s):29 x_ddot + 2*zeta*wn*x_dot + wn^2*x = -a_base(t).30- Peak pseudo acceleration: wn^2 * max|x(t)|, the SRS ordinate. For a31 lightly damped oscillator this equals the peak absolute acceleration32 of the oscillator mass within the Q-squared correction.33- Half-sine pulse: a(t) = A*sin(pi*t/T) for 0 <= t < T, else 0.34- Decaying-sine pulse: a(t) = A*sin(2*pi*fd*t)*exp(-t/tau) for t >= 035 with fd = 1/T and tau default 3*T.36- Integration: fixed-step RK4 from rest with dt = min(1/(fn*50),37 T/200) per oscillator. Each oscillator is integrated over its38 excitation support: the pulse end T for the half-sine, and the time39 the envelope A*exp(-t/tau) first falls below 1% of A (ENVELOPE_FLOOR)40 for the decaying sine. The SRS ordinate is the peak of the forced41 response over that support. The ideal half-sine leaves a residual42 base velocity; the low-frequency free ring after the pulse is an43 artifact of that idealization and is excluded, which keeps the44 classical half-sine SRS shape (see the worked example anchors).45- Output: one dict per grid frequency {freq_hz, peak_ms2, peak_g}; the46 curve maximum carries the amplifying frequency.47- Units: amplitude m/s2 (G = 9.80665), durations s, frequencies Hz,48 ordinates m/s2 and g. SI throughout.49- FAR 25 frames the equipment and structure dynamic loads context; the50 relations above are standard engineering methodology, summary-only.5152## Workflow53541. State the shock input: pulse type (half-sine or decaying-sine),55 amplitude A in m/s2 (or g times 9.80665), pulse duration T in s,56 and the quality factor Q (default 10). For the decaying sine set57 the decay time tau (default 3*T).582. Choose the SRS frequency grid: the natural frequencies of the59 equipment modes under evaluation, typically a log-spaced band60 around the pulse content, for example [5..1000] Hz for a 10 ms61 pulse.623. Call srs_curve with the pulse and grid. The module computes63 zeta = 1/(2Q), integrates each oscillator with RK4 at64 dt = min(1/(fn*50), T/200) over the excitation support, and returns65 the curve list of {freq_hz, peak_ms2, peak_g}.664. Call max_response on the curve for the peak pseudo acceleration and67 its amplifying frequency, the shock qualification driver.685. Read individual ordinates off the curve: the low-frequency branch69 (oscillators slow relative to the pulse) rises from near zero, the70 amplification peak sits where the pulse spectrum meets the71 resonance, and the high-frequency branch approaches the input72 amplitude as the oscillator follows the base.736. Confirm the deterministic checks with the contract test74 scripts/test_shock_response_spectrum.py.7576## Worked example7778Half-sine pulse, amplitude 10 g (98.0665 m/s2), duration 10 ms, Q 10,79grid [5, 10, 20, 30, 40, 50, 60, 80, 100, 150, 200, 300, 500, 1000] Hz:8081- At 5 Hz the oscillator is slow relative to the pulse: 0.309 g,82 consistent with the anchor 0.31 g.83- The curve maximum sits at 80 Hz with 16.462 g, consistent with the84 anchor 16.5 g near 80 Hz.85- At 1000 Hz the oscillator follows the base: 10.111 g, consistent86 with the anchor 10.1 g high-frequency asymptote.87- Shape: 20 Hz gives 4.367 g and 500 Hz gives 10.427 g, both below the88 80 Hz peak, so the amplification band is monotone up to and down89 from the maximum.9091Intermediate half-sine ordinates (g): 10 Hz 1.202, 30 Hz 8.459, 40 Hz9212.222, 50 Hz 14.557, 60 Hz 15.678, 100 Hz 16.201, 150 Hz 14.192,93200 Hz 12.110, 300 Hz 11.009.9495Decaying-sine case, amplitude 10 g, T 10 ms, tau 30 ms, Q 10: the96pulse content sits at fd = 1/T = 100 Hz and the curve maximum is9735.780 g at exactly 100 Hz, the resonance of the decaying transient.9899100## Pitfalls101102- Reading the low-frequency branch as zero response: oscillators103 slow relative to the pulse still respond (0.309 g at 5 Hz for the104 worked 10 g pulse); the SRS rises from near zero only at very low105 frequency.106- Expecting the maximum at the pulse's own frequency: for the107 half-sine the amplification peak sits where the pulse spectrum108 meets the resonance (80 Hz for a 10 ms pulse, not 1/T = 100 Hz);109 the decaying-sine maximum, in contrast, sits at 1/T exactly.110- Trusting the free ring after a half-sine: the ideal pulse leaves a111 residual base velocity whose low-frequency ring is an artifact of112 the idealization and is excluded from the support, keeping the113 classical SRS shape.114- Choosing a grid that skips the peak: the maximum and its115 amplifying frequency only appear if a grid point lands in the116 amplification band, so the grid must cover the equipment modes and117 the pulse content.118- Confusing pseudo acceleration with peak absolute acceleration:119 the SRS ordinate is wn^2 * max|x(t)|, which equals the peak120 absolute acceleration only within the Q-squared correction for121 light damping.122- Feeding non-physical pulse inputs: amplitude or duration at or123 below zero, q <= 0.5, empty grids, frequencies at or below zero,124 unknown pulse types and non-positive decay tau all raise125 ValueError.126## Verification127128- Confirm the half-sine worked example values above: 0.309 g at 5 Hz129 (within 10% and within 0.05 g of the 0.31 g anchor), maximum at130 80 Hz at 16.462 g (frequency in [60, 100] Hz, peak within 10% of the131 16.5 g anchor), 10.111 g at 1000 Hz (within 10% of the 10.1 g132 anchor), and the monotonic checks peak(20 Hz) < peak(80 Hz) and133 peak(500 Hz) < peak(80 Hz).134- Confirm the decaying-sine maximum is finite and sits at 100 Hz,135 inside [70, 130] Hz.136- Confirm srs_curve output is deterministic: repeated calls return137 identical curves (no RNG anywhere).138- Confirm ValueError rejection: amplitude <= 0, pulse duration <= 0,139 quality factor q <= 0.5, empty frequency grid, any natural frequency140 <= 0, unknown pulse type, non-positive decay tau for the decaying141 sine, and non-positive wn, out-of-range zeta, non-positive total142 time or time step in sdof_peak.143- Run the contract test offline: python3144 scripts/test_shock_response_spectrum.py (32 tests, deterministic).145146## Related leaves147148- structures/loads/random-vibration-analysis: the steady-state149 counterpart for the random regime of the same SDOF equipment150 response model; together the two leaves cover the shock and151 vibration qualification regimes.152- structures/loads/gust-maneuver-loads: the loads pack context for153 airframe limit loads from discrete gust and maneuver conditions.154- avionics/do160/environmental-qualification: test condition planning155 for equipment environmental qualification, the consumer of these156 response levels.157158## Behavior contract (gate 3)159160Run the deterministic contract test (stdlib unittest, offline):161162 python3 scripts/test_shock_response_spectrum.py163164The test covers the analytic base acceleration histories (half-sine165support and decaying-sine envelope), the half-sine worked example166anchors (5 Hz 0.31 g, maximum near 80 Hz at 16.5 g, 1000 Hz 10.1 g,167monotonic shape), the exact deterministic module values, the decaying-168sine maximum near 1/T with its finite resonant peak, determinism of169repeated runs, the g to m/s2 unit consistency of the curve dicts, the170direct sdof_peak round trip, the effect of damping on the resonant171peak, and ValueError rejection of every non-physical input.172173## Compliance174175- Standards referenced, not reproduced: FAR 25 frames the dynamic176 loads and equipment context; the SDOF response relations above are177 standard engineering methodology, summary-only per standards-map.yaml178 (far-25 reference-only).179- compliance: STANDARDS-REF, gated: false.