Electromagnetismo II
Semestre: 2016-1 Prof. Alejandro Reyes Coronado Ayud. Carlos Alberto Maciel Escudero
Soluci´ on Proyecto 1.
Cuadrado
Genera un programa de c´omputo que calcule num´ericamente la soluci´on a la ecuaci´on 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´an a un potencial igual a φ = 100.
Soluci´on
Para resolver el problema se program´o el M´etodo de Relajaci´onel en Fortran 90. El m´etodo establece que en el punto (xo, yo) el potencial φ (xo, yo) se encuentra determinado por el valor que toma ´este ´ultimo en sus vecinos sim´etricos, como se muestra en la figura.
La idea para demostrar lo anterior es expandir en Taylor cada uno de los potenciales vecinos:
φ (xo± δ, yo) = φ (xo, yo) ± ∂φ
∂x x=xo
δ + 1 2
∂2φ
∂x2 x=xo
δ2+ O δ3 φ (xo, yo± δ, zo) = φ (xo, yo) ± ∂φ
∂y y=yo
δ + 1 2
∂2φ
∂y2 y=yo
δ2+ O δ3
Entonces a segundo orden resulta que
φ (xo± δ, yo) + φ (xo, yo± δ) = 4φ (xo, yo) + ∇2φ
(x=xo,y=yo)δ2 Como el potencial electrost´atico satisface la ecuaci´on 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´etodo, 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´on de resolver lo anterior, program´e 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´es, ´este invoca una subrutina, denominada relajaci´on, 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´acticamente no muestre cambio alguna con su predecesora. Finalmente, con la matriz de potencial el´ectrico (digamos la certera), el programa invoca la subrutina campo que calcula el campo electrost´atico 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´e 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 (AtA). El cual pueden verificar que es bilineal, definido positivamente y sim´etrico.
2. La derivada num´erica que utilic´e para calcular el campo el´ectrico es una derivada de tres puntos, la cual necesita el punto anterior, el posterior y el punto en cuesti´on para calcular la derivada. Para mayor detalle de esto pueden revisar el libro: Richard Burden, ”An´alisis num´erico”.
3. Al ejecutar el programa les pedir´a en consola que indiquen el refinamiento, esto es para que indiquen que tan fina quieren hacer la malla, es decir, cu´antos puntos quieren que tenga.
C´odigo Fortran
!---!
!---Main---!
!---!
!---Declaraci´on 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´on--- prec=1E-5
call relajacion(V,n,m,prec)
!---Invoca la subrutina que calcula el campo el´ectrico--- call campo(V,n,Ex,Ey)
!---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´etodo de Relajaci´on---!
!---!
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
end do end do
call magnitud(V-V_ant,n,dif) print*, dif
end do
end subroutine
!---!
!---Subrutina que calcula el campo el´ectrico---!
!---!
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´atico, las curvas equipotenciales y los vectores de campo el´ectrico pueden utilizar gnuplot, a continuaci´on les dejo el c´odigo para graficar cada una.
C´odigo Gnuplot
Potencial Electrost´atico
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´ectrost´atico"
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´ectrost´atico
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´ectrico"
unset key replot
set term png
set out "campo.png"
replot
Yo decid´ı utilizar Origin para graficar cada uno de los anteriores, a continuaci´on les muestro mis resultados:
Para realizar esta gr´afica s´olo agreguen los datos del archivo potencial.dat, luego seleccionen la ´ultima columna, click derecho, Properties y en Plot Designation cambien a Z. Por ´ultimo seleccionen las tres columnas vayan a Plot, 3D XYZ, 3D Scatter.
Para graficar las curvas de nivel agreguen los datos del archivo potencial.dat, luego selec- cionen la ´ultima columna, click derecho, Properties y en Plot Designation cambien a Z. Por
´
ultimo 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´ultima columna, click derecho, Properties y en Plot Designation cambien a X. Por ´ultimo seleccionen las cuatro columnas vayan a Plot, Specialized, Vector XYXY.
Soluci´ on Proyecto 1.
C´ırculo
La idea es exactamente la misma que para el caso del cuadrado, s´olo que ahora las condicio- nes de frontera son sobre dos radios: rmax y rmin que yo establec´ı igual 5 y 2,5 respectivamente.
El refinamiento que pide inicialemnte el programa es para realizar el malleo del la regi´on sobre el cual vamos a calcular el potencial. A continuaci´on les muestro el c´odigo que realic´e en Fortran 90.
C´odigo Fortran
!---!
!---Main---!
!---!
!---Declaraci´on de la matriz--- program laplace
IMPLICIT NONE
real(16), allocatable :: V(:,:),Ex(:,:),Ey(:,:) complex(16), allocatable :: P(:,:)
integer :: i,j,k,n
real(16) :: prec,Vo,inicial,r,rmax,rmin,hx,hy,x,y,eps 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 hx=10./n hy=10./n inicial=50.
rmax=5.
rmin=2.5 eps=1E-4 x=0.
i=1 j=1
allocate (V(n+6,n+6),Ex(n+6,n+6),Ey(n+6,n+6),P(n+6,n+6)) do while (x<=10.)
y=0.
j=1
do while (y<=10.)
r=sqrt((x-5.)**2+(y-5.)**2) if (abs(r-rmin)<eps) then V(i,j)=100.
else if (r<rmin .AND. abs(r-rmin)>eps) then
V(i,j)=100.
else if (r>rmin .AND. r<rmax .AND. abs(r-rmax)>eps) then V(i,j)=inicial
else if (r>rmax) then V(i,j)=0.
else if (abs(r-rmax)<eps) then V(i,j)=0.
end if
P(i,j)=CMPLX(x,y) y=y+hy
j=j+1 end do x=x+hx i=i+1 end do
!---Invoca la subrutina que calcula el metodo de relajaci´on--- prec=1E-5
call relajacion(V,n,hx,hy,rmin,rmax,prec,eps)
!---Invoca la subrutina que calcula el campo el´ectrico--- call campo(V,n,Ex,Ey)
!---Escritura del potencial y el campo en un archivo .dat--- do i=1,n+6
do j=1,n+6
write(1,10) REAL(P(i,j)),AIMAG(P(i,j)),V(i,j) end do
end do
10 format("",3F20.12) do i=1,n+6
do j=1,n+6
write(2,20) REAL(P(i,j)),AIMAG(P(i,j)),Ex(i,j)/10.+REAL(P(i,j)),Ey(i,j)/10.+AIMAG(P(i,j)) end do
end do
20 format("",4F20.12) end program
!---!
!---Subrutina M´etodo de Relajaci´on---!
!---!
subroutine relajacion(V,n,hx,hy,rmin,rmax,prec,eps) IMPLICIT NONE
integer, intent(in) :: n
real(16), dimension(n+6,n+6), intent(inout) :: V real(16), intent(in) :: prec,eps,rmin,rmax,hx,hy integer :: i,j
real(16) :: dif,r,x,y
real(16), dimension(n+6,n+6) :: V_ant dif=1.
do while (dif>=prec) V_ant=V
x=0.
i=1
do while (x<=10.) y=0.
j=1
do while (y<=10.)
r=sqrt((x-5.)**2+(y-5.)**2) if (abs(r-rmin)<eps) then V(i,j)=100.
else if (abs(r-rmax)<eps) then V(i,j)=0.
else if (r>rmax) then
V(i,j)=(V(i-1,j)+V(i+1,j)+V(i,j-1)+V(i,j+1))/4.
else if (r<rmin .AND. abs(r-rmin)>eps) then V(i,j)=100.
else if (rmin<r .AND. r<rmax .AND. abs(r-rmax)>eps) then V(i,j)=(V(i-1,j)+V(i+1,j)+V(i,j-1)+V(i,j+1))/4.
end if y=y+hy j=j+1 end do x=x+hx i=i+1 end do
call magnitud(V-V_ant,n,dif) print*, dif
end do
end subroutine
!---!
!---Subrutina que calcula el campo el´ectrico---!
!---!
subroutine campo(V,n,Ex,Ey) IMPLICIT NONE
integer, intent(in) :: n
real(16), dimension(n+6,n+6), intent(in) :: V real(16), dimension(n+6,n+6), intent(out) :: Ex,Ey
integer :: i,j,h h=1
do i=2,n+5 do j=2,n+5
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
Utilizando exactamente la misma metodologa del cuadrado, obtuve las siguientes gr´aficas para el potencial, las curvas equipotenciales y el campo el´ectrico.