Statistiques
| Révision :

root / Ising / MP / Ising2D-MP.py @ 88

Historique | Voir | Annoter | Télécharger (5,34 ko)

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