blob: 554890de907ec22208eba12b7b39ef7294dc087d [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
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +02006 real*8 :: magne, energ, TEMP, E, DIFE, DELTA, M, SUMA, W(-8:8)
7 integer*4 :: I, J, IMC, MCTOT, MCINI, MCD, IPAS, N, SEED, NSEED, SEED0, pbc
avm9996345a8a462022-06-04 12:41:03 +02008 integer :: genrand_int31
9 character(100) :: NOM
Adrià Vilanova Martínez1ee4edb2022-06-13 22:37:08 +020010 logical :: SAVEFINALCONF
avm9996345a8a462022-06-04 12:41:03 +020011
12 integer :: SUMI
13 real(dp) :: SUME, SUME2, SUMM, SUMAM, SUMM2, VARE, VARM, CV, CHI
14
15 ! This should be replaced by L but it doesn't work dynamically, so we're
16 ! setting 64 as the upper limit which should be higher than L.
17 integer*2 :: S(1:64, 1:64)
18
19 ! Inicialitzem algunes variables sobre el problema
Adrià Vilanova Martínez1ee4edb2022-06-13 22:37:08 +020020 namelist /DADES/ L, NOM, TEMP, NSEED, SEED0, MCTOT, MCINI, MCD, SAVEFINALCONF
Adrià Vilanova Martínezc102e962022-06-04 23:53:44 +020021 read(nml = DADES, unit = 5)
avm9996345a8a462022-06-04 12:41:03 +020022
23 N = L*L
24
avm9996345a8a462022-06-04 12:41:03 +020025 ! Cache dels valors de l'exponencial
26 do I = 0, 8
27 W(I) = (2**30 - 1 + 2**30)*exp(-float(I)/TEMP)
28 enddo
29
30 SUMI = 0
31 SUME = 0
32 SUME2 = 0
33
34 SUMM = 0
35 SUMAM = 0
36 SUMM2 = 0
37
38 do SEED = SEED0, SEED0 + NSEED - 1
39 print *, "Seed: ", SEED
40
41 ! Inicialitzem la matriu d'spins aleatòriament
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +020042 call generateSpinMatrix(S, L, SEED)
avm9996345a8a462022-06-04 12:41:03 +020043
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +020044 E = energ(S, L)
45 M = magne(S, L)
avm9996345a8a462022-06-04 12:41:03 +020046
47 ! Iterem amb el mètode de Montecarlo
48 do IMC = 1, MCTOT
49 do IPAS = 1, N
50 ! LOS LOOPS HACEN COSAS
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +020051 I = mod(genrand_int31(), L) + 1
52 J = mod(genrand_int31(), L) + 1
53 SUMA = S(PBC(I - 1, L), J) + &
54 S(PBC(I + 1, L), J) + &
55 S(I, PBC(J - 1, L)) + &
56 S(I, PBC(J + 1, L))
avm9996345a8a462022-06-04 12:41:03 +020057 DIFE = 2*SUMA*S(I, J)
58
59 if (DIFE > 0) then
60 DELTA = genrand_int31()
61 if (DELTA >= W(int(DIFE))) then
62 ! NO ho acceptem
63 cycle
64 endif
65 endif
66
67 ! Sí ho acceptem:
68 S(I, J) = -S(I, J)
69 E = E + DIFE
70 M = M + 2*S(I, J)
71 enddo
72
avm9996345a8a462022-06-04 12:41:03 +020073 if (IMC > MCINI .and. mod(IMC, MCD) == 0) then
74 SUMI = SUMI + 1
75
76 SUME = SUME + E
77 SUME2 = SUME2 + E*E
78
79 SUMM = SUMM + M
80 SUMAM = SUMAM + abs(M)
81 SUMM2 = SUMM2 + M*M
82 endif
83 enddo
84 enddo
85
86 ! Normalitzem els promitjos
87 SUME = SUME/SUMI
88 SUME2 = SUME2/SUMI
89 SUMM = SUMM/SUMI
90 SUMAM = SUMAM/SUMI
91 SUMM2 = SUMM2/SUMI
92 VARE = SUME2 - SUME**2
93 VARM = SUMM2 - SUMM**2
94 CV = (SUME2 - SUME**2)/real(N*TEMP**2)
95 CHI = (SUMM2 - SUMAM**2)/real(N*TEMP)
96
97 ! Guardem a un fiter els promitjos
98 open(unit = 13, file = "data_out/" // trim(NOM) // ".res")
Adrià Vilanova Martínez1ee4edb2022-06-13 22:37:08 +020099 ! Valors: L, T, <E>, <E**2>, Var(E), <M>, <|M|>, <M**2>, Var(M), C_V, CHI
avm9996345a8a462022-06-04 12:41:03 +0200100 write(13, *) L, TEMP, SUME, SUME2, VARE, SUMM, SUMAM, SUMM2, VARM, CV, CHI
101
Adrià Vilanova Martínez1ee4edb2022-06-13 22:37:08 +0200102 if (SAVEFINALCONF) then
103 call writeConfig(S, L, "data_out/" // trim(NOM) // ".conf")
104 endif
105
avm9996345a8a462022-06-04 12:41:03 +0200106 ! Tanquem els fitxers de sortida
avm9996345a8a462022-06-04 12:41:03 +0200107 close(13)
108endprogram main