Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (5,38 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
from multiprocessing import Pool
17

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

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

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

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

    
65
    return(Energy/(E.shape[0]*E.shape[1]*1.0))
66

    
67
def CriticalT(T,E):
68

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

    
74
def DisplayCurves(T,E,M,J,B):
75

    
76
    plt.xlabel("Temperature")
77
    plt.ylabel("Energy")
78

    
79
    Experience,=plt.plot(T,E,label="Energy") 
80

    
81
    plt.legend()
82
    plt.show()
83

    
84

    
85
if __name__=='__main__':
86

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

    
103
    # Curves is True to print the curves
104
    Curves=False
105

    
106
    try:
107
        opts, args = getopt.getopt(sys.argv[1:],"hcj:b:z:i:s:e:p:u:",["coupling=","magneticfield=","size=","iterations=","tempstart=","tempend=","tempstep=","units"])
108
    except getopt.GetoptError:
109
        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 <Units of processing> -c (Print Curves)' % sys.argv[0]
110
        sys.exit(2)
111
    
112
    for opt, arg in opts:
113
        if opt == '-h':
114
            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 <Units of Processing> -c (Print Curves)' % sys.argv[0]
115
            sys.exit()
116
        elif opt == '-c':
117
            Curves=True
118
        elif opt in ("-j", "--coupling"):
119
            J = float(arg)
120
        elif opt in ("-b", "--magneticfield"):
121
            B = float(arg)
122
        elif opt in ("-s", "--tempmin"):
123
            Tmin = float(arg)
124
        elif opt in ("-e", "--tempmax"):
125
            Tmax = arg
126
        elif opt in ("-p", "--tempstep"):
127
            Tstep = numpy.uint32(arg)
128
        elif opt in ("-i", "--iterations"):
129
            Iterations = int(arg)
130
        elif opt in ("-z", "--size"):
131
            Size = int(arg)
132
        elif opt in ("-u", "--units"):
133
            Procs = int(arg)
134
      
135
    print "Process Units : %s" % Procs
136
    print "Coupling Factor J : %s" % J
137
    print "Magnetic Field B :  %s" % B
138
    print "Size of lattice : %s" % Size
139
    print "Iterations : %s" % Iterations
140
    print "Temperature on start : %s" % Tmin
141
    print "Temperature on end : %s" % Tmax
142
    print "Temperature step : %s" % Tstep
143

    
144
    LAPIMAGE=False
145

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

    
148
    ImageOutput(sigmaIn,"Ising2D_Serial_%i_Initial" % (Size))
149

    
150
    Trange=numpy.arange(Tmin,Tmax+Tstep,Tstep)
151

    
152
    def MetropolisStrip(T):
153
        # Indispensable d'utiliser copy : [:] ne fonctionne pas avec numpy !
154
        sigma=numpy.copy(sigmaIn)
155
        duration=Metropolis(sigma,J,B,T,Iterations)
156
        ImageOutput(sigma,"Ising2D_MP_%i_%1.1f_Final" % (Size,T))
157
        print "CPU Time : %f" % (duration)
158
        indice=numpy.where(Trange==T)[0][0]
159
        E,M=Energy(sigma,J,B),Magnetization(sigma,B)
160
        print "Total Energy at Temperature %f : %f" % (T,E)
161
        print "Total Magnetization at Temperature %f : %f" % (T,M)
162
        return([T,E,M])
163

    
164
    pool=Pool(processes=Procs)
165
    print "Start on %i processors..." % Procs
166
    # Apply MAP to POOL
167
    # MAP: distribution of usecases T to be applied to MetropolisStrip 
168
    Results=pool.map(MetropolisStrip,Trange)
169

    
170
    E=numpy.array(Results)[:,1]
171
    M=numpy.array(Results)[:,2]
172
    
173
    # Save output
174
    numpy.savez("Ising2D_MP_%i_%.8i" % (Size,Iterations),(Trange,E,M))
175
      
176
    # Estimate Critical temperature
177
    print "The critical temperature on %ix%i lattice with J=%f, B=%f is %f " % (Size,Size,J,B,CriticalT(Trange,E))
178
  
179
    if Curves:
180
        DisplayCurves(Trange,E,M,J,B)
181