{
"cells": [
{
"cell_type": "markdown",
"id": "f8dcb0be",
"metadata": {},
"source": [
"# Cours ENPC - Pratique du calcul scientifique"
]
},
{
"cell_type": "markdown",
"id": "efac08c2",
"metadata": {},
"source": [
"Before you turn in this assignment, make sure everything runs as expected. First, **restart the kernel** and then **run all cells**. Make sure you fill in any place that says `YOUR CODE HERE` or \"YOUR ANSWER HERE\", as well as your name and group number below:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6e32661c",
"metadata": {},
"outputs": [],
"source": [
"NAME = \"\"\n",
"GROUP = \"\""
]
},
{
"cell_type": "markdown",
"id": "0136f8ef",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "markdown",
"checksum": "11536394e9ca05b3fe7627e697e8ae4f",
"grade": false,
"grade_id": "cell-9546f1bdb893cdcd",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"## Examen de rattrapage\n",
"\n",
"- Ce notebook est à soumettre sur Educnet avant 16h15.\n",
"\n",
"- L’examen comporte trois exercices indépendants. Dans chaque exercice les\n",
" cellules peuvent éventuellement dependre des cellules précèdentes.\n",
"\n",
"- Afin de faciliter l'évaluation de votre code,\n",
" ne pas changer les signatures des fonctions à implémenter.\n",
"\n",
"- La cellulle ci-dessous importe les bibliothèques utilisées dans ce notebook. Si une ou plusieurs d'entre elles manquent sur votre machine, vous êtes invités à les installer au préalable."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a57b1a8f",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "399438db784622c2a59302a326d371b2",
"grade": false,
"grade_id": "cell-4d638a879ba6f86e",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"using ForwardDiff\n",
"using LaTeXStrings\n",
"using LinearAlgebra\n",
"using Plots\n",
"using Polynomials"
]
},
{
"cell_type": "markdown",
"id": "fe25b04b",
"metadata": {},
"source": [
"## [Exercice 1] Interpolation pour l'équation des poutres"
]
},
{
"cell_type": "markdown",
"id": "a9d93a90",
"metadata": {
"lines_to_next_cell": 2
},
"source": [
"Le but de cet exercice est d'explorer une application de l'interpolation polynomiale à la résolution d'une équation différentielle.\n",
"Plus précisément, nous allons mettre en œuvre une méthode numérique pour résoudre approximativement l'équation des poutres d'Euler-Bernoulli avec des conditions aux limites de Dirichlet homogènes :\n",
"\n",
"$$\n",
"u \\in C^4([0,1]), \\qquad \\left\\{ \\begin{aligned} u''''(x) &= \\varphi(x) \\qquad \\forall\\, x \\in (0,1),\\\\\n",
"u(0) &= u'(0) = u'(1) = u(1) = 0, \\end{aligned} \\right.\n",
"$$\n",
"\n",
"où $\\varphi(x) = (2\\pi)^4\\cos(2\\pi x)$ est une charge transverse appliquée à la poutre.\n",
"Afin de résoudre l'équation numériquement,\n",
"nous allons approximer le terme de droite $\\varphi$ par un polynôme interpolant $\\widehat \\varphi$,\n",
"puis résoudre l'équation exactement avec $\\widehat \\varphi$ au lieu de $\\varphi$.\n",
"\n",
"0. Commençons par écrire une fonction `fit_values_and_slopes(u₀, up₀, u₁, up₁)` qui retourne l'unique polynôme de degré 3 tel que\n",
" $$\n",
" p(0) = u_0, \\qquad p'(0) = up_0, \\qquad p(1) = u_1, \\qquad p'(1) = up_1.\n",
" $$"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "94188e2a",
"metadata": {},
"outputs": [],
"source": [
"function fit_values_and_slopes(u₀, up₀, u₁, up₁)\n",
" # We look for polynomials p(x) = a₀ + a₁ x + a₂ x² + a₃ x³\n",
" A = [1 0 0 0; 0 1 0 0; 1 1 1 1; 0 1 2 3]\n",
" α = A\\[u₀; up₀; u₁; up₁]\n",
" return Polynomial(α)\n",
"end\n",
"\n",
"# Test code\n",
"p = fit_values_and_slopes(-1, -1, 1, 1)\n",
"plot(p, xlims=(0, 1))"
]
},
{
"cell_type": "markdown",
"id": "79ee3492",
"metadata": {},
"source": [
"1. Écrire une fonction `approx(n)` implémentant l'approche décrite ci-dessus pour résoudre l'EDP.\n",
" La fonction devra retourner une approximation polynomiale de la solution basée sur une interpolation de **degré** $n$ du membre de droite à des points équidistants entre 0 et 1 compris.\n",
"\n",
" \n",
" \n",
" Indication (cliquer pour afficher)\n",
"
\n",
"\n",
" - Utiliser la fonction `fit` de la bibliothèque `Polynomials.jl` pour obtenir le polynôme interpolateur :\n",
"\n",
" ```julia\n",
" p = fit(x, y)\n",
" ```\n",
"\n",
" où `x` sont les nœuds d'interpolation et `y` sont les valeurs correspondantes de la fonction à interpoler.\n",
"\n",
" - Pour calculer la solution analytique lorsque le membre de droite est un polynôme,\n",
" on pourra remarquer que toutes les solutions sont des polynômes,\n",
" et que sans les conditions aux bords, la solution est unique modulo un polynôme cubique.\n",
"\n",
" - La fonction `integrate` de la bibliothèque `Polynomials.jl` permet de calculer une primitive d'un polynôme :\n",
" ```julia\n",
" P = integrate(p)\n",
" ```\n",
"\n",
" - Utiliser le format `BigFloat` pour limiter les erreurs d'arrondi.\n",
" En particulier, la fonction `LinRange{BigFloat}(a, b, N)` permet de créer un vecteur de `N` nombres au format `BigFloat` également distribués entre `a` et `b` inclus.\n",
" ```julia\n",
" X = LinRange{BigFloat}(0, 1, n + 1)\n",
" ```\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b28140c",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "53a972cd519e2a5b9555cdb722e35266",
"grade": false,
"grade_id": "interp_pde",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# Right-hand side\n",
"φ(x) = (2*big(π))^4 * cospi(2*x)\n",
"\n",
"# Exact solution (for comparison purposes)\n",
"uₑ(x) = cospi(2*x) - 1\n",
"\n",
"function approx(n)\n",
" X = LinRange{BigFloat}(0, 1, n + 1)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end;"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2b7c09fe",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "794336f1e976ed6fabbc4a8351d3fc99",
"grade": true,
"grade_id": "cell-e79ffe6285cd8198",
"locked": true,
"points": 2,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert typeof(approx(3)) == Polynomial{BigFloat, :x}\n",
"@assert degree(approx(3)) == 7\n",
"@assert approx(3)(0) ≈ 0\n",
"@assert approx(3)(1) ≈ 0\n",
"@assert derivative(approx(3))(0) ≈ 0\n",
"@assert derivative(approx(3))(1) ≈ 0"
]
},
{
"cell_type": "markdown",
"id": "ec8cdd87",
"metadata": {},
"source": [
"2. Écrire une fonction `estimate_error(n)` qui approxime l'erreur,\n",
" en norme $L^\\infty$,\n",
" entre la solution approchée par l'approche ci-dessus et la solution exacte.\n",
" La solution exacte est donnée par\n",
" $$\n",
" u_e(x) = \\cos(2\\pi x) - 1.\n",
" $$"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b9087f01",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "8df0edb8ea70bb6581037e0c1941f03a",
"grade": false,
"grade_id": "interp_error",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# Exact solution (for comparison purposes)\n",
"uₑ(x) = cospi(2*x) - 1\n",
"\n",
"function estimate_error(n)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end;"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "515eedfa",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "c31c4b8d83e4dc0187358814d0ced950",
"grade": true,
"grade_id": "cell-9764a7b6ad0837c3",
"locked": true,
"points": 2,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert estimate_error(2) > 0\n",
"@assert estimate_error(20) < 1e-3\n",
"@assert estimate_error(20) > 1e-20\n",
"@assert estimate_error(40) < 1e-12"
]
},
{
"cell_type": "markdown",
"id": "d0540971",
"metadata": {},
"source": [
"3. Tracer un graphique de l'erreur en fonction de $n$ pour $n$ allant de 5 à 30.\n",
" Utiliser l'échelle par défaut pour l'axe des abcisses et une échelle logarithmique pour l'axe des ordonnées."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "40c5b77b",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "97daacc40b3e33b0c7588dc5a60db184",
"grade": true,
"grade_id": "interp_plot",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# YOUR CODE HERE\n",
"throw(ErrorException(\"No code provided\"))"
]
},
{
"cell_type": "markdown",
"id": "7d1589d9",
"metadata": {},
"source": [
"### [Exercice 2] Différence finies pour Poisson non-linéaire\n",
"On s'intéresse dans cet exercice à la résolution de l'équation de Poisson non-linéaire suivante :\n",
"$$\n",
"\\tag{Poisson}\n",
"- \\frac{\\mathrm d} {\\mathrm d x} \\left( \\kappa(u, \\alpha) \\frac{\\mathrm d u} {\\mathrm d x} \\right) = 1,\n",
"\\qquad u(0) = u(1) = 0, \\qquad \\kappa(u, α) := 1 + α u^2,\n",
"$$\n",
"où $\\alpha \\in \\mathbb R_{\\geq 0}$ un paramètre positif.\n",
"Cette équation modélise la température à l'équilibre dans une barre unidimensionnelle dont les extrémités sont maintenues à température nulle,\n",
"en présence d'une source de chaleur uniforme.\n",
"La non-linéarité de cette équation provient du fait que la conductivité thermique $\\kappa$ dépend explicitement de la solution $u$.\n",
"Pour résoudre numériquement cette équation,\n",
"on utilisera la méthode des différences finies.\n",
"Soit une grille d'abcisses équidistantes\n",
"$$\n",
"0 = x_0 < x_1 < \\dots < x_{N-1} < x_N = 1, \\qquad x_i = \\frac{i}{N},\n",
"$$\n",
"et soit $(u_i)_{i \\in \\{0, \\dots N\\}}$ les valeurs de la solution à ces points.\n",
"La condition aux limites implique que $u_0 = u_N = 0$,\n",
"et il ne sera donc pas nécessaire d'inclure ces valeurs dans les inconnues.\n",
"Aux points intérieurs, on utilise l'approximation\n",
"$$\n",
"- \\frac{\\mathrm d} {\\mathrm d x} \\left( \\kappa(u, α) \\frac{\\mathrm d u} {\\mathrm d x} \\right) (x_i)\n",
"\\approx \\frac{F_{i+\\frac{1}{2}} - F_{i-\\frac{1}{2}}}{\\Delta x},\n",
"\\qquad\n",
"i \\in \\{1, \\dotsc, N-1\\},\n",
"\\tag{Approx}\n",
"$$\n",
"où $\\Delta x = 1/N$ et, pour $k \\in \\{0, \\dotsc, N-1\\}$,\n",
"$$\n",
"F_{k + \\frac{1}{2}} := - \\kappa_{k+\\frac{1}{2}} \\frac{u_{k+1} - u_{k}}{\\Delta x}, \\qquad\n",
"\\kappa_{k + \\frac{1}{2}} := \\frac{\\kappa(u_{i}, α) + \\kappa(u_{i+1}, α)}{2}.\n",
"$$\n",
"Le terme $F_{k+ 1/2}$ est une approximation du flux de chaleur vers la droite,\n",
"c'est à dire de la fonction qui à $x \\in [0, 1]$ associe $- \\kappa\\bigl(u(x), α\\bigr) u'(x)$,\n",
"au point $x_k + \\frac{\\Delta x}{2}$.\n",
"En substituant l'approximation (Approx) dans (PDE) et en réarrangant les termes,\n",
"on obtient le système suivant :\n",
"$$\n",
"\\forall i \\in \\{1, \\dotsc, N-1\\}, \\qquad\n",
"\\frac{1}{\\Delta x^2} \\left( - \\kappa_{i-\\frac{1}{2}} u_{i-1} + \\Bigl(\\kappa_{i-\\frac{1}{2}} + \\kappa_{i+\\frac{1}{2}}\\Bigr) u_{i} - \\kappa_{i+\\frac{1}{2}} u_{i+1} \\right) = 1,\n",
"$$\n",
"qui constitue un système non-linéaire de $N-1$ équations en les inconnues $\\mathbf u = (u_1, \\dotsc, u_{N-1})^\\top$.\n",
"Notons que les coefficients $(\\kappa_{k+1/2})_{k \\in \\{0, \\dots, N-1\\}}$ dépendent de manière non-linéaire de $\\mathbf u$ et $α$,\n",
"mais cette dépendance est omise dans la notation par souci de concision.\n",
"Ce système peut être réécrit sous forme matricielle comme suit :\n",
"$$\n",
"\\tag{NonLin}\n",
"\\frac{\\mathsf A_N(\\mathbf u, α)}{Δx^2}\n",
"\\begin{pmatrix}\n",
" u_1 \\\\\n",
" u_2 \\\\\n",
" u_3 \\\\\n",
" \\vdots \\\\\n",
" u_{N-2} \\\\\n",
" u_{N-1}\n",
"\\end{pmatrix}\n",
"=\n",
"\\begin{pmatrix}\n",
" 1 \\\\\n",
" 1 \\\\\n",
" 1 \\\\\n",
" \\vdots \\\\\n",
" 1 \\\\\n",
" 1\n",
"\\end{pmatrix}\n",
"=: \\mathbf b\n",
"$$\n",
"où $\\mathsf A_N(\\mathbf u, α) \\in \\mathbb R^{(N-1)\\times (N-1)}$ est la matrice suivante (dimension N-1 x N-1):\n",
"$$\n",
"A_N(\\mathbf u, α) =\n",
"\\begin{pmatrix}\n",
" \\kappa_{1/2} + \\kappa_{3/2} & - \\kappa_{3/2} \\\\\n",
" -\\kappa_{3/2} & \\kappa_{3/2} + \\kappa_{5/2} & - \\kappa_{5/2} \\\\\n",
" & -\\kappa_{5/2} & \\kappa_{5/2} + \\kappa_{7/2} & - \\kappa_{7/2} \\\\\n",
" & & \\ddots & \\ddots & \\ddots & \\\\\n",
" & & & -\\kappa_{N-5/2} & \\kappa_{N-5/2} + \\kappa_{N-3/2} & -\\kappa_{N-3/2} \\\\\n",
" & & & & -\\kappa_{N-3/2} & \\kappa_{N-3/2} + \\kappa_{N-1/2} \\\\\n",
"\\end{pmatrix}.\n",
"$$\n",
"\n",
"0. On fournit ci-dessous une fonction `build_A(N, u, α)` permettant de construire la matrice $\\mathsf A_N(\\mathbf u, \\alpha)$.\n",
" \n",
" \n",
" Indication (cliquer pour afficher)\n",
"
\n",
"\n",
" En vue de pouvoir dans la suite dériver la matrice $\\mathsf A_N$ par rapport à $α$ en utilisant la différentiation automatique,\n",
" il est crucial que la matrice $\\mathbf A$ puisse contenir des nombres duaux.\n",
" C'est pourquoi on utilise la commande\n",
" ```julia\n",
" A = zeros(typeof(α), N+1, N+1)\n",
" ```\n",
" pour initialiser la matrice `A`.\n",
" De cette manière, les élément de la matrice sont du même type que le paramètre $α$.\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "124a4c21-3a99-4b2c-a400-84f7de3730d9",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "c4fc9bdb21f51860a85061679144a681",
"grade": false,
"grade_id": "cell-7cc040866d32d6b0",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"κ(u, α) = 1 + α^2 * u^2\n",
"\n",
"function build_A(N, u, α)\n",
" @assert length(u) == N-1\n",
" A = zeros(typeof(α), N+1, N+1)\n",
" v = [0.; u; 0.]\n",
" for i in 2:N\n",
" A[i, i-1] = - (κ(v[i-1], α) + κ(v[i], α)) / 2\n",
" A[i, i] = (κ(v[i-1], α) + 2κ(v[i], α) + κ(v[i+1], α)) / 2\n",
" A[i, i+1] = - (κ(v[i], α) + κ(v[i+1], α)) / 2\n",
" end\n",
" return A[2:end-1, 2:end-1]\n",
"end\n",
"\n",
"@assert begin N = 20; size(build_A(N, zeros(N-1), 0.)) == (N - 1, N - 1) end\n",
"@assert begin N = 20; build_A(N, zeros(N-1), 0.) == SymTridiagonal(fill(2, N-1), fill(-1, N-2)) end"
]
},
{
"cell_type": "markdown",
"id": "4d1d4efb",
"metadata": {},
"source": [
"1. Pour résoudre le système non-linéaire (NonLin),\n",
" on se propose d'utiliser une méthode de point fixe basée sur l'itération\n",
" $$\n",
" \\frac{\\mathsf A_{N}(\\mathbf u^{n}, α)}{Δ x^2} \\mathbf u^{n+1} = \\mathbf b.\n",
" $$\n",
" Cette itération permet de générer,\n",
" à partir d'une approximation courante de la solution $\\mathbf u^n$,\n",
" une nouvelle approximation $\\mathbf u^{n+1}$.\n",
" Écrire une fonction `solve_nonlin(N, α; maxiter=500, ε=1e-12)` permettant de calculer une solution approximative de (NonLin) par cette approche,\n",
" en utilisant comme critère d'arrêt que.\n",
" $$\n",
" \\left\\| \\frac{\\mathsf A_N(\\mathbf u, α)}{Δx^2} \\mathbf u - \\mathbf b \\right\\| \\leq ε\n",
" $$\n",
" La fonction devra renvoyer uniquement le résultat final $\\mathbf u = (u_1, \\dotsc, u_{N-1})^\\top$ de l'itération,\n",
" ou `nothing` si une solution n'a pas été trouvée après `maxiter` itérations.\n",
" \n",
" \n",
" Indication (cliquer pour afficher)\n",
"
\n",
"\n",
" Afin de pouvoir dans la suite dériver la solution par rapport au paramètre $α$ en utilisant la différentiation automaiique,\n",
" il est important que les éléments `u` puissent contenir des nombres duaux.\n",
" Il est donc recommandé d'initialiser `u` comme suit :\n",
" ```julia\n",
" u = zeros(typeof(α), N-1)\n",
" ```\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6499aa1",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "d0213ec58811a7e45223919f524bc7de",
"grade": false,
"grade_id": "solve_nonlin",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function solve_nonlin(N, α; maxiter=1000, ε=1e-10)\n",
" b = ones(N-1)\n",
" u = zeros(typeof(α), N-1)\n",
" A = N^2 * build_A(N, u, α)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end;"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4e7d5b3e",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "3f417d22c2dcfb06e7bf0cac21cb7d06",
"grade": true,
"grade_id": "cell-68fd71f3ebf99d3e",
"locked": true,
"points": 2,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert size(solve_nonlin(10, 1.)) == (9,)\n",
"@assert solve_nonlin(10, 0; ε = 1e-100) == nothing\n",
"@assert begin N, α = 20, 1.; u = solve_nonlin(N, α); A_ = build_A(N, u, α); norm(N^2*A_*u - ones(N-1)) ≤ 1e-5 end"
]
},
{
"cell_type": "markdown",
"id": "780f44f1",
"metadata": {},
"source": [
"2. Écrire une fonction `solve_poisson(N, α)` permettant de résoudre approximativement (Poisson),\n",
" en faisant appel à la fonction `solve_nonlin` définie au point précédent.\n",
" Plus précisément, la fonction devra renvoyer les vecteurs $(x_0, x_1, \\dotsc, x_N)^\\top$ et $(u_0, u_1, \\dotsc, u_N)^\\top$,\n",
" où les **points aux limites sont inclus**.\n",
" \n",
" \n",
" Hint (click to display)\n",
"
\n",
"\n",
" Pour ajouter des éléments au début et à la fin d'un vecteur,\n",
" on pourra utiliser la concaténation verticale grâce à `;`\n",
"\n",
" ```julia\n",
" v1 = [1., 2., 3.]\n",
" v2 = [0.; v1; 0.] # v2 = [0., 1., 2., 3., 0.]\n",
" ```\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e642215",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "5899b96cfee935b5d4bdae4a537c9471",
"grade": false,
"grade_id": "solve_poisson",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function solve_poisson(N, α)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad1d6e71",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "1f188a125d5d773ea0a839f81b393517",
"grade": true,
"grade_id": "cell-0daaf7cc0874d73d",
"locked": true,
"points": 1,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert solve_poisson(20, 1.) isa Tuple\n",
"@assert length(solve_poisson(20, 1.)) == 2\n",
"@assert solve_poisson(20, 1.)[1] == (0:20)/20"
]
},
{
"cell_type": "markdown",
"id": "fe3fae17",
"metadata": {},
"source": [
"3. Fixer $α = 30.0$ et illustrer dans ce cas la convergence de la méthode numérique quand $N \\to \\infty$,\n",
" en traçant sur un même graphe les solutions numériques obtenues pour les valeurs de $N$ données ci-dessous."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "caa0f074",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "d63c961f8e8873d5d6a48c127871c5fa",
"grade": true,
"grade_id": "plot_poisson_1",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"α = 30.\n",
"p = plot(title=L\"Convergence as $N \\to \\infty$\", xlims=(0, 1),\n",
" legend=:outertopright)\n",
"for N in (5, 10, 20, 30, 40)\n",
" # Plot numerical solution for current value of `N`\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end\n",
"p"
]
},
{
"cell_type": "markdown",
"id": "03d1fc13",
"metadata": {},
"source": [
"4. Fixer $N = 50$, et illustrer sur un même graphe\n",
" - La solution exacte de l'équation de Poisson quand $\\alpha = 0$,\n",
" qui est donnée par\n",
" $$\n",
" u(x) = \\frac{1}{8} - \\frac{1}{2} \\left(x - \\frac{1}{2} \\right)^2.\n",
" $$\n",
" - Les solutions numériques obtenues pour $α \\in \\{0, 10, 20, 50, 100\\}$."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9f6d7c94",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "c9d2ddb08d49a0237c57d88cad4148f9",
"grade": true,
"grade_id": "plot_poisson_2",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"N = 50\n",
"u_exact(x) = 1/8 - (x - .5)^2/2\n",
"p = plot(title=\"Solution to the nonlinear Poisson equation\", xlims=(0, 1),\n",
" legend=:outertopright)\n",
"\n",
"# YOUR CODE HERE\n",
"throw(ErrorException(\"No code provided\"))\n",
"p"
]
},
{
"cell_type": "markdown",
"id": "0cfe0e47",
"metadata": {},
"source": [
"5. On suppose maintenant que le paramètre $\\alpha$ est inconnu,\n",
" mais que la température moyenne de la barre a été mesurée:\n",
" $$\n",
" \\tag{Constraint}\n",
" \\int_{0}^{1} u(x) \\, \\mathrm dx = \\overline u.\n",
" $$\n",
" On s'intéresse au problème inverse visant à calculer le paramètre $α$ correspondant à la température moyenne mesurée.\n",
" Pour ce faire, commencer par écrire une fonction `mean_temperature(N, α)`,\n",
" donnant la température moyenne dans la barre pour la valeur de $α$ donnée,\n",
" sur base d'une approximation numérique de la solution de l'équation de Poisson par `solve_poisson`.\n",
" On pourra supposer que le nombre $N$ est pair,\n",
" de manière à ce que la méthode de Simpson puisse étre utilisée."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e2971944",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "1b75523596c27fdcdcff310db89c804d",
"grade": false,
"grade_id": "mean_temperature",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function mean_temperature(N, α)\n",
" @assert N % 2 == 0\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "715287f6",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "a033a25bb797751a94858a5a79da7581",
"grade": true,
"grade_id": "2",
"locked": true,
"points": 0,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert mean_temperature(10, 10.) isa Float64\n",
"@assert mean_temperature(100, 0.) ≈ 1/12\n",
"@assert mean_temperature(100, 10.) < 1/12"
]
},
{
"cell_type": "markdown",
"id": "7f2cb2bc",
"metadata": {},
"source": [
"6. Écrire ensuite une fonction `newton_raphson(x, f; maxiter=100, ε = 1e-12)`\n",
" implémentant la méthode de Newton-Raphson pour résoudre l'équation scalaire $f(x) = 0$,\n",
" avec comme critère d'arrêt que $| f(x) | \\leq \\varepsilon$.\n",
" La fonction devra renvoyer uniquement le résultat final de l'itération,\n",
" ou `nothing` si une solution n'a pas été trouvée après `maxiter` itérations.\n",
" On considérera uniquement le cas où `x` est un scalaire et `f` est une fonction de $\\mathbb R$ dans $\\mathbb R$.\n",
"\n",
" \n",
" \n",
" Indication (cliquer pour afficher)\n",
"
\n",
"\n",
" Pour calculer numériquement la dérivée de $f$,\n",
" la bibliothèque `ForwardDiff` peut être utilisée.\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "60e45859",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "a6bf68c3ea52bf71a4ca1839a07197d6",
"grade": false,
"grade_id": "newton_raphson",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"const dx = ForwardDiff.Dual(0., 1.)\n",
"function newton_raphson(f, x; maxiter=100, ε = 1e-12)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end;"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bc762d5f",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "6f8cb0202a02d2602bd4e19dabff6f41",
"grade": true,
"grade_id": "cell-d2e7364ddc277254",
"locked": true,
"points": 2,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert newton_raphson(x -> x^2 - 2, 1) ≈ √2\n",
"@assert newton_raphson(x -> x^2 - 2, -1) ≈ -√2\n",
"@assert newton_raphson(x -> x^3 - 2, 1) ≈ cbrt(2)\n",
"@assert newton_raphson(x -> cos(x) - .5, 2) ≈ acos(.5)"
]
},
{
"cell_type": "markdown",
"id": "ab521ae8",
"metadata": {},
"source": [
"7. Écrire une fonction `get_alpha(N)` permettant de calculer $α$ de manière à ce que l'équation (Constraint) soit satisfaite avec $\\overline u = .07$.\n",
" Pour ce faire, appliquer la méthode de Newton-Raphson à une fonction appropriée,\n",
" faisant intervenir un appel à `mean_temperature` avec la valeur de $N$ passée en argument.\n",
" \n",
" \n",
" Indications (cliquer pour afficher)\n",
"
\n",
"\n",
" Il vaut mieux ne pas initialiser l'itération de Newton-Raphson à $α = 0$.\n",
" En effet, la dérivée partielle par rapport à $α$ de la conductivité thermique $\\kappa$ est égale à 0 en $α = 0$.\n",
" On pourra par exemple initialiser l'itération à $α = 10$\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d76a2cbc",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "908ef2507e5f495ee99ddb6ea62f24a9",
"grade": true,
"grade_id": "get_alpha",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function get_alpha(N)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
" return α\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "f119b659",
"metadata": {},
"source": [
"8. Illustrer sur un graphe la variation de la valeur trouvée pour $α$ en fonction de $N$,\n",
" par exemple pour $N \\in \\{10, \\dotsc, 100\\}$."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d077124b-d74f-47fa-a936-2da2f758a557",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "590fc9619511f69233c02a2647340840",
"grade": true,
"grade_id": "plot_alpha",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# YOUR CODE HERE\n",
"throw(ErrorException(\"No code provided\"))"
]
},
{
"cell_type": "markdown",
"id": "1b8b808c",
"metadata": {},
"source": [
"### [Exercice 3] Une équation différentielle à la rescousse"
]
},
{
"cell_type": "markdown",
"id": "e559b563",
"metadata": {},
"source": [
"Les plongeurs amateurs disposent parfois d'une bouée de secours autogonflable,\n",
"qu'ils peuvent utiliser pour remonter rapidement à la surface en cas de problème.\n",
"Cet exercice vise à étudier la remontée d'un plongeur à l'aide d'une telle bouée à laquelle il est attaché,\n",
"et à délimiter les conditions d'utilisation de la bouée afin de garantir une ascension suffisamment rapide.\n",
"On fera plusieurs hypothèses simplificatrices :\n",
"\n",
"- La bouée contient du CO₂, modélisé par un gaz idéal.\n",
"\n",
"- La température du CO₂ dans la bouée est constante, égale à 25°C\n",
"\n",
"- Bien que son volume soit variable en fonction de la pression,\n",
" la bouée reste toujours de forme sphérique.\n",
"\n",
"- Le volume du plongeur est indépendant de sa profondeur.\n",
"\n",
"- Le coefficient du traînée $C_d$ du système \"plongeur + bouée\" est constant, égal à 0.47.\n",
"\n",
"- On néglige la masse à vide de la bouée; toute sa masse provient du CO₂ qu'elle contient."
]
},
{
"cell_type": "markdown",
"id": "ada6bc7f",
"metadata": {},
"source": [
"Les paramètres physiques du problème sont donnés ci-dessous:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "acd3fe20",
"metadata": {},
"outputs": [],
"source": [
"# Temperature [K]\n",
"const T = 298.15 # = 25°C\n",
"\n",
"# Density of water [kg/m³]\n",
"const ρ_w = 1000\n",
"\n",
"# Gravitational acceleration [m/s²]\n",
"const g = 9.81\n",
"\n",
"# Mass of the diver [kg]\n",
"const m_diver = 80\n",
"\n",
"# Volume of the diver [m³]\n",
"const V_diver = .07\n",
"\n",
"# Cross section of diver [m²]\n",
"const A_diver = .25\n",
"\n",
"# Drag coefficient\n",
"const C_d = 0.47\n",
"\n",
"# Universal gas constant [J/mol·K]\n",
"const R = 8.314\n",
"\n",
"# Molar mass of CO₂ [kg/mol]\n",
"const M_CO₂ = 0.04401\n",
"\n",
"# Sea level pressure [Pa]\n",
"const P₀ = 101325"
]
},
{
"cell_type": "markdown",
"id": "b3bea51c",
"metadata": {},
"source": [
"**Remarques**:\n",
"- La densité du plongeur est supérieure à la densité de l'eau. Il s'ensuit que, sans bouée, un plongeur inconscient coulerait.\n",
"\n",
"- La masse de la bouée n'a pas encore été définie,\n",
" car elle a vocation à varier dans cet exercice.\n",
" On la notera `m_buoy`."
]
},
{
"cell_type": "markdown",
"id": "00f7a41e",
"metadata": {},
"source": [
"Notons $z(t)$ la coordonnée verticale du plongeur.\n",
"On supposera, par convention,\n",
"que $z = 0$ correspond au niveau de la surface de l'eau,\n",
"et que $z ≤ 0$ correspond au dessous de la surface.\n",
"Notons aussi $v(t) = \\dot z(t)$,\n",
"la vitesse verticale du plongeur vers le haut.\n",
"\n",
"1. Écrire une fonction `V_buoy(z, m_buoy)`,\n",
" retournant le volume de la bouée à une profondeur $z ≤ 0$,\n",
" lorsque celle-ci contient une masse `m_buoy` de CO₂.\n",
" Pour ce faire, utiliser la loi des gaz parfaits :\n",
" $$\n",
" V = \\frac{n R T}{P},\n",
" \\qquad n := \\frac{m_{\\rm buoy}}{M_{\\rm CO_2}}.\n",
" $$\n",
" Ici $n$ est le nombre de moles de CO₂ contenues dans la bouée.\n",
" On rappelle que la pression hydrostatique à une profondeur $z ≤ 0$ est donnée par\n",
" $$\n",
" P(z) = P_0 - g \\rho_w z.\n",
" $$"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b3bd6e0",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "717bd28f5cd65eb0edf23bd02a2505d5",
"grade": false,
"grade_id": "V_buoy",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# Volume of the buoy at depth `z` (z ≤ 0)\n",
"function V_buoy(z, m_buoy)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end;"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f5187d3e",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "d27043eccfb0e49d16dee56c0472d52b",
"grade": true,
"grade_id": "cell-0eef22c644cfc99f",
"locked": true,
"points": 1,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert V_buoy(0, 1.) ≈ (R * T) / (P₀ * M_CO₂)\n",
"@assert V_buoy(0, 1.)*P₀ ≈ V_buoy(-1, 1.)*(P₀ + ρ_w * g)"
]
},
{
"cell_type": "markdown",
"id": "e3bc2de1",
"metadata": {},
"source": [
"On modélise les forces sur le système,\n",
"toutes dans la direction $z$, comme suit :\n",
"\n",
"- La **force de gravité** est donnée par\n",
"\n",
" $$\n",
" F_g = - m \\cdot g, \\qquad m := m_{\\rm diver} + m_{\\rm buoy}.\n",
" $$\n",
"\n",
"- La **poussée d'Archimède** est donnée par\n",
"\n",
" $$\n",
" F_a(z) = \\rho_w \\cdot V(z) \\cdot g, \\qquad V(z) := V_{\\rm diver} + V_{\\rm buoy}(z).\n",
" $$\n",
"\n",
"- La **force de traînée** est donnée par\n",
" $$\n",
" F_d(v) = - \\frac{1}{2} \\rho_w \\cdot A_{\\rm total} \\cdot C_d \\cdot v^2 \\cdot {\\rm sign}(v).\n",
" $$\n",
" Pour la surface de référence $A_{\\rm total}$,\n",
" on prendra pour simplifier le maximum entre celle de la bouée et celle du plongeur.\n",
" Comme la bouée est supposée sphérique,\n",
" sa surface de référence peut être calculée explicitement,\n",
" et on a donc\n",
" $$\n",
" A_{\\rm total} = \\max\\left\\{ A_{\\rm diver}, π\\left(\\frac{3V_{\\rm buoy}}{4π}\\right)^{\\frac{2}{3}} \\right\\}.\n",
" $$\n",
"\n",
"En appliquant la seconde loi de Newton, on obtient\n",
"une équation différentielle décrivant le mouvement du plongeur :\n",
"$$\n",
"\\tag{EDO}\n",
"\\left\\{\n",
"\\begin{aligned}\n",
"\\dot z &= v, \\\\\n",
"\\dot v &= \\frac{F_g + F_a(z) + F_d(v)}{m_{\\rm diver} + m_{\\rm buoy}}.\n",
"\\end{aligned}\n",
"\\right.\n",
"$$\n",
"\n",
"2. Soit $X = (z, v)^\\top$.\n",
" L'équation (EDO) peut-être réécrite sous la forme\n",
" $$\n",
" \\tag{EDOv}\n",
" \\dot X(t) = f\\bigl(X; m_{\\rm buoy})\n",
" $$\n",
" Écrire la fonction $f$ sous forme d'une fonction Julia `f(X, m_buoy)`,\n",
" où `m_buoy` est vu comme un paramètre."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8fcb790",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "bfabf3a2254c546feb14d31612ebe8fc",
"grade": false,
"grade_id": "f_ode",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# Parameter `A` in the drag force (depends on volume `Vb` of the buoy)\n",
"A_total(Vb) = max(A_diver, π*(3Vb/4π)^(2/3))\n",
"\n",
"function f(X, m_buoy)\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75e24f37",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "a1f6868e5f13839622500231e2487610",
"grade": true,
"grade_id": "cell-e119b00105e73c51",
"locked": true,
"points": 2,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert f([0., 0.], 0.) |> length == 2\n",
"@assert f([0., 0.], 0.)[1] == 0.\n",
"@assert f([0., 5.], 0.)[1] == 5.\n",
"@assert f([-1., 0.], 0.)[2] ≈ f([0., 0.], 0.)[2]\n",
"@assert f([-1., 0.], .1)[2] ≥ f([0., 0.], 0.)[2]\n",
"@assert f([0., 0.], 0.)[2] ≈ -1.22625\n",
"@assert f([0., 0.], .1)[2] ≈ 5.5709364718165455"
]
},
{
"cell_type": "markdown",
"id": "bf139448",
"metadata": {},
"source": [
"3. Écrire une fonction `rkx(Xₙ, h, Δ)` implémentant un pas de temps de taille $\\Delta$ de la méthode de Runge-Kutta suivante pour une équation différentielle générique de la forme $X' = h(X)$:\n",
" $$\n",
" X_{n+1} = X_n + \\frac{\\Delta}{9}\\left(2k_1 + 3k_2 + 4k_3 \\right),\n",
" $$\n",
" où\n",
" \\begin{align*}\n",
" k_1 &= \\ h(X_n), \\\\\n",
" k_2 &= \\ h\\!\\left(X_n + \\frac{\\Delta}{2} k_1\\right), \\\\\n",
" k_3 &= \\ h\\!\\left(X_n + \\frac{3\\Delta}{4} k_2\\right).\n",
" \\end{align*}\n",
" La fonction devra renvoyer $X_{n+1}$."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "79a6cfbd",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "4ab800cf7768833dbc3097c8558f2281",
"grade": false,
"grade_id": "rkx",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# YOUR CODE HERE\n",
"throw(ErrorException(\"No code provided\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a63e1c5a",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "e874d2949b8d0d3a7a47bf8bf1edacfa",
"grade": true,
"grade_id": "cell-35dffc49bd8d021b",
"locked": true,
"points": 1,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert rkx([0.], X -> [1.], 1.) ≈ [1]\n",
"@assert rkx([1.], X -> X, 1.) ≈ [2 + 1/2 + 1/6]"
]
},
{
"cell_type": "markdown",
"id": "1fce2f3e",
"metadata": {},
"source": [
"4. Écrire une fonction `solve_ode(Δ, z₀, m_buoy; tmax=20)` pour résoudre (EDOv)\n",
" avec une condition initiale $X(0) = (z₀, 0)^\\top$,\n",
" en utilisant la méthode de Runge-Kutta de point précédent avec pas de temps fixe `Δ`.\n",
" On supposera que `z₀ < 0`.\n",
" Votre fonction devra renvoyer un vecteur de temps `ts` et un vecteur de vecteurs `Xs` contenant la solution à ces temps.\n",
"\n",
" On calculera le mouvement du plongeur jusqu'à ce qu'il ait atteint la surface,\n",
" ou jusqu'à `tmax` s'il n'a pas atteint la surface après ce temps.\n",
" Il faudra donc que soit `Xs[end][1] ≥ 0`, soit `ts[end] ≥ tmax`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a95fc9a",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "aee13cc888f15b041f4454710150d1b7",
"grade": false,
"grade_id": "solve_ode",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function solve_ode(Δ, z₀, m_buoy; tmax=20)\n",
" X₀ = [z₀; 0.]\n",
" ts = [0.]\n",
" Xs = [X₀]\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
" return ts, Xs\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dd865014",
"metadata": {
"deletable": false,
"editable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "16fa05b1b5fed7274dc49cd91b28e520",
"grade": true,
"grade_id": "cell-362b4d008e1484af",
"locked": true,
"points": 2,
"schema_version": 3,
"solution": false,
"task": false
}
},
"outputs": [],
"source": [
"@assert solve_ode(.01, -1., 0.) |> length == 2\n",
"@assert solve_ode(.01, -1., 0.)[1][end] ≈ 20\n",
"@assert solve_ode(.01, -1., .1)[2][1] |> length == 2\n",
"@assert solve_ode(.01, -1., .1)[2][end][1] ≥ 0\n",
"@assert solve_ode(.01, -1., .1)[2][end-1][1] ≤ 0\n",
"@assert solve_ode(.01, -10., .1)[1][end] > 5\n",
"@assert solve_ode(.01, -10., .1)[1][end] < 6"
]
},
{
"cell_type": "markdown",
"id": "11d21d0c",
"metadata": {},
"source": [
"5. Écrire une fonction `plot_z(Δ, z₀, ms)` permettant d'illustrer sur un même graphe la coordonnée $z$ du plongeur en fonction du temps,\n",
"pour **une** valeur de $z_0$ donnée et **plusieurs** valeurs de `m_buoy` dans le vecteur `ms`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2e1c9dc7",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "0e5b7eb7d6f81cc4e1d51f1ed2c05f54",
"grade": true,
"grade_id": "plot_z",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function plot_z(Δ, z₀, ms)\n",
" p = plot(title=\"Depth of the diver\")\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
" return p\n",
"end\n",
"\n",
"Δ, z₀, ms = .01, -20., [.1, .2, .3]\n",
"plot_z(Δ, z₀, ms)"
]
},
{
"cell_type": "markdown",
"id": "24159795",
"metadata": {},
"source": [
"6. Écrire une fonction `plot_v(Δ, z₀, ms)` permettant d'illustrer sur un même graphe la vitesse du plongeur en fonction du temps,\n",
"pour **une** valeur de $z₀$ donnée et **plusieurs** valeurs de `m_buoy` dans le vecteur `ms`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "911a4324",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "c503b39de38ff37cae2dc8e268a0227f",
"grade": true,
"grade_id": "plot_v",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function plot_v(Δ, z₀, ms)\n",
" p = plot(title=\"Velocity of the diver\")\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
" return p\n",
"end\n",
"\n",
"Δ, z₀, ms = .01, -20., [.1, .2, .3]\n",
"plot_v(Δ, z₀, ms)"
]
},
{
"cell_type": "markdown",
"id": "35241c91",
"metadata": {},
"source": [
"7. On fixe à partir de maintenant la masse de la bouée à `m_buoy = .1`.\n",
" Écrire une fonction `rescue_time(z₀)`,\n",
" qui retourne une approximation du temps mis par le plongeur pour rejoindre la surface\n",
" à partir d'une profondeur initiale $z_0$.\n",
" Pour ce faire, résoudre l'équation différentielle avec un pas de temps fixe $Δ = 0.01$,\n",
" et estimer le temps de sauvetage par interpolation linéaire sur le dernier pas de temps,\n",
" durant lequel la coordonnée $z$ passe au dessus de 0."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "870b3fb7",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "a785d9cdda06ab2cbc187b1ab98ef48c",
"grade": true,
"grade_id": "rescue_time",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"function rescue_time(z₀)\n",
" Δ, m_buoy = .01, .1\n",
" # YOUR CODE HERE\n",
" throw(ErrorException(\"No code provided\"))\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "6b0bf075",
"metadata": {},
"source": [
"8. Faire un plot du temps de remontée en fonction de `z₀`,\n",
" pour des valeurs de ce paramètre dans l'intervalle $[-30, -5]$.\n",
" Estimer graphiquement, par exemple à l'aide de la fonction `vline`,\n",
" la profondeur maximale telle que le plongeur peut rejoindre la surface en moins de 10 secondes grâce à la bouée."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "928d87cf",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "85eddcc0c920e0afb11ae920c143e2d2",
"grade": true,
"grade_id": "plot_rescue_time",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# YOUR CODE HERE\n",
"throw(ErrorException(\"No code provided\"))"
]
},
{
"cell_type": "markdown",
"id": "bd9862f2",
"metadata": {},
"source": [
"9. **Question ouverte**. Afin de déterminer les normes d'utilisation de la bouée,\n",
" calculer avec précision,\n",
" par la méthode de votre choix,\n",
" la valeur de `z₀` permettant au plongeur de rejoindre la surface en exactement 10 secondes.\n",
" Vous pouvez pour ce faire utiliser la bibliothèque `ForwardDiff`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "60161eff",
"metadata": {
"deletable": false,
"nbgrader": {
"cell_type": "code",
"checksum": "44db7d8ed0bfd3e559f1ea095c970a77",
"grade": true,
"grade_id": "bonus",
"locked": false,
"points": 1,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"# YOUR CODE HERE\n",
"throw(ErrorException(\"No code provided\"))"
]
}
],
"metadata": {
"citation-manager": {
"items": {}
},
"jupytext": {
"encoding": "# -*- coding: utf-8 -*-"
},
"kernelspec": {
"display_name": "Julia 1.10.4",
"language": "julia",
"name": "julia-1.10"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.10.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}