blob: 3a2260d3249bad264036d68fbdf27fb8d26e825c [file] [log] [blame]
avm9996345a8a462022-06-04 12:41:03 +02001program main
2 use, intrinsic :: iso_c_binding, only: sp=>c_float, dp=>c_double
3 use iso_fortran_env
4 implicit none
5 integer*4 :: L
6 real*8 :: MAGNE, ENERG, TEMP, E, DIFE, DELTA, M, SUMA, V1, V2, V3, V4, W(-8:8)
7 integer*4 :: I, J, IMC, MCTOT, MCINI, MCD, IPAS, N, SEED, NSEED, SEED0, PBC
8 integer :: genrand_int31
9 character(100) :: NOM
10
11 integer :: SUMI
12 real(dp) :: SUME, SUME2, SUMM, SUMAM, SUMM2, VARE, VARM, CV, CHI
13
14 ! This should be replaced by L but it doesn't work dynamically, so we're
15 ! setting 64 as the upper limit which should be higher than L.
16 integer*2 :: S(1:64, 1:64)
17
18 ! Inicialitzem algunes variables sobre el problema
19 namelist /DADES/ L, NOM, TEMP, NSEED, SEED0, MCTOT, MCINI, MCD
20 open(10, file="mc2.dat")
21 read(10, DADES)
22 close(10)
23
24 N = L*L
25
26 ! Obrim el fitxer on escriurem els resultats a cada iteració
27 open(unit = 12, file = "data_out/" // trim(NOM) // ".out")
28
29 ! Cache dels valors de l'exponencial
30 do I = 0, 8
31 W(I) = (2**30 - 1 + 2**30)*exp(-float(I)/TEMP)
32 enddo
33
34 SUMI = 0
35 SUME = 0
36 SUME2 = 0
37
38 SUMM = 0
39 SUMAM = 0
40 SUMM2 = 0
41
42 do SEED = SEED0, SEED0 + NSEED - 1
43 print *, "Seed: ", SEED
44
45 ! Inicialitzem la matriu d'spins aleatòriament
46 call WRITECONFIGSEED(S, L, SEED)
47
48 E = ENERG(S, L)
49 M = MAGNE(S, L)
50 !write (12, *) "0", E, M
51
52 ! Iterem amb el mètode de Montecarlo
53 do IMC = 1, MCTOT
54 do IPAS = 1, N
55 ! LOS LOOPS HACEN COSAS
56 I = MOD(genrand_int31(), L) + 1
57 J = MOD(genrand_int31(), L) + 1
58 V1 = S(PBC(I - 1, L), J)
59 V2 = S(PBC(I + 1, L), J)
60 V3 = S(I, PBC(J - 1, L))
61 V4 = S(I, PBC(J + 1, L))
62 SUMA = V1 + V2 + V3 + V4
63 DIFE = 2*SUMA*S(I, J)
64
65 if (DIFE > 0) then
66 DELTA = genrand_int31()
67 if (DELTA >= W(int(DIFE))) then
68 ! NO ho acceptem
69 cycle
70 endif
71 endif
72
73 ! Sí ho acceptem:
74 S(I, J) = -S(I, J)
75 E = E + DIFE
76 M = M + 2*S(I, J)
77 enddo
78
79 if (mod(IMC, 10000) == 0) then
80 print *, "Iter:", IMC, "Energia:", E, "Magn:", INT(M)
81 endif
82 !write (12, *) IMC, E, M
83
84 if (IMC > MCINI .and. mod(IMC, MCD) == 0) then
85 SUMI = SUMI + 1
86
87 SUME = SUME + E
88 SUME2 = SUME2 + E*E
89
90 SUMM = SUMM + M
91 SUMAM = SUMAM + abs(M)
92 SUMM2 = SUMM2 + M*M
93 endif
94 enddo
95 enddo
96
97 ! Normalitzem els promitjos
98 SUME = SUME/SUMI
99 SUME2 = SUME2/SUMI
100 SUMM = SUMM/SUMI
101 SUMAM = SUMAM/SUMI
102 SUMM2 = SUMM2/SUMI
103 VARE = SUME2 - SUME**2
104 VARM = SUMM2 - SUMM**2
105 CV = (SUME2 - SUME**2)/real(N*TEMP**2)
106 CHI = (SUMM2 - SUMAM**2)/real(N*TEMP)
107
108 ! Guardem a un fiter els promitjos
109 open(unit = 13, file = "data_out/" // trim(NOM) // ".res")
110 !write(13, *) "L, T, <E>, <E**2>, Var(E), <M>, <M**2>, Var(M), C_V, CHI"
111 write(13, *) L, TEMP, SUME, SUME2, VARE, SUMM, SUMAM, SUMM2, VARM, CV, CHI
112
113 ! Tanquem els fitxers de sortida
114 close(12)
115 close(13)
116endprogram main