La ecuación de Laplace, procedimiento numérico

Una serie de Taylor es una aproximación de una función mediante un polinomio

El desarrollo de Taylor de una función y(x) alrededor de un punto x0 es

y(x)=y( x 0 )+ dy dx | x 0 (x x 0 )+ 1 2 d 2 y d x 2 | x 0 ( x x 0 ) 2 +... 1 n! d n y d x n | x 0 ( x x 0 ) n +...

El desarrollo de Taylor hasta n=2 alrededor del punto xi es

y( x i+1 )=y( x i +h)=y( x i )+h dy dx | x i + h 2 2 d 2 y d x 2 | x i +... y( x i1 )=y( x i h)=y( x i )h dy dx | x i + h 2 2 d 2 y d x 2 | x i +...

Sumamos ambas ecuaciones y despejamos a derivada segunda de la función en xi

d 2 y d x 2 | x i y( x i+1 )+y( x i1 )2y( x i ) h 2

El potencial V(x,y) es una función de dos variables, solución de la ecuación de Laplace

2 V x 2 + 2 V y 2 =0

Sustituimos las derivadas parciales por sus expresiones aproximadas en el punto (xi, yi)

V( x i+1 , y j )+V( x i1 , y i )2V( x i , y j ) h 2 + V( x i , y j+1 )+V( x i , y j1 )2V( x i , y j ) h 2 0 4V( x i , y j )=V( x i+1 , y j )+V( x i1 , y j )+V( x i , y j+1 )+V( x i , y j1 )

Consideremos un recinto rectangular de dimensiones a y b. Dividimos el eje X en m+1 intervalos, a=(m+1)h y el eje Y en n+1 intervalos, b=(n+1)h

Las coordenadas de un punto interior cualquiera de la malla son, xi=i·h, yj=j·h (i=1,2...m, j=1,2,...n)

Conocidos los potenciales en el borde, V(0,yj), V(xi,0), V(a,yj), V(xi,b) (en color negro), calcularemos los potenciales Vi,j en los puntos del interior, en color rojo, verde y azul, (xi,yj), (i=1,2...m, j=1,2,...n).

Sistema de ecuaciones lineales

El potencial Vi,j del punto (xi,yj) se calcula a partir de los potenciales de los cuatro más próximos, tal como se muestra en la figura de la derecha

4 V i,j = V i+1,j + V i1,j + V i,j+1 + V i,j1

Consideremos el ejemplo de la figura, m=5 y n=4. Pondremos a la izquierda del signo de la igualdad las incógnitas y a la derecha los datos. Tendremos un sistema lineal de m·n=5·4=20 ecuaciones con 20 incógnitas. Distinguiremos tres regiones:

  1. Esquinas, puntos de color rojo

  2. 4V11-V21-V12=V01+V10
    -V41+4V51-V52=V50+V61
    -V13+4V14-V24=V04+V15
    -V53-V44+4V54=V55+V64

  3. Puntos de color verde, cerca del borde

  4. Puntos interiores, de color azul

  5. 4V22-V12-V32-V21-V23=0
    4V32-V22-V42-V31-V33=0
    4V42-V32-V52-V41-V43=0
    4V23-V13-V33-V24-V22=0
    4V33-V23-V43-V34-V32=0
    4V43-V33-V53-V44-V42=0

Escribimos el sistema de ecuaciones de forma matricial, A·X=B

( 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 4 )( V 11 V 21 V 31 V 41 V 51 V 12 V 22 V 32 V 42 V 52 V 13 V 23 V 33 V 43 V 53 V 14 V 24 V 34 V 44 V 54 )=( V 10 + V 01 V 20 V 30 V 40 V 50 + V 61 V 02 0 0 0 V 62 V 03 0 0 0 V 63 V 04 + V 15 V 25 V 35 V 45 V 55 + V 64 )

Matriz de los coeficientes

Dividimos la matriz A de los coeficientes en submatrices que se repiten, tal como se muestra en la figura

La submatriz D cuadrada de dimensión m=5, se repite a lo largo de la diagonal de la matriz A, se repite también la matriz diagonal E y la matriz nula O, todas de la misma dimensión. El diagrama de bloques se muestra en la figura

MATLAB facilita el trabajo con matrices: crear matrices, acceder a sus elementos, etc. El código para crear la matriz A de los coeficientes de dimensión m·n a partir de las submatrices D y E de dimensión m es

A=zeros(n*m);
D=diag(4*ones(1,m))+diag(-1*ones(1,m-1),1)+diag(-1*ones(1,m-1),-1);
E=diag(-1*ones(1,m));
for i=0:n-1
    A(1+i*m:(i+1)*m,1+i*m:(i+1)*m)=D;
end
for i=1:n-1
    A(1+i*m:(i+1)*m,1+(i-1)*m:m*i)=E;
    A(1+(i-1)*m:i*m,1+i*m:(i+1)*m)=E;
end

Este código vale para cualquier problema, basta especificar el número de intervalos m y n

Vector de los términos independientes

Más trabajo requiere especificar las condiciones de contorno, el vector B de los términos independientes. Supongamos que las condiciones de contorno son

{ V 0,j = V 0 j=1,2...n V m+1,j = V 0 j=1,2...n V i,0 = V 0 i=1,2...m V i,n+1 = V 0 i=1,2...m

Primero crearemos una función que traslade la posición de un punto interior (i,j) en su posición k en el vector columna B. Por ejemplo, la posición de la incógnita V2,3 es k=12

...
f=@(i,j) i+(j-1)*m;
...

Los términos independientes distintos de cero, son producidos por los cuatro puntos rojos de las esquinas y los puntos verdes próximos al borde. Los puntos interiores, (de color azul) dan lugar a un valor nulo

El código para crear el vector B es el siguiente

...
    %condiciones de contorno
VS=ones(1,m); %abajo
VN=ones(1,m); %arriba
VE=-ones(1,n); %derecha
VO=-ones(1,n); %izquierda
f=@(i,j) i+(j-1)*m;
%Vector términos independientes
B=zeros(n*m,1);
%puntos rojos
B(f(1,1))=VO(1)+VS(1);
B(f(m,1))=VS(m)+VE(1);
B(f(1,n))=VN(1)+VO(n);
B(f(m,n))=VN(m)+VE(n);
%puntos verdes
for k=2:m-1
    B(f(k,1))=VS(k);
    B(f(k,n))=VN(k);
end
for k=2:n-1
    B(f(1,k))=VO(k);
    B(f(m,k))=VE(k);
end

Vector de las incógnitas

Una vez que hemos definido el vector A de los coeficientes y el vector B de los términos independientes, despejamos el vector X de las incógnitas, A·X=B, utilizando el operador división por la izquierda '\'

...
X=A\B;
R=zeros(n,m);
for j=1:n
    for i=1:m
        k=f(i,j);
        R(n+1-j,i)=X(k);
     end
end
...

Los valores del potencial Vi,j en los puntos interiores del recinto rectangular son

R =
    0.0390    0.4286    0.5325    0.4286    0.0390
   -0.2727    0.1429    0.2727    0.1429   -0.2727
   -0.2727    0.1429    0.2727    0.1429   -0.2727
    0.0390    0.4286    0.5325    0.4286    0.0390

Como cabría esperar, hay simetría en los valores del potencial

Solución analítica

En la página previa titulada La ecuación de Laplace, coordenadas rectangulares, estudiamos el caso general. El potencial V(x,y) es la suma de cuatro contribuciones, tal como se muestra en la figura

V 1 (x,y)= 2 b n=1 ( 0 b V(0,y)sin( nπ b y )dy { sinh( nπ b (ax) ) sinh( nπ b a ) }sin( nπ b y ) ) = 4 V 0 π n=1,3,5... ( 1 n { sinh( nπ b (ax) ) sinh( nπ b a ) }sin( nπ b y ) ) V 2 (x,y)= 2 b n=1 ( 0 b V(a,y)sin( nπ b y )dy { sinh( nπ b x ) sinh( nπ b a ) }sin( nπ b y ) ) = 4 V 0 π n=1,3,5... ( 1 n { sinh( nπ b x ) sinh( nπ b a ) }sin( nπ b y ) ) V 3 (x,y)= 2 a n=1 ( 0 a V(x,0)sin( nπ a x )dx { sinh( nπ a (by) ) sinh( nπ a b ) }sin( nπ a x ) ) = 4 V 0 π n=1,3,5... ( 1 n { sinh( nπ a (by) ) sinh( nπ a b ) }sin( nπ a x ) ) V 4 (x,y)= 2 a n=1 ( 0 a V(x,b)sin( nπ a x )dx { sinh( nπ a y ) sinh( nπ a b ) }sin( nπ a x ) ) = 4 V 0 π n=1,3,5... ( 1 n { sinh( nπ a y ) sinh( nπ a b ) }sin( nπ a x ) )

El resultado de la suma de las cuatro contribuciones es

V(x,y)= 4 V 0 π n=1,3,5... 1 n { ( sinh( nπ a (by) )+sinh( nπ a y ) ) sin( nπ a x ) sinh( nπ a b ) ( sinh( nπ b (ax) )+sinh( nπ b x ) ) sin( nπ b y ) sinh( nπ b a ) }

Definimos la función que calcula el potencial V(x,y), empleando N=100 términos del desarrollo en serie

function z = laplace_potencial_4(x,y, N, a, b)
    z=0;
    for n=0:N
        z1=(sinh((2*n+1)*pi*(a-x)/b)+sinh((2*n+1)*pi*x/b)).
*sin((2*n+1)*pi*y/b)/sinh((2*n+1)*pi*a/b);
        z2=(sinh((2*n+1)*pi*(b-y)/a)+sinh((2*n+1)*pi*y/a)).
*sin((2*n+1)*pi*x/a)/sinh((2*n+1)*pi*b/a);
        z=z+(z2-z1)*4/((2*n+1)*pi);
    end
end

Representamos la función V(x,y) mediante mesh

m=5; %eje X
n=4; %eje Y
h=0.5; 
a=(m+1)*h;
b=(n+1)*h;
...
[x,y] = meshgrid(0:0.1:a, 0:0.1:b);
N=100;
z=laplace_potencial_4(x,y, N, a, b);
mesh(x,y,z)
xlabel('x')
ylabel('y')
zlabel('V(x,y)')
title('Potencial')

Unimos todas las porciones del script y comparamos el resultado analítico (puntos de color azul) y el numérico, (puntos de color rojo)

m=5; %eje X
n=4; %eje Y
h=0.5; 
a=(m+1)*h;
b=(n+1)*h;
%matriz V
A=zeros(n*m);
D=diag(4*ones(1,m))+diag(-1*ones(1,m-1),1)+diag(-1*ones(1,m-1),-1);
E=diag(-1*ones(1,m));
for i=0:n-1
    A(1+i*m:(i+1)*m,1+i*m:(i+1)*m)=D;
end
for i=1:n-1
    A(1+i*m:(i+1)*m,1+(i-1)*m:m*i)=E;
    A(1+(i-1)*m:i*m,1+i*m:(i+1)*m)=E;
end
%condiciones de contorno
VS=ones(1,m); %abajo
VN=ones(1,m); %arriba
VE=-ones(1,n); %derecha
VO=-ones(1,n); %izquierda
f=@(i,j) i+(j-1)*m;
%Vector términos
B=zeros(n*m,1);
%puntos rojos
B(f(1,1))=VO(1)+VS(1);
B(f(m,1))=VS(m)+VE(1);
B(f(1,n))=VN(1)+VO(n);
B(f(m,n))=VN(m)+VE(n);
%puntos verdes
for k=2:m-1
    B(f(k,1))=VS(k);
    B(f(k,n))=VN(k);
end
for k=2:n-1
    B(f(1,k))=VO(k);
    B(f(m,k))=VE(k);
end
X=A\B;
N=100;
g=@(x,y) laplace_potencial_4(x,y, N, a,b);
hold on
R=zeros(n,m);
for j=1:n
    for i=1:m
        k=f(i,j);
        R(n+1-j,i)=X(k);
        z=g(i*h,j*h);
        plot3(i*h,j*h,z,'o','markersize',3,'markeredgecolor',
'b','markerfacecolor','b')
        plot3(i*h,j*h,X(k),'o','markersize',3,'markeredgecolor',
'r','markerfacecolor','r')
    end
end
%comparación con la solución analítica
[x,y] = meshgrid(0:0.1:a, 0:0.1:b);
z=laplace_potencial_4(x,y, N, a, b);
mesh(x,y,z)
hold off
xlabel('x')
ylabel('y')
zlabel('V(x,y)')
title('Potencial')
view(47,32)

Comparación

La representación tridimensional no permite ver adecudamente, la comparación entre los resultados analíticos y numéricos.

Añadimos las siguientes líneas de código al script

...
figure
subplot(2,1,1)
gy=@(y) g(2*h,y);
hold on
fplot(gy,[0,b])
i=2;
for j=1:n
    k=f(i,j);
    line([j*h,j*h],[0,X(k)], 'color','r')
    plot(j*h,X(k),'o','markersize',3,'markeredgecolor','r',
'markerfacecolor','r')
end
hold off
grid on
xlabel('y')
ylabel('V(2h,y)')
title('Comparación')
subplot(2,1,2)
gx=@(x) g(x,2*h);
hold on
fplot(gx,[0,a])
j=2;
for i=1:m
    k=f(i,j);
    line([i*h,i*h],[0,X(k)], 'color','r')
    plot(i*h,X(k),'o','markersize',3,'markeredgecolor','r',
'markerfacecolor','r')
end
hold off
grid on
xlabel('x')
ylabel('V(x,2h)')
title('Comparación')

El procedimiento numérico se aproxima a la solución analítica, con muy pocos intervalos. Sin embargo, a medida que crece el número de intervalos, el número de ecuaciones se multiplica y el procedimiento directo resulta impracticable. Describimos un procedimiento iterativo, que conduce a la solución rápidamente.

Proceso iterativo

Consideremos un recinto rectangular de dimensiones a y b. Dividimos el eje X en m-1 intervalos, a=(m-1)h y el eje Y en n-1 intervalos, b=(n-1)h

Conocidos los potenciales en los bordes, Vi,1, Vi,m, (i=2,...n-1), V1,j, Vn,j, (j=2,...m-1), en color negro, calcularemos los potenciales Vi,j en los puntos del interior, en color azul, (i=2...n-1, j=2,...m-1).

Como hemos visto, el potencial Vi,j del punto (i,j) se calcula a partir de los potenciales de los cuatro más próximos, tal como se muestra en la figura de la derecha,

4 V i,j k+1 = V i+1,j k + V i1,j k + V i,j+1 k + V i,j1 k

El superíndice k se refiere al valor del potencial de los puntos interiores Vi,j en en la iteracción k. k=0, se refiere al valor inicial del potencial de los puntos interiores

El proceso iterativo concluye cuando se alcanza un máximo número de iteracciones o cuando el error relativo definido para cada uno de los puntos interiores i,j es menor que una cantidad fijada ε

| V i,j k+1 V i,j k V i,j k+1 |<ε

Declaramos una matriz V0, de n filas y n columnas. Establecemos sus valores fijos en los bordes (negros) y un valor inicial (cero) en los puntos (i,j) del interior (azules)

m=7; %columnas
n=6; %filas
V0=zeros(n,m);
%condiciones de contorno
for i=2:n-1 %izquierda/derecha
    V0(i,1)=-1;
    V0(i,m)=-1;
end
for j=2:m-1 %arriba/abajo
    V0(1,j)=1;
    V0(n,j)=1;
end

Asignamos a los vértices, puntos de color rojo, el valor medio del potencial de los dos puntos más proximos de los bordes

V 1,1 = 1 2 ( V 1,2 + V 2,1 ) V n,1 = 1 2 ( V n1,1 + V n,2 ) V 1,m = 1 2 ( V 1,m1 + V 2,m ) V n,m = 1 2 ( V n1,m + V n,m1 )

%las cuatro esquinas
 V0(1,1)=(V0(1,2)+V0(2,1))/2;
 V0(n,1)=(V0(n-1,1)+V0(n,2))/2;
 V0(1,m)=(V0(1,m-1)+V0(2,m))/2;
 V0(n,m)=(V0(n-1,m)+V0(n,m-1))/2;

El proceso iterativo es muy fácil de programar, para ello declaramos una matriz V de la misma dimensión que V0, que va a guardar los potenciales de los puntos interiores y los fijos de los bordes, en la iteracción k+1

...
V=V0;
N=100; %máximo número de iteracciones
for k=1:N
    contador=0;
    for i=2:n-1
        for j=2:m-1
            V(i,j)=(V0(i+1,j)+V0(i-1,j)+V0(i,j-1)+V0(i,j+1))/4;
            error=abs((V(i,j)-V0(i,j))/V(i,j));
            if error<0.0001
                contador=contador+1;
            end
        end
    end
    if contador==(n-2)*(m-2) %termina el proceso iterativo
        break;
     end
    V0=V;
end

Unimos las porciones de código, para crear el script

m=7; %columnas
n=6; %filas
V0=zeros(n,m);
%condiciones de contorno
for i=2:n-1 %izquierda/derecha
    V0(i,1)=-1;
    V0(i,m)=-1;
end
for j=2:m-1 %arriba/abajo
    V0(1,j)=1;
    V0(n,j)=1;
end
%las cuatro esquinas
V0(1,1)=(V0(1,2)+V0(2,1))/2;
V0(n,1)=(V0(n-1,1)+V0(n,2))/2;
V0(1,m)=(V0(1,m-1)+V0(2,m))/2;
V0(n,m)=(V0(n-1,m)+V0(n,m-1))/2;

%proceso ierativo
V=V0;
N=100; %máximo número de iteracciones
for k=1:N
    contador=0;
    for i=2:n-1
        for j=2:m-1
            V(i,j)=(V0(i+1,j)+V0(i-1,j)+V0(i,j-1)+V0(i,j+1))/4;
            error=abs((V(i,j)-V0(i,j))/V(i,j));
            if error<0.0001
                contador=contador+1;
            end
        end
    end
    if contador==(n-2)*(m-2) %termina el proceso iterativo
        break;
     end
    V0=V;
end
if k==N
    disp('Se ha superado el máximo número de iteracciones')
else
        disp(V(2:n-1,2:m-1)) %puntos interiores
end

El resultado como podemos apreciar es muy parecido al obtenido medinte el procedimiento directo. Véase la matriz R de los potenciales de los puntos interiores en el apartado anterior

    0.0389    0.4285    0.5324    0.4285    0.0389
   -0.2728    0.1428    0.2727    0.1428   -0.2728
   -0.2728    0.1428    0.2727    0.1428   -0.2728
    0.0389    0.4285    0.5324    0.4285    0.0389

El procedimiento iterativo se termina cuando el número de iteracciones k=47. El procedimiento se puede mejorar introduciendo una combinación lineal de V0 (iteraccion k) y V (iteraccion k+1)