1 year ago
#353610
SrD4443
How to increase eqsteps without getting that much fluctuation in a 1D Ising model code?
I have written a Fortran 90 code of 1-D Ising model for 100 lattice sites. I have calculated magnetization, energy, susceptibility and specific heat and plotted using gnuplot. I am getting almost expected results in E~t and m~t plots but I am unsure if c~t and sus~t plots are correct or not.
Also I have taken 100000 eqsteps for equilibrium. If i reduce the eqsteps to 100 or 200, I am getting too much fluctuation. Please help me how can I get result with smaller eqsteps.
program ising1d
implicit none
integer,allocatable,dimension(:)::lattice
real,allocatable,dimension(:)::mag
integer,dimension(100000)::seed=12345678
integer::i,row,d,p,eqsteps
integer::mcs,w
real::j,t,rval1,rval2,average_m
real::y,dE,sum_m,sum_E,average_E,E
real::sum_m2,sum_E2,average_m2,average_E2,c,sus
real,dimension(20000)::mm,EE
j=1.0
t=0.01
d=100
allocate(lattice(d))
open (unit = 9, file = "ss.txt", action = "write", status = "replace")
do while (t <= 10)
sum_E=0
sum_m=0
sum_m2=0
average_m2=0
w=1
do mcs=1,200
do row=1,d
call random_number(rval1)
if (rval1 .ge. 0.5)then
lattice(row)=1.0
else
lattice(row)=-1.0
end if
end do
! This loop is for taking measurements
! This loop is for getting equilibrium
do eqsteps=1,100000
! print*,lattice
! choosing an random site to flip
call random_number(y)
p=1+floor(y*d)
! print*,"the flipping site is :",p
! boundary condition
if(p==d) then
lattice(p+1)=lattice(1)
else if (p==1)then
lattice(p-1)=lattice(d)
else
lattice(p)=lattice(p)
end if
! energy change
dE=2*(lattice(p))*(lattice(p-1)+lattice(p+1))
! print*,"the change of energy is :",dE
! metropolis part
if (dE .le. 0) then
lattice(p)=-lattice(p)
! print*, "flipped"
else if (dE .gt. 0) then
call random_number(rval2)
if (rval2 .lt. exp(-1.0*dE/t)) then
lattice(p)=-lattice(p)
! print*, "flipped"
else
lattice(p)=lattice(p)
! print*, " not flipped"
end if
else
lattice(p)=lattice(p)
end if
end do
mm(w)=abs(sum(lattice))
sum_m = sum_m + mm(w)
sum_m2=sum_m2 + mm(w)*mm(w)
call calc_energy(d,row,E)
EE(w)=E
sum_E=sum_E+EE(w)
sum_E2=sum_E2+EE(w)*EE(w)
w=w+1
end do
average_m=sum_m/(w*d)
average_E=sum_E/(w*d)
average_m2=sum_m2/(w*w*d*d)
average_E2=sum_E2/(w*w*d*d)
c=(average_E2-average_E*average_E)/(t*t)
sus=(average_m2-average_m*average_m)/t
write(9,*) t,average_m,average_E,c,sus
print*,t,average_m,average_E,c,sus
t = t + 0.01
end do
close(9)
contains
!energy calculation
subroutine calc_energy(d,row,E)
integer,intent(in)::d,row
real, intent(out)::E
integer::k
real::E00=0
do k=2,d-1
E00=E00+lattice(k)*(lattice(k-1)+lattice(k+1))
end do
E=-0.5*(E00+lattice(1)*(lattice(2)+lattice(d))+lattice(d)*(lattice(d-1)+lattice(1)))
E00=0
end subroutine calc_energy
end program ising1d
I am expecting to get result with smaller eqstep size.
fortran
physics
0 Answers
Your Answer