blob: 20efdcadabcffff619151bb02c45449e0e1ad9b8 [file] [log] [blame]
avm99963802583e2022-05-12 10:56:56 +02001program main
2 use, intrinsic :: iso_c_binding, only: sp=>c_float, dp=>c_double
3 implicit none
4 integer*4, PARAMETER :: L = 32
5 integer*2 :: S(1:L, 1:L)
6 real*8 :: MAGNE, ENERG, TEMP, E, DIFE, DELTA, M, SUMA, W(-8:8), genrand_real2
7 integer*4 :: PBC(0:L+1), I, J, IMC, MCTOT, MCINI, MCD, IPAS, N, SEED, NSEED, SEED0
8 character :: TEMPSTRING*100, str*20
9 character(:), allocatable :: NOM
10
11 integer :: SUMI
12 real(dp) :: SUME, SUME2, SUMM, SUMAM, SUMM2, VARE, VARM
13
14 if (command_argument_count() < 1) then
15 print *, "Error: please supply a command-line argument with the"
16 print *, "temperature, via './mc1 {TEMPERATURE}', where {TEMPERATURE}"
17 print *, "is the temperature."
18 stop
19 endif
20
21 ! Inicialitzem algunes variables sobre el problema
22 call get_command_argument(1, TEMPSTRING) ! Ex: 2.0d0
23 TEMPSTRING = trim(adjustl(TEMPSTRING))
24 read (TEMPSTRING, *) TEMP
25 NSEED = 10
26 SEED0 = 117654
27 MCTOT = 10000
28 MCINI = 1000
29 MCD = 10
30 N = L*L
31 NOM = "out_data/" // "SIM-L-" // trim(str(L)) // "-TEMP-" // &
32 trim(str(int(1000*TEMP))) // "-MCTOT-" // trim(str(MCTOT))
33
34 ! Obrim el fitxer on escriurem els resultats a cada iteració
35 open(unit = 12, file = NOM // ".out")
36
37 ! Inicialitzem variable que ens fa latent la periodicitat
38 PBC(0) = L
39 PBC(L + 1) = 1
40 do I = 1, L
41 PBC(I) = I
42 enddo
43
44 ! Cache dels valors de l'exponencial
45 do I = -8, 8
46 W(I) = exp(-float(I)/TEMP)
47 enddo
48
49 do SEED = SEED0, SEED0 + NSEED - 1
50 print *, "Seed: ", SEED
51
52 ! Inicialitzem la matriu d'spins aleatòriament
53 call WRITECONFIGSEED(S, L, SEED)
54
55 E = ENERG(S, L, PBC)
56 M = MAGNE(S, L)
57 print *, "Energia inicial:", E, "Magnet. inicial:", M
58 write (12, *) "0", E, M
59
60 ! Iterem amb el mètode de Montecarlo
61 do IMC = 1, MCTOT
62 do IPAS = 1, N
63 ! LOS LOOPS HACEN COSAS
64 I = INT(genrand_real2()*L) + 1
65 J = INT(genrand_real2()*L) + 1
66 SUMA = S(PBC(I - 1), J) + S(PBC(I + 1), J) + S(I, PBC(J - 1)) + S(I, PBC(J + 1))
67 DIFE = 2*SUMA*S(I, J)
68
69 if (DIFE > 0) then
70 DELTA = genrand_real2()
71 if (DELTA >= W(int(DIFE))) then
72 ! NO ho acceptem
73 cycle
74 endif
75 endif
76
77 ! Sí ho acceptem:
78 S(I, J) = -S(I, J)
79 E = E + DIFE
80 M = M + 2*S(I, J)
81 enddo
82
83 if (mod(IMC, 1000) == 0) then
84 print *, "Iter:", IMC, "Energia:", E, "Magn:", INT(M)
85 endif
86 write (12, *) IMC, E, M
87
88 if (IMC > MCINI .and. mod(IMC, MCD) == 0) then
89 SUMI = SUMI + 1
90
91 SUME = SUME + E
92 SUME2 = SUME2 + E*E
93
94 SUMM = SUMM + M
95 SUMAM = SUMAM + abs(M)
96 SUMM2 = SUMM2 + M*M
97 endif
98 enddo
99 enddo
100
101 ! Normalitzem els promitjos
102 SUME = SUME/SUMI
103 SUME2 = SUME2/SUMI
104 SUMM = SUMM/SUMI
105 SUMAM = SUMAM/SUMI
106 SUMM2 = SUMM2/SUMI
107 VARE = SUME2 - SUME*SUME
108 VARM = SUMM2 - SUMM*SUMM
109
110 ! Guardem a un fiter els promitjos
111 open(unit = 13, file = NOM // ".res")
112 write(13, *) L, TEMP, SUMI, SUME, SUME2, VARE, SUMM, SUMAM, SUMM2, VARM
113
114 ! Tanquem els fitxers de sortida
115 close(12)
116 close(13)
117endprogram main