Note
Go to the end to download the full example code.
SDOF transient — step-load response#
A single-DOF mass-spring-damper subjected to a step load shows off the
Newmark-β transient integrator in
solve_transient(). We integrate
for long enough to watch the underdamped oscillation settle toward the
new static equilibrium, then compare the result to the textbook
second-order response.
from __future__ import annotations
import matplotlib.pyplot as plt
import numpy as np
import scipy.sparse as sp
from femorph_solver.solvers.transient import solve_transient
Set up a 1-DOF oscillator#
Step load at t = 0#
Newmark-β with the default unconditionally-stable parameters#
Analytical comparison#
Plot Newmark vs analytic#
fig, ax = plt.subplots(figsize=(6, 3))
ax.plot(result.time, u_fs, label="Newmark-β", color="#1f77b4")
ax.plot(result.time, u_exact, "--", label="analytic", color="black", linewidth=0.8)
ax.axhline(
u_static,
color="red",
linestyle=":",
linewidth=0.8,
label=f"static limit u_s = {u_static:.4f}",
)
ax.set_xlabel("time [s]")
ax.set_ylabel("displacement [m]")
ax.set_title("SDOF step-load response (ζ = 0.05)")
ax.legend(loc="lower right")
ax.grid(True, alpha=0.3)
fig.tight_layout()
err = np.max(np.abs(u_fs - u_exact)) / u_static
print(f"max relative error vs analytic: {err:.3e}")

max relative error vs analytic: 2.423e-05
Total running time of the script: (0 minutes 0.270 seconds)