-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
1 changed file
with
361 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |