\n",
"\n",
"Based on [Physics Simulations in Python](__https://physics.weber.edu/schroeder/scicomp/PythonManual.pdf__) by Daniel V. Schroeder (Weber State University, [__dschroeder@weber.edu__](dschroeder@weber.edu). Adapted with permission by [__Ruth Van de Water__](rsvandewater@noctrl.edu) April, 2019. Last updated June 21, 2022."
]
},
{
"cell_type": "markdown",
"id": "71dc7015-bb8b-4e6f-8c58-5ee8c1ba7e0f",
"metadata": {},
"source": [
"As you have now seen for yourselves, even the simulation of a point-like projectile moving in two dimensions under the influence of gravity and drag -- _which one of the simplest classical systems imaginable_ -- can require a very small step size ($\\Delta t$ in this case) and thousands of iterations to converge to 3- or 4-digit accuracy. As the step size is reduced and the number of iterations increases, the time it takes to run the simulation of course increases too. You can therefore imagine that, at some point, it will become impractical to improve your simulation with the \"brute-force\" approach of decreasing the step size. \n",
"\n",
"Fortunately, however, there is another way to improve numerical computer simulations besides running longer: you can improve the algorithm. Mathematicians since at least the 17th century -- possibly earlier -- have spent countless hours developing and improving algorithms to solve differential equations (of which Newton’s Second Law is one) numerically, with computer scientists jumping in on the action more recently. The algorithm that you employed in Parts 1 and 2 of this activity was devised by [Leonhard Euler](__https://en.wikipedia.org/wiki/Leonhard_Euler__) (1707–1783) and is known as Euler’s method. In Part 3 of this activity, you will now program and test an improved version of Euler’s method developed by [Lewis Fry Richardson](__https://en.wikipedia.org/wiki/Lewis_Fry_Richardson__) (1881-1953) and known as the Euler-Richardson method.\n",
"\n",
"To improve upon Euler’s method, it is useful to revisit the position and momentum-update equations, \n",
"\n",
"\\begin{equation}\n",
"\\vec{r}_f = \\vec{r}_i + \\vec{v} \\Delta t\n",
"\\end{equation} and \\begin{equation}\n",
"\\vec{p}_f = \\vec{p}_i + \\vec{F}_{net} \\Delta t.\n",
"\\end{equation} \n",
"\n",
"In these equations, and are the position and momentum at the beginning of a time interval (time ), while and are the position and momentum at the end of the same time interval (time ). The velocity and net force, however, do not have any “initial” or “final” subscripts, so what and should we use to update the position and momenta? \n",
"\n",
"In parts 1 and 2 — although you may not have explicitly thought about it — you used the velocity and net force at the beginning of the time interval, and , in the position- and momentum-update equations. A better approximation for the average velocity and average net force in the interval between and , however, would probably be obtained by using the velocity and and net force at the midpoint of the time interval, and . This is the essence of the Euler-Richardson method. The exact algorithm is provided at the top of the next page. "
]
},
{
"cell_type": "markdown",
"id": "29e4e667-d65b-4907-92d0-5415f38ae46e",
"metadata": {},
"source": [
"## Code\n",
"\n",
"$\\color{blue}{\\mathbf{Program\\!:\\, }}$ Copy your projectile-motion program from Part 1 into a code cell below. (_Don't forget the_ `import` _statements!_) In this new program:\n",
"\n",
"- modify the loop in your code that calculates the trajectory of the ball to employ the improved algorithm at the top of the following page, \n",
"\n",
"- reset the step size dt to 0.1 second, and\n",
"\n",
"- run your new program.\n",
"\n",
"If your new code is working correctly, you will likely not notice a difference in the motion of the ball when you run it. Your calculated range and time-of-flight should also be in the same ballpark as before. \n"
]
},
{
"cell_type": "markdown",
"id": "443e6e56-fac8-4393-a208-e661d21c06e0",
"metadata": {},
"source": [
"$\\color{magenta}{\\mathbf{Exercise\\!:\\, }}$ Once you believe that the improved algorithm is working, fill out the table below using the same simulation parameters as in Part 2. (This will allow you to directly compare the two algorithms.)\n",
"\n",
"\n",
"\n",
"| $\\Delta t$ (s) | $t_f$ (s) | $x_f$ (m) | \\# iterations |\n",
"| --- | --- | --- | --- |\n",
"| 0.1 | ??? | ??? | ??? |\n",
"| 0.01 | ??? | ??? | ??? |\n",
"| $etc.$ | | | |\n",
" \n",
"\n",
"\n",
"_Is the Euler-Richardson algorithm from Part 3 more accurate than the Euler algorithm from Parts 1 and 2? How can you tell?_"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "503a9988-4ecf-4433-8649-d71e05acbe83",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f1810b4-3036-4c3e-be3d-0a159b83466b",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "3e59e364-78b0-47a4-b274-09bbc164129f",
"metadata": {},
"source": [
"\n",
"

You should find that, **with the Euler-Richardson algorithm, the step size can now be ***significantly* larger\n",
" than before.

(*If this is not the case, there is likely an error in your implementation.*)\n",
""
]
}
],
"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.8.13"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}