Statistiques
| Révision :

root / Ising / Serial / Ising2D-Serial.py @ 93

Historique | Voir | Annoter | Télécharger (4,86 ko)

1
#!/usr/bin/env python
2
#
3
# Ising2D model in serial mode
4
#
5
# CC BY-NC-SA 2011 : <emmanuel.quemener@ens-lyon.fr> 
6

    
7
import sys
8
import numpy
9
from PIL import Image
10
from math import exp
11
from random import random
12
import time
13
import getopt
14
import matplotlib.pyplot as plt
15

    
16
def ImageOutput(sigma,prefix):
17
    Max=sigma.max()
18
    Min=sigma.min()
19
    
20
    # Normalize value as 8bits Integer
21
    SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
22
    image = Image.fromarray(SigmaInt)
23
    image.save("%s.jpg" % prefix)
24
    
25
def Metropolis(sigma,J,B,T,iterations): 
26
    start=time.time()
27

    
28
    SizeX,SizeY=sigma.shape
29
    
30
    for p in xrange(0,iterations):
31
        # Random access coordonate
32
        X,Y=numpy.random.randint(SizeX),numpy.random.randint(SizeY)
33
        
34
        DeltaE=sigma[X,Y]*(2.*J*(sigma[X,(Y+1)%SizeY]+
35
                                 sigma[X,(Y-1)%SizeY]+
36
                                 sigma[(X-1)%SizeX,Y]+
37
                                 sigma[(X+1)%SizeX,Y])+B)
38
        
39
        if DeltaE < 0. or random() < exp(-DeltaE/T):
40
            sigma[X,Y]=-sigma[X,Y]
41
    duration=time.time()-start
42
    return(duration)
43

    
44
def Magnetization(sigma,M):
45
    return(numpy.sum(sigma)/(sigma.shape[0]*sigma.shape[1]*1.0))
46

    
47
def Energy(sigma,J,B):
48
    # Copier et caster 
49
    E=numpy.copy(sigma).astype(numpy.float32)
50
    
51
    # Appel par slice
52
    E[1:-1,1:-1]=E[1:-1,1:-1]*(2.*J*(E[:-2,1:-1]+E[2:,1:-1]+
53
                                     E[1:-1,:-2]+E[1:-1,2:])+B)
54
    
55
    # Bien nettoyer la peripherie
56
    E[:,0]=0
57
    E[:,-1]=0
58
    E[0,:]=0
59
    E[-1,:]=0
60
    
61
    Energy=numpy.sum(E)
62

    
63
    return(Energy/(E.shape[0]*E.shape[1]*1.0))
64

    
65
def CriticalT(T,E):
66

    
67
    Epoly=numpy.poly1d(numpy.polyfit(T,E,T.size/3))
68
    dEpoly=numpy.diff(Epoly(T))
69
    dEpoly=numpy.insert(dEpoly,0,0)
70
    return(T[numpy.argmin(dEpoly)])
71

    
72
def DisplayCurves(T,E,M,J,B):
73

    
74
    plt.xlabel("Temperature")
75
    plt.ylabel("Energy")
76

    
77
    Experience,=plt.plot(T,E,label="Energy") 
78

    
79
    plt.legend()
80
    plt.show()
81

    
82

    
83
if __name__=='__main__':
84

    
85
    # Set defaults values
86
    # Coupling factor
87
    J=1.
88
    # Magnetic Field
89
    B=0.
90
    # Size of Lattice
91
    Size=256
92
    # Default Temperatures (start, end, step)
93
    Tmin=0.1
94
    Tmax=5
95
    Tstep=0.1
96
    # Default Number of Iterations
97
    Iterations=Size*Size*Size
98

    
99
    # Curves is True to print the curves
100
    Curves=False
101

    
102
    try:
103
        opts, args = getopt.getopt(sys.argv[1:],"hcj:b:z:i:s:e:p:",["coupling=","magneticfield=","size=","iterations=","tempstart=","tempend=","tempstep="])
104
    except getopt.GetoptError:
105
        print '%s -j <Coupling Factor> -b <Magnetic Field> -z <Size of Square Lattice> -i <Iterations> -s <Minimum Temperature> -e <Maximum Temperature> -p <steP Temperature> -c (Print Curves)' % sys.argv[0]
106
        sys.exit(2)
107
    
108
    for opt, arg in opts:
109
        if opt == '-h':
110
            print '%s -j <Coupling Factor> -b <Magnetic Field> -z <Size of Square Lattice> -i <Iterations> -s <Minimum Temperature> -e <Maximum Temperature> -p <steP Temperature> -c (Print Curves)' % sys.argv[0]
111
            sys.exit()
112
        elif opt == '-c':
113
            Curves=True
114
        elif opt in ("-j", "--coupling"):
115
            J = float(arg)
116
        elif opt in ("-b", "--magneticfield"):
117
            B = float(arg)
118
        elif opt in ("-s", "--tempmin"):
119
            Tmin = float(arg)
120
        elif opt in ("-e", "--tempmax"):
121
            Tmax = float(arg)
122
        elif opt in ("-p", "--tempstep"):
123
            Tstep = float(arg)
124
        elif opt in ("-i", "--iterations"):
125
            Iterations = int(arg)
126
        elif opt in ("-z", "--size"):
127
            Size = int(arg)
128
      
129
    print "Coupling Factor : %s" % J
130
    print "Magnetic Field :  %s" % B
131
    print "Size of square lattice : %s" % Size
132
    print "Iterations : %s" % Iterations
133
    print "Temperature on start : %s" % Tmin
134
    print "Temperature on end : %s" % Tmax
135
    print "Temperature step : %s" % Tstep
136

    
137
    LAPIMAGE=False
138

    
139
    sigmaIn=numpy.where(numpy.random.randn(Size,Size)>0,1,-1).astype(numpy.int8)
140

    
141
    ImageOutput(sigmaIn,"Ising2D_Serial_%i_Initial" % (Size))
142

    
143
    Trange=numpy.arange(Tmin,Tmax+Tstep,Tstep)
144

    
145
    E=[]
146
    M=[]
147

    
148
    for T in Trange:
149
        # Indispensable d'utiliser copy : [:] ne fonctionne pas avec numpy !
150
        sigma=numpy.copy(sigmaIn)
151
        duration=Metropolis(sigma,J,B,T,Iterations)
152
        E=numpy.append(E,Energy(sigma,J,B))
153
        M=numpy.append(M,Magnetization(sigma,B))
154
        ImageOutput(sigma,"Ising2D_Serial_%i_%1.1f_Final" % (Size,T))
155
    
156
        print "CPU Time : %f" % (duration)
157
        print "Total Energy at Temperature %f : %f" % (T,E[-1])
158
        print "Total Magnetization at Temperature %f : %f" % (T,M[-1])
159

    
160
    if Curves:
161
        DisplayCurves(Trange,E,M,J,B)
162

    
163
    # Save output
164
    numpy.savez("Ising2D_Serial_%i_%.8i" % (Size,Iterations),(Trange,E,M))
165
    
166
    # Estimate Critical temperature
167
    print "The critical temperature on %ix%i lattice with J=%f, B=%f is %f " % (Size,Size,J,B,CriticalT(Trange,E))