Está en la página 1de 8

Electromagnetismo I

Semestre: 2015-2
Prof. Alejandro Reyes Coronado
Ayud. Carlos Alberto Maciel Escudero
Ayud. Christian Esparza López
Solución al Proyecto 1

Solución por Carlos Maciel Escudero

Solución Proyecto 1

Genera un programa de cómputo que calcule numéricamente la solución a la ecuación de


Laplace en dos dimensiones para un conjunto discreto de puntos. Los puntos de la frontera
exterior se encuentran a un potencial φ = 0, mientras que los puntos de la frontera interna
están a un potencial igual a φ = 100.

Solución

Para resolver el problema se programó el Método de Relajaciónel en Fortran 90. El método


establece que en el punto (xo , yo ) el potencial φ (xo , yo ) se encuentra determinado por el valor
que toma éste último en sus vecinos simétricos, como se muestra en la figura.
La idea para demostrar lo anterior es expandir en Taylor cada uno de los potenciales vecinos:

1 ∂ 2 φ

∂φ 2 3

φ (xo ± δ, yo ) = φ (xo , yo ) ± δ+ δ + O δ
∂x x=xo 2 ∂x2 x=xo
1 ∂ 2 φ

∂φ
δ2 + O δ3

φ (xo , yo ± δ, zo ) = φ (xo , yo ) ± δ+ 2
∂y y=yo 2 ∂y
y=yo

Entonces a segundo orden resulta que



φ (xo ± δ, yo ) + φ (xo , yo ± δ) = 4φ (xo , yo ) + ∇2 φ (x=xo ,y=yo ) δ 2

Como el potencial electrostático satisface la ecuación de Laplace,

φ (xo + δ, yo ) + φ (xo − δ, yo ) + φ (xo , yo + δ) + φ (xo , yo − δ)


φ (xo , yo ) =
4

lo cual prueba el argumento anterior.

Una vez entendido la idea del método, podemos utilizar este resultado para resolver el pro-
blema del proyecto. De forma que, el programa en Fortran 90 debe calcular el promedio del
potencial en cada punto conocidos los potencial vecinos. Con la intención de resolver lo anterior,
programé un algoritmo que genera una matriz donde se guardan los valores iniciales del po-
tencial, estableciendo un valor aleatorio a aquellos puntos que no tienen asociado un potencial,
es decir, los puntos que se encuentran fuera de los contornos de los cuadrados. Después, éste
invoca una subrutina, denominada relajación, que calcula una nueva matriz con el promedio
de los cuatro primeros vecinos y compara la matriz inicial con la nueva. Si la magnitud de la
diferencia de las matrices es mayor o igual a prec entonces vuelve a calcular una nueva matriz
con los promedios y la compara ahora con la matriz anterior; esto lo realiza hasta alcanzar
una matriz que prácticamente no muestre cambio alguna con su predecesora. Finalmente, con
la matriz de potencial eléctrico (digamos la certera), el programa invoca la subrutina campo
que calcula el campo electrostático a partir de derivar el potencial. Tanto el potencial como el
campo se guardan en archivos .dat respectivamente.

Observaciones:
1. Para calcular la norma de una matriz utilicé el producto interior definido en el espacio de
Hilbert de las matrı́ces de n × n con coeficientes en los reales, dado por: hA, Ai = tr (At A). El
cual pueden verificar que es bilineal, definido positivamente y simétrico.
2. La derivada numérica que utilicé para calcular el campo eléctrico es una derivada de tres
puntos, la cual necesita el punto anterior, el posterior y el punto en cuestión para calcular
la derivada. Para mayor detalle de esto pueden revisar el libro: Richard Burden, ”Análisis
numérico”.
3. Al ejecutar el programa les pedirá en consola que indiquen el refinamiento, esto es para que
indiquen que tan fina quieren hacer la malla, es decir, cuántos puntos quieren que tenga.

2
Código Fortran

!---------------------------------------------------------------------------!
!------------------------------------Main-----------------------------------!
!---------------------------------------------------------------------------!

!-------------------------Declaración de la matriz--------------------------
program laplace
IMPLICIT NONE
real(16), allocatable :: V(:,:),Ex(:,:),Ey(:,:)
integer :: i,j,k,n,m
real(16) :: prec,Vo,inicial
open(1,file="potencial.dat",status="REPLACE")
open(2,file="campo.dat",status="REPLACE")

!-------------Llenado de la matriz y las condiciones iniciales---------------


write(*,*) ">>Indica el refinamiento:"
read*, n
inicial=30.
m=n/10
allocate (V(n,n),Ex(n,n),Ey(n,n))
do i=1,n
do j=1,n
if (i==4*m .AND. j>=4*m .AND. j<=7*m) then
V(i,j)=100.
else if (i==7*m .AND. j>=4*m .AND. j<=7*m) then
V(i,j)=100.
else if (j==4*m .AND. i>=4*m .AND. i<=7*m) then
V(i,j)=100.
else if (j==7*m .AND. i>=4*m .AND. i<=7*m) then
V(i,j)=100.
else if (i==1 .OR. i==10*m .OR. j==1 .OR. j==10*m) then
V(i,j)=0.
else
V(i,j)=inicial
end if
end do
end do

!---------Invoca la subrutina que calcula el metodo de relajación------------


prec=1E-5
call relajacion(V,n,m,prec)

!----------Invoca la subrutina que calcula el campo eléctrico----------------


call campo(V,n,Ex,Ey)

3
!--------Escritura del potencial y el campo en un archivo .dat---------------
do i=1,n
do j=1,n
write(1,10) i,j,V(i,j)
end do
end do
10 format("",2I6.0,F20.12)
do i=1,n
do j=1,n
write(2,20) i,j,Ex(i,j)/10.,Ey(i,j)/10.
end do
end do
20 format("",2I6.0,2F20.12)

end program

!---------------------------------------------------------------------------!
!------------------Subrutina Método de Relajación---------------------------!
!---------------------------------------------------------------------------!
subroutine relajacion(V,n,m,prec)
IMPLICIT NONE
integer, intent(in) :: n,m
real(16), dimension(n,n), intent(inout) :: V
real(16), intent(in) :: prec
integer :: i,j
real(16) :: dif
real(16), dimension(n,n) :: V_ant
dif=1.
do while (dif>=prec)
V_ant=V
do i=2,n-1
do j=2,n-1
if (i==4*m .AND. j>=4*m .AND. j<=7*m) then
V(i,j)=100.
else if (i==7*m .AND. j>=4*m .AND. j<=7*m) then
V(i,j)=100.
else if (j==4*m .AND. i>=4*m .AND. i<=7*m) then
V(i,j)=100.
else if (j==7*m .AND. i>=4*m .AND. i<=7*m) then
V(i,j)=100.
else if (i==1 .OR. i==10*m .OR. j==1 .OR. j==10*m) then
V(i,j)=0.
else
V(i,j)=(V(i-1,j)+V(i+1,j)+V(i,j-1)+V(i,j+1))/4.
end if

4
end do
end do
call magnitud(V-V_ant,n,dif)
print*, dif
end do
end subroutine

!---------------------------------------------------------------------------!
!--------------Subrutina que calcula el campo eléctrico---------------------!
!---------------------------------------------------------------------------!
subroutine campo(V,n,Ex,Ey)
IMPLICIT NONE
integer, intent(in) :: n
real(16), dimension(n,n), intent(in) :: V
real(16), dimension(n,n), intent(out) :: Ex,Ey
integer :: i,j,h
h=1
do i=2,n-1
do j=2,n-1
Ex(i,j)=-(V(i+1,j)-V(i-1,j))/(2*h)
Ey(i,j)=-(V(i,j+1)-V(i,j-1))/(2*h)
end do
end do
end subroutine

!---------------------------------------------------------------------------!
!----------Subrutina que calcula la magnitud de una matriz------------------!
!---------------------------------------------------------------------------!
subroutine magnitud(A,dimA,dif)
IMPLICIT NONE
integer, intent(in) :: dimA
real(16), dimension(dimA,dimA), intent(in) :: A
real(16), intent(out) :: dif
real(16), dimension(dimA,dimA) :: B
integer :: i
dif=0.
B=matmul(transpose(A),A)
do i=1,dimA
dif=dif+B(i,i)
end do
end subroutine

Para graficar el potencial electrostático, las curvas equipotenciales y los vectores de campo
eléctrico pueden utilizar gnuplot, a continuación les dejo el código para graficar cada una.

5
Código Gnuplot

Potencial Electrostático

splot "potencial.dat" using 1:2:3


set xlabel "X"
set ylabel "Y"
set zlabel "V(X,Y)"
set xrange [0:100]
set yrange [0:100]
set zrange [0:100]
set title "Potencial Eléctrostático"
unset key
replot
set term png
set out "potencial.png"
replot

Curvas equipotenciales

plot "potencial.dat" using 1:2:3:4 with vector head


set xlabel "X"
set ylabel "Y"
set xrange [0:100]
set yrange [0:100]
set title "Curvas Equipotenciales"
unset surface
set contour base
unset key
replot
set term png
set out "equipotenciales.png"
replot

Vectores de Campo Eléctrostático

plot "campo.dat" using 1:2:3:4 with vector head


set xlabel "X"
set ylabel "Y"
set xrange [0:100]
set yrange [0:100]
set title "Lı́neas de Campo Eléctrico"
unset key
replot
set term png
set out "campo.png"
replot

6
Yo decidı́ utilizar Origin para graficar cada uno de los anteriores, a continuación les muestro
mis resultados:

Para realizar esta gráfica sólo agreguen los datos del archivo potencial.dat, luego seleccionen
la última columna, click derecho, Properties y en Plot Designation cambien a Z. Por último
seleccionen las tres columnas vayan a Plot, 3D XYZ, 3D Scatter.

7
Para graficar las curvas de nivel agreguen los datos del archivo potencial.dat, luego selec-
cionen la última columna, click derecho, Properties y en Plot Designation cambien a Z. Por
último seleccionen las tres columnas vayan a Plot, Contour, XYX Contour.

Para graficar el campo vectorial agreguen los datos del archivo campo.dat, luego seleccionen
la penúltima columna, click derecho, Properties y en Plot Designation cambien a X. Por último
seleccionen las cuatro columnas vayan a Plot, Specialized, Vector XYXY.

También podría gustarte