Skip to content

Commit

Permalink
50 / 60 : add Duffing oscillator
Browse files Browse the repository at this point in the history
help from Gemini
  • Loading branch information
beachdweller committed May 22, 2024
1 parent 184d87e commit d936337
Showing 1 changed file with 361 additions and 0 deletions.
361 changes: 361 additions & 0 deletions 50_ode/60_Duffing_Oscillator.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,361 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "5be0b46c",
"metadata": {},
"outputs": [],
"source": [
"# This cell is for the Google Colaboratory\n",
"# https://stackoverflow.com/a/63519730\n",
"if 'google.colab' in str(get_ipython()):\n",
" path_py = '/content/nmisp_py'\n",
"\n",
" import os\n",
" if not os.path.exists(path_py):\n",
" import subprocess\n",
" subprocess.run(\n",
" ('git', 'clone', 'https://github.com/kangwonlee/nmisp_py')\n",
" )\n",
" assert os.path.exists(path_py)\n",
"\n",
" import sys\n",
" sys.path.insert(0, path_py)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "59f65864",
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "80961b0e",
"metadata": {},
"outputs": [],
"source": [
"import ode_solver\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "71f66d5c",
"metadata": {},
"source": [
"# Duffing Oscillator<br>더핑 진동자\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "44252d39",
"metadata": {},
"source": [
"The Duffing oscillator is a simple model of a mass-spring system with a nonlinear spring. The nonlinearity arises from the fact that the spring's restoring force is not proportional to its displacement. The Duffing oscillator is described by the following second-order differential equation:\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "73714a65",
"metadata": {},
"source": [
"$$\n",
"m\\frac{d^2}{dt^2}x(t) + c\\frac{d}{dt}x(t) + k x(t) + \\alpha x^3 = F cos \\omega t\n",
"$$\n"
]
},
{
"cell_type": "markdown",
"id": "13ddf9ca",
"metadata": {},
"source": [
"| symbol<br>기호 | unit<br>단위 | description<br>설명 |\n",
"|:-------------:|:-------------:|-------------|\n",
"| $t$ | sec | time |\n",
"| $x(t)$ | m | the displacement of the mass from its equilibrium position |\n",
"| $\\frac{d}{dt}x(t)$ | m/s | the velocity of the mass. |\n",
"| $\\frac{d^2}{dt^2}x(t)$ | m/s/s | the acceleration of the mass. |\n",
"| $m$ | kg | the mass of the object attached to the spring. |\n",
"| $c$ | N/(m/s) | the damping coefficient. |\n",
"| $k$ | N/m | the linear stiffness coefficient of the spring. |\n",
"| $alpha$ | $N/{m^3}$ | the nonlinear stiffness coefficient of the spring. |\n",
"| $F$ | N | the amplitude of the external driving force. |\n",
"| $\\omega$ | rad/sec | the angular frequency of the external driving force. |\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "dc1c07ad",
"metadata": {},
"source": [
"## The Nonlinear Term\n",
"\n",
"The key feature of the Duffing equation is the term $\\alpha x^3$. This term introduces a cubic nonlinearity into the system. When the displacement $x$ is small, this term is negligible, and the system behaves like a simple harmonic oscillator. However, as the displacement increases, the nonlinear term becomes significant, leading to deviations from simple harmonic motion.\n",
"\n",
"## Physical Interpretation\n",
"\n",
"The Duffing oscillator can model a variety of physical systems, including:\n",
"\n",
"* Mechanical Systems: A mass-spring system where the spring's stiffness changes as it is stretched or compressed.\n",
"* Electrical Circuits: An RLC circuit with a nonlinear inductor or capacitor.\n",
"* Structural Systems: A beam or plate with large deflections, where the geometric nonlinearities become important.\n",
"\n",
"## Chaotic Behavior\n",
"\n",
"For certain combinations of parameters (m, c, k, alpha, F, omega), the Duffing oscillator can exhibit chaotic behavior. This means that the system's response is extremely sensitive to initial conditions, and its long-term behavior is unpredictable.\n",
"\n",
"## Numerical Solution\n",
"\n",
"The Duffing equation is a nonlinear differential equation, and in most cases, it does not have an analytical solution. Therefore, numerical methods, such as the Runge-Kutta methods, are essential for simulating the behavior of the Duffing oscillator."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ac5a05da",
"metadata": {},
"outputs": [],
"source": [
"m_kg = 1.0\n",
"c_Npmps = 0.25\n",
"k_Npm = 1\n",
"alpha_Npm3 = 0.1\n",
"F_N = 0.5\n",
"omega_rps = 1.5\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5b22c988",
"metadata": {},
"outputs": [],
"source": [
"def get_Duffing_oscillator_slope(\n",
" m_kg:float, c_Npmps:float, k_Npm:float, alpha_Npm3:float,\n",
" F_N:float, omega_rps:float):\n",
" '''\n",
" Return a closure calculating slope function \n",
" 기울기 함수를 계산하는 내포 함수를 반환\n",
" '''\n",
"\n",
" neg_m_inv = (-1.0) / m_kg\n",
" neg_c_m = c_Npmps * neg_m_inv\n",
" neg_k_m = k_Npm * neg_m_inv\n",
" neg_alpha_m = alpha_Npm3 * neg_m_inv\n",
" F_m = F_N / m_kg\n",
"\n",
" def f(t:float, xv:np.ndarray,):\n",
" '''\n",
" Calculate slope vector of the Duffing Oscillator\n",
" 더핑 연산자의 기울기 벡터를 계산\n",
" '''\n",
" x, dxdt = xv\n",
" dx_dt = dxdt\n",
" da_dt = neg_k_m * x + neg_c_m * dxdt + neg_alpha_m * x**3 + F_m * np.cos(omega_rps * t)\n",
" \n",
" return np.array((dx_dt, da_dt))\n",
"\n",
" return f\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "459468e2",
"metadata": {},
"outputs": [],
"source": [
"def sim_1dof_vib(\n",
" slope, x_0:np.ndarray=np.array((0.0, 0.0)),\n",
" t_end=10.0, figsize=(14, 14),\n",
" delta_t_sec=1e-3,\n",
" ):\n",
" '''\n",
" Simulate a one degree of freedom vibration system\n",
" 1자유도 진동계 시뮬레이션\n",
" '''\n",
" t_array = np.arange(0, t_end, delta_t_sec)\n",
" \n",
" t_out, x_out = ode_solver.rk4(slope, t_array, x_0)\n",
" x_out = np.array(x_out)\n",
" _, axs = plt.subplots(2, 1, figsize=figsize)\n",
"\n",
" for k in range(2):\n",
" axs[k].plot(t_out, x_out[:, k])\n",
" axs[k].grid(True)\n",
" axs[k].set_xlabel('t(sec)')\n",
" axs[0].set_ylabel('$x(t)$')\n",
" axs[1].set_ylabel(r'$\\frac{d}{dt}x(t)$')\n",
"\n",
" return axs\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "98fa7e2c",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"F_N, omega_rps = 0.1, 1\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ce7dd8ed-ca27-468c-9146-a51d2b210f10",
"metadata": {},
"outputs": [],
"source": [
"F_N, omega_rps = 0.5, 1.5\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "314b8c22-e3da-4e74-82a6-60c4e2603766",
"metadata": {},
"outputs": [],
"source": [
"F_N, omega_rps = 1.0, 0.5\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7bd5b1c6-c768-4333-902e-bb1513cd6d2e",
"metadata": {},
"outputs": [],
"source": [
"F_N, omega_rps = 1.0, 1.0\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "37a5f4aa",
"metadata": {},
"outputs": [],
"source": [
"F_N, omega_rps = 1.0, 2.0\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e08df8a1-15a8-4434-9c98-75dae9e10614",
"metadata": {},
"outputs": [],
"source": [
"F_N, omega_rps = 1.5, 0.8\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "db8b566f-b12d-44c6-9d66-7ad974bacd62",
"metadata": {},
"outputs": [],
"source": [
"F_N, omega_rps = 1.5, 1.2\n",
"\n",
"Duffing_oscillator = get_Duffing_oscillator_slope(m_kg, c_Npmps, k_Npm, alpha_Npm3, F_N, omega_rps)\n",
"ax = sim_1dof_vib(\n",
" Duffing_oscillator,\n",
" np.array((0, 0))\n",
")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b922b424-8cb1-4900-8227-987626495e6c",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

0 comments on commit d936337

Please sign in to comment.