def panels(self): """Create two panels of nodes at the front and back of lattice.""" front, back = [], [] for y, z in product(range(1, self.__ydim + 1), range(1, self.__zdim + 1)): front.append(tau(self.__xdim, y, z)) back.append(tau(1, y, z)) return (back, front)
def determine_shell(self, node): """ Instantiates a shell of immediately neighbouring points that correspond to the fusion connections in a brickwork pattern. This is done by a positive and negative x-direction connection, and then alternation each consecutive node in any of three directions, between positive and negative connections in y-direction and z-direction. """ shell = [] nodex = self.__latt.node[node]['X'] nodey = self.__latt.node[node]['Y'] nodez = self.__latt.node[node]['Z'] value = self.__latt.node[node]['value'] # Factor to determine the alternating brickwork lattice connections. factor = (-1)**(nodey + nodez + nodex) # The x-dimension is not affected by alternating factor. if 1 < nodex < self.__xdim: if value in [3, 2]: alt_ = 1 if value == 3 else -1 shell.append(tau(nodex + alt_, nodey, nodez)) shell.append(tau(nodex - alt_, nodey, nodez)) elif nodex == self.__xdim: if value in [3, 2]: shell.append(tau(nodex - 1, nodey, nodez)) else: if value in [3, 2]: shell.append(tau(nodex + 1, nodey, nodez)) # The y-dimension is affected by alternating factor. if 1 < nodey < self.__ydim: if value in [3, 1]: shell.append(tau(nodex, nodey + factor, nodez)) elif nodey == self.__ydim: if factor == -1: if value in [3, 1]: shell.append(tau(nodex, nodey - 1, nodez)) else: if factor == +1: if value in [3, 1]: shell.append(tau(nodex, nodey + 1, nodez)) # The z-dimension is affected by alternating factor if 1 < nodez < self.__zdim: if value in [3, 1]: shell.append(tau(nodex, nodey, nodez + factor)) elif nodez == self.__zdim: if factor == -1: if value in [3, 1]: shell.append(tau(nodex, nodey, nodez - 1)) else: if factor == 1: if value in [3, 1]: shell.append(tau(nodex, nodey, nodez + 1)) self.__latt.node[node]['shell'] = shell
def shortest_path(self): percolate = self.assess_percolation() if percolate: for y in range(1, self.__ydim + 1): for z in range(1, self.__zdim + 1): self.__latt.add_edge(tau(1, y, z), 'Back') self.__latt.add_edge(tau(self.__xdim, y, z), 'Front') length = len(nx.shortest_path(self.__latt, 'Back', 'Front')) - 2 self.__latt.remove_node('Back') self.__latt.remove_node('Front') return length else: return 0
def wise_chain(self, node, mate): """ Procedure to determine next node in the series of lattice points to consider, given the diamond/brickwork connection convention. """ # Considers the neighbouring 'mate' of the current node. xm = self.__latt.node[mate]['X'] ym = self.__latt.node[mate]['Y'] zm = self.__latt.node[mate]['Z'] mfactor = (-1)**(xm + ym + zm) # There is no next unless convinced otherwise. to_continue, next_node = True, None if xm == self.__latt.node[node]['X'] + 1: # If +ve 1 in the x-direction if xm == self.__xdim: to_continue = False else: next_node = tau(xm + 1, ym, zm) elif xm == self.__latt.node[node]['X'] - 1: # If -ve 1 in the x-direction if xm == 1: # If hitting the edge of the lattice to_continue = False else: next_node = tau(xm - 1, ym, zm) elif int(np.abs(self.__latt.node[node]['Y'] - ym)) == 1: # If a positive of negative difference in the y-direction. if mfactor == 1: if zm == self.__zdim: to_continue = False else: next_node = tau(xm, ym, zm + 1) elif mfactor == -1: if zm == 1: to_continue = False else: next_node = tau(xm, ym, zm - 1) elif int(np.abs(self.__latt.node[node]['Z'] - zm)) == 1: # If a positive of negative difference in the z-direction. if mfactor == 1: if ym == self.__ydim: to_continue = False else: next_node = tau(xm, ym + 1, zm) elif mfactor == -1: if ym == 1: to_continue = False else: next_node = tau(xm, ym - 1, zm) return next_node, to_continue
def __init__(self, xdim, ydim=None, zdim=None, p=0.75): """ Forms microclusters for all points in the graph. Parameters ---------- p : float Probability of fusion of two photons. """ if ydim == None and zdim == None: ydim, zdim = xdim, xdim elif zdim == None: zdim = ydim self.__xdim, self.__ydim, self.__zdim = xdim, ydim, zdim self.__p = p M = nx.Graph() M.graph['xdim'], M.graph['ydim'], M.graph['zdim'] = xdim, ydim, zdim M.graph['Prob'] = p probs = np.array( [p**2, p**2 + p * (1 - p), p**2 + 2 * (1 - p) * p, 1.0]) nvals = [3, 2, 1, 0] for x in range(1, xdim + 1): for y in range(1, ydim + 1): for z in range(1, zdim + 1): M.add_node(tau(x, y, z)) M.node[tau(x, y, z)]['X'] = x M.node[tau(x, y, z)]['Y'] = y M.node[tau(x, y, z)]['Z'] = z # Marker for when connecting the nodes so # to avoid double-counting branches. M.node[tau(x, y, z)]['Checked'] = False # Now simulates stochastic microcluster formation success. rand = nr.random() accept = list(rand < probs) try: nv = nvals[accept.index(False)] except ValueError: nv = 0 # Returns the first False where rand falls in prob range, # instead of extra lines of if-else statements. M.node[tau(x, y, z)]['value'] = nv self.__latt = M self.__connected = False