{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Vibrations d'une corde inhomogène" ] }, { "attachments": { "string.png": { "image/png": "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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "Les oscillations d'une corde de masse linéique constante sont décrites, bien sûr, par l'équation d'ondes:\n", "$$\\left(\\frac{\\partial^2}{\\partial x^2}-\\frac{1}{c^2}\\frac{\\partial^2}{\\partial t^2}\\right)\\phi(x, t)=0\\,.$$\n", "Ici $c^2=\\tau/\\mu$ est la vitesse de propagation des ondes, $\\tau$ est la tension et $\\mu$ est la masse linéique.\n", "Si les extrémités de la corde à $x=0$ et à $x=L$ sont fixes, alors les ondes stationnaires sont les superpositions des modes sinusoïdales,\n", "$$\\phi(x, t)=\\sum_n A_n X_n(x) T_n(t)\\quad\\text{avec}\\quad X_n(x)=\\sin\\frac{n\\pi x}{L}\\,,\\quad T_n(t)=\\sin\\omega_n(t-t_0)\\,,\\quad\\omega_n=\\frac{n\\pi c}{L}\\,.$$\n", "\n", "\n", "Mais si la masse linéique $\\mu$ de la corde est une fonction de $x$? On pourrait par exemple imaginer une corde dont l'épaisseur croît linéairement avec $x$, alors la section transversale et donc la masse linéique seront des fonctions quadratiques de $x$.\n", "![string.png](attachment:string.png)\n", "\n", "Si le rayon de la corde à $x=L$ est deux fois plus grand que son rayon à $x=0$, alors\n", "$$\n", "\\mu(x)=\\mu_0\\left(1+\\frac{x}{L}\\right)^2\\,.\n", "$$\n", "\n", "L'équation d'ondes devient\n", "$$\n", "\\left(\\frac{\\partial^2}{\\partial x^2}-\\frac{\\mu(x)}{\\tau}\\frac{\\partial^2}{\\partial t^2}\\right)\\phi(x, t)=0\n", "$$\n", "En posant $\\phi(x,t)=X(x) T(t)$ on obtient\n", "$$\n", "\\frac{\\tau}{X(x)\\mu(x)}\\frac{\\partial^2X}{\\partial x^2}=\\frac{1}{T}\\frac{\\partial^2 T}{\\partial t^2}\\,.\n", "$$\n", "Puisque le membre de droite de cette équation ne dépend pas de $x$ et le membre de gauche ne dépend pas de $t$, on conclut que les deux membres sont constants,\n", "$$\n", "\\frac{1}{T}\\frac{\\partial^2 T}{\\partial t^2}=\\omega^2\\,,\\qquad \\frac{\\tau}{X(x)\\mu(x)}\\frac{\\partial^2X}{\\partial x^2}=\\omega^2\\,.\n", "$$\n", "On a alors\n", "$$\n", "\\frac{\\partial^2 T}{\\partial t^2}+\\omega^2 T=0\n", "$$\n", "et $T(t)$ est une fonction sinusoïdale comme avant. Par contre, pour la fonction $X(x)$ on trouve l'équation différentielle\n", "$$\n", "\\boxed{\\frac{\\tau}{\\mu_0\\left(1+\\frac{x}{L}\\right)^2}\\frac{\\partial^2X}{\\partial x^2}=-\\omega^2 X\\,.}\n", "$$\n", "On va adopter des unités tels que $L=1$, $\\tau=1$ et $\\mu_0=1$. Notre objectif sera alors de trouver les valeurs propres et les vecteurs propres de l'opérateur différentiel\n", "$$\n", "{\\cal D}=\\frac{1}{\\left(1+x\\right)^2}\\frac{\\partial^2}{\\partial x^2}\n", "$$\n", "avec les conditions aux limites $X(0)=X(1)=0$. Les valeurs propres nous donneront les fréquences possibles $\\omega$ et les vecteurs propres nous donneront l'aspect des ondes stationnaires en fonction de $x$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " **Exo 1:** Sur papier, trouver la forme discrétisée de l'opérateur ${\\cal D}$. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " **Exo 2:** Implémenter la discrétisation de l'opérateur $\\frac{1}{(1+x)^2}$ en Python. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "# Une fonction qui retourne une représentation discrétisée en matrice (N+1) x (N+1) de l'opérateur 1 /(1+x)^2\n", "def matrice1sur1px2(N):\n", " # à vous de compléter!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour obtenir les bonnes conditions aux limites, on peut suivre le raisonnement de l'exemple de la membrane vibrante. En fait, ici la situation est un peu plus simple car il faut seulement forcer $X(0)=0$ et $X(Na)=X(1)=0$. Alors la première ligne de la matrice qui représente ${\\cal D}$ doit être $(\\Omega\\;0\\;0\\,\\ldots 0)$ et la dernière ligne doit être $(0\\;0\\;0\\,\\ldots 0\\;\\Omega)$, avec $|\\Omega|$ suffisamment grand. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exo 3:** Implémenter l'opérateur ${\\cal D}$ en Python, y inclus les conditions aux limites.
*Indication*: pour l'opérateur $\\partial^2/\\partial x^2$ vous pouvez vous servir des exemples du cours.
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Une fonction qui retourne une représentation matricielle (N+1) x (N+1) de l'opérateur D\n", "def matriceD(N):\n", " LARGE = 1.E10\n", " # à vous de compléter!\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Maintenant on va chercher les valeurs propres et les vecteurs propres de cette matrice." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exo 4:** Trouver les valeurs propres et les vecteurs propres correspondants pour $N=200$ et les stocker dans deux tableaux **valeurs** et **vecteurs**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import scipy.linalg\n", "# à vous de compléter!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les tableaux **valeurs** et **vecteurs** ne sont pas encore triés. Pour obtenir les premiers modes aux fréquences $\\omega$ les plus basses, il convient de créer un tableau **indices** d'indices, où **indices[0]** correspond à l'indice de la plus petite valeur propre et **indices[N]** à l'indice de la plus grande. Ceci se fait avec la fonction **numpy.argsort** comme suit:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "indices = np.argsort(np.abs(valeurs))\n", "# Maintenant valeurs[indices[i]] est la fréquence du i-ème mode et vecteurs[:, indices[i]] est sa fonction propre." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Enfin on va afficher les résultats. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exo 5:** Tracer les premiers 3 modes dans une figure et le 7ème - 9ème dans une deuxième. Afficher les fréquences $\\omega$ correspondantes. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "# à vous de compléter!\n" ] } ], "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.9" } }, "nbformat": 4, "nbformat_minor": 2 }