GPUE  v1.0
GPU Gross-Pitaevskii Equation numerical solver for Bose-Einstein condensates
vort.py
Go to the documentation of this file.
1 
2 import os
3 from numpy import genfromtxt
4 import math as m
5 import numpy as np
6 import copy as cp
7 import ConfigParser
8 import sys
9 
10 
11 if (len(sys.argv) == 2):
12  data_dir = "../" + sys.argv[1] + "/"
13 else:
14  data_dir = ""
15 c = ConfigParser.ConfigParser()
16 c.readfp(open(data_dir + 'Params.dat', "r"))
17 
18 xDim = int(c.getfloat('Params','xDim'))
19 yDim = int(c.getfloat('Params','yDim'))
20 gndMaxVal = int(c.getfloat('Params','gsteps'))
21 evMaxVal = int(c.getfloat('Params','esteps'))
22 incr = int(c.getfloat('Params','printSteps'))
23 dx = (c.getfloat('Params','dx'))
24 dt = (c.getfloat('Params','dt'))
25 xMax = (c.getfloat('Params','xMax'))
26 yMax = (c.getfloat('Params','yMax'))
27 
28 # quick check to make sure evMax Steps is right. This is simply because of the
29 # way GPUE outputs data.
30 if (evMaxVal % incr == 0):
31  evMaxVal = evMaxVal - incr
32 
33 
34 class Vortex: #Tracks indivisual vortices over time.
35 
37  def __init__(self,uid,x,y,isOn,sign=1):
38 
39  self.uid = uid
40  self.x = x
41  self.y = y
42  self.sign = sign
43  self.isOn = isOn
44  self.next = None
45 
46 
47  def update_uid(self,uid):
48 
49  self.uid = uid
50 
51 
52  def update_on(self,isOn): #Vortex is trackable
53 
54  self.isOn = isOn
55 
56 
57  def update_next(self,next): #Get next vortex
58 
59  self.next = next
60 
61 
62  def dist(self,vtx): #Distance between self and vtx
63 
64  r = m.sqrt((self.x - vtx.x)**2 + (self.y - vtx.y)**2)
65  return r
66 
67 
68 class VtxList: #Linked-list for tracking vortices
69 
71  def __init__(self):
72 
73  self.head = None
74  self.tail = None
75  self.length = 0
76 
77 
78  def element(self,pos): #Get vtx at position pos
79 
80  pos_l = 0
81  if pos < self.length:
82  vtx = self.head
83  while pos_l < pos:
84  pos_l = pos_l +1
85  vtx = vtx.next
86  else:
87  print "Out of bounds"
88  exit(-1)
89  return vtx
90 
91 
92  def vtx_uid(self,uid): #Get vtx with identifier uid
93 
94  vtx = self.head
95  pos = 0
96  while vtx.uid != uid:
97  vtx = vtx.next
98  pos = pos +1
99  return [vtx,pos]
100 
101 
102  def max_uid(self): #Return position and value of largest uid
103 
104  val = 0
105  vtx = self.head
106  val = vtx.uid
107  pos = 0
108  #while pos < self.length:
109  while True:
110  vtx = vtx.next
111  if(vtx == None):
112  break
113  if vtx.uid > val:
114  val = vtx.uid
115  pos = pos +1
116  return [val,pos]
117 
118 
119  def add(self,Vtx,index=None): #Add a vtx at index, otherwise end
120 
121  if self.length == 0:
122  self.head = Vtx
123  self.tail = Vtx
124  self.length = 1
125  elif index == None:
126  self.tail.next = Vtx
127  self.tail = Vtx
128  self.length = self.length +1
129  else:
130  Vtx.next = self.element(index)
131  self.element(index-1).next = Vtx
132  self.length = self.length + 1
133 
134 
135  def as_np(self): #Return numpy array with format x,y,sign,uid,isOn
136 
137  dtype = [('x',float),('y',float),('sign',int),('uid',int),('isOn',int)]
138  data =[]# np.array([],dtype=dtype)
139  i = 0
140  vtx = self.head
141  while vtx != None:
142  data.append([vtx.x, vtx.y, vtx.sign, vtx.uid, vtx.isOn])
143  vtx = vtx.next
144  i = i+1
145  return (data)
146 
147 
148  def write_out(self,time,data): #Write out CSV file as x,y,sign,uid,isOn
149 
150  np.savetxt(data_dir+'vort_ord_'+str(time)+'.csv',data,fmt='%10.5f,%10.5f,%i,%i,%i',delimiter=',')
151 
152 
153  def idx_min_dist(self,vortex, isSelf=False): #Closest vtx to self
154 
155  counter = 0
156  ret_idx = counter
157  vtx = self.head
158  if vtx != None:
159  r = vtx.dist(vortex)
160  while vtx.next != None:
161  vtx = vtx.next
162  counter = counter +1
163  if r > vtx.dist(vortex):
164  r = vtx.dist(vortex)
165  ret_idx = counter
166  return (ret_idx,r)
167 
168 
169  def remove(self,pos): #Remove vortices outside artificial boundary
170 
171  if self.length > 1 and pos > 1:
172  current = self.element(pos-1).next
173  self.element(pos - 1).next = current.next
174  current.next = None
175  self.length = self.length - 1
176  return current
177  elif pos == 0:
178  current = self.head
179  self.head = self.head.next
180  self.length = self.length - 1
181  return current
182  else:
183  self.head = None
184  self.length = 0
185  return None
186 
187 
188  def swap_uid(self,uid_i,uid_f): #Swap uid between vtx
189 
190  vtx_pos = self.vtx_uid(uid_i)
191  self.remove(pos_i)
192  self.add(vtx,index=pos_f)
193 
194 
195  def vort_decrease(self,positions,vorts_p): #Turn off vortex timeline
196 
197  for i4 in positions:
198  #print positions, "Decrease"
199  vtx = cp.copy(i4)
200  vtx.update_on(False)
201  vtx.update_next(None)
202  self.add(vtx)
203 
204 
205  def vort_increase(self,positions,vorts_p): #Add new vtx to tracking
206 
207  counter = 1
208  max_uid = vorts_p.max_uid()
209  for i4 in positions:
210  #print positions, "Increase"
211  self.element(i4).update_uid(max_uid[0] + counter)
212  counter = counter+1
213 
214 
215 def run(start,fin,incr): #Performs the tracking
216 
217  v_arr_p=genfromtxt(data_dir+'vort_arr_' + str(incr),delimiter=',')
218  for i in range( start + incr*2, fin + 1, incr): #loop over samples in time
219  vorts_p = VtxList()
220  vorts_c = VtxList()
221  v_arr_c=genfromtxt(data_dir+'vort_arr_' + str(i), delimiter=',')
222  if i==start + incr*2:
223  #from IPython import embed; embed()
224  v_arr_p_coords = np.array([a for a in v_arr_p[:,[1,3]]]) # Select the coordinates from the previous timestep
225  v_arr_c_coords = np.array([a for a in v_arr_c[:,[1,3]]]) # Select the coordinates from the current timestep
226  v_arr_p_sign = np.array([a for a in v_arr_p[:,4]]) # Select the vortex signs from previous
227  v_arr_c_sign = np.array([a for a in v_arr_c[:,4]]) # Select the vortex signs from current
228  else:
229  v_arr_p_coords = np.array([a for a in v_arr_p[:,[0,1]]]) #Previous coords
230  v_arr_p_sign = np.array([a for a in v_arr_p[:,2]]) #Previous sign
231 
232  v_arr_c_coords = np.array([a for a in v_arr_c[:,[1,3]]]) #Current coords
233  v_arr_c_sign = np.array([a for a in v_arr_c[:,4]]) #Current sign
234  for i1 in range(0,v_arr_p_coords.size/2): #loop over previous coordinates for a given time
235  vtx_p = Vortex(i1,v_arr_p_coords[i1][0],v_arr_p_coords[i1][1],True,sign=v_arr_p_sign[i1]) # Create a vortex object with uid given by number i1
236  vorts_p.add(vtx_p)#Add vortex to the list
237 
238  for i2 in range(0,v_arr_c_coords.size/2): #loop over current coordinates for a given time
239  vtx_c = Vortex(-1-i2,v_arr_c_coords[i2][0],v_arr_c_coords[i2][1],True,sign=v_arr_c_sign[i2]) # Create a vortex object with uid -1 - i2
240  vorts_c.add(vtx_c) #Add vortex object to list
241 
242  for i3 in range(0,vorts_p.length): # For all previous vortices in list
243  index_r = vorts_c.idx_min_dist(vorts_p.element(i3)) # Find the smallest distance vortex index between current and previous data
244 
245  v0c = vorts_c.element(index_r[0]).sign #Get the sign of the smallest distance vortex
246  v0p = vorts_p.element(i3).sign # Get the sign of the current vortex at index i3
247  v1c = vorts_c.element(index_r[0]).uid #Get uid of current vortex
248  #Check if distance is less than 7 grid points, and that the sign is matched between previous and current vortices, and that the current vortex has a negative uid, indicating that a pair has not yet been found. If true, then update the current vortex index to that of the previous vortex index, and turn vortex on --- may be dangerous
249  if (index_r[1] < 30) and (vorts_c.element(index_r[0]).sign == vorts_p.element(i3).sign) and (vorts_c.element(index_r[0]).uid < 0) and (vorts_p.element(i3).isOn == True):
250  vorts_c.element(index_r[0]).update_uid(vorts_p.element(i3).uid)
251  vorts_c.element(index_r[0]).update_on(True)
252  else:
253  print "Failed to find any matching vortex. Entering interactive mode. Exit with Ctrl+D"
254  from IPython import embed; embed()
255 
256 
257  #You will never remember why this works
258  uid_c = [[a for a in b][3] for b in vorts_c.as_np()] # Slice the uids for current data
259  uid_p = [[a for a in b][3] for b in vorts_p.as_np()] # Slice uids for previous data
260  #Check the difference between current and previous vtx data
261  dpc = set(uid_p).difference(set(uid_c)) # Creates a set and checks the elements for differences. Namely, finds which uids are unique to previous (ie which ones are no longer in current due to annihilation or falling outside boundary), which uids are only in current (ie newly found vortices, or older vortices that have reappeared)
262  dcp = set(uid_c).difference(set(uid_p))
263  vtx_pos_p=[]
264  vtx_pos_c=[]
265  #For all elements in the set of previous to current, note [vtx, pos] vtx for previous, and pos for current
266  for i5 in dpc:
267  vtx_pos_p = np.append(vtx_pos_p,vorts_p.vtx_uid(i5)[0]) #vtx
268  for i6 in dcp:
269  vtx_pos_c = np.append(vtx_pos_c,vorts_c.vtx_uid(i6)[1]) #pos
270  if len(dpc or dcp) >= 1: #if any differences were found, call the below functions
271  vorts_c.vort_decrease(vtx_pos_p,vorts_p)
272  vorts_c.vort_increase(vtx_pos_c,vorts_p)
273 
274  # Sort the vortices in current based on uid value, and write out the data
275  vorts_c_update=sorted(vorts_c.as_np(),key=lambda vtx: vtx[3])
276  vorts_c.write_out(i,np.asarray(vorts_c_update))
277  print "[" + str(i) +"]", "Length of previous=" + str(len(v_arr_p_coords)), "Length of current=" + str(len(vorts_c_update))
278  v_arr_p=genfromtxt(data_dir+'vort_ord_' + str(i) + '.csv',delimiter=',' )
279 
280 
282 run(0, evMaxVal, incr)
end if(length(DT.vertexAttachments{ii})==5) if plotit plot(x(ii)
def vort_decrease(self, positions, vorts_p)
Definition: vort.py:195
def write_out(self, time, data)
Definition: vort.py:148
def remove(self, pos)
Definition: vort.py:169
def add(self, Vtx, index=None)
Definition: vort.py:119
def update_uid(self, uid)
Definition: vort.py:47
def dist(self, vtx)
Definition: vort.py:62
% set(gca, 'Color', [0 0 0])
def update_on(self, isOn)
Definition: vort.py:52
def __init__(self, uid, x, y, isOn, sign=1)
Definition: vort.py:37
def as_np(self)
Definition: vort.py:135
def vtx_uid(self, uid)
Definition: vort.py:92
def vort_increase(self, positions, vorts_p)
Definition: vort.py:205
def update_next(self, next)
Definition: vort.py:57
def max_uid
Definition: vort.py:208
def swap_uid(self, uid_i, uid_f)
Definition: vort.py:188
def run(start, fin, incr)
Definition: vort.py:215
def element(self, pos)
Definition: vort.py:78
def idx_min_dist(self, vortex, isSelf=False)
Definition: vort.py:153