"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"# la librairie time nous sera utile pour calculer le temps d'execution des scripts\n",
"import time \n",
"#Option d'affichage et taille de police sur les figures:\n",
"fs=20\n",
"plt.rc('xtick',labelsize=fs)\n",
"plt.rc('ytick',labelsize=fs)\n",
"#plt.rc('text', usetex=True)\n",
"%matplotlib inline "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"On se propose dans ce TP, de représenter et d'analyser des données issues d'une simulation numérique.\n",
"\n",
"Pour cela on dispose de 3 fichiers:\n",
"\n",
"* CM_rho.dat qui contient les données de pression \n",
"* CM_UX.dat qui contient les données de vitesse longitudinal\n",
"* CM_UY.dat qui contient les données de vitesse transversal\n",
"\n",
"\n",
"Ces données sont issues d'une simulation numérique de l'écoulement autour d'un cylindre de diamètre $D$ pour un nombre de Mach de $M_\\infty=0.2$ réalisée sur un maillage structuré uniforme de $400\\times200$ mailles. Le centre du cylindre est situé au point $[50,100]$ et son coté est représenté à l'aide de 10 mailles.($D=10$). Les données des fichiers de vitesse sont normalisées par une grandeur de référence: $U_0=588.89$ m/s. Les grandeurs de masse volumique sont normailsées par $\\rho_0=1.22 kg/m^3$. On prendra dans pour ce TP la vitesse du son à température normale (20°C) soit $c_\\infty=340$m/s. \n",
"\n",
"Les objectifs de ce TP sont:\n",
"* Représenter des données en 2D\n",
"* Extraires des informations de ces données\n",
"* Calculer d'autres grandeurs issues de ces données.\n",
"\n",
"\n",
"
1 - Chargement des données
\n",
"\n",
"D'abord, afin de pouvoir utiliser les données et les représenter, il faut les charger en mémoire c'est à dire lire le fichier de données et les stocker dans un tableau. Pour cela il existe de nombreux moyen en Python. Pour ce TP nous utiliserons la fonction fromfile de numpy qui permet de lire des données binaires. \n",
"\n",
"Uniquement la première fois que vous executez ce notebook, vous devez télécharger les données en décommentant les lignes suivantes:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#! wget http://hpp.education/Lessons/CFD_FIP/Files/CM_rho.dat\n",
"#! wget http://hpp.education/Lessons/CFD_FIP/Files/CM_UX.dat\n",
"#! wget http://hpp.education/Lessons/CFD_FIP/Files/CM_UY.dat"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ensuite, après avoir calculé la valeur de $U_\\infty$ on charge les données que l'on va renormaliser:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nx,ny=?,?\n",
"U0,Uinf,rho0=?,?,?\n",
"rho=rho0*np.fromfile('CM_rho.dat').reshape(ny,nx)\n",
"ux=U0*np.fromfile('CM_UX.dat').reshape(ny,nx)/Uinf\n",
"uy=U0*np.fromfile('CM_UY.dat').reshape(ny,nx)/Uinf\n",
"rho.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A partir des données chargées, retouver les valuer min, max et moyenne pour la vitesse longitudinale (la vitesse moyenne doit être proche de 1):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(ux.min(),ux.max(),ux.mean())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
2 - Visualisation des données
\n",
"\n",
"Maintenant que les données sont en mémoire, nous pouvons les \"visualiser\" en utilisant les fonctions de visualisation 2D. Familiarisez-vous avec les lignes suivantes et comparez les fonctions ***pcolormesh*** et ***contourf***. On pourra également changer les colormap en modifiant le paramètre *cmap*. (Les colormap de matplotlib sont disponibles ici)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(14,6))\n",
"plt.pcolormesh(rho,cmap=\"jet\",shading=\"gouraud\")\n",
"plt.axis('equal')\n",
"plt.xlabel('$X$',fontsize=fs)\n",
"plt.ylabel('$Y$',fontsize=fs)\n",
"plt.colorbar()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(14,6))\n",
"plt.pcolormesh(ux,cmap=\"Greys\",shading=\"gouraud\")\n",
"plt.axis('equal')\n",
"plt.xlabel('$X$',fontsize=fs)\n",
"plt.ylabel('$Y$',fontsize=fs)\n",
"plt.colorbar()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(14,6))\n",
"plt.pcolormesh(uy,cmap=\"jet\",shading=\"gouraud\")\n",
"plt.axis('equal')\n",
"plt.xlabel('$X$',fontsize=fs)\n",
"plt.ylabel('$Y$',fontsize=fs)\n",
"plt.colorbar()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Commentaires:\n",
"\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il peut également être utile de représenter une certaine partie des données.\n",
"\n",
"A partir des données chargées, tracer deux profils de pression en amont et en aval du profil:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(16,6))\n",
"x1,x2=40,60\n",
"plt.plot(rho[:,x1],'b',label=\"x=\"+str(x1))\n",
"plt.plot(rho[:,x2],'r',label=\"x=\"+str(x2))\n",
"plt.xlabel('$Y$',fontsize=fs)\n",
"plt.legend(fontsize=fs);plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Même chose pour le profil de vitesse en choisissant 3 lignes longitudinales dont celle qui passe par le plan de symétrie:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y1,y2,y3=?,?,?\n",
"\n",
"plt.figure(figsize=(16,6))\n",
"plt.plot(ux[y1,:],'b',label=\"y=\"+str(y1))\n",
"plt.plot(ux[y2,:],'k',label=\"y=\"+str(y2))\n",
"plt.plot(ux[y3,:],'r',label=\"y=\"+str(y3))\n",
"plt.xlabel('$X$',fontsize=fs)\n",
"plt.legend(fontsize=fs);plt.grid(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Commentaires:\n",
"\n",
"\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"