Le condensateur est constitué de deux plaques conductrices infinies dans la direction z.
Figure pleine pageOn note V le potentiel électrique. L'équation de Laplace à deux dimensions est :
L'équation de Laplace pour le potentiel est discrétisée par la méthode des différences finies. La méthode itérative de Gauss-Seidel avec sur-relaxation est utilisée pour résoudre le système d'équations linéaires obtenu. Pour en savoir plus : Équation de Poisson : résolution numérique. On teste aussi une méthode multigrilles.
Pour le module Python utilisé voir : Équation de Poisson : module python.
Le domaine de calcul est carré. Il faut fixer une condition limite sur les bords du domaine. Une première approche consiste à imposer le potentiel sur les bords, à une valeur nulle. Physiquement, cela correspond à une expérience faite dans une boîte métallique (ou dans une cage de Faraday).
Un maillage carré de 128 par 128 mailles est utilisé. Les deux plaques du condensateur sont définies sur un maillage réduite de 16 par 16 mailles. Une condition de Dirichlet est imposée sur chaque plaque, avec un potentiel -1 et +1. Des conditions limites de Dirichlet sont attribuées aux bords du domaine, avec un potentiel nul.
from matplotlib.pyplot import * import math import numpy import poisson.main n=7 p=4 levels = n-p+1 laplace=poisson.main.Poisson(p,p,levels,1.0,1.0,x0=-0.5,y0=-0.5) laplace.laplacien() laplace.dirichlet_borders(0.0) distance = 2 longueur = 8 laplace.dirichlet_polygon(8-distance/2,8-longueur/2,[0],[longueur],1.0) laplace.dirichlet_polygon(8+distance/2,8-longueur/2,[0],[longueur],-1.0) result=laplace.iterations_norm(5,50,omega=1.9) figure(figsize=(8,6)) plot(result[0],result[1]) xlabel('niter') ylabel('norm')
La norme de la matrice des valeurs de V permet de contrôler la convergence des itérations de Gauss-Seidel :
plotA.pdfV=laplace.get_array() Ex=-laplace.get_derivX() Ey=-laplace.get_derivY() extent = laplace.get_extent() figure(figsize=(8,8)) contour(V,20,extent=extent) imshow(~laplace.get_mask(),extent=extent,alpha=0.5, cmap=cm.gray)
Tracé des lignes équipotentielles :
plotB.pdffigure() x=laplace.get_x() plot(x,Ex[2**(n-1),:]) xlabel('x') ylabel('Ex')
Champ électrique sur l'axe central traversant les plaques :
plotC.pdffigure() y=laplace.get_y() laplace.close() plot(y,Ex[:,int(math.pow(2,n-1))]) xlabel('y') ylabel('Ex')
Champ électrique dans le plan médian :
plotD.pdfLes bords du domaine, où le potentiel est nul, ont certainement une influence sur le résultat. Pour réduire l'effet des bords, on doit réduire la taille du condensateur par rapport à celle du domaine. Il faut parallèlement augmenter le nombre de mailles afin de conserver une bonne résolution à l'intérieur du condensateur. On augmente d'un facteur 2 la taille du maillage réduit et celui du maillage fin. La convergence étant plus lente, on est amené à augmenter le nombre d'itérations. Pour accélérer le calcul, on utilise l'implémentation OpenCL (calcul sur carte graphique).
n=8 p=5 levels = n-p+1 laplace=poisson.main.Poisson(p,p,levels,1.0,1.0,x0=-0.5,y0=-0.5) laplace.laplacien() laplace.dirichlet_borders(0.0) distance = 2 longueur = 8 laplace.dirichlet_polygon(16-distance/2,16-longueur/2,[0],[longueur],1.0) laplace.dirichlet_polygon(16+distance/2,16-longueur/2,[0],[longueur],-1.0) result=laplace.opencl_iterations_norm(10,50,omega=1.95) figure(figsize=(8,6)) plot(result[0],result[1]) xlabel('niter') ylabel('norm')plotE.pdf
V=laplace.get_array() Ex=-laplace.get_derivX() Ey=-laplace.get_derivY() extent = laplace.get_extent() figure(figsize=(8,8)) contour(V,40,extent=extent)plotF.pdf
figure() x=laplace.get_x() plot(x,Ex[2**(n-1),:]) xlabel('x') ylabel('Ex')
Champ électrique sur l'axe central traversant les plaques :
plotG.pdffigure() y=laplace.get_y() laplace.close() plot(y,Ex[:,int(math.pow(2,n-1))]) xlabel('y') ylabel('Ex')
Champ électrique dans le plan médian :
plotH.pdfSi le domaine est assez grand par rapport au condensateur, on s'approche du cas théorique où le potentiel est nul à l'infini.
Lorsque le maillage est très grand (ici 256x256), on a intérêt à essayer une méthode multigrille pour accélérer la convergence. Voici le résultat avec une méthode à 4 grilles (cycle en V) :
n=8 p=5 levels = n-p+1 laplace=poisson.main.Poisson(p,p,levels,1.0,1.0,x0=-0.5,y0=-0.5) laplace.laplacien() laplace.dirichlet_borders(0.0) distance = 2 longueur = 8 laplace.dirichlet_polygon(16-distance/2,16-longueur/2,[0],[longueur],1.0) laplace.dirichlet_polygon(16+distance/2,16-longueur/2,[0],[longueur],-1.0) result1=laplace.multigrid_Vcycles_norm(1,4,50,2,1,20) figure(figsize=(8,6)) plot(result[0],result[1],label='1 grille') plot(result1[0],result1[1],label='4 grilles') xlabel('niter') ylabel('norm') legend(loc='lower right')plotI.pdf
V=laplace.get_array() Ex=-laplace.get_derivX() Ey=-laplace.get_derivY() extent = laplace.get_extent() figure(figsize=(8,8)) contour(V,40,extent=extent)plotJ.pdf
Le même problème peut être résolu avec une condition limite sur les bords du domaine de type Neumann, ce qui revient à imposer la composante normale du champ électrique sur les bords du domaine. Voyons ce qu'on obtient avec un champ nul sur les bords.
n=8 p=5 levels = n-p+1 laplace=poisson.main.Poisson(p,p,levels,1.0,1.0,x0=-0.5,y0=-0.5) laplace.laplacien() laplace.neumann_borders(0.0,0.0,0.0,0.0,0.0) distance = 2 longueur = 8 laplace.dirichlet_polygon(16-distance/2,16-longueur/2,[0],[longueur],1.0) laplace.dirichlet_polygon(16+distance/2,16-longueur/2,[0],[longueur],-1.0) result=laplace.opencl_iterations_norm(50,50,omega=1.95) figure(figsize=(8,6)) plot(result[0],result[1]) xlabel('niter') ylabel('norm')plotK.pdf
On voit que la convergence est beaucoup plus lente lorsque la condition limite sur les bords est de type Neumann (comparer le nombre d'itérations).
V=laplace.get_array() Ex=-laplace.get_derivX() Ey=-laplace.get_derivY() extent = laplace.get_extent() figure(figsize=(8,8)) contour(V,40,extent=extent)plotL.pdf
Sans surprise, les lignes équipotentielles sont modifiées à l'approche des bords.
Voyons comment une méthode multigrille améliore la convergence (cycles en V et multigrille complet).
n=8 p=5 levels = n-p+1 laplace=poisson.main.Poisson(p,p,levels,1.0,1.0,x0=-0.5,y0=-0.5) laplace.laplacien() laplace.neumann_borders(0.0,0.0,0.0,0.0,0.0) distance = 2 longueur = 8 laplace.dirichlet_polygon(16-distance/2,16-longueur/2,[0],[longueur],1.0) laplace.dirichlet_polygon(16+distance/2,16-longueur/2,[0],[longueur],-1.0) result1=laplace.multigrid_Vcycles_norm(1,4,50,2,1,40) laplace.init_array() result2=laplace.multigrid_full_norm(5,levels,100,2,2) figure(figsize=(8,6)) plot(result[0],result[1],label='1 grille') plot(result1[0],result1[1],label='4 grilles V') plot(result2[0],result2[1],label='4 grilles Full') xlabel('niter') ylabel('norm') legend(loc='lower right')plotM.pdf
Les plaques du condensateur sont percées en leur milieu pour laisser passer une particule chargée.
Figure pleine pagen=8 p=5 levels = n-p+1 laplace=poisson.main.Poisson(p,p,levels,1.0,1.0,x0=-0.5,y0=-0.5) laplace.laplacien() laplace.dirichlet_borders(0.0) laplace.dirichlet_polygon(16,11,[0],[4],1.0) laplace.dirichlet_polygon(16,17,[0],[4],1.0) laplace.dirichlet_polygon(17,11,[0],[4],-1.0) laplace.dirichlet_polygon(17,17,[0],[4],-1.0) result=laplace.opencl_iterations_norm(20,50,omega=1.95) figure(figsize=(8,6)) plot(result[0],result[1]) xlabel('niter') ylabel('norm')plotN.pdf
V=laplace.get_array() Ex=-laplace.get_derivX() Ey=-laplace.get_derivY() extent = laplace.get_extent() figure(figsize=(8,8)) contour(V,40,extent=extent) imshow(~laplace.get_mask(),extent=extent,alpha=0.5, cmap=cm.gray)plotO.pdf
On regarde au voisinage de l'ouverture :
figure(figsize=(9,8)) contour(V,40,extent=extent) imshow(~laplace.get_mask(),extent=extent,alpha=0.5, cmap=cm.gray) axis([-0.1,0.1,-0.1,0.1])plotP.pdf
Voici le champ électrique sur l'axe de l'ouverture :
figure() x=laplace.get_x() plot(x,Ex[2**(n-1),:]) xlabel('x') ylabel('Ex')plotQ.pdf