diff --git a/EDP/TP/.ipynb_checkpoints/TP_chaleur_python_eleves_2022_2023-checkpoint.ipynb b/EDP/TP/.ipynb_checkpoints/TP_chaleur_python_eleves_2022_2023-checkpoint.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..c8508de92308c7b304b23b386e29ecc7326a22ec --- /dev/null +++ b/EDP/TP/.ipynb_checkpoints/TP_chaleur_python_eleves_2022_2023-checkpoint.ipynb @@ -0,0 +1,578 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<center>\n", + "<h1> Résolution de l'équation de la chaleur par discrétisation différences finies en temps et en espace</h1>\n", + "<h1> Année 2022-2023 - IENM2 </h1>\n", + "<h1> Nom: </h1>\n", + "<h1> Prénom: </h1> \n", + "</center>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Objectifs " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:MistyRose\">\n", + "<br>\n", + "Nous souhaitons résoudre le problème de la chaleur muni de conditions limites de type Dirichlet homogènes suivant:\n", + "<br> \n", + "$$ (P)~ \\left \\{\n", + " \\begin{array}{11}\n", + " \\ \\displaystyle \\frac{\\partial u}{\\partial t}-\\Delta u = f \\, \\, \\, \\, \\, \\, (\\Omega \\times [0, T])\\\\\n", + " \\ u(0,t)=0 \\, \\, \\, \\, \\, \\, (\\partial \\Omega) \\\\\n", + " \\ u(1,t)=0 \\, \\, \\, \\, \\, \\, (\\partial \\Omega) \\\\\n", + " \\ u(x,0)=u_{0}(x) \\, \\, \\, \\, \\, \\, (t=0)\n", + " \\end{array} \n", + " \\right. $$\n", + "<br> \n", + "sur un domaine monodimensionnel $\\Omega$ par une méthode de discrétisation de type différences finies. Nous vous proposons de détailler pas à pas les différentes étapes en réalisant \n", + "systématiquement des tests unitaires afin de valider vos implantations.<br> \n", + "\n", + "Les étapes proposées sont les suivantes:<br>\n", + "- Imposer une solution exacte $ u_{ex}(x,t)$ au problème $(P)$. \n", + "- En déduire une condition initiale $ u_{0}(x)$ au problème $(P)$. \n", + "- En déduire $f$ le terme source associé à $ u_{ex}(x,t)$. \n", + "- Résoudre numériquement $(P)$ en utilisant les schémas d'Euler explicite et implicite. \n", + "- Déterminer numériquement l'ordre de convergence des schémas de discrétisation en temps. \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import des librairies Python nécessaires" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import scipy as sc\n", + "import scipy.sparse as sparse\n", + "import scipy.sparse.linalg\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "#import matplotlib.animation as animation\n", + "import math" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition des paramètres du problème (P)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (<ipython-input-2-e30d73daff6c>, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"<ipython-input-2-e30d73daff6c>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m N_t =\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "# Nombre de pas de discretisation en temps \n", + "N_t = \n", + "# Nombre de pas de discretisation en espace \n", + "M = \n", + "# Nombre de points de discretisation en espace\n", + "N = M + 1\n", + "# Temps final [s]\n", + "T = \n", + "# Pas de discretisation temporel sur [0 T]\n", + "delta_t = T/N_t\n", + "# Pas de discretisation spatial sur le domaine [0,1]\n", + "h = 1/(N-1)\n", + "# Nombre CFL \n", + "c = " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition de la fonction solution exacte choisie, du second membre de l'équation de la chaleur et déduction du schéma de construction associé à la solution exacte " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Indiquer ici le choix de la solution exacte. En déduire le second membre de l'équation définissant le problème (P).\n", + "</div> " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def solution_exacte(x,t):\n", + " \"\"\"\n", + " Fonction representant la solution exacte du probleme de la chaleur. \n", + " Cette fonction doit verifier les conditions initiales et limites sur \n", + " la frontiere du domaine. \n", + " Entrees:\n", + " x: abscisse du point de maillage [float]\n", + " t: temps discret considere [float]\n", + " Sortie:\n", + " Valeur de la solution exacte evaluee en x et au temps t [float]\n", + " \"\"\"\n", + " # A COMPLETER\n", + "\n", + "def second_membre(x, t):\n", + " \"\"\"\n", + " Fonction representant le second membre associe a la solution exacte du probleme \n", + " de la chaleur. \n", + " Entrees:\n", + " x: abscisse du point de maillage [float]\n", + " t: temps discret considere [float]\n", + " Sortie:\n", + " Valeur du second membre evalue en x et au temps t [float]\n", + " \"\"\"\n", + " # A COMPLETER\n", + "\n", + "def schema_exact(N, h, c, T, delta_t, u0):\n", + " \"\"\"\n", + " Fonction representant le tableau bidimensionnel [espace, temps] correspondant a la \n", + " solution en chaque point du maillage et a tout temps discret.\n", + " Entrees:\n", + " N: Nombre de points de discretisation en espace [int]\n", + " h: Pas de maillage spatial [float]\n", + " c: Nombre CFL [float]\n", + " T: Temps final [float]\n", + " delta_t: Pas de discretisation temporel [float]\n", + " u0: condition initiale [array]\n", + " Sortie:\n", + " U_exacte: Tableau bidimensionnel de la solution evaluee en tout x et a tout temps t [float]\n", + " \"\"\"\n", + " # Initialisation de la solution \n", + " \n", + " # Prise en compte de la solution initiale\n", + " \n", + " # Deduction de la solution aux autres instants \n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition de la condition initiale et affichage de la solution exacte pour différents instants " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Definition de la condition initiale comme un tableau monodimensionnel en espace\n", + "#\n", + "u0 = np.zeros(N, dtype=float)\n", + "# A COMPLETER pour avoir votre condition initiale\n", + "\n", + "#\n", + "# Deduction de la solution exacte par appel de la fonction schema_exact\n", + "#\n", + "U = schema_exact(N, h, c, T, delta_t, u0)\n", + "#\n", + "# Representation graphique a differents instants a choisir\n", + "#\n", + "x = np.linspace(0, 1, N)\n", + "plt.plot(x, U[:,0], label=\"à T=0\")\n", + "plt.plot(x, U[:, int(N_t/5)], label=\"à T/5\")\n", + "plt.plot(x, U[:, int(N_t/2)], label=\"à T/2\")\n", + "plt.plot(x, U[:,int(T/delta_t)-1], label=\"à T\" )\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.title(\"Evolution de la température sur la barre pour T=\" + str(T))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construction du schéma explicite en temps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def schema_explicite(N, h, c, T, delta_t, U_explicite):\n", + " \"\"\"\n", + " Fonction representant le tableau bidimensionnel [espace, temps] correspondant a la \n", + " solution en chaque point du maillage et a tout temps discret obtenue avec le schema \n", + " explicite.\n", + " Entrees:\n", + " N: Nombre de points de discretisation en espace [int]\n", + " h: Pas de maillage spatial [float]\n", + " c: Nombre CFL [float]\n", + " T: Temps final [float]\n", + " delta_t: Pas de discretisation temporel [float]\n", + " u0: condition initiale [array]\n", + " Sortie:\n", + " U_explicite: Tableau bidimensionnel de la solution du schema explicite evaluee en tout x et a tout temps t [float]\n", + " \"\"\"\n", + "\n", + " #\n", + " # Création de la matrice A via une matrice creuse (interieur du domaine)\n", + " #\n", + " \n", + " \n", + " #\n", + " # Application du schéma sur les points interieurs\n", + " #\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Affichage de la solution discrète pour le schéma explicite pour différents instants " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "#\n", + "# La condition initiale est celle qui a été définie ci-dessus\n", + "\n", + "#\n", + "# Deduction de la solution du schema explicite en temps\n", + "#\n", + "U_explicite = np.zeros((N, int(T/delta_t)), dtype=float)\n", + "U_explicite[:,0] = u0\n", + "Ue = schema_explicite(N,h,c, T, delta_t, U_explicite)\n", + "#\n", + "# Representation graphique a differents instants a choisir\n", + "#\n", + "x = np.linspace(0, 1, N)\n", + "plt.plot(x, Ue[:,0], label=\"à T=0\")\n", + "plt.plot(x, Ue[:, int(N_t/5)], label=\"à T/5\")\n", + "plt.plot(x, Ue[:, int(N_t/2)], label=\"à T/2\")\n", + "plt.plot(x, Ue[:,int(T/delta_t)-1], label=\"à T\" )\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.title(\"Evolution de la température sur la barre pour T=\" + str(T))\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construction du schéma implicite en temps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def schema_implicite(N,h,c, T, delta_t, U_implicite):\n", + " \"\"\"\n", + " Fonction representant le tableau bidimensionnel [espace, temps] correspondant a la \n", + " solution en chaque point du maillage et a tout temps discret obtenue avec le schema \n", + " explicite.\n", + " Entrees:\n", + " N: Nombre de points de discretisation en espace [int]\n", + " h: Pas de maillage spatial [float]\n", + " c: Nombre CFL [float]\n", + " T: Temps final [float]\n", + " delta_t: Pas de discretisation temporel [float]\n", + " u0: condition initiale [array]\n", + " Sortie:\n", + " U_implicite: Tableau bidimensionnel de la solution du schema implicite evaluee en tout x et a tout temps t [float]\n", + " \"\"\"\n", + " #\n", + " # Création de la matrice A via une matrice creuse\n", + " #\n", + " \n", + " #\n", + " # Application du schéma sur les points interieurs\n", + " # \n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Affichage de la solution discrète pour le schéma implicite pour différents instants " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# La condition initiale est celle qui a été définie ci-dessus\n", + "\n", + "#\n", + "# Deduction de la solution du schema implicite en temps\n", + "#\n", + "U_implicite = np.zeros((N, int(T/delta_t)), dtype=float)\n", + "U_implicite[:,0] = u0\n", + "Ui = schema_implicite(N,h,c, T, delta_t, U_implicite)\n", + "#\n", + "# Representation graphique a differents instants a choisir\n", + "#\n", + "x = np.linspace(0, 1, N)\n", + "plt.plot(x, Ui[:,0], label=\"à T=0\")\n", + "plt.plot(x, Ui[:, int(N_t/5)], label=\"à T/5\")\n", + "plt.plot(x, Ui[:, int(N_t/2)], label=\"à T/2\")\n", + "plt.plot(x, Ui[:,int(T/delta_t)-1], label=\"à T\" )\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.title(\"Evolution de la température sur la barre pour T=\" + str(T))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Détermination de l'ordre de convergence des schémas de discrétisation en temps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Indiquer ici comment vous calculez cet ordre de convergence. Quelle est la valeur attendue pour les schémas d'Euler explicite ou implicite ? Vérifier ce résultat graphiquement. \n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def erreur(U_exacte, U, h):\n", + " \"\"\"\n", + " Calcul de l'erreur discrete \n", + " Entrees:\n", + " U_exacte: solution exacte du probleme considere [float]\n", + " U : solution discrete pour un schema donne [float]\n", + " h : pas de discretisation spatial [float]\n", + " Sortie: \n", + " norme de l'erreur discrete [float]\n", + " \"\"\"\n", + " # A COMPLETER" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def ordre_discretisation_temps(h, N, T):\n", + " \"\"\"\n", + " Calcul de l'ordre de discretisation en temps\n", + " Entrées : \n", + " h: pas de discretisation spatial [float]\n", + " N: nombre de points de discretisation en espace [int]\n", + " T: temps final [float]\n", + " Sortie : \n", + " time_step: pas de temps en loi log [float, array]\n", + " erreur : erreur en loi log[float, array]\n", + " \"\"\"\n", + " time_step = np.zeros(10)\n", + " error = np.zeros(10)\n", + " count = 0\n", + " \n", + " for loop in range(20, 120, 10):\n", + " delta = 1./loop\n", + " c = delta/(h**2)\n", + " #\n", + " # Initialisation pour la solution exacte\n", + " #\n", + " u0 = np.zeros(N, dtype=float)\n", + " # A COMPLETER\n", + " U_exacte = schema_exact(N, h, c, T, delta, u0) \n", + " #\n", + " # Initialisation pour la solution numérique\n", + " #\n", + " U_implicite = np.zeros((N, int(T/delta)), dtype=float)\n", + " u0 = np.zeros(N, dtype=float)\n", + " # A COMPLETER\n", + " U_implicite[:,0] = u0\n", + " #\n", + " #\n", + " #\n", + " U_implicite = schema_implicite(N, h, c, T, delta, U_implicite)\n", + " error[count] = math.log(erreur(U_exacte, U_implicite, h))\n", + " time_step[count] = math.log(delta) \n", + " count += 1\n", + " \n", + " return time_step, error" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Construction des elements pour l'analyse du schema\n", + "#\n", + "time_step, error = ordre_discretisation_temps(h, N, T)\n", + "\n", + "#\n", + "# Creation de la figure\n", + "#\n", + "theta = 1.0\n", + "fig = plt.figure()\n", + "plt.plot(time_step,error,marker='*',color='blue',label='Euler implicite (theta='\"%3.2f\"%theta+')')\n", + "plt.plot(time_step,1.*time_step,color='red',label='Ordre 1 en temps')\n", + "plt.plot(time_step,2.*time_step,color='green',label='Ordre 2 en temps')\n", + "plt.xlabel(\"Log(Delta t)\")\n", + "plt.ylabel(\"Log(Norme de l'erreur)\")\n", + "plt.title('Analyse de convergence: Equation de la chaleur')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Indiquer ici l'ordre de convergence obtenu effectivement. Obtenez-vous le comportement obtenu ? \n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Affichage des donnees pour validation et inter-comparaison\n", + "#\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Schéma de discrétisation en temps du second ordre" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Résoudre (P) cette fois avec le schéma temporel d'ordre deux implicite Crank-Nicolson. Commenter votre code pour indiquer les changements effectués. Vérifier par une méthodologie identique l'ordre de convergence de ce schéma. \n", + "</div>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bonus: Généralisation pour des conditions limites spatiales non homogènes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:MistyRose\">\n", + "<br>\n", + "Nous souhaitons résoudre désormais le problème de la chaleur muni de conditions limites de \n", + "type Dirichlet non homogènes suivant:\n", + "<br> \n", + "$$ (P_{nh}) ~ \\left \\{\n", + " \\begin{array}{11}\n", + " \\ \\displaystyle \\frac{\\partial u}{\\partial t}-\\Delta u = f \\, \\, \\, \\, \\, \\, (\\Omega \\times [0, T]),\\\\\n", + " \\ u(0,t)= u_g{(t)} \\, \\, \\, \\, \\, \\, (\\partial \\Omega), \\\\\n", + " \\ u(1,t)= u_d{(t)} \\, \\, \\, \\, \\, \\, (\\partial \\Omega), \\\\\n", + " \\ u(x,0)= u_{0}(x) \\, \\, \\, \\, \\, \\, (t=0),\n", + " \\end{array} \n", + " \\right. $$\n", + "<br> \n", + "sur un domaine monodimensionnel $\\Omega$ par une méthode de discrétisation de type différences finies.<br> \n", + "\n", + "Reprendre les étapes proposées précédemment:\n", + "\n", + "- Imposer une condition initiale et une solution exacte $ u_{ex}(x,t)$ au problème $(P_{nh})$. \n", + "- En déduire $f$ le terme source associé à $ u_{ex}$. \n", + "- Résoudre numériquement $(P_{nh})$ en utilisant un schéma de votre choix. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.6.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/EDP/TP/TP_chaleur_python_eleves_2022_2023.ipynb b/EDP/TP/TP_chaleur_python_eleves_2022_2023.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..c8508de92308c7b304b23b386e29ecc7326a22ec --- /dev/null +++ b/EDP/TP/TP_chaleur_python_eleves_2022_2023.ipynb @@ -0,0 +1,578 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<center>\n", + "<h1> Résolution de l'équation de la chaleur par discrétisation différences finies en temps et en espace</h1>\n", + "<h1> Année 2022-2023 - IENM2 </h1>\n", + "<h1> Nom: </h1>\n", + "<h1> Prénom: </h1> \n", + "</center>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Objectifs " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:MistyRose\">\n", + "<br>\n", + "Nous souhaitons résoudre le problème de la chaleur muni de conditions limites de type Dirichlet homogènes suivant:\n", + "<br> \n", + "$$ (P)~ \\left \\{\n", + " \\begin{array}{11}\n", + " \\ \\displaystyle \\frac{\\partial u}{\\partial t}-\\Delta u = f \\, \\, \\, \\, \\, \\, (\\Omega \\times [0, T])\\\\\n", + " \\ u(0,t)=0 \\, \\, \\, \\, \\, \\, (\\partial \\Omega) \\\\\n", + " \\ u(1,t)=0 \\, \\, \\, \\, \\, \\, (\\partial \\Omega) \\\\\n", + " \\ u(x,0)=u_{0}(x) \\, \\, \\, \\, \\, \\, (t=0)\n", + " \\end{array} \n", + " \\right. $$\n", + "<br> \n", + "sur un domaine monodimensionnel $\\Omega$ par une méthode de discrétisation de type différences finies. Nous vous proposons de détailler pas à pas les différentes étapes en réalisant \n", + "systématiquement des tests unitaires afin de valider vos implantations.<br> \n", + "\n", + "Les étapes proposées sont les suivantes:<br>\n", + "- Imposer une solution exacte $ u_{ex}(x,t)$ au problème $(P)$. \n", + "- En déduire une condition initiale $ u_{0}(x)$ au problème $(P)$. \n", + "- En déduire $f$ le terme source associé à $ u_{ex}(x,t)$. \n", + "- Résoudre numériquement $(P)$ en utilisant les schémas d'Euler explicite et implicite. \n", + "- Déterminer numériquement l'ordre de convergence des schémas de discrétisation en temps. \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import des librairies Python nécessaires" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import scipy as sc\n", + "import scipy.sparse as sparse\n", + "import scipy.sparse.linalg\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "#import matplotlib.animation as animation\n", + "import math" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition des paramètres du problème (P)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (<ipython-input-2-e30d73daff6c>, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"<ipython-input-2-e30d73daff6c>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m N_t =\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "# Nombre de pas de discretisation en temps \n", + "N_t = \n", + "# Nombre de pas de discretisation en espace \n", + "M = \n", + "# Nombre de points de discretisation en espace\n", + "N = M + 1\n", + "# Temps final [s]\n", + "T = \n", + "# Pas de discretisation temporel sur [0 T]\n", + "delta_t = T/N_t\n", + "# Pas de discretisation spatial sur le domaine [0,1]\n", + "h = 1/(N-1)\n", + "# Nombre CFL \n", + "c = " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition de la fonction solution exacte choisie, du second membre de l'équation de la chaleur et déduction du schéma de construction associé à la solution exacte " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Indiquer ici le choix de la solution exacte. En déduire le second membre de l'équation définissant le problème (P).\n", + "</div> " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def solution_exacte(x,t):\n", + " \"\"\"\n", + " Fonction representant la solution exacte du probleme de la chaleur. \n", + " Cette fonction doit verifier les conditions initiales et limites sur \n", + " la frontiere du domaine. \n", + " Entrees:\n", + " x: abscisse du point de maillage [float]\n", + " t: temps discret considere [float]\n", + " Sortie:\n", + " Valeur de la solution exacte evaluee en x et au temps t [float]\n", + " \"\"\"\n", + " # A COMPLETER\n", + "\n", + "def second_membre(x, t):\n", + " \"\"\"\n", + " Fonction representant le second membre associe a la solution exacte du probleme \n", + " de la chaleur. \n", + " Entrees:\n", + " x: abscisse du point de maillage [float]\n", + " t: temps discret considere [float]\n", + " Sortie:\n", + " Valeur du second membre evalue en x et au temps t [float]\n", + " \"\"\"\n", + " # A COMPLETER\n", + "\n", + "def schema_exact(N, h, c, T, delta_t, u0):\n", + " \"\"\"\n", + " Fonction representant le tableau bidimensionnel [espace, temps] correspondant a la \n", + " solution en chaque point du maillage et a tout temps discret.\n", + " Entrees:\n", + " N: Nombre de points de discretisation en espace [int]\n", + " h: Pas de maillage spatial [float]\n", + " c: Nombre CFL [float]\n", + " T: Temps final [float]\n", + " delta_t: Pas de discretisation temporel [float]\n", + " u0: condition initiale [array]\n", + " Sortie:\n", + " U_exacte: Tableau bidimensionnel de la solution evaluee en tout x et a tout temps t [float]\n", + " \"\"\"\n", + " # Initialisation de la solution \n", + " \n", + " # Prise en compte de la solution initiale\n", + " \n", + " # Deduction de la solution aux autres instants \n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Définition de la condition initiale et affichage de la solution exacte pour différents instants " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Definition de la condition initiale comme un tableau monodimensionnel en espace\n", + "#\n", + "u0 = np.zeros(N, dtype=float)\n", + "# A COMPLETER pour avoir votre condition initiale\n", + "\n", + "#\n", + "# Deduction de la solution exacte par appel de la fonction schema_exact\n", + "#\n", + "U = schema_exact(N, h, c, T, delta_t, u0)\n", + "#\n", + "# Representation graphique a differents instants a choisir\n", + "#\n", + "x = np.linspace(0, 1, N)\n", + "plt.plot(x, U[:,0], label=\"à T=0\")\n", + "plt.plot(x, U[:, int(N_t/5)], label=\"à T/5\")\n", + "plt.plot(x, U[:, int(N_t/2)], label=\"à T/2\")\n", + "plt.plot(x, U[:,int(T/delta_t)-1], label=\"à T\" )\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.title(\"Evolution de la température sur la barre pour T=\" + str(T))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construction du schéma explicite en temps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def schema_explicite(N, h, c, T, delta_t, U_explicite):\n", + " \"\"\"\n", + " Fonction representant le tableau bidimensionnel [espace, temps] correspondant a la \n", + " solution en chaque point du maillage et a tout temps discret obtenue avec le schema \n", + " explicite.\n", + " Entrees:\n", + " N: Nombre de points de discretisation en espace [int]\n", + " h: Pas de maillage spatial [float]\n", + " c: Nombre CFL [float]\n", + " T: Temps final [float]\n", + " delta_t: Pas de discretisation temporel [float]\n", + " u0: condition initiale [array]\n", + " Sortie:\n", + " U_explicite: Tableau bidimensionnel de la solution du schema explicite evaluee en tout x et a tout temps t [float]\n", + " \"\"\"\n", + "\n", + " #\n", + " # Création de la matrice A via une matrice creuse (interieur du domaine)\n", + " #\n", + " \n", + " \n", + " #\n", + " # Application du schéma sur les points interieurs\n", + " #\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Affichage de la solution discrète pour le schéma explicite pour différents instants " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "#\n", + "# La condition initiale est celle qui a été définie ci-dessus\n", + "\n", + "#\n", + "# Deduction de la solution du schema explicite en temps\n", + "#\n", + "U_explicite = np.zeros((N, int(T/delta_t)), dtype=float)\n", + "U_explicite[:,0] = u0\n", + "Ue = schema_explicite(N,h,c, T, delta_t, U_explicite)\n", + "#\n", + "# Representation graphique a differents instants a choisir\n", + "#\n", + "x = np.linspace(0, 1, N)\n", + "plt.plot(x, Ue[:,0], label=\"à T=0\")\n", + "plt.plot(x, Ue[:, int(N_t/5)], label=\"à T/5\")\n", + "plt.plot(x, Ue[:, int(N_t/2)], label=\"à T/2\")\n", + "plt.plot(x, Ue[:,int(T/delta_t)-1], label=\"à T\" )\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.title(\"Evolution de la température sur la barre pour T=\" + str(T))\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construction du schéma implicite en temps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def schema_implicite(N,h,c, T, delta_t, U_implicite):\n", + " \"\"\"\n", + " Fonction representant le tableau bidimensionnel [espace, temps] correspondant a la \n", + " solution en chaque point du maillage et a tout temps discret obtenue avec le schema \n", + " explicite.\n", + " Entrees:\n", + " N: Nombre de points de discretisation en espace [int]\n", + " h: Pas de maillage spatial [float]\n", + " c: Nombre CFL [float]\n", + " T: Temps final [float]\n", + " delta_t: Pas de discretisation temporel [float]\n", + " u0: condition initiale [array]\n", + " Sortie:\n", + " U_implicite: Tableau bidimensionnel de la solution du schema implicite evaluee en tout x et a tout temps t [float]\n", + " \"\"\"\n", + " #\n", + " # Création de la matrice A via une matrice creuse\n", + " #\n", + " \n", + " #\n", + " # Application du schéma sur les points interieurs\n", + " # \n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Affichage de la solution discrète pour le schéma implicite pour différents instants " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# La condition initiale est celle qui a été définie ci-dessus\n", + "\n", + "#\n", + "# Deduction de la solution du schema implicite en temps\n", + "#\n", + "U_implicite = np.zeros((N, int(T/delta_t)), dtype=float)\n", + "U_implicite[:,0] = u0\n", + "Ui = schema_implicite(N,h,c, T, delta_t, U_implicite)\n", + "#\n", + "# Representation graphique a differents instants a choisir\n", + "#\n", + "x = np.linspace(0, 1, N)\n", + "plt.plot(x, Ui[:,0], label=\"à T=0\")\n", + "plt.plot(x, Ui[:, int(N_t/5)], label=\"à T/5\")\n", + "plt.plot(x, Ui[:, int(N_t/2)], label=\"à T/2\")\n", + "plt.plot(x, Ui[:,int(T/delta_t)-1], label=\"à T\" )\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.title(\"Evolution de la température sur la barre pour T=\" + str(T))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Détermination de l'ordre de convergence des schémas de discrétisation en temps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Indiquer ici comment vous calculez cet ordre de convergence. Quelle est la valeur attendue pour les schémas d'Euler explicite ou implicite ? Vérifier ce résultat graphiquement. \n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def erreur(U_exacte, U, h):\n", + " \"\"\"\n", + " Calcul de l'erreur discrete \n", + " Entrees:\n", + " U_exacte: solution exacte du probleme considere [float]\n", + " U : solution discrete pour un schema donne [float]\n", + " h : pas de discretisation spatial [float]\n", + " Sortie: \n", + " norme de l'erreur discrete [float]\n", + " \"\"\"\n", + " # A COMPLETER" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def ordre_discretisation_temps(h, N, T):\n", + " \"\"\"\n", + " Calcul de l'ordre de discretisation en temps\n", + " Entrées : \n", + " h: pas de discretisation spatial [float]\n", + " N: nombre de points de discretisation en espace [int]\n", + " T: temps final [float]\n", + " Sortie : \n", + " time_step: pas de temps en loi log [float, array]\n", + " erreur : erreur en loi log[float, array]\n", + " \"\"\"\n", + " time_step = np.zeros(10)\n", + " error = np.zeros(10)\n", + " count = 0\n", + " \n", + " for loop in range(20, 120, 10):\n", + " delta = 1./loop\n", + " c = delta/(h**2)\n", + " #\n", + " # Initialisation pour la solution exacte\n", + " #\n", + " u0 = np.zeros(N, dtype=float)\n", + " # A COMPLETER\n", + " U_exacte = schema_exact(N, h, c, T, delta, u0) \n", + " #\n", + " # Initialisation pour la solution numérique\n", + " #\n", + " U_implicite = np.zeros((N, int(T/delta)), dtype=float)\n", + " u0 = np.zeros(N, dtype=float)\n", + " # A COMPLETER\n", + " U_implicite[:,0] = u0\n", + " #\n", + " #\n", + " #\n", + " U_implicite = schema_implicite(N, h, c, T, delta, U_implicite)\n", + " error[count] = math.log(erreur(U_exacte, U_implicite, h))\n", + " time_step[count] = math.log(delta) \n", + " count += 1\n", + " \n", + " return time_step, error" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Construction des elements pour l'analyse du schema\n", + "#\n", + "time_step, error = ordre_discretisation_temps(h, N, T)\n", + "\n", + "#\n", + "# Creation de la figure\n", + "#\n", + "theta = 1.0\n", + "fig = plt.figure()\n", + "plt.plot(time_step,error,marker='*',color='blue',label='Euler implicite (theta='\"%3.2f\"%theta+')')\n", + "plt.plot(time_step,1.*time_step,color='red',label='Ordre 1 en temps')\n", + "plt.plot(time_step,2.*time_step,color='green',label='Ordre 2 en temps')\n", + "plt.xlabel(\"Log(Delta t)\")\n", + "plt.ylabel(\"Log(Norme de l'erreur)\")\n", + "plt.title('Analyse de convergence: Equation de la chaleur')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Indiquer ici l'ordre de convergence obtenu effectivement. Obtenez-vous le comportement obtenu ? \n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Affichage des donnees pour validation et inter-comparaison\n", + "#\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Schéma de discrétisation en temps du second ordre" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:LightGrey\">\n", + "Résoudre (P) cette fois avec le schéma temporel d'ordre deux implicite Crank-Nicolson. Commenter votre code pour indiquer les changements effectués. Vérifier par une méthodologie identique l'ordre de convergence de ce schéma. \n", + "</div>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bonus: Généralisation pour des conditions limites spatiales non homogènes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<div style=\"background:MistyRose\">\n", + "<br>\n", + "Nous souhaitons résoudre désormais le problème de la chaleur muni de conditions limites de \n", + "type Dirichlet non homogènes suivant:\n", + "<br> \n", + "$$ (P_{nh}) ~ \\left \\{\n", + " \\begin{array}{11}\n", + " \\ \\displaystyle \\frac{\\partial u}{\\partial t}-\\Delta u = f \\, \\, \\, \\, \\, \\, (\\Omega \\times [0, T]),\\\\\n", + " \\ u(0,t)= u_g{(t)} \\, \\, \\, \\, \\, \\, (\\partial \\Omega), \\\\\n", + " \\ u(1,t)= u_d{(t)} \\, \\, \\, \\, \\, \\, (\\partial \\Omega), \\\\\n", + " \\ u(x,0)= u_{0}(x) \\, \\, \\, \\, \\, \\, (t=0),\n", + " \\end{array} \n", + " \\right. $$\n", + "<br> \n", + "sur un domaine monodimensionnel $\\Omega$ par une méthode de discrétisation de type différences finies.<br> \n", + "\n", + "Reprendre les étapes proposées précédemment:\n", + "\n", + "- Imposer une condition initiale et une solution exacte $ u_{ex}(x,t)$ au problème $(P_{nh})$. \n", + "- En déduire $f$ le terme source associé à $ u_{ex}$. \n", + "- Résoudre numériquement $(P_{nh})$ en utilisant un schéma de votre choix. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.6.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/EDP/TP/slide-intro-TP.pdf b/EDP/TP/slide-intro-TP.pdf new file mode 100644 index 0000000000000000000000000000000000000000..82ae1b99c604d283794b51a9424cef756c08f9f1 Binary files /dev/null and b/EDP/TP/slide-intro-TP.pdf differ