blob: 0a999b8454cb6c2411a628269f09bbe2369079e9 [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ínez24d87012022-06-16 00:29:59 +020010 logical :: SAVEFINALCONF, SAVEEVOLUTION
avm9996345a8a462022-06-04 12:41:03 +020011
12 integer :: SUMI
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020013 real(dp) :: SUME, SUME2, SUMM, SUMAM, SUMM2, VARE_TIMES_SUMI, VARM_TIMES_SUMI, CV, CHI
avm9996345a8a462022-06-04 12:41:03 +020014
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020015 ! Donat que les matrius a Fortran han de tenir una mida fixada i no poden
16 ! dependre dinàmicament d'un paràmetre L, fem S de mida 128x128, i establim
17 ! 128 com el valor màxim de L.
18 integer*2 :: S(1:128, 1:128)
avm9996345a8a462022-06-04 12:41:03 +020019
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020020 ! Inicialitzem algunes variables sobre el problema, que es passen al programa amb un namelist
Adrià Vilanova Martínezcbb47202022-06-16 00:37:40 +020021 ! L: Mida del sistema
22 ! NOM: Prefix dels noms dels fitxers on es desaran les dades.
23 ! TEMP: Temperatura reduïda per la simulació.
24 ! NSEED: Nombres de seeds que es simularan.
25 ! SEED0: Nombre de la seed inicial.
26 ! MCTOT: Nombre d'iteracions Montecarlo que es faran per cada llavor.
27 ! MCD: Cada cuantes iteracions Montecarlo s'han d'enregistrar les magnituds.
28 ! SAVEFINALCONF: Si s'ha de desar un fitxer amb la configuració final.
29 ! SAVEEVOLUTION: Si s'ha de desar un fitxer amb l'evolució temporal de les magnituds.
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020030 namelist /DADES/ L, NOM, TEMP, NSEED, SEED0, MCTOT, MCINI, MCD, SAVEFINALCONF, SAVEEVOLUTION
Adrià Vilanova Martínezc102e962022-06-04 23:53:44 +020031 read(nml = DADES, unit = 5)
avm9996345a8a462022-06-04 12:41:03 +020032
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020033 if (L < 1 .or. L > 128) then
34 print *, "ERROR: L ha de ser un enter entre 1 i 128."
35 stop
36 endif
37
avm9996345a8a462022-06-04 12:41:03 +020038 N = L*L
39
avm9996345a8a462022-06-04 12:41:03 +020040 ! Cache dels valors de l'exponencial
41 do I = 0, 8
42 W(I) = (2**30 - 1 + 2**30)*exp(-float(I)/TEMP)
43 enddo
44
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020045 ! Variables on anirem sumant les magnituds per fer el promig posteriorment
avm9996345a8a462022-06-04 12:41:03 +020046 SUMI = 0
47 SUME = 0
48 SUME2 = 0
49
50 SUMM = 0
51 SUMAM = 0
52 SUMM2 = 0
53
Adrià Vilanova Martínezcbb47202022-06-16 00:37:40 +020054 ! Si s'ha especificat de desar l'evolució temporal, obrim el fitxer on la desarem
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020055 if (SAVEEVOLUTION) then
56 open(12, file = "data_out/" // trim(NOM) // ".ev")
57 endif
58
59 ! Fem la simulació per NSEED seeds inicials.
avm9996345a8a462022-06-04 12:41:03 +020060 do SEED = SEED0, SEED0 + NSEED - 1
61 print *, "Seed: ", SEED
62
63 ! Inicialitzem la matriu d'spins aleatòriament
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +020064 call generateSpinMatrix(S, L, SEED)
avm9996345a8a462022-06-04 12:41:03 +020065
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +020066 E = energ(S, L)
67 M = magne(S, L)
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020068 if (SAVEEVOLUTION) then
69 write (12, *) "0", E, M
70 endif
avm9996345a8a462022-06-04 12:41:03 +020071
72 ! Iterem amb el mètode de Montecarlo
73 do IMC = 1, MCTOT
74 do IPAS = 1, N
Adrià Vilanova Martínezebb87792022-06-04 20:07:20 +020075 I = mod(genrand_int31(), L) + 1
76 J = mod(genrand_int31(), L) + 1
77 SUMA = S(PBC(I - 1, L), J) + &
78 S(PBC(I + 1, L), J) + &
79 S(I, PBC(J - 1, L)) + &
80 S(I, PBC(J + 1, L))
avm9996345a8a462022-06-04 12:41:03 +020081 DIFE = 2*SUMA*S(I, J)
82
83 if (DIFE > 0) then
84 DELTA = genrand_int31()
85 if (DELTA >= W(int(DIFE))) then
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020086 ! NO ho acceptem, passem a la següent volta del loop
avm9996345a8a462022-06-04 12:41:03 +020087 cycle
88 endif
89 endif
90
91 ! Sí ho acceptem:
92 S(I, J) = -S(I, J)
93 E = E + DIFE
94 M = M + 2*S(I, J)
95 enddo
96
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +020097 if (SAVEEVOLUTION) then
98 write (12, *) IMC, E, M
99 endif
100
101 ! Per evitar les correlacions de configuracions consecutives, només
102 ! prenem mesures cada MCD configuracions.
avm9996345a8a462022-06-04 12:41:03 +0200103 if (IMC > MCINI .and. mod(IMC, MCD) == 0) then
104 SUMI = SUMI + 1
105
106 SUME = SUME + E
107 SUME2 = SUME2 + E*E
108
109 SUMM = SUMM + M
110 SUMAM = SUMAM + abs(M)
111 SUMM2 = SUMM2 + M*M
112 endif
113 enddo
114 enddo
115
116 ! Normalitzem els promitjos
117 SUME = SUME/SUMI
118 SUME2 = SUME2/SUMI
119 SUMM = SUMM/SUMI
120 SUMAM = SUMAM/SUMI
121 SUMM2 = SUMM2/SUMI
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +0200122 VARE_TIMES_SUMI = SUME2 - SUME**2
123 VARM_TIMES_SUMI = SUMM2 - SUMM**2
avm9996345a8a462022-06-04 12:41:03 +0200124 CV = (SUME2 - SUME**2)/real(N*TEMP**2)
125 CHI = (SUMM2 - SUMAM**2)/real(N*TEMP)
126
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +0200127 ! Guardem a un fitxer els promitjos
avm9996345a8a462022-06-04 12:41:03 +0200128 open(unit = 13, file = "data_out/" // trim(NOM) // ".res")
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +0200129 ! Valors: L, T, <E>, <E**2>, Var(E)*SUMI, <M>, <|M|>, <M**2>, Var(M)*SUMI, C_V, CHI
130 write(13, *) L, TEMP, SUME, SUME2, VARE_TIMES_SUMI, SUMM, SUMAM, SUMM2, VARM_TIMES_SUMI, CV, CHI
avm9996345a8a462022-06-04 12:41:03 +0200131
Adrià Vilanova Martínez1ee4edb2022-06-13 22:37:08 +0200132 if (SAVEFINALCONF) then
133 call writeConfig(S, L, "data_out/" // trim(NOM) // ".conf")
134 endif
135
avm9996345a8a462022-06-04 12:41:03 +0200136 ! Tanquem els fitxers de sortida
avm9996345a8a462022-06-04 12:41:03 +0200137 close(13)
Adrià Vilanova Martínez24d87012022-06-16 00:29:59 +0200138 if (SAVEEVOLUTION) then
139 close(12)
140 endif
avm9996345a8a462022-06-04 12:41:03 +0200141endprogram main