Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
nmap2024
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Egenolf, Thilo
nmap2024
Commits
07f43eec
Unverified
Commit
07f43eec
authored
7 months ago
by
tegenolf
Committed by
GitHub
7 months ago
Browse files
Options
Downloads
Patches
Plain Diff
Add files via upload
parent
aa6aa372
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
week2/nmap2.ipynb
+889
-0
889 additions, 0 deletions
week2/nmap2.ipynb
with
889 additions
and
0 deletions
week2/nmap2.ipynb
0 → 100644
+
889
−
0
View file @
07f43eec
{
"cells": [
{
"cell_type": "markdown",
"id": "guided-sense",
"metadata": {},
"source": [
"<h1 style=\"text-align: center; vertical-align: middle;\">Numerical Methods in Accelerator Physics</h1>\n",
"<h2 style=\"text-align: center; vertical-align: middle;\">Python examples -- Week 2</h2>"
]
},
{
"cell_type": "markdown",
"id": "instrumental-stylus",
"metadata": {},
"source": [
"<h2>Run this first!</h2>\n",
"\n",
"Imports and modules:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "universal-freedom",
"metadata": {},
"outputs": [],
"source": [
"from config2 import *\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"id": "conventional-header",
"metadata": {},
"source": [
"<h3>Pendulum parameters, Hamiltonian</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cellular-passport",
"metadata": {},
"outputs": [],
"source": [
"m = 1 # point mass\n",
"g = 1 # magnitude of the gravitational field\n",
"L = 1 # length of the rod"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "worthy-bridges",
"metadata": {},
"outputs": [],
"source": [
"### Values of hamiltonian for comparison with theory\n",
"TH, PP = np.meshgrid(np.linspace(-np.pi * 1.1, np.pi * 1.1, 100), \n",
" np.linspace(-3, 3, 100))\n",
"\n",
"HH = hamiltonian(TH, PP)"
]
},
{
"cell_type": "markdown",
"id": "reverse-algebra",
"metadata": {},
"source": [
"<h3>Euler-Cromer Method (slide 10)</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "broke-edward",
"metadata": {},
"outputs": [],
"source": [
"def solve_eulercromer(theta, p, dt=0.1):\n",
" ### from Euler:\n",
" theta_next = theta + dt * p / (m * L*L)\n",
" p_next = p - dt * m * g * L * np.sin(theta_next)\n",
" return (theta_next, p_next)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "pediatric-prompt",
"metadata": {},
"outputs": [],
"source": [
"### Initial values:\n",
"theta_ini = -1.1\n",
"p_ini = 0\n",
"n_steps = 100"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "italic-muscle",
"metadata": {},
"outputs": [],
"source": [
"results_eulercromer = np.zeros((n_steps, 2), dtype=np.float32)\n",
"results_eulercromer[0] = (theta_ini, p_ini)\n",
"\n",
"for k in range(1, n_steps):\n",
" results_eulercromer[k] = solve_eulercromer(*results_eulercromer[k - 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "leading-liberal",
"metadata": {},
"outputs": [],
"source": [
"### Explicit Euler for comparison:\n",
"results_euler = np.zeros((n_steps, 2), dtype=np.float32) # for comparison\n",
"results_euler[0] = (theta_ini, p_ini)\n",
"\n",
"for k in range(1, n_steps):\n",
" results_euler[k] = solve_euler(*results_euler[k - 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "posted-irrigation",
"metadata": {},
"outputs": [],
"source": [
"plt.contour(TH, PP, HH, levels=10, linestyles='--', linewidths=1)\n",
"\n",
"plt.plot(results_euler[:, 0], results_euler[:, 1], c='b', label='Euler')\n",
"plt.plot(results_eulercromer[:, 0], results_eulercromer[:, 1], c='c', label='Euler-Cromer')\n",
"\n",
"plt.legend(bbox_to_anchor=(1.05, 1))\n",
"set_axes()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "scientific-comparison",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(\n",
" hamiltonian(results_euler[:, 0], results_euler[:, 1]), \n",
" c='b', label='Euler')\n",
"plt.plot(\n",
" hamiltonian(results_eulercromer[:, 0], results_eulercromer[:, 1]), \n",
" c='c', label='Euler-Cromer')\n",
"plt.axhline(hamiltonian(theta_ini, p_ini), c='r', label='theory')\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel(r'$\\mathcal{H}(\\theta, p)$')\n",
"plt.legend(bbox_to_anchor=(1.05, 1));"
]
},
{
"cell_type": "markdown",
"id": "fitted-occasions",
"metadata": {},
"source": [
"<h3>Leapfrog Method (slide 12)</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "lovely-silver",
"metadata": {},
"outputs": [],
"source": [
"def solve_leapfrog(theta, p, dt=0.1):\n",
" theta_half = theta + dt / 2 * p / (m * L*L)\n",
" p_next = p - dt * m * g * L * np.sin(theta_half)\n",
" theta_next = theta_half + dt / 2 * p_next / (m * L*L)\n",
" return (theta_next, p_next)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "civil-tunnel",
"metadata": {},
"outputs": [],
"source": [
"results_leapfrog = np.zeros((n_steps, 2), dtype=np.float32)\n",
"results_leapfrog[0] = (theta_ini, p_ini)\n",
"\n",
"for k in range(1, n_steps):\n",
" results_leapfrog[k] = solve_leapfrog(*results_leapfrog[k - 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "determined-consortium",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(\n",
" hamiltonian(results_euler[:, 0], results_euler[:, 1]), \n",
" c='b', label='Euler, $\\mathcal{O}(\\Delta t^2)$')\n",
"plt.plot(\n",
" hamiltonian(results_eulercromer[:, 0], results_eulercromer[:, 1]), \n",
" c='c', label='Euler-Cromer, $\\mathcal{O}(\\Delta t^2)$')\n",
"plt.plot(\n",
" hamiltonian(results_leapfrog[:, 0], results_leapfrog[:, 1]), \n",
" c='k', label='leapfrog, $\\mathcal{O}(\\Delta t^3)$')\n",
"plt.axhline(hamiltonian(theta_ini, p_ini), c='r', lw=2, label='theory')\n",
"\n",
"plt.ylim(0.5, 0.6)\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel(r'$\\mathcal{H}(\\theta, p)$')\n",
"plt.legend(bbox_to_anchor=(1.05, 1));"
]
},
{
"cell_type": "markdown",
"id": "worst-bikini",
"metadata": {},
"source": [
"<h3>Collection of pendulums (slides 14 & 17)</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "respiratory-chaos",
"metadata": {},
"outputs": [],
"source": [
"theta_grid = np.linspace(-0.5 * np.pi, 0.5 * np.pi, 21)\n",
"p_grid = np.linspace(-0.3, 0.3, 5)\n",
"\n",
"thetas, ps = np.meshgrid(theta_grid, p_grid)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "smart-school",
"metadata": {},
"outputs": [],
"source": [
"N = len(theta_grid) * len(p_grid)\n",
"N"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "australian-baker",
"metadata": {},
"outputs": [],
"source": [
"plt.scatter(thetas, ps, c='b', marker='.')\n",
"\n",
"plot_hamiltonian()"
]
},
{
"cell_type": "markdown",
"id": "electrical-union",
"metadata": {},
"source": [
"<h3>Time evolution</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "sixth-plain",
"metadata": {},
"outputs": [],
"source": [
"n_steps = 100"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "weird-lawyer",
"metadata": {},
"outputs": [],
"source": [
"results_thetas = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_thetas[0] = thetas.flatten()\n",
"\n",
"results_ps = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_ps[0] = ps.flatten()\n",
"\n",
"for k in range(1, n_steps):\n",
" results_thetas[k], results_ps[k] = solve_leapfrog(results_thetas[k - 1], results_ps[k - 1])"
]
},
{
"cell_type": "markdown",
"id": "special-canadian",
"metadata": {},
"source": [
"<h3>Observations of centroids (slide 19)</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "indonesian-redhead",
"metadata": {},
"outputs": [],
"source": [
"centroids_theta = 1/N * np.sum(results_thetas, axis=1)\n",
"centroids_p = 1/N * np.sum(results_ps, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "outside-wonder",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(centroids_theta, label=r'$\\langle\\theta\\rangle$')\n",
"plt.plot(centroids_p, label=r'$\\langle p\\rangle$')\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('Centroid amplitude')\n",
"plt.legend(bbox_to_anchor=(1.05, 1));"
]
},
{
"cell_type": "markdown",
"id": "forbidden-merit",
"metadata": {},
"source": [
"<h3>Observations of RMS size</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "continental-preliminary",
"metadata": {},
"outputs": [],
"source": [
"var_theta = 1/N * np.sum(results_thetas * results_thetas, axis=1)\n",
"var_p = 1/N * np.sum(results_ps * results_ps, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "metropolitan-princess",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(var_theta, label=r'$\\langle\\theta^2\\rangle$')\n",
"plt.plot(var_p, label=r'$\\langle p^2\\rangle$')\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('Variance')\n",
"plt.legend(bbox_to_anchor=(1.05, 1));"
]
},
{
"cell_type": "markdown",
"id": "quick-humor",
"metadata": {},
"source": [
"<h3>Distribution evolution over time</h3> "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "homeless-deployment",
"metadata": {},
"outputs": [],
"source": [
"k = 18\n",
"\n",
"plt.scatter(results_thetas[k], results_ps[k], c='b', marker='.')\n",
"\n",
"plot_hamiltonian()"
]
},
{
"cell_type": "markdown",
"id": "lined-glory",
"metadata": {},
"source": [
"<h3>RMS emittance evolution (slide 20) $$\\epsilon = \\sqrt{\\langle \\theta^2\\rangle \\langle p^2\\rangle - \\langle \\theta\\,p\\rangle^2}$$</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "welsh-effort",
"metadata": {},
"outputs": [],
"source": [
"def emittance(theta, p):\n",
" N = len(theta)\n",
" \n",
" # subtract centroids\n",
" theta = theta - 1/N * np.sum(theta)\n",
" p = p - 1/N * np.sum(p)\n",
" \n",
" # compute Σ matrix entries\n",
" theta_sq = 1/N * np.sum(theta * theta)\n",
" p_sq = 1/N * np.sum(p * p)\n",
" crossterm = 1/N * np.sum(theta * p)\n",
" \n",
" # determinant of Σ matrix\n",
" epsilon = np.sqrt(theta_sq * p_sq - crossterm * crossterm)\n",
" return epsilon"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "impaired-russian",
"metadata": {},
"outputs": [],
"source": [
"results_emit = np.zeros(n_steps, dtype=np.float32)\n",
"\n",
"for k in range(n_steps):\n",
" results_emit[k] = emittance(results_thetas[k], results_ps[k])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "enhanced-dairy",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(results_emit)\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('RMS emittance $\\epsilon$');"
]
},
{
"cell_type": "markdown",
"id": "taken-survival",
"metadata": {},
"source": [
"<h3>Exercise: Linearized pendulum motion</h3>"
]
},
{
"cell_type": "markdown",
"id": "thorough-failing",
"metadata": {},
"source": [
"$$\\left.\\begin{matrix}\\,\n",
" \\theta_{k+1/2} &=& \\theta_k + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k}}{mL^2} \\\\\n",
" p_{k+1} &=& p_k - \\Delta t\\cdot m g L\\sin\\theta_{k+1/2} \\\\\n",
" \\theta_{k+1} &=& \\theta_{k+1/2} + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k+1}}{mL^2}\n",
"\\end{matrix}\\right\\} \\quad \\stackrel{\\text{Taylor}}{\\Longrightarrow} \\quad \\left\\{\\begin{matrix}\\,\n",
" \\theta_{k+1/2} &=& \\theta_k + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k}}{mL^2} \\\\\n",
" p_{k+1} &=& p_k - \\Delta t\\cdot m g L\\color{red}{\\left(\\theta_{k+1/2}-\\frac{\\theta_{k+1/2}^3}{3!}+\\frac{\\theta_{k+1/2}^5}{5!}-\\frac{\\theta_{k+1/2}^7}{7!}+...\\right)} \\\\\n",
" \\theta_{k+1} &=& \\theta_{k+1/2} + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k+1}}{mL^2}\n",
"\\end{matrix}\\right.$$ "
]
},
{
"cell_type": "markdown",
"id": "quiet-updating",
"metadata": {},
"source": [
"$$\\left.\\begin{matrix}\\,\n",
" \\theta_{k+1/2} &=& \\theta_k + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k}}{mL^2} \\\\\n",
" p_{k+1} &=& p_k - \\Delta t\\cdot m g L\\sin\\theta_{k+1/2} \\\\\n",
" \\theta_{k+1} &=& \\theta_{k+1/2} + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k+1}}{mL^2}\n",
"\\end{matrix}\\right\\} \\quad \\stackrel{\\text{First order}}{\\Longrightarrow} \\quad \\left\\{\\begin{matrix}\\,\n",
" \\theta_{k+1/2} &=& \\theta_k + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k}}{mL^2} \\\\\n",
" p_{k+1} &=& p_k - \\Delta t\\cdot m g L\\cdot\\color{red}{\\theta_{k+1/2}} \\\\\n",
" \\theta_{k+1} &=& \\theta_{k+1/2} + {\\cfrac{\\Delta t}{2}}\\cdot\\cfrac{p_{k+1}}{mL^2}\n",
"\\end{matrix}\\right.$$ "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "living-spyware",
"metadata": {},
"outputs": [],
"source": [
"def solve_leapfrog_linear(theta, p, dt=dt):\n",
" theta_half = theta + dt / 2 * p / (m * L*L)\n",
" p_next = p - dt * m * g * L * theta_half\n",
" theta_next = theta_half + dt / 2 * p_next / (m * L*L)\n",
" return (theta_next, p_next)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bored-commodity",
"metadata": {},
"outputs": [],
"source": [
"results_thetas_linear = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_thetas_linear[0] = thetas.flatten()\n",
"\n",
"results_ps_linear = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_ps_linear[0] = ps.flatten()\n",
"\n",
"for k in range(1, n_steps):\n",
" results_thetas_linear[k], results_ps_linear[k] = solve_leapfrog_linear(results_thetas_linear[k - 1], results_ps_linear[k - 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "quantitative-programmer",
"metadata": {},
"outputs": [],
"source": [
"var_theta_linear = 1/N * np.sum(results_thetas_linear * results_thetas_linear, axis=1)\n",
"var_p_linear = 1/N * np.sum(results_ps_linear * results_ps_linear, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "three-better",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"plt.plot(var_theta_linear, label=r'$\\langle\\theta^2\\rangle$')\n",
"plt.plot(var_p_linear, label=r'$\\langle p^2\\rangle$')\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('Variance')\n",
"plt.legend(bbox_to_anchor=(1.05, 1));"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "statutory-thriller",
"metadata": {},
"outputs": [],
"source": [
"results_emit_linear = np.zeros(n_steps, dtype=np.float32)\n",
"\n",
"for k in range(n_steps):\n",
" results_emit_linear[k] = emittance(results_thetas_linear[k], results_ps_linear[k])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "equipped-campus",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(results_emit_linear)\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('RMS emittance $\\epsilon$');"
]
},
{
"cell_type": "markdown",
"id": "breeding-invalid",
"metadata": {},
"source": [
"<h3>Centroid offset in (original) pendulum</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "chemical-aquarium",
"metadata": {},
"outputs": [],
"source": [
"results_thetas2 = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_thetas2[0] = thetas.flatten() + 0.1 * np.pi\n",
"\n",
"results_ps2 = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_ps2[0] = ps.flatten()\n",
"\n",
"for k in range(1, n_steps):\n",
" results_thetas2[k], results_ps2[k] = solve_leapfrog(results_thetas2[k - 1], results_ps2[k - 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "greek-brunswick",
"metadata": {},
"outputs": [],
"source": [
"centroids_theta2 = 1/N * np.sum(results_thetas2, axis=1)\n",
"centroids_p2 = 1/N * np.sum(results_ps2, axis=1)\n",
"\n",
"plt.plot(centroids_theta, label=r'no offset: $\\langle\\theta\\rangle$')\n",
"plt.plot(centroids_theta2, label=r'with offset: $\\langle\\theta\\rangle$')\n",
"plt.plot(centroids_p2, label=r'with offset: $\\langle p\\rangle$')\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('Centroid amplitude')\n",
"plt.legend(bbox_to_anchor=(1.05, 1));"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "voluntary-transparency",
"metadata": {},
"outputs": [],
"source": [
"results_emit2 = np.zeros(n_steps, dtype=np.float32)\n",
"\n",
"for k in range(n_steps):\n",
" results_emit2[k] = emittance(results_thetas2[k], results_ps2[k])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "legitimate-objective",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(results_emit, label='no offset')\n",
"plt.plot(results_emit2, label='with offset')\n",
"\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel('RMS emittance $\\epsilon$')\n",
"plt.legend();"
]
},
{
"cell_type": "markdown",
"id": "rough-funds",
"metadata": {},
"source": [
"<h3>Long-term behaviour</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "canadian-section",
"metadata": {},
"outputs": [],
"source": [
"n_steps = 3000"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "primary-lightning",
"metadata": {},
"outputs": [],
"source": [
"results_thetas3 = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_thetas3[0] = thetas.flatten() + 0.1 * np.pi\n",
"\n",
"results_ps3 = np.zeros((n_steps, N), dtype=np.float32)\n",
"results_ps3[0] = ps.flatten()\n",
"\n",
"for k in range(1, n_steps):\n",
" results_thetas3[k], results_ps3[k] = solve_leapfrog(results_thetas3[k - 1], results_ps3[k - 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ordinary-advertising",
"metadata": {},
"outputs": [],
"source": [
"plot_macro_evolution(results_thetas3, results_ps3);"
]
},
{
"cell_type": "markdown",
"id": "figured-attendance",
"metadata": {},
"source": [
"<h3>Employ FFT on pendulum motion (slide 31)</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "coordinated-boring",
"metadata": {},
"outputs": [],
"source": [
"## Observe two particles:\n",
"i1 = N // 2 - 10\n",
"i2 = N // 2\n",
"\n",
"plt.plot(results_thetas3[:, i1])\n",
"plt.plot(results_thetas3[:, i2])\n",
"plt.xlabel('Steps $k$')\n",
"plt.ylabel(r'$\\theta$');"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "supported-involvement",
"metadata": {},
"outputs": [],
"source": [
"## Obtain the FFT spectra for both:\n",
"spec1 = np.fft.rfft(results_thetas3[:, i1])\n",
"spec2 = np.fft.rfft(results_thetas3[:, i2])\n",
"\n",
"freq = np.fft.rfftfreq(n_steps)\n",
"\n",
"## Frequency of linearized system\n",
"freq_theory = np.sqrt(1 / 1) * 0.1 / (2 * np.pi)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "weird-retrieval",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(freq, np.abs(spec1))\n",
"plt.plot(freq, np.abs(spec2))\n",
"plt.axvline(freq_theory, c='k', zorder=0, ls='--')\n",
"plt.xlim(0, 0.05)\n",
"plt.xlabel('Phase advance per $\\Delta t$ [$2\\pi$]')\n",
"plt.ylabel('FFT spectrum')\n",
"plt.yscale('log');"
]
},
{
"cell_type": "markdown",
"id": "desirable-venice",
"metadata": {},
"source": [
"<h3>Frequency vs Amplitude</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "textile-commons",
"metadata": {},
"outputs": [],
"source": [
"specs = np.abs(np.fft.rfft(results_thetas3.T))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "standing-there",
"metadata": {},
"outputs": [],
"source": [
"max_ids = np.argmax(specs, axis=1)\n",
"amplitudes = np.max(specs, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "developed-input",
"metadata": {},
"outputs": [],
"source": [
"i_range = np.where(ps.flatten() == 0)[0]\n",
"\n",
"plt.scatter(results_thetas3[0][i_range], freq[max_ids][i_range])\n",
"\n",
"plt.axhline(freq_theory, c='k', ls='--', zorder=0)\n",
"plt.xticks([-np.pi/2, 0, np.pi/2, np.pi], [r\"$-\\pi/2$\", \"0\", r\"$\\pi/2$\", r\"$\\pi$\"])\n",
"plt.xlabel(r'Initial $\\theta$ ($p=0$)')\n",
"plt.ylabel('Phase advance / \\n' + r'integration step $\\Delta t$ [$2\\pi$]');\n",
"plt.ylim(0.012, 0.0165);"
]
},
{
"cell_type": "markdown",
"id": "unavailable-scenario",
"metadata": {},
"source": [
"<h3>NAFF Algorithm (slide 32)</h3>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "present-helena",
"metadata": {},
"outputs": [],
"source": [
"import PyNAFF"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "global-distributor",
"metadata": {},
"outputs": [],
"source": [
"freqs_naff = []\n",
"\n",
"for signal in results_thetas3.T[i_range]:\n",
" freq_naff = PyNAFF.naff(signal, turns=n_steps - 1, nterms=1)\n",
" try:\n",
" freq_naff = freq_naff[0, 1]\n",
" except IndexError:\n",
" freq_naff = 0\n",
" freqs_naff += [freq_naff]\n",
"\n",
"freqs_naff = np.array(freqs_naff)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "statutory-union",
"metadata": {},
"outputs": [],
"source": [
"plt.scatter(results_thetas3[0][i_range], freq[max_ids][i_range])\n",
"plt.plot(results_thetas3[0][i_range], freqs_naff, c='r', marker='.')\n",
"\n",
"plt.axhline(freq_theory, c='k', ls='--', zorder=0)\n",
"plt.xticks([-np.pi/2, 0, np.pi/2, np.pi], [r\"$-\\pi/2$\", \"0\", r\"$\\pi/2$\", r\"$\\pi$\"])\n",
"plt.xlabel(r'Initial $\\theta$ ($p=0$)')\n",
"plt.ylabel('Phase advance / \\n' + r'integration step $\\Delta t$ [$2\\pi$]');"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "inappropriate-listening",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(results_thetas3[0][i_range], 100 * (freq[max_ids][i_range] - freqs_naff) / freqs_naff)\n",
"plt.xlabel(r'Initial $\\theta$ ($p=0$)')\n",
"plt.ylabel('Error (FFT - NAFF) / NAFF ' + r'[%]');"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
%% Cell type:markdown id:guided-sense tags:
<h1
style=
"text-align: center; vertical-align: middle;"
>
Numerical Methods in Accelerator Physics
</h1>
<h2
style=
"text-align: center; vertical-align: middle;"
>
Python examples -- Week 2
</h2>
%% Cell type:markdown id:instrumental-stylus tags:
<h2>
Run this first!
</h2>
Imports and modules:
%% Cell type:code id:universal-freedom tags:
```
python
from
config2
import
*
%
matplotlib
inline
```
%% Cell type:markdown id:conventional-header tags:
<h3>
Pendulum parameters, Hamiltonian
</h3>
%% Cell type:code id:cellular-passport tags:
```
python
m
=
1
# point mass
g
=
1
# magnitude of the gravitational field
L
=
1
# length of the rod
```
%% Cell type:code id:worthy-bridges tags:
```
python
### Values of hamiltonian for comparison with theory
TH
,
PP
=
np
.
meshgrid
(
np
.
linspace
(
-
np
.
pi
*
1.1
,
np
.
pi
*
1.1
,
100
),
np
.
linspace
(
-
3
,
3
,
100
))
HH
=
hamiltonian
(
TH
,
PP
)
```
%% Cell type:markdown id:reverse-algebra tags:
<h3>
Euler-Cromer Method (slide 10)
</h3>
%% Cell type:code id:broke-edward tags:
```
python
def
solve_eulercromer
(
theta
,
p
,
dt
=
0.1
):
### from Euler:
theta_next
=
theta
+
dt
*
p
/
(
m
*
L
*
L
)
p_next
=
p
-
dt
*
m
*
g
*
L
*
np
.
sin
(
theta_next
)
return
(
theta_next
,
p_next
)
```
%% Cell type:code id:pediatric-prompt tags:
```
python
### Initial values:
theta_ini
=
-
1.1
p_ini
=
0
n_steps
=
100
```
%% Cell type:code id:italic-muscle tags:
```
python
results_eulercromer
=
np
.
zeros
((
n_steps
,
2
),
dtype
=
np
.
float32
)
results_eulercromer
[
0
]
=
(
theta_ini
,
p_ini
)
for
k
in
range
(
1
,
n_steps
):
results_eulercromer
[
k
]
=
solve_eulercromer
(
*
results_eulercromer
[
k
-
1
])
```
%% Cell type:code id:leading-liberal tags:
```
python
### Explicit Euler for comparison:
results_euler
=
np
.
zeros
((
n_steps
,
2
),
dtype
=
np
.
float32
)
# for comparison
results_euler
[
0
]
=
(
theta_ini
,
p_ini
)
for
k
in
range
(
1
,
n_steps
):
results_euler
[
k
]
=
solve_euler
(
*
results_euler
[
k
-
1
])
```
%% Cell type:code id:posted-irrigation tags:
```
python
plt
.
contour
(
TH
,
PP
,
HH
,
levels
=
10
,
linestyles
=
'
--
'
,
linewidths
=
1
)
plt
.
plot
(
results_euler
[:,
0
],
results_euler
[:,
1
],
c
=
'
b
'
,
label
=
'
Euler
'
)
plt
.
plot
(
results_eulercromer
[:,
0
],
results_eulercromer
[:,
1
],
c
=
'
c
'
,
label
=
'
Euler-Cromer
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
))
set_axes
()
```
%% Cell type:code id:scientific-comparison tags:
```
python
plt
.
plot
(
hamiltonian
(
results_euler
[:,
0
],
results_euler
[:,
1
]),
c
=
'
b
'
,
label
=
'
Euler
'
)
plt
.
plot
(
hamiltonian
(
results_eulercromer
[:,
0
],
results_eulercromer
[:,
1
]),
c
=
'
c
'
,
label
=
'
Euler-Cromer
'
)
plt
.
axhline
(
hamiltonian
(
theta_ini
,
p_ini
),
c
=
'
r
'
,
label
=
'
theory
'
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
r
'
$\mathcal{H}(\theta, p)$
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
));
```
%% Cell type:markdown id:fitted-occasions tags:
<h3>
Leapfrog Method (slide 12)
</h3>
%% Cell type:code id:lovely-silver tags:
```
python
def
solve_leapfrog
(
theta
,
p
,
dt
=
0.1
):
theta_half
=
theta
+
dt
/
2
*
p
/
(
m
*
L
*
L
)
p_next
=
p
-
dt
*
m
*
g
*
L
*
np
.
sin
(
theta_half
)
theta_next
=
theta_half
+
dt
/
2
*
p_next
/
(
m
*
L
*
L
)
return
(
theta_next
,
p_next
)
```
%% Cell type:code id:civil-tunnel tags:
```
python
results_leapfrog
=
np
.
zeros
((
n_steps
,
2
),
dtype
=
np
.
float32
)
results_leapfrog
[
0
]
=
(
theta_ini
,
p_ini
)
for
k
in
range
(
1
,
n_steps
):
results_leapfrog
[
k
]
=
solve_leapfrog
(
*
results_leapfrog
[
k
-
1
])
```
%% Cell type:code id:determined-consortium tags:
```
python
plt
.
plot
(
hamiltonian
(
results_euler
[:,
0
],
results_euler
[:,
1
]),
c
=
'
b
'
,
label
=
'
Euler, $\mathcal{O}(\Delta t^2)$
'
)
plt
.
plot
(
hamiltonian
(
results_eulercromer
[:,
0
],
results_eulercromer
[:,
1
]),
c
=
'
c
'
,
label
=
'
Euler-Cromer, $\mathcal{O}(\Delta t^2)$
'
)
plt
.
plot
(
hamiltonian
(
results_leapfrog
[:,
0
],
results_leapfrog
[:,
1
]),
c
=
'
k
'
,
label
=
'
leapfrog, $\mathcal{O}(\Delta t^3)$
'
)
plt
.
axhline
(
hamiltonian
(
theta_ini
,
p_ini
),
c
=
'
r
'
,
lw
=
2
,
label
=
'
theory
'
)
plt
.
ylim
(
0.5
,
0.6
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
r
'
$\mathcal{H}(\theta, p)$
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
));
```
%% Cell type:markdown id:worst-bikini tags:
<h3>
Collection of pendulums (slides 14 & 17)
</h3>
%% Cell type:code id:respiratory-chaos tags:
```
python
theta_grid
=
np
.
linspace
(
-
0.5
*
np
.
pi
,
0.5
*
np
.
pi
,
21
)
p_grid
=
np
.
linspace
(
-
0.3
,
0.3
,
5
)
thetas
,
ps
=
np
.
meshgrid
(
theta_grid
,
p_grid
)
```
%% Cell type:code id:smart-school tags:
```
python
N
=
len
(
theta_grid
)
*
len
(
p_grid
)
N
```
%% Cell type:code id:australian-baker tags:
```
python
plt
.
scatter
(
thetas
,
ps
,
c
=
'
b
'
,
marker
=
'
.
'
)
plot_hamiltonian
()
```
%% Cell type:markdown id:electrical-union tags:
<h3>
Time evolution
</h3>
%% Cell type:code id:sixth-plain tags:
```
python
n_steps
=
100
```
%% Cell type:code id:weird-lawyer tags:
```
python
results_thetas
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_thetas
[
0
]
=
thetas
.
flatten
()
results_ps
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_ps
[
0
]
=
ps
.
flatten
()
for
k
in
range
(
1
,
n_steps
):
results_thetas
[
k
],
results_ps
[
k
]
=
solve_leapfrog
(
results_thetas
[
k
-
1
],
results_ps
[
k
-
1
])
```
%% Cell type:markdown id:special-canadian tags:
<h3>
Observations of centroids (slide 19)
</h3>
%% Cell type:code id:indonesian-redhead tags:
```
python
centroids_theta
=
1
/
N
*
np
.
sum
(
results_thetas
,
axis
=
1
)
centroids_p
=
1
/
N
*
np
.
sum
(
results_ps
,
axis
=
1
)
```
%% Cell type:code id:outside-wonder tags:
```
python
plt
.
plot
(
centroids_theta
,
label
=
r
'
$\langle\theta\rangle$
'
)
plt
.
plot
(
centroids_p
,
label
=
r
'
$\langle p\rangle$
'
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
Centroid amplitude
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
));
```
%% Cell type:markdown id:forbidden-merit tags:
<h3>
Observations of RMS size
</h3>
%% Cell type:code id:continental-preliminary tags:
```
python
var_theta
=
1
/
N
*
np
.
sum
(
results_thetas
*
results_thetas
,
axis
=
1
)
var_p
=
1
/
N
*
np
.
sum
(
results_ps
*
results_ps
,
axis
=
1
)
```
%% Cell type:code id:metropolitan-princess tags:
```
python
plt
.
plot
(
var_theta
,
label
=
r
'
$\langle\theta^2\rangle$
'
)
plt
.
plot
(
var_p
,
label
=
r
'
$\langle p^2\rangle$
'
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
Variance
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
));
```
%% Cell type:markdown id:quick-humor tags:
<h3>
Distribution evolution over time
</h3>
%% Cell type:code id:homeless-deployment tags:
```
python
k
=
18
plt
.
scatter
(
results_thetas
[
k
],
results_ps
[
k
],
c
=
'
b
'
,
marker
=
'
.
'
)
plot_hamiltonian
()
```
%% Cell type:markdown id:lined-glory tags:
<h3>
RMS emittance evolution (slide 20) $$
\e
psilon =
\s
qrt{
\l
angle
\t
heta^2
\r
angle
\l
angle p^2
\r
angle -
\l
angle
\t
heta
\,
p
\r
angle^2}$$
</h3>
%% Cell type:code id:welsh-effort tags:
```
python
def
emittance
(
theta
,
p
):
N
=
len
(
theta
)
# subtract centroids
theta
=
theta
-
1
/
N
*
np
.
sum
(
theta
)
p
=
p
-
1
/
N
*
np
.
sum
(
p
)
# compute Σ matrix entries
theta_sq
=
1
/
N
*
np
.
sum
(
theta
*
theta
)
p_sq
=
1
/
N
*
np
.
sum
(
p
*
p
)
crossterm
=
1
/
N
*
np
.
sum
(
theta
*
p
)
# determinant of Σ matrix
epsilon
=
np
.
sqrt
(
theta_sq
*
p_sq
-
crossterm
*
crossterm
)
return
epsilon
```
%% Cell type:code id:impaired-russian tags:
```
python
results_emit
=
np
.
zeros
(
n_steps
,
dtype
=
np
.
float32
)
for
k
in
range
(
n_steps
):
results_emit
[
k
]
=
emittance
(
results_thetas
[
k
],
results_ps
[
k
])
```
%% Cell type:code id:enhanced-dairy tags:
```
python
plt
.
plot
(
results_emit
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
RMS emittance $\epsilon$
'
);
```
%% Cell type:markdown id:taken-survival tags:
<h3>
Exercise: Linearized pendulum motion
</h3>
%% Cell type:markdown id:thorough-failing tags:
$$
\l
eft.
\b
egin{matrix}
\,
\t
heta_{k+1/2} &=&
\t
heta_k + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k}}{mL^2}
\\
p_{k+1} &=& p_k -
\D
elta t
\c
dot m g L
\s
in
\t
heta_{k+1/2}
\\
\t
heta_{k+1} &=&
\t
heta_{k+1/2} + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k+1}}{mL^2}
\e
nd{matrix}
\r
ight
\}
\q
uad
\s
tackrel{
\t
ext{Taylor}}{
\L
ongrightarrow}
\q
uad
\l
eft
\{\b
egin{matrix}
\,
\t
heta_{k+1/2} &=&
\t
heta_k + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k}}{mL^2}
\\
p_{k+1} &=& p_k -
\D
elta t
\c
dot m g L
\c
olor{red}{
\l
eft(
\t
heta_{k+1/2}-
\f
rac{
\t
heta_{k+1/2}^3}{3!}+
\f
rac{
\t
heta_{k+1/2}^5}{5!}-
\f
rac{
\t
heta_{k+1/2}^7}{7!}+...
\r
ight)}
\\
\t
heta_{k+1} &=&
\t
heta_{k+1/2} + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k+1}}{mL^2}
\e
nd{matrix}
\r
ight.$$
%% Cell type:markdown id:quiet-updating tags:
$$
\l
eft.
\b
egin{matrix}
\,
\t
heta_{k+1/2} &=&
\t
heta_k + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k}}{mL^2}
\\
p_{k+1} &=& p_k -
\D
elta t
\c
dot m g L
\s
in
\t
heta_{k+1/2}
\\
\t
heta_{k+1} &=&
\t
heta_{k+1/2} + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k+1}}{mL^2}
\e
nd{matrix}
\r
ight
\}
\q
uad
\s
tackrel{
\t
ext{First order}}{
\L
ongrightarrow}
\q
uad
\l
eft
\{\b
egin{matrix}
\,
\t
heta_{k+1/2} &=&
\t
heta_k + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k}}{mL^2}
\\
p_{k+1} &=& p_k -
\D
elta t
\c
dot m g L
\c
dot
\c
olor{red}{
\t
heta_{k+1/2}}
\\
\t
heta_{k+1} &=&
\t
heta_{k+1/2} + {
\c
frac{
\D
elta t}{2}}
\c
dot
\c
frac{p_{k+1}}{mL^2}
\e
nd{matrix}
\r
ight.$$
%% Cell type:code id:living-spyware tags:
```
python
def
solve_leapfrog_linear
(
theta
,
p
,
dt
=
dt
):
theta_half
=
theta
+
dt
/
2
*
p
/
(
m
*
L
*
L
)
p_next
=
p
-
dt
*
m
*
g
*
L
*
theta_half
theta_next
=
theta_half
+
dt
/
2
*
p_next
/
(
m
*
L
*
L
)
return
(
theta_next
,
p_next
)
```
%% Cell type:code id:bored-commodity tags:
```
python
results_thetas_linear
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_thetas_linear
[
0
]
=
thetas
.
flatten
()
results_ps_linear
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_ps_linear
[
0
]
=
ps
.
flatten
()
for
k
in
range
(
1
,
n_steps
):
results_thetas_linear
[
k
],
results_ps_linear
[
k
]
=
solve_leapfrog_linear
(
results_thetas_linear
[
k
-
1
],
results_ps_linear
[
k
-
1
])
```
%% Cell type:code id:quantitative-programmer tags:
```
python
var_theta_linear
=
1
/
N
*
np
.
sum
(
results_thetas_linear
*
results_thetas_linear
,
axis
=
1
)
var_p_linear
=
1
/
N
*
np
.
sum
(
results_ps_linear
*
results_ps_linear
,
axis
=
1
)
```
%% Cell type:code id:three-better tags:
```
python
plt
.
plot
(
var_theta_linear
,
label
=
r
'
$\langle\theta^2\rangle$
'
)
plt
.
plot
(
var_p_linear
,
label
=
r
'
$\langle p^2\rangle$
'
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
Variance
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
));
```
%% Cell type:code id:statutory-thriller tags:
```
python
results_emit_linear
=
np
.
zeros
(
n_steps
,
dtype
=
np
.
float32
)
for
k
in
range
(
n_steps
):
results_emit_linear
[
k
]
=
emittance
(
results_thetas_linear
[
k
],
results_ps_linear
[
k
])
```
%% Cell type:code id:equipped-campus tags:
```
python
plt
.
plot
(
results_emit_linear
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
RMS emittance $\epsilon$
'
);
```
%% Cell type:markdown id:breeding-invalid tags:
<h3>
Centroid offset in (original) pendulum
</h3>
%% Cell type:code id:chemical-aquarium tags:
```
python
results_thetas2
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_thetas2
[
0
]
=
thetas
.
flatten
()
+
0.1
*
np
.
pi
results_ps2
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_ps2
[
0
]
=
ps
.
flatten
()
for
k
in
range
(
1
,
n_steps
):
results_thetas2
[
k
],
results_ps2
[
k
]
=
solve_leapfrog
(
results_thetas2
[
k
-
1
],
results_ps2
[
k
-
1
])
```
%% Cell type:code id:greek-brunswick tags:
```
python
centroids_theta2
=
1
/
N
*
np
.
sum
(
results_thetas2
,
axis
=
1
)
centroids_p2
=
1
/
N
*
np
.
sum
(
results_ps2
,
axis
=
1
)
plt
.
plot
(
centroids_theta
,
label
=
r
'
no offset: $\langle\theta\rangle$
'
)
plt
.
plot
(
centroids_theta2
,
label
=
r
'
with offset: $\langle\theta\rangle$
'
)
plt
.
plot
(
centroids_p2
,
label
=
r
'
with offset: $\langle p\rangle$
'
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
Centroid amplitude
'
)
plt
.
legend
(
bbox_to_anchor
=
(
1.05
,
1
));
```
%% Cell type:code id:voluntary-transparency tags:
```
python
results_emit2
=
np
.
zeros
(
n_steps
,
dtype
=
np
.
float32
)
for
k
in
range
(
n_steps
):
results_emit2
[
k
]
=
emittance
(
results_thetas2
[
k
],
results_ps2
[
k
])
```
%% Cell type:code id:legitimate-objective tags:
```
python
plt
.
plot
(
results_emit
,
label
=
'
no offset
'
)
plt
.
plot
(
results_emit2
,
label
=
'
with offset
'
)
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
'
RMS emittance $\epsilon$
'
)
plt
.
legend
();
```
%% Cell type:markdown id:rough-funds tags:
<h3>
Long-term behaviour
</h3>
%% Cell type:code id:canadian-section tags:
```
python
n_steps
=
3000
```
%% Cell type:code id:primary-lightning tags:
```
python
results_thetas3
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_thetas3
[
0
]
=
thetas
.
flatten
()
+
0.1
*
np
.
pi
results_ps3
=
np
.
zeros
((
n_steps
,
N
),
dtype
=
np
.
float32
)
results_ps3
[
0
]
=
ps
.
flatten
()
for
k
in
range
(
1
,
n_steps
):
results_thetas3
[
k
],
results_ps3
[
k
]
=
solve_leapfrog
(
results_thetas3
[
k
-
1
],
results_ps3
[
k
-
1
])
```
%% Cell type:code id:ordinary-advertising tags:
```
python
plot_macro_evolution
(
results_thetas3
,
results_ps3
);
```
%% Cell type:markdown id:figured-attendance tags:
<h3>
Employ FFT on pendulum motion (slide 31)
</h3>
%% Cell type:code id:coordinated-boring tags:
```
python
## Observe two particles:
i1
=
N
//
2
-
10
i2
=
N
//
2
plt
.
plot
(
results_thetas3
[:,
i1
])
plt
.
plot
(
results_thetas3
[:,
i2
])
plt
.
xlabel
(
'
Steps $k$
'
)
plt
.
ylabel
(
r
'
$\theta$
'
);
```
%% Cell type:code id:supported-involvement tags:
```
python
## Obtain the FFT spectra for both:
spec1
=
np
.
fft
.
rfft
(
results_thetas3
[:,
i1
])
spec2
=
np
.
fft
.
rfft
(
results_thetas3
[:,
i2
])
freq
=
np
.
fft
.
rfftfreq
(
n_steps
)
## Frequency of linearized system
freq_theory
=
np
.
sqrt
(
1
/
1
)
*
0.1
/
(
2
*
np
.
pi
)
```
%% Cell type:code id:weird-retrieval tags:
```
python
plt
.
plot
(
freq
,
np
.
abs
(
spec1
))
plt
.
plot
(
freq
,
np
.
abs
(
spec2
))
plt
.
axvline
(
freq_theory
,
c
=
'
k
'
,
zorder
=
0
,
ls
=
'
--
'
)
plt
.
xlim
(
0
,
0.05
)
plt
.
xlabel
(
'
Phase advance per $\Delta t$ [$2\pi$]
'
)
plt
.
ylabel
(
'
FFT spectrum
'
)
plt
.
yscale
(
'
log
'
);
```
%% Cell type:markdown id:desirable-venice tags:
<h3>
Frequency vs Amplitude
</h3>
%% Cell type:code id:textile-commons tags:
```
python
specs
=
np
.
abs
(
np
.
fft
.
rfft
(
results_thetas3
.
T
))
```
%% Cell type:code id:standing-there tags:
```
python
max_ids
=
np
.
argmax
(
specs
,
axis
=
1
)
amplitudes
=
np
.
max
(
specs
,
axis
=
1
)
```
%% Cell type:code id:developed-input tags:
```
python
i_range
=
np
.
where
(
ps
.
flatten
()
==
0
)[
0
]
plt
.
scatter
(
results_thetas3
[
0
][
i_range
],
freq
[
max_ids
][
i_range
])
plt
.
axhline
(
freq_theory
,
c
=
'
k
'
,
ls
=
'
--
'
,
zorder
=
0
)
plt
.
xticks
([
-
np
.
pi
/
2
,
0
,
np
.
pi
/
2
,
np
.
pi
],
[
r
"
$-\pi/2$
"
,
"
0
"
,
r
"
$\pi/2$
"
,
r
"
$\pi$
"
])
plt
.
xlabel
(
r
'
Initial $\theta$ ($p=0$)
'
)
plt
.
ylabel
(
'
Phase advance /
\n
'
+
r
'
integration step $\Delta t$ [$2\pi$]
'
);
plt
.
ylim
(
0.012
,
0.0165
);
```
%% Cell type:markdown id:unavailable-scenario tags:
<h3>
NAFF Algorithm (slide 32)
</h3>
%% Cell type:code id:present-helena tags:
```
python
import
PyNAFF
```
%% Cell type:code id:global-distributor tags:
```
python
freqs_naff
=
[]
for
signal
in
results_thetas3
.
T
[
i_range
]:
freq_naff
=
PyNAFF
.
naff
(
signal
,
turns
=
n_steps
-
1
,
nterms
=
1
)
try
:
freq_naff
=
freq_naff
[
0
,
1
]
except
IndexError
:
freq_naff
=
0
freqs_naff
+=
[
freq_naff
]
freqs_naff
=
np
.
array
(
freqs_naff
)
```
%% Cell type:code id:statutory-union tags:
```
python
plt
.
scatter
(
results_thetas3
[
0
][
i_range
],
freq
[
max_ids
][
i_range
])
plt
.
plot
(
results_thetas3
[
0
][
i_range
],
freqs_naff
,
c
=
'
r
'
,
marker
=
'
.
'
)
plt
.
axhline
(
freq_theory
,
c
=
'
k
'
,
ls
=
'
--
'
,
zorder
=
0
)
plt
.
xticks
([
-
np
.
pi
/
2
,
0
,
np
.
pi
/
2
,
np
.
pi
],
[
r
"
$-\pi/2$
"
,
"
0
"
,
r
"
$\pi/2$
"
,
r
"
$\pi$
"
])
plt
.
xlabel
(
r
'
Initial $\theta$ ($p=0$)
'
)
plt
.
ylabel
(
'
Phase advance /
\n
'
+
r
'
integration step $\Delta t$ [$2\pi$]
'
);
```
%% Cell type:code id:inappropriate-listening tags:
```
python
plt
.
plot
(
results_thetas3
[
0
][
i_range
],
100
*
(
freq
[
max_ids
][
i_range
]
-
freqs_naff
)
/
freqs_naff
)
plt
.
xlabel
(
r
'
Initial $\theta$ ($p=0$)
'
)
plt
.
ylabel
(
'
Error (FFT - NAFF) / NAFF
'
+
r
'
[%]
'
);
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment