Table des matières PDFPython

Équation de Schrödinger à deux dimensions : module Python

1. Introduction

Ce document présente le module python pyschrodinger2d, qui permet de résoudre numériquement des problèmes de diffusion d'un paquet d'onde par un potentiel, ou de diffraction par un obstacle (diffraction par des fentes).

La méthode numérique est exposée dans Équation de Schrödinger à deux dimensions.

La représentation graphique de la densité de probabilité est faite sous forme d'image ou sous forme de surfaces.

Si l'on dispose d'une carte graphique moyen ou haut de gamme, on peut utiliser une plateforme OpenCL pour faire les calculs. Avec un processeur multicœurs, l'utilisation d'OpenCL peut être intéressante.

2. Installation

Exécutables d'installation pour python win32 :

Exécutable d'installation pour python 3.5 amd64 :

Code source :

Bibliothèques nécessaires pour la compilation : openGL, glew, freeglut, pthread, openCL (optionnel)

Installation par PIP pour python win32 :

3. Scripts de démonstration

4. Interface

4.a. Définition du maillage

La classe principale est Schrodinger2d. Elle se trouve dans le module pyschrodinger2d.main. Son constructeur effectue les allocations de mémoire pour le maillage, et permet de définir la palette de couleur utilisée pour les représentations graphiques.

Le maillage comporte un nombre de points puissance de 2 dans les deux directions x et y. On définit un maillage réduit et un niveau de subdivision pour définir le maillage utilisé dans les calculs. Le maillage réduit est utilisé pour définir le problème.

Une seule instance de cette classe est utilisable, car le programme C sous-jacent ne comporte qu'une instance des données.

4.e. Ordre des définitions

Pour résumer, voici dans quel ordre les définitions doivent être faites :

  • Définition du potentiel (si nécessaire).
  • Appel de la fonction schrodinger(dt) pour définir le pas de temps.
  • Définition de conditions limites (si nécessaire). La condition limite sur le bord du domaine est automatiquement définie.

4.g. Initialisation OpenCL

Pour le calcul sur une plateforme OpenCL, des fonctions de configuration doivent être appelées après le constructeur.

La première fonction permet d'afficher les plateformes openCL présentes sur le système, et pour chaque plateforme les périphériques associés. Les plateformes et les périphériques sont numérotés à partir de 0.

Par défaut, la plateforme 0 et le périphérique 0 sont sélectionnés. La fonction suivante permet de sélectionner une plateforme openCL et un périphérique :

Si des pilotes OpenCL sont installés pour le processeur central, celui-ci apparaît comme plateforme OpenCL. L'utilisation d'OpenCL n'a vraiment d'intérêt que sur un processeur graphique d'une carte graphique moyen ou haut de gamme (type carte pour jeu ou pour station de travail graphique). Il faut choisir la plateforme correspondante.

La fonction suivante doit être appelée après la sélection de la plateforme :

La fonction suivante doit être appelée lorsque toute la configuration du système est faite (après la fonction init décrite ci-dessous.

Lorsque les calculs sont terminés, on doit libérer la mémoire avec la fonction suivante :

4.i. Récupération de la fonction d'onde

La fonction suivante permet d'obtenir la fonction d'onde sous forme de deux matrices, une pour la partie réelle, l'autre pour la partie imaginaire.

La fonction suivante permet d'obtenir la densité de probabilité, c'est-à-dire le module au carré de la fonction d'onde. Ce module est divisé par sa valeur maximale si l'argument normalize introduit dans le constructeur vaut True.

Si normalize=False, la fonction d'onde est normalisée au sens des probabilités, dans la mesure ou le paquet d'onde initial est normalisé. La normalisation faite lorsque normalize=True est une normalisation au sens du traitement d'image, qui permet de ramener les valeurs dans l'intervalle [0,1].

La fonction suivante permet de récupérer la densité de probabilité sous la forme d'une image RGB. Les couleurs sont calculées avec la palette définie dans le constructeur. Les lignes d'annulation de la fonction d'onde et les zones rectangulaires ou circulaires de potentiel non nuls apparaissent en blanc sur l'image.

Les valeurs des trois couches RGB sont des flottants dans l'intervalle [0,1]. Lorsque normalize=False, il y a écrêtage à 1 des valeurs dépassant 1.

4.j. Animation graphique (OpenGL)

Une animation graphique peut être obtenue pendant le calcul avec la fonction suivante :

Il peut être nécessaire de générer les images de l'animation pour faire un montage vidéo. La fonction suivante effectue des itérations et renvoit l'image finale (celle-ci n'est pas affichée) :

5. Exemple

import numpy
from schrodinger2d.main import Schrodinger2d
from matplotlib.pyplot import *
import imageio
            

On définit un maillage réduit de 128 points par 64. Le niveau de subdivision est 3, ce qui donne un maillage final de 1024 par 512, suffisant pour faire une bonne simulation. La taille du domaine est 2 par 1.

px_min = 7
py_min = 6
levels = 3
Lx = 2.0
solver = Schrodinger2d(px_min,py_min,levels,Lx,normalize=False,colormap=2,gamma=0.6)
             

On initialise la plateforme OpenCL (si l'on dispose d'une carte graphique) :

solver.opencl_platforms()
solver.set_opencl_platform_device(0,0)
solver.opencl_init()
             

On doit ensuite définir le pas de temps. Un bon choix est deux fois le pas d'espace au carré :

dt = 2*solver.dx**2
solver.schrodinger(dt)
             

Pour obtenir la diffraction par deux fentes, on définit trois traits de condition limite nulle :

lignes_nulles_fentesA = [[64,0,29,"u"],[64,31,2,"u"],[64,35,29,"u"]]
solver.zero_line_list(lignes_nulles_fentesA)
             

Il est important d'appeler la fonction schrodinger avant la fonction zero_line_list. Dans le cas contraire, la fonction schrodinger écraserait les lignes définies.

On définit un paquet d'onde de déplaçant dans le sens de la longueur, et initialement situé à gauche :

x0=0.7
y0=0.5
k0 = 250
sigma0 = 0.1
E=k0*k0
solver.paquet(x0,y0,k0,sigma0)
             

On doit alors initialiser les matrices et les tampons mémoires pour OpenCL :

solver.init()
solver.opencl_create_memory()
             

Voici le calcul de quelques itérations :

ti = 0.0
tf = 50*dt
solver.opencl_iterations(ti,tf)
             

On récupère la densité de probabilité pour l'afficher :

img = solver.get_proba_colors()
figure()
imshow(img)
             
plotA
plotA.pdf

Avec cette palette de couleurs, les zones de forte densité sont rouges.

Pour faire un montage vidéo, on peut utiliser le module imageio :

writer = imageio.get_writer('../../../../figures/numerique/diffusion/pyschrodinger2d/fentes-img.mp4',fps=10)
t = 0
solver.paquet(x0,y0,k0,sigma0)
solver.opencl_release_memory()
solver.opencl_create_memory()
delta_t = dt
while t < 200*dt:
    img = solver.offscreen_rendering(t,t+delta_t,opencl=1,width=solver.width,height=solver.height,rendering=1)
    t+=delta_t
    writer.append_data(img) 
writer.close()
              

Avec normalize=False, il y a une saturation de couleur rouge lorsque la densité probabilité dépasse 1 (ce qui se produit lorsque le paquet est proche des fentes).

Voici comment obtenir une animation avec une surface :

writer = imageio.get_writer('../../../../figures/numerique/diffusion/pyschrodinger2d/fentes-surf.mp4',fps=10)
t = 0
solver.paquet(x0,y0,k0,sigma0)
solver.opencl_release_memory()
solver.opencl_create_memory()
delta_t = dt
while t < 200*dt:
    img = solver.offscreen_rendering(t,t+delta_t,opencl=1,width=solver.width,height=solver.height,rendering=2,surface_height=0.2,angle_x=45,angle_z=10)
    t+=delta_t
    writer.append_data(img)
writer.close()
              
solver.opencl_release_memory()
solver.close()
             
Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.