avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 1 | program 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ínez | ebb8779 | 2022-06-04 20:07:20 +0200 | [diff] [blame] | 6 | 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 |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 8 | integer :: genrand_int31 |
| 9 | character(100) :: NOM |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 10 | logical :: SAVEFINALCONF, SAVEEVOLUTION |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 11 | |
| 12 | integer :: SUMI |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 13 | real(dp) :: SUME, SUME2, SUMM, SUMAM, SUMM2, VARE_TIMES_SUMI, VARM_TIMES_SUMI, CV, CHI |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 14 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 15 | ! 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) |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 19 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 20 | ! Inicialitzem algunes variables sobre el problema, que es passen al programa amb un namelist |
| 21 | namelist /DADES/ L, NOM, TEMP, NSEED, SEED0, MCTOT, MCINI, MCD, SAVEFINALCONF, SAVEEVOLUTION |
Adrià Vilanova Martínez | c102e96 | 2022-06-04 23:53:44 +0200 | [diff] [blame] | 22 | read(nml = DADES, unit = 5) |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 23 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 24 | if (L < 1 .or. L > 128) then |
| 25 | print *, "ERROR: L ha de ser un enter entre 1 i 128." |
| 26 | stop |
| 27 | endif |
| 28 | |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 29 | N = L*L |
| 30 | |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 31 | ! Cache dels valors de l'exponencial |
| 32 | do I = 0, 8 |
| 33 | W(I) = (2**30 - 1 + 2**30)*exp(-float(I)/TEMP) |
| 34 | enddo |
| 35 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 36 | ! Variables on anirem sumant les magnituds per fer el promig posteriorment |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 37 | SUMI = 0 |
| 38 | SUME = 0 |
| 39 | SUME2 = 0 |
| 40 | |
| 41 | SUMM = 0 |
| 42 | SUMAM = 0 |
| 43 | SUMM2 = 0 |
| 44 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 45 | ! Si s'ha especificat de guardar l'evolució temporal, obrim el fitxer on la guardarem |
| 46 | if (SAVEEVOLUTION) then |
| 47 | open(12, file = "data_out/" // trim(NOM) // ".ev") |
| 48 | endif |
| 49 | |
| 50 | ! Fem la simulació per NSEED seeds inicials. |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 51 | do SEED = SEED0, SEED0 + NSEED - 1 |
| 52 | print *, "Seed: ", SEED |
| 53 | |
| 54 | ! Inicialitzem la matriu d'spins aleatòriament |
Adrià Vilanova Martínez | ebb8779 | 2022-06-04 20:07:20 +0200 | [diff] [blame] | 55 | call generateSpinMatrix(S, L, SEED) |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 56 | |
Adrià Vilanova Martínez | ebb8779 | 2022-06-04 20:07:20 +0200 | [diff] [blame] | 57 | E = energ(S, L) |
| 58 | M = magne(S, L) |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 59 | if (SAVEEVOLUTION) then |
| 60 | write (12, *) "0", E, M |
| 61 | endif |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 62 | |
| 63 | ! Iterem amb el mètode de Montecarlo |
| 64 | do IMC = 1, MCTOT |
| 65 | do IPAS = 1, N |
Adrià Vilanova Martínez | ebb8779 | 2022-06-04 20:07:20 +0200 | [diff] [blame] | 66 | I = mod(genrand_int31(), L) + 1 |
| 67 | J = mod(genrand_int31(), L) + 1 |
| 68 | SUMA = S(PBC(I - 1, L), J) + & |
| 69 | S(PBC(I + 1, L), J) + & |
| 70 | S(I, PBC(J - 1, L)) + & |
| 71 | S(I, PBC(J + 1, L)) |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 72 | DIFE = 2*SUMA*S(I, J) |
| 73 | |
| 74 | if (DIFE > 0) then |
| 75 | DELTA = genrand_int31() |
| 76 | if (DELTA >= W(int(DIFE))) then |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 77 | ! NO ho acceptem, passem a la següent volta del loop |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 78 | cycle |
| 79 | endif |
| 80 | endif |
| 81 | |
| 82 | ! Sí ho acceptem: |
| 83 | S(I, J) = -S(I, J) |
| 84 | E = E + DIFE |
| 85 | M = M + 2*S(I, J) |
| 86 | enddo |
| 87 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 88 | if (SAVEEVOLUTION) then |
| 89 | write (12, *) IMC, E, M |
| 90 | endif |
| 91 | |
| 92 | ! Per evitar les correlacions de configuracions consecutives, només |
| 93 | ! prenem mesures cada MCD configuracions. |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 94 | if (IMC > MCINI .and. mod(IMC, MCD) == 0) then |
| 95 | SUMI = SUMI + 1 |
| 96 | |
| 97 | SUME = SUME + E |
| 98 | SUME2 = SUME2 + E*E |
| 99 | |
| 100 | SUMM = SUMM + M |
| 101 | SUMAM = SUMAM + abs(M) |
| 102 | SUMM2 = SUMM2 + M*M |
| 103 | endif |
| 104 | enddo |
| 105 | enddo |
| 106 | |
| 107 | ! Normalitzem els promitjos |
| 108 | SUME = SUME/SUMI |
| 109 | SUME2 = SUME2/SUMI |
| 110 | SUMM = SUMM/SUMI |
| 111 | SUMAM = SUMAM/SUMI |
| 112 | SUMM2 = SUMM2/SUMI |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 113 | VARE_TIMES_SUMI = SUME2 - SUME**2 |
| 114 | VARM_TIMES_SUMI = SUMM2 - SUMM**2 |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 115 | CV = (SUME2 - SUME**2)/real(N*TEMP**2) |
| 116 | CHI = (SUMM2 - SUMAM**2)/real(N*TEMP) |
| 117 | |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 118 | ! Guardem a un fitxer els promitjos |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 119 | open(unit = 13, file = "data_out/" // trim(NOM) // ".res") |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 120 | ! Valors: L, T, <E>, <E**2>, Var(E)*SUMI, <M>, <|M|>, <M**2>, Var(M)*SUMI, C_V, CHI |
| 121 | write(13, *) L, TEMP, SUME, SUME2, VARE_TIMES_SUMI, SUMM, SUMAM, SUMM2, VARM_TIMES_SUMI, CV, CHI |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 122 | |
Adrià Vilanova Martínez | 1ee4edb | 2022-06-13 22:37:08 +0200 | [diff] [blame] | 123 | if (SAVEFINALCONF) then |
| 124 | call writeConfig(S, L, "data_out/" // trim(NOM) // ".conf") |
| 125 | endif |
| 126 | |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 127 | ! Tanquem els fitxers de sortida |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 128 | close(13) |
Adrià Vilanova Martínez | 24d8701 | 2022-06-16 00:29:59 +0200 | [diff] [blame^] | 129 | if (SAVEEVOLUTION) then |
| 130 | close(12) |
| 131 | endif |
avm99963 | 45a8a46 | 2022-06-04 12:41:03 +0200 | [diff] [blame] | 132 | endprogram main |