Blog : Tracer l’allée de tourbillons de von Karman
Imaginons que nous ayons besoin de cartes de contours de vitesse au format vectoriel (SVG, PDF).
En général, on utilise Matplotlib à cette fin. La bibliothèque inclut la
fonction tricontourf, capable de trianguler directement les données. Cependant,
nous avons ici un “trou” au milieu du domaine (le cylindre) qui ne doit surtout
pas être triangulé. Nous exploitons donc le fichier VTK issu de l’objet fonction
cuttingPlane.
Le tracé se divise en deux étapes : la préparation des données et le tracé proprement dit.
Pour la préparation, nous utilisons le module Python de VTK afin de lire les
données et de les trianguler proprement pour Matplotlib. Nous en extrayons
ensuite les sommets, les valeurs de vitesse et les triangles, qui sont
directement transmis à la fonction tricontourf.
Voici le code Python correspondant.
D’abord, nous importons les modules nécessaires :
#!/usr/bin/env python3
import vtk
from vtk.util import numpy_support
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
Le premier est VTK, servant à lire et manipuler la sortie de
l’objet fonction. Nous importons ensuite NumPy pour la
manipulation rapide de tableaux, et enfin Matplotlib
pour le tracé. make_axes_locatable est nécessaire pour ajuster la barre de
couleurs (colorbar).
reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName('postProcessing/surfacesf/200/centerPlane.vtp')
reader.Update()
data = reader.GetOutput()
triangle_filter = vtk.vtkTriangleFilter()
triangle_filter.SetInputData(data)
triangle_filter.Update()
data = triangle_filter.GetOutput()
Puis, nous lisons et triangulons les données de vitesse.
vtk_points = data.GetPoints().GetData()
points = numpy_support.vtk_to_numpy(vtk_points)
x = points[:, 0]
y = points[:, 1]
vtk_vectors = data.GetPointData().GetArray("U")
vtk_cells = data.GetPolys().GetData()
cells_raw = numpy_support.vtk_to_numpy(vtk_cells)
triangles = cells_raw.reshape(-1, 4)[:, 1:]
U = numpy_support.vtk_to_numpy(vtk_vectors)
magU = np.linalg.norm(U, axis=1)
Nous extrayons ensuite les sommets du fichier VTK, les valeurs de vitesse aux cellules, la topologie des triangles, puis nous calculons la norme de la vitesse.
fig, ax = plt.subplots(figsize=(8, 6))
contour_filled = ax.tricontourf(x, y, triangles, magU, levels=16, cmap="turbo")
ax.tricontour(
x, y, triangles, magU, levels=16, colors="white", linewidths=0.5, alpha=0.5
)
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
cbar = fig.colorbar(contour_filled, cax=cax)
ax.set_aspect("equal")
Enfin, nous traçons les données. Quelques ajustements sur la barre de couleurs ont été nécessaires pour l’aligner parfaitement sur la hauteur de la figure.
for f in ["svg", "pdf", "eps", "png"]:
plt.savefig("velocity.{}".format(f), dpi=300, bbox_inches="tight", pad_inches=0.5)
Pour terminer, nous sauvegardons la figure dans les formats souhaités. Un nombre élevé de niveaux de contours génère des fichiers vectoriels plus lourds qu’un PNG, mais ils peuvent être agrandis sans aucune perte de qualité.
