-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add notebook with tutorial on basics. (#63)
* Add notebook with tutorial on basics. * Add markdown file for basic tutorial. * Really add .md file. * Properly format new tutorial .md file. * Update docs/src/tutorials/bseries_basics.md Co-authored-by: Hendrik Ranocha <[email protected]> * Update docs/src/tutorials/bseries_basics.md Co-authored-by: Hendrik Ranocha <[email protected]> * Update docs/src/tutorials/bseries_basics.md Co-authored-by: Hendrik Ranocha <[email protected]> * Use Kutta's method. * minor whitespace change for better rendering without scrolling Co-authored-by: Hendrik Ranocha <[email protected]>
- Loading branch information
Showing
3 changed files
with
477 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
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,322 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"In this notebook we use `bseries.jl` to investigate error expansions for RK methods applied to specific problems." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Load the packages we will use. These must first be installed using: import Pkg; Pkg.add(\"package_name\")\n", | ||
"using BSeries\n", | ||
"using Latexify # Only needed for some pretty-printing cells below\n", | ||
"import SymPy; sp=SymPy;" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# B-Series for a generic ODE" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"First we specify the Butcher coefficients of the RK method.\n", | ||
"This can include symbolic expressions and parameterized families of methods.\n", | ||
"Here is a generic 2-stage, 2nd-order method:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"α = sp.symbols(\"α\", real=true)\n", | ||
"A = [0 0; 1/(2*α) 0]; b = [1-α, α]; c = [0, 1/(2*α)]\n", | ||
"coeffs2 = bseries(A,b,c,3)\n", | ||
"latexify(coeffs2, cdot=false)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We have generated the B-series up to terms of order $h^3$. The terms $F_f()$\n", | ||
"represent elementary differentials, which are products of derivatives of the\n", | ||
"ODE right-hand side. Since we haven't specified an ODE, these are indicated\n", | ||
"simply by the associated rooted tree. The rooted trees are printed as nested\n", | ||
"lists, essentially in the form used in Butcher's book. The rooted trees written\n", | ||
"in this way can be rendered in LaTex using the package `forest`; unfortunately,\n", | ||
"there is no easy way to render them in the browser.\n", | ||
"\n", | ||
"Here is a B-series for a 4th-order method, expanded up to 5th-order terms:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"A = [0 0 0 0; 1//2 0 0 0; 0 1//2 0 0; 0 0 1 0];\n", | ||
"b = [1//6, 1//3, 1//3, 1//6];\n", | ||
"c = [0, 1//2, 1//2, 1];\n", | ||
"\n", | ||
"coeffs4 = bseries(A,b,c,5)\n", | ||
"latexify(coeffs4, cdot=false)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can also print out the B-series coefficients this way:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"coeffs4" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"In this form, the rooted trees are printed as level sequences. The corresponding coefficients are on the right." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Exact series and local error" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can also get the B-series of the exact solution:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"coeffs_ex = ExactSolution(coeffs4)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"latexify(coeffs_ex,cdot=false)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can find the local error by subtracting the exact solution B-series from the RK method B-series:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"latexify(coeffs4-coeffs_ex,cdot=false)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"This confirms that the method is of 4th order, since all terms involving\n", | ||
"smaller powers of $h$ vanish exactly. We don't see the $h^6$ and higher\n", | ||
"order terms since we only generated the truncated B-series up to 5th order.\n", | ||
"\n", | ||
"For the 2nd-order method, we get:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"latexify(coeffs2-coeffs_ex,cdot=false)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"This confirms again the accuracy of the method, and shows us that we\n", | ||
"can eliminate one of the leading error terms completely if we take\n", | ||
"$\\alpha=3/4$ (this is known as Ralston's method, or sometimes as Heun's method)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# B-Series for a specific ODE" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Next, let us define an ODE. We'll consider the Prothero-Robinson problem:\n", | ||
"\n", | ||
"$$\n", | ||
" y'(t) = \\lambda(y-\\sin(t)) + \\cos(t).\n", | ||
"$$\n", | ||
"\n", | ||
"For a non-autonomous ODE like this, it's convenient to rewrite the problem\n", | ||
"in autonomous form. We set $u=[y,t]^T$ and\n", | ||
"\n", | ||
"\\begin{align}\n", | ||
"u_1'(t) & = \\lambda(u_1 - \\sin(u_2)) + \\cos(u_2) \\\\\n", | ||
"u_2'(t) & = t.\n", | ||
"\\end{align}" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"λ = sp.symbols(\"λ\", real=true)\n", | ||
"y, t = sp.symbols(\"y t\", real=true)\n", | ||
"h = sp.symbols(\"h\", real=true)\n", | ||
"\n", | ||
"u = [y, t]\n", | ||
"ff = [λ*(u[1]-sin(t))+cos(t), 1]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Finally, we get the B-Series for our RK method applied to our ODE:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"evaluate(ff,u,h,coeffs4)[1]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Notice that the series is truncated at the same order that we specified\n", | ||
"when we initially generated it from the RK coefficients.\n", | ||
"\n", | ||
"Here's the B-Series for the exact solution of the same ODE:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"evaluate(ff,u,h,coeffs_ex)[1]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"And their difference, which is the local error:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"expr = sp.simplify(evaluate(ff,u,h,coeffs4)-evaluate(ff,u,h,coeffs_ex))[1]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# B-series for a generic RK method" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can also examine just the elementary differentials, without specifying a RK method:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"elementary_differentials(ff,u,5)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Julia 1.7.2", | ||
"language": "julia", | ||
"name": "julia-1.7" | ||
}, | ||
"language_info": { | ||
"file_extension": ".jl", | ||
"mimetype": "application/julia", | ||
"name": "julia", | ||
"version": "1.7.2" | ||
}, | ||
"toc": { | ||
"base_numbering": 1, | ||
"nav_menu": {}, | ||
"number_sections": true, | ||
"sideBar": true, | ||
"skip_h1_title": false, | ||
"title_cell": "Table of Contents", | ||
"title_sidebar": "Contents", | ||
"toc_cell": false, | ||
"toc_position": {}, | ||
"toc_section_display": true, | ||
"toc_window_display": false | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.