Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (4,9 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=J*sigma[X,Y]*(2*(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):
50
    # Copier et caster 
51
    E=numpy.copy(sigma).astype(numpy.float32)
52
    
53
    # Appel par slice
54
    E[1:-1,1:-1]=-J*E[1:-1,1:-1]*(E[:-2,1:-1]+E[2:,1:-1]+
55
                                  E[1:-1,:-2]+E[1:-1,2:])
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 DisplayCurves(T,E,M,J,B):
68

    
69
    plt.xlabel("Temperature")
70
    plt.ylabel("Energy")
71

    
72
    Experience,=plt.plot(T,E,label="Energy") 
73

    
74
    plt.legend()
75
    plt.show()
76

    
77

    
78
if __name__=='__main__':
79

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

    
96
    # Curves is True to print the curves
97
    Curves=False
98

    
99
    try:
100
        opts, args = getopt.getopt(sys.argv[1:],"hcj:b:z:i:s:e:p:u:",["coupling=","magneticfield=","size=","iterations=","tempstart=","tempend=","tempstep=","units"])
101
    except getopt.GetoptError:
102
        print '%s -j <Coupling Factor> -b <Magnetic Field> -z <Size of Lattice> -i <Iterations> -s <Minimum Temperature> -e <Maximum Temperature> -p <steP Temperature> -u <Unit of process> -c (Print Curves)' % sys.argv[0]
103
        sys.exit(2)
104
    
105
    for opt, arg in opts:
106
        if opt == '-h':
107
            print '%s -j <Coupling Factor> -b <Magnetic Field> -z <Size of Lattice> -i <Iterations> -s <Minimum Temperature> -e <Maximum Temperature> -p <steP Temperature> -c (Print Curves)' % sys.argv[0]
108
            sys.exit()
109
        elif opt == '-c':
110
            Curves=True
111
        elif opt in ("-j", "--coupling"):
112
            J = float(arg)
113
        elif opt in ("-b", "--magneticfield"):
114
            B = float(arg)
115
        elif opt in ("-s", "--tempmin"):
116
            Tmin = float(arg)
117
        elif opt in ("-e", "--tempmax"):
118
            Tmax = arg
119
        elif opt in ("-p", "--tempstep"):
120
            Tstep = numpy.uint32(arg)
121
        elif opt in ("-i", "--iterations"):
122
            Iterations = int(arg)
123
        elif opt in ("-z", "--size"):
124
            Size = int(arg)
125
        elif opt in ("-u", "--unit"):
126
            Procs = int(arg)
127
      
128
    print "Process Units : %s" % Procs
129
    print "Coupling Factor J : %s" % J
130
    print "Magnetic Field B :  %s" % B
131
    print "Size of 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
    def MetropolisStrip(T):
149
        # Indispensable d'utiliser copy : [:] ne fonctionne pas avec numpy !
150
        sigma=numpy.copy(sigmaIn)
151
        duration=Metropolis(sigma,J,B,T,Iterations)
152
        ImageOutput(sigma,"Ising2D_Serial_%i_%1.1f_Final" % (Size,T))
153
        print "CPU Time : %f" % (duration)
154
        E,M=Energy(sigma,J),Magnetization(sigma,B)
155
        print "Total Energy at Temperature %f : %f" % (T,E)
156
        print "Total Magnetization at Temperature %f : %f" % (T,M)
157
        return(T,E,M)
158

    
159
    pool=Pool(processes=Procs)
160
    print "Start on %i processors..." % Procs
161
    # Apply MAP to POOL
162
    # MAP: distribution of usecases T to be applied to MetropolisStrip 
163
    Results=pool.map(MetropolisStrip,Trange)
164

    
165
    if Curves:
166
        DisplayCurves(Trange,E,M,J,B)
167

    
168
    # Save output
169
    numpy.savez("Ising2D_MP_%i_%.8i" % (Size,Iterations),(Trange,E,M))
170