Statistiques
| Révision :

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

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

1 89 equemene
#!/usr/bin/env python
2 89 equemene
#
3 89 equemene
# Ising2D model in serial mode
4 89 equemene
#
5 89 equemene
# CC BY-NC-SA 2011 : <emmanuel.quemener@ens-lyon.fr>
6 89 equemene
7 89 equemene
import sys
8 89 equemene
import numpy
9 89 equemene
from PIL import Image
10 89 equemene
from math import exp
11 89 equemene
from random import random
12 89 equemene
import time
13 89 equemene
import getopt
14 89 equemene
import matplotlib.pyplot as plt
15 89 equemene
16 89 equemene
def ImageOutput(sigma,prefix):
17 89 equemene
    Max=sigma.max()
18 89 equemene
    Min=sigma.min()
19 89 equemene
20 89 equemene
    # Normalize value as 8bits Integer
21 89 equemene
    SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
22 89 equemene
    image = Image.fromarray(SigmaInt)
23 89 equemene
    image.save("%s.jpg" % prefix)
24 89 equemene
25 89 equemene
def Metropolis(sigma,J,B,T,iterations):
26 89 equemene
    start=time.time()
27 89 equemene
28 89 equemene
    SizeX,SizeY=sigma.shape
29 89 equemene
30 89 equemene
    for p in xrange(0,iterations):
31 89 equemene
        # Random access coordonate
32 89 equemene
        X,Y=numpy.random.randint(SizeX),numpy.random.randint(SizeY)
33 89 equemene
34 89 equemene
        DeltaE=sigma[X,Y]*(2.*J*(sigma[X,(Y+1)%SizeY]+
35 89 equemene
                                 sigma[X,(Y-1)%SizeY]+
36 89 equemene
                                 sigma[(X-1)%SizeX,Y]+
37 89 equemene
                                 sigma[(X+1)%SizeX,Y])+B)
38 89 equemene
39 89 equemene
        if DeltaE < 0. or random() < exp(-DeltaE/T):
40 89 equemene
            sigma[X,Y]=-sigma[X,Y]
41 89 equemene
    duration=time.time()-start
42 89 equemene
    return(duration)
43 89 equemene
44 89 equemene
def Magnetization(sigma,M):
45 89 equemene
    return(numpy.sum(sigma)/(sigma.shape[0]*sigma.shape[1]*1.0))
46 89 equemene
47 89 equemene
def Energy(sigma,J,B):
48 89 equemene
    # Copier et caster
49 89 equemene
    E=numpy.copy(sigma).astype(numpy.float32)
50 89 equemene
51 89 equemene
    # Appel par slice
52 89 equemene
    E[1:-1,1:-1]=E[1:-1,1:-1]*(2.*J*(E[:-2,1:-1]+E[2:,1:-1]+
53 89 equemene
                                     E[1:-1,:-2]+E[1:-1,2:])+B)
54 89 equemene
55 89 equemene
    # Bien nettoyer la peripherie
56 89 equemene
    E[:,0]=0
57 89 equemene
    E[:,-1]=0
58 89 equemene
    E[0,:]=0
59 89 equemene
    E[-1,:]=0
60 89 equemene
61 89 equemene
    Energy=numpy.sum(E)
62 89 equemene
63 89 equemene
    return(Energy/(E.shape[0]*E.shape[1]*1.0))
64 89 equemene
65 89 equemene
def CriticalT(T,E):
66 89 equemene
67 89 equemene
    Epoly=numpy.poly1d(numpy.polyfit(T,E,T.size/3))
68 89 equemene
    dEpoly=numpy.diff(Epoly(T))
69 89 equemene
    dEpoly=numpy.insert(dEpoly,0,0)
70 89 equemene
    return(T[numpy.argmin(dEpoly)])
71 89 equemene
72 89 equemene
def DisplayCurves(T,E,M,J,B):
73 89 equemene
74 89 equemene
    plt.xlabel("Temperature")
75 89 equemene
    plt.ylabel("Energy")
76 89 equemene
77 89 equemene
    Experience,=plt.plot(T,E,label="Energy")
78 89 equemene
79 89 equemene
    plt.legend()
80 89 equemene
    plt.show()
81 89 equemene
82 89 equemene
83 89 equemene
if __name__=='__main__':
84 89 equemene
85 89 equemene
    # Set defaults values
86 89 equemene
    # Coupling factor
87 89 equemene
    J=1.
88 89 equemene
    # Magnetic Field
89 89 equemene
    B=0.
90 89 equemene
    # Size of Lattice
91 89 equemene
    Size=256
92 89 equemene
    # Default Temperatures (start, end, step)
93 89 equemene
    Tmin=0.1
94 89 equemene
    Tmax=5
95 89 equemene
    Tstep=0.1
96 89 equemene
    # Default Number of Iterations
97 89 equemene
    Iterations=Size*Size*Size
98 89 equemene
99 89 equemene
    # Curves is True to print the curves
100 89 equemene
    Curves=False
101 89 equemene
102 89 equemene
    try:
103 89 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hcj:b:z:i:s:e:p:",["coupling=","magneticfield=","size=","iterations=","tempstart=","tempend=","tempstep="])
104 89 equemene
    except getopt.GetoptError:
105 89 equemene
        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 89 equemene
        sys.exit(2)
107 89 equemene
108 89 equemene
    for opt, arg in opts:
109 89 equemene
        if opt == '-h':
110 89 equemene
            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 89 equemene
            sys.exit()
112 89 equemene
        elif opt == '-c':
113 89 equemene
            Curves=True
114 89 equemene
        elif opt in ("-j", "--coupling"):
115 89 equemene
            J = float(arg)
116 89 equemene
        elif opt in ("-b", "--magneticfield"):
117 89 equemene
            B = float(arg)
118 89 equemene
        elif opt in ("-s", "--tempmin"):
119 89 equemene
            Tmin = float(arg)
120 89 equemene
        elif opt in ("-e", "--tempmax"):
121 89 equemene
            Tmax = float(arg)
122 89 equemene
        elif opt in ("-p", "--tempstep"):
123 89 equemene
            Tstep = float(arg)
124 89 equemene
        elif opt in ("-i", "--iterations"):
125 89 equemene
            Iterations = int(arg)
126 89 equemene
        elif opt in ("-z", "--size"):
127 89 equemene
            Size = int(arg)
128 89 equemene
129 89 equemene
    print "Coupling Factor : %s" % J
130 89 equemene
    print "Magnetic Field :  %s" % B
131 89 equemene
    print "Size of square lattice : %s" % Size
132 89 equemene
    print "Iterations : %s" % Iterations
133 89 equemene
    print "Temperature on start : %s" % Tmin
134 89 equemene
    print "Temperature on end : %s" % Tmax
135 89 equemene
    print "Temperature step : %s" % Tstep
136 89 equemene
137 89 equemene
    LAPIMAGE=False
138 89 equemene
139 89 equemene
    sigmaIn=numpy.where(numpy.random.randn(Size,Size)>0,1,-1).astype(numpy.int8)
140 89 equemene
141 89 equemene
    ImageOutput(sigmaIn,"Ising2D_Serial_%i_Initial" % (Size))
142 89 equemene
143 89 equemene
    Trange=numpy.arange(Tmin,Tmax+Tstep,Tstep)
144 89 equemene
145 89 equemene
    E=[]
146 89 equemene
    M=[]
147 89 equemene
148 89 equemene
    for T in Trange:
149 89 equemene
        # Indispensable d'utiliser copy : [:] ne fonctionne pas avec numpy !
150 89 equemene
        sigma=numpy.copy(sigmaIn)
151 89 equemene
        duration=Metropolis(sigma,J,B,T,Iterations)
152 89 equemene
        E=numpy.append(E,Energy(sigma,J,B))
153 89 equemene
        M=numpy.append(M,Magnetization(sigma,B))
154 89 equemene
        ImageOutput(sigma,"Ising2D_Serial_%i_%1.1f_Final" % (Size,T))
155 89 equemene
156 89 equemene
        print "CPU Time : %f" % (duration)
157 89 equemene
        print "Total Energy at Temperature %f : %f" % (T,E[-1])
158 89 equemene
        print "Total Magnetization at Temperature %f : %f" % (T,M[-1])
159 89 equemene
160 89 equemene
    if Curves:
161 89 equemene
        DisplayCurves(Trange,E,M,J,B)
162 89 equemene
163 89 equemene
    # Save output
164 89 equemene
    numpy.savez("Ising2D_Serial_%i_%.8i" % (Size,Iterations),(Trange,E,M))
165 89 equemene
166 89 equemene
    # Estimate Critical temperature
167 89 equemene
    print "The critical temperature on %ix%i lattice with J=%f, B=%f is %f " % (Size,Size,J,B,CriticalT(Trange,E))