Damped Harmonic Oscillator

Nov 21, 2022

Or: Implementing a damped spring model in 16 lines of code.

Governing Equation:

Zero-input response f(t) = 0

Solve

Exponential ansatz:

Plugging in gives

Two solutions x_1(t) = \left(A_1 e^{\sigma t}\right) e^{-\bar{\lambda}t} and x_2(t) = \left(A_2e^{-\sigma t}\right) e^{-\bar{\lambda}t}

To solve for A_1 and A_2 we need two initial condition x(t_o)=x_o and \dot{x}(t_o)=\dot{x}_o , i.e.

Let t_o=0 , then all the exponentials are 1, so it simplifies to

Altogether it becomes

Which can be rearranged to

Click to see derivation

One can see that e^{-\bar{\lambda}t} contributes uniform decay and anchors the characteristic timescale of the system.

Now define the odd and even exponential factors as

Thus, the most general form for all cases can be expressed as

Sample Lua Implementation

function sprung_response(t,d,v,k,c,m)
   local decay = c/2/m
   local omega = math.sqrt(k/m)
   local resid = decay*decay-omega*omega
   local scale = math.sqrt(math.abs(resid))
   local T1,T0 = t , 1
   if resid<0 then
      T1,T0 = math.sin( scale*t)/scale , math.cos( scale*t)
   elseif resid>0 then
      T1,T0 = math.sinh(scale*t)/scale , math.cosh(scale*t)
   end
   local dissipation = math.exp(-decay*t)
   local evolved_pos = dissipation*( d*(T0+T1*decay) + v*(   T1      ) )
   local evolved_vel = dissipation*( d*(-T1*omega^2) + v*(T0-T1*decay) )
  return evolved_pos , evolved_vel
end

Damping Cases

The e^{-\bar{\lambda}t} factor is the global dissipator, and \tau_1, \tau_0 are the first- and zeroth-order time-integrators.

If all system parameters (m,c,k) are real, then \sigma can be either real, imaginary, or zero, giving rise to the three well-known over/under/critically damped classifications.

Substituting each cases’ \sigma into T_n evaluates to the following:

Critically Damped (\sigma = 0):

Special Case: Unimpeded \mu = \omega = 0 \Rightarrow \bar{\lambda} = 0

Underdamped (\sigma = i\kappa \textnormal{ , } \kappa \in \mathbb{R}):

Special Case: Undamped \mu = 0 \Rightarrow \bar{\lambda} = 0, \kappa = \omega

Overdamped (\sigma = \alpha \textnormal{ , } \alpha \in \mathbb{R}):

Special Case: Unsprung \omega = 0 \Rightarrow \bar{\lambda} = \alpha = \frac{\mu}{2}