Skip to content

Commit f2b57ae

Browse files
committed
Add version 2.
1 parent 234e442 commit f2b57ae

19 files changed

+416
-4
lines changed

fortran/build.cmd

-4
This file was deleted.
File renamed without changes.

fortran/v1/build.cmd

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gfortran util.f90 ising.f90 ising_main.f90 -o ising
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

fortran/v2/build.cmd

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gfortran util.f90 ising.f90 handle.f90 main.f90 -o ising

fortran/v2/handle.f90

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
module handle
2+
use ising
3+
implicit none
4+
real, parameter :: esp = 0.000001, J1 = 1
5+
contains
6+
real function get_delta_energy(spin, row, col) result(delta_energy)
7+
implicit none
8+
integer, intent(in) :: row, col
9+
type(spins), intent(in) :: spin
10+
integer(kind=1) :: sr, sl, st, sb
11+
12+
if (row < 2) then
13+
st = spin%data(spin%rows, col)
14+
sb = spin%data(row + 1 , col)
15+
else if(row > spin%rows-1) then
16+
st = spin%data(row - 1 , col)
17+
sb = spin%data(1 , col)
18+
else
19+
st = spin%data(row - 1 , col)
20+
sb = spin%data(row + 1 , col)
21+
end if
22+
23+
if (col < 2) then
24+
sl = spin%data(row, spin%cols)
25+
sr = spin%data(row , col + 1)
26+
else if(col > spin%cols-1) then
27+
sl = spin%data(row , col - 1)
28+
sr = spin%data(row , 1)
29+
else
30+
sl = spin%data(row , col - 1)
31+
sr = spin%data(row , col + 1)
32+
end if
33+
delta_energy = 2*spin%data(row, col)*(J1*(sl+sr+st+sb)+spin%magn)
34+
end function get_delta_energy
35+
36+
real function get_total_energy(spin) result(total_energy)
37+
implicit none
38+
type(spins) :: spin
39+
integer :: row, col
40+
integer(kind=1) :: sr, sb
41+
42+
total_energy = 0
43+
do col = 1, spin%cols
44+
do row = 1, spin%rows
45+
if (row > spin%rows-1) then
46+
sb = spin%data(1, col)
47+
else
48+
sb = spin%data(row+1, col)
49+
end if
50+
if (col > spin%cols-1) then
51+
sr = spin%data(row, 1)
52+
else
53+
sr = spin%data(row, col+1)
54+
end if
55+
total_energy = total_energy - spin%data(row, col)*(J1*(sr+sb)+spin%magn)
56+
end do
57+
end do
58+
end function get_total_energy
59+
60+
real function ising_average(spin, value) result(value_average)
61+
!
62+
! Calculate average value of ising quantity by given value.
63+
!
64+
! spin [type(spins)] spin data storage of ising system.
65+
! value [real] value of ising quantity.
66+
! return [real] average value of ising quantity.
67+
!
68+
implicit none
69+
real :: value
70+
type(spins) :: spin
71+
value_average = value/(spin%rows*spin%cols)
72+
end function ising_average
73+
74+
! update function to update ising system.
75+
subroutine update(spin, step, time, row, col)
76+
implicit none
77+
integer(kind=4) :: step, time
78+
integer :: row, col
79+
type(spins) :: spin
80+
real :: delta_energy, u
81+
82+
call random_number(u)
83+
delta_energy = get_delta_energy(spin, row, col)
84+
if (delta_energy < esp .or. exp(-delta_energy/spin%temp) > u) then
85+
spin%data(row, col) = -spin%data(row, col)
86+
endif
87+
88+
if (step .eq. 1) then
89+
write(*,"(T4,I0,T12,F0.6)") time, ising_average(spin,get_total_energy(spin))
90+
endif
91+
end subroutine update
92+
end module handle

fortran/v2/ising.f90

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module ising
2+
!
3+
! Ising 2d simulation module.
4+
!
5+
! Author: ph
6+
! Email: huipan.hnu@qq.com
7+
! Date: 2017.07.02
8+
!
9+
use util
10+
implicit none
11+
type :: spins
12+
! spins type for storage of spin data
13+
integer :: rows, cols
14+
real :: temp, magn
15+
integer(kind=1), pointer :: data(:, :)
16+
end type spins
17+
contains
18+
subroutine init_spins(spin, rows, cols, temp, magn)
19+
!
20+
! Init spins according to given spin and other pramaters.
21+
!
22+
! spin [type(spins)] spin data storage of ising system.
23+
! rows [integer] 2d square ising system rows.
24+
! cols [integer] 2d square ising system cols.
25+
! temp [real] temperature of ising system.
26+
! magn [real] magnet filed of ising system.
27+
!
28+
implicit none
29+
integer :: rows, cols
30+
real :: temp, magn, rdata(rows, cols)
31+
type(spins) :: spin
32+
integer :: row , col
33+
34+
call init_random_seed()
35+
call random_number(rdata)
36+
allocate(spin%data(rows, cols))
37+
where(rdata < 0.5)
38+
spin%data = -1
39+
elsewhere
40+
spin%data = 1
41+
end where
42+
spin%rows = rows
43+
spin%cols = cols
44+
spin%temp = temp
45+
spin%magn = magn
46+
end subroutine init_spins
47+
48+
subroutine ising_simulate(spin, steps, times, handle)
49+
!
50+
! Ising module simulation based on Monte-Carl method.
51+
!
52+
! spin [type(spins)] spin data storage of ising system.
53+
! steps [integer] steps of inner loop, also sampling steps.
54+
! times [integer] outter loop iteration, also sampling times.
55+
! handle [function] supply update function for Monte-Carl method.
56+
!
57+
implicit none
58+
type(spins) :: spin
59+
integer(kind=4) :: steps, times, step, time
60+
integer :: row, col
61+
real :: position(2)
62+
external :: handle
63+
64+
do time = 1, times
65+
do step = 1, steps
66+
call random_number(position)
67+
row = int(position(1)*spin%rows+1)
68+
col = int(position(2)*spin%cols+1)
69+
call handle(spin, step, time, row, col)
70+
end do
71+
end do
72+
end subroutine ising_simulate
73+
end module ising

fortran/v2/ising_plot.py

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env python3
2+
3+
import numpy as np
4+
import pylab as plb
5+
import os
6+
import argparse
7+
8+
def main():
9+
"""
10+
Draw spin file to image and display or save to image file.
11+
12+
Usage: `spin_plot [-l] [fdata] [-o fsave]`
13+
Params:
14+
--fdata data file from ising simulating.
15+
--fsave image file to save in.
16+
"""
17+
parser = argparse.ArgumentParser()
18+
parser.add_argument("-l", "--log", help="plot log data.", action="store_true")
19+
parser.add_argument("fdata", help="data file from ising simulation.")
20+
parser.add_argument("-o", "--fsave", help="image file to save in.")
21+
args = parser.parse_args()
22+
if not os.path.isfile(args.fdata):
23+
print('Error: data file not exist !')
24+
else:
25+
# load data file.
26+
data = np.loadtxt(args.fdata)
27+
28+
# plot data to image.
29+
if args.log:
30+
plb.plot(data[:,0], data[:,1])
31+
else:
32+
plb.imshow(data)
33+
plb.set_cmap('gray')
34+
35+
# save image file
36+
if args.fsave is not None:
37+
if args.log:
38+
plb.savefig(args.fsave)
39+
else:
40+
plb.imsave(args.fsave, data)
41+
else:
42+
plb.show()
43+
44+
if __name__ == '__main__':
45+
main()

fortran/v2/main.f90

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
subroutine show_usage()
2+
!
3+
! show help message of this pogram.
4+
!
5+
implicit none
6+
write(*,"(A,/)") 'Usage: ising.exe [rows] [cols] [temp] [magn] [steps] [times] [outfile]'
7+
write(*,"(A,/)") 'Params:'
8+
write(*,"(T4,A,/)") "--[rows] lattic system rows."
9+
write(*,"(T4,A,/)") "--[cols] lattic system cols."
10+
write(*,"(T4,A,/)") "--[temp] temperature of system."
11+
write(*,"(T4,A,/)") "--[magn] magnet filed of system."
12+
write(*,"(T4,A,/)") "--[steps] steps of sampling in Monte Carlo."
13+
write(*,"(T4,A,/)") "--[times] sampling times."
14+
write(*,"(T4,A,/)") "--[outfile] file to save simulation result of spin data."
15+
end subroutine show_usage
16+
17+
program main
18+
!
19+
! ising module 2d simulation main function.
20+
!
21+
! Usage: `ising [rows] [cols] [temp] [magn] [steps] [times] [outfile]`
22+
! Params:
23+
! --[rows] lattic system rows.
24+
! --[cols] lattic system cols.
25+
! --[temp] temperature of system.
26+
! --[magn] magnet filed of system.
27+
! --[steps] steps of sampling in Monte Carlo.
28+
! --[times] sampling times.
29+
! --[outfile] optional, file to save simulation result of spin data.
30+
!
31+
! Example:
32+
! cmd:
33+
! `ising 64 64 2.27 0. 1000 10 spin.csv`
34+
! out:
35+
! 1 -1.975586
36+
! 2 -1.974609
37+
! 3 -1.974609
38+
! 4 -1.979004
39+
! 5 -1.977539
40+
! 6 -1.976562
41+
! 7 -1.981445
42+
! 8 -1.986328
43+
! 9 -1.985840
44+
! 10 -1.986816
45+
!
46+
! Author: ph
47+
! Email: huipan.hnu@qq.com
48+
! Date: 2017.06.20
49+
!
50+
use util
51+
use ising
52+
use handle
53+
implicit none
54+
55+
type(spins) :: spin
56+
real :: temp, magn
57+
character(len=32) :: arg
58+
integer :: rows, cols, steps, times, i, narg
59+
60+
narg = iargc()
61+
62+
! only if number of paramters is 5 or 6, program can be continued.
63+
if (narg /= 6 .and. narg /= 7) then
64+
write(*,"(A,/)") 'Error: number of args not fit !'
65+
call show_usage()
66+
stop
67+
endif
68+
69+
! get input command args.
70+
do i = 1, 6
71+
call getarg(i,arg)
72+
select case(i)
73+
case(1)
74+
read(arg, *) rows
75+
case(2)
76+
read(arg, *) cols
77+
case(3)
78+
read(arg, *) temp
79+
case(4)
80+
read(arg, *) magn
81+
case(5)
82+
read(arg, *) steps
83+
case(6)
84+
read(arg, *) times
85+
end select
86+
end do
87+
88+
! init spin site data.
89+
call init_spins(spin, rows, cols, temp, magn)
90+
91+
! start simulating.
92+
call ising_simulate(spin, steps, times, update)
93+
94+
! save result spin site data to file.
95+
if (narg .eq. 7) then
96+
call getarg(i,arg)
97+
open(unit=12, file=arg)
98+
endif
99+
call show_matrix(int(spin%data), 12)
100+
101+
! deallocate spin data.
102+
deallocate(spin%data)
103+
end program main

fortran/v2/runtime.f90

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
program main
2+
!
3+
! Execute program and count it's running time.
4+
!
5+
! Usage: runtime [command]
6+
!
7+
! Author: ph
8+
! Email: huipan.hnu@qq.com
9+
! Date: 2017.06.20
10+
!
11+
implicit none
12+
character(len=512) :: cmd_line
13+
character(len=32) :: args(32)
14+
integer :: i, narg, time(0:1)
15+
narg = iargc()
16+
do i = 1, narg
17+
call getarg(i,args(i))
18+
end do
19+
write(cmd_line,"(TR1,32A)") args(1:narg)
20+
call system_clock(time(0))
21+
call system(cmd_line)
22+
call system_clock(time(1))
23+
write(*,"('[Finished in ',(F0.3),'s]')") real(time(1)-time(0))/1000
24+
end program main

fortran/v2/test.f90

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
program main
2+
implicit none
3+
write(*,"(A,' ',A)") "123","ph"
4+
end program main

0 commit comments

Comments
 (0)