Metropolis - Potts 2D: mudanças entre as edições
Ir para navegação
Ir para pesquisar
Sem resumo de edição |
Sem resumo de edição |
||
Linha 29: | Linha 29: | ||
END PROGRAM | END PROGRAM | ||
!-------------------------------------------------------------! | |||
! Algoritmo de Metropolis ! | |||
!-------------------------------------------------------------! | |||
SUBROUTINE metropolis | SUBROUTINE metropolis | ||
USE variaveis_globais | USE variaveis_globais | ||
Linha 89: | Linha 89: | ||
DO s=1,L2 | DO s=1,L2 | ||
r = u(1,L2) | r = u(1,L2) | ||
2 | 2 r_new = u(1,L2) | ||
IF (spin(r_new) == spin(r)) GO TO 2 | IF (spin(r_new) == spin(r)) GO TO 2 | ||
IF (spin(r_new) /= spin(r)) GO TO 3 | IF (spin(r_new) /= spin(r)) GO TO 3 | ||
spin(r_new) = theta(u(1,Q_state)) | spin(r_new) = theta(u(1,Q_state)) | ||
3 | 3 k_right = kronecker(spin(r),spin(right(r))) | ||
k_left = kronecker(spin(r),spin(left(r))) | k_left = kronecker(spin(r),spin(left(r))) | ||
k_up = kronecker(spin(r),spin(up(r))) | k_up = kronecker(spin(r),spin(up(r))) | ||
Linha 128: | Linha 128: | ||
CONTAINS | CONTAINS | ||
!-------------------------------------------------------------! | !-------------------------------------------------------------! | ||
! Funções ! | ! Funções ! | ||
!-------------------------------------------------------------! | !-------------------------------------------------------------! | ||
!Inicializa os spins de forma aleatória | !Inicializa os spins de forma aleatória | ||
FUNCTION spins_aleat(Q) | FUNCTION spins_aleat(Q) | ||
USE variaveis_globais | USE variaveis_globais | ||
Linha 153: | Linha 153: | ||
END FUNCTION spins_aleat | END FUNCTION spins_aleat | ||
!Inicializa os spins d forma ordenada, todos iguais | !Inicializa os spins d forma ordenada, todos iguais | ||
FUNCTION spins(Q) | FUNCTION spins(Q) | ||
USE variaveis_globais | USE variaveis_globais | ||
Linha 174: | Linha 174: | ||
END FUNCTION spins | END FUNCTION spins | ||
!Delta de Kronecker | !Delta de Kronecker | ||
FUNCTION kronecker(i,j) | FUNCTION kronecker(i,j) | ||
REAL :: i,j | REAL :: i,j | ||
Linha 186: | Linha 186: | ||
END FUNCTION kronecker | END FUNCTION kronecker | ||
!Gera números inteiros aleatórios | !Gera números inteiros aleatórios | ||
FUNCTION u(a,b) | FUNCTION u(a,b) | ||
INTEGER :: u,a,b | INTEGER :: u,a,b | ||
Linha 194: | Linha 194: | ||
RETURN | RETURN | ||
END FUNCTION u | END FUNCTION u | ||
!-------------------------------------------------------------! | !-------------------------------------------------------------! | ||
END SUBROUTINE metropolis | END SUBROUTINE metropolis |
Edição das 13h51min de 17 de outubro de 2022
MODULE variaveis_globais REAL(8) :: pi = 4*atan(1.) INTEGER :: L,L2,MCS,o,v,Q_state REAL :: Temp,B INTEGER,DIMENSION(33) :: seed REAL,DIMENSION(10) :: temperatura END MODULE variaveis_globais PROGRAM potts USE variaveis_globais IMPLICIT NONE DO o=1,33 seed(o) =o END DO CALL random_seed(put=seed) B = 1 L = 64 L2 = L*L MCS = 2000 Temp = 1. Q_state = 100 ! DO v=1,10 ! temperatura(v) = 0.2*v ! END DO
CALL metropolis END PROGRAM !-------------------------------------------------------------! ! Algoritmo de Metropolis ! !-------------------------------------------------------------! SUBROUTINE metropolis USE variaveis_globais IMPLICIT NONE INTEGER :: i,j,t,s,r,r2,r_new,f,n INTEGER :: k_right,k_left,k_up,k_down REAL(8) :: de,rn,prob,E0,E1,E2 INTEGER,DIMENSION(L2) :: right,left,up,down REAL(8),DIMENSION(L2) :: energia REAL,DIMENSION(L2) :: spin REAL(8),DIMENSION(MCS) :: e_media,mag REAL(8),DIMENSION(:),ALLOCATABLE :: theta REAL(8),DIMENSION(10) :: energia_media DO i=1,L DO j=1,L right((i-1)*L+j) = (i-1)*L+j+1 left((i-1)*L+j) = (i-1)*L+j-1 up((i-1)*L+j) = (i-1)*L+j-L down((i-1)*L+j) = (i-1)*L+j+L IF (i == 1) THEN up((i-1)*L+j) = L2-L+j END IF IF (i == L) THEN down((i-1)*L+j) = j END IF IF (j == 1) THEN left((i-1)*L+j) = i*L END IF IF (j == L) THEN right((i-1)*L+j) = i*L-(L-1) END IF END DO END DO
spin = spins_aleat(Q_state) ALLOCATE(theta(Q_state)) ! WRITE(*,*) spin E0 = 0 DO s=1,L2 k_right = kronecker(spin(i),spin(right(i))) k_left = kronecker(spin(i),spin(left(i))) k_up = kronecker(spin(i),spin(up(i))) k_down = kronecker(spin(i),spin(down(i))) E0 = E0 - B*(k_right + k_left + k_up + k_down) END DO WRITE(*,*) E0 DO n=1,Q_state theta(n) = 2.*pi*n/Q_state END DO OPEN(2,file='energia.dat',status='unknown') ! DO f=1,10 DO t=1,MCS DO s=1,L2 r = u(1,L2) 2 r_new = u(1,L2) IF (spin(r_new) == spin(r)) GO TO 2 IF (spin(r_new) /= spin(r)) GO TO 3 spin(r_new) = theta(u(1,Q_state)) 3 k_right = kronecker(spin(r),spin(right(r))) k_left = kronecker(spin(r),spin(left(r))) k_up = kronecker(spin(r),spin(up(r))) k_down = kronecker(spin(r),spin(down(r))) E1 = B*(k_right + k_left + k_up + k_down) k_right = kronecker(spin(r_new),spin(right(r))) k_left = kronecker(spin(r_new),spin(left(r))) k_up = kronecker(spin(r_new),spin(up(r))) k_down = kronecker(spin(r_new),spin(down(r))) E2 = B*(k_right + k_left + k_up + k_down) de = E2 - E1 IF (de .le. 0) THEN spin(r) = spin(r_new) ELSE prob = exp(-de/Temp) CALL random_number(rn) IF (rn < prob) THEN spin(r) = spin(r_new) END IF END IF energia(s) = E0 + de END DO e_media(t) = 1./L2*sum(energia) mag(t) = 1./L2*sum(spin) WRITE(2,*) t,e_media(t),mag(t) END DO ! energia_media(f) = 1./MCS*sum(e_media) ! WRITE(2,*) temperatura(f),energia_media(f) ! END DO CLOSE(2)
CONTAINS !-------------------------------------------------------------! ! Funções ! !-------------------------------------------------------------!
!Inicializa os spins de forma aleatória FUNCTION spins_aleat(Q) USE variaveis_globais INTEGER :: n,k,Q,m REAL,DIMENSION(Q) :: theta REAL,DIMENSION(L2) :: spins_aleat DO n=1,Q theta(n) = 2.*pi*n/Q END DO IF (Q .le. 2) THEN DO k=1,L2 spins_aleat(k) = cos(theta(u(1,Q))) END DO ELSE IF (Q > 2) THEN DO m=1,L2 spins_aleat(m) = theta(u(1,Q)) END DO END IF RETURN END FUNCTION spins_aleat
!Inicializa os spins d forma ordenada, todos iguais FUNCTION spins(Q) USE variaveis_globais INTEGER :: n,k,Q,m REAL,DIMENSION(Q) :: theta REAL,DIMENSION(L2) :: spins DO n=1,Q theta(n) = 2.*pi*n/Q END DO IF (Q .le. 2) THEN DO k=1,L2 spins(k) = cos(theta(1)) END DO ELSE IF (Q > 2) THEN DO m=1,L2 spins(m) = theta(1) END DO END IF RETURN END FUNCTION spins
!Delta de Kronecker FUNCTION kronecker(i,j) REAL :: i,j INTEGER :: kronecker IF (i == j) THEN kronecker = 1 ELSE kronecker = 0 END IF RETURN END FUNCTION kronecker
!Gera números inteiros aleatórios FUNCTION u(a,b) INTEGER :: u,a,b REAL :: r CALL random_number(r) u = int(b*r) + a RETURN END FUNCTION u !-------------------------------------------------------------! END SUBROUTINE metropolis