def center(self): """ Fix the center of mass of the lattice at (0, 0). """ error_handling.empty_coor(self.coor) self.coor["x"] -= np.mean(self.coor["x"]) self.coor["y"] -= np.mean(self.coor["y"])
def center(self): ''' Fix the center of mass of the lattice at (0, 0). ''' error_handling.empty_coor(self.coor) self.coor['x'] -= np.mean(self.coor['x']) self.coor['y'] -= np.mean(self.coor['y'])
def shift_y(self, shift): """ Shift by *delta_x* the x coordinates. :param shift: Real number. Shift value. """ error_handling.empty_coor(self.coor) error_handling.real_number(shift, "shift") self.coor["y"] += shift
def shift_y(self, shift): ''' Shift by *delta_x* the x coordinates. :param shift: Real number. Shift value. ''' error_handling.empty_coor(self.coor) error_handling.real_number(shift, 'shift') self.coor['y'] += shift
def clean_coor(self): """ Keep only the sites with different coordinates. """ error_handling.empty_coor(self.coor) coor = self.coor[["x", "y"]].copy() coor["x"], coor["y"] = self.coor["x"].round(4), self.coor["y"].round(4) _, idx = np.unique(coor, return_index=True) self.coor = self.coor[idx] self.sites = len(self.coor)
def clean_coor(self): ''' Keep only the sites with different coordinates. ''' error_handling.empty_coor(self.coor) coor = self.coor[['x', 'y']].copy() coor['x'], coor['y'] = self.coor['x'].round(4), self.coor['y'].round(4) _, idx = np.unique(coor, return_index=True) self.coor = self.coor[idx] self.sites = len(self.coor)
def __iadd__(self, other): ''' Overloading operator +=. ''' error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) self.coor = np.concatenate([self.coor, other.coor]) self.sites += other.sites self.tags = np.unique([self.tags, other.tags]) return self
def __iadd__(self, other): """ Overloading operator +=. """ error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) self.coor = np.concatenate([self.coor, other.coor]) self.sites += other.sites self.tags = np.unique([self.tags, other.tags]) return self
def boundary_line(self, cx, cy, co): ''' Select sites according to :math:`c_yy+c_xx > c_0`. :param cx: Real number. cx value. :param cy: Real number. cy value. :param co: Real number. co value. ''' error_handling.empty_coor(self.coor) error_handling.real_number(cx, 'cx') error_handling.real_number(cy, 'cy') error_handling.real_number(co, 'co') self.coor = self.coor[cy * self.coor['y'] + cx * self.coor['x'] > co] self.sites = len(self.coor)
def rotation(self, theta): r''' Rotate the lattice structure by the angle :math:`\theta`. :param theta: Rotation angle in degrees. ''' error_handling.empty_coor(self.coor) error_handling.real_number(theta, 'theta') theta *= PI / 360 for dic in self.unit_cell: x = self.coor['x'] - dic['r0'][0] y = self.coor['y'] - dic['r0'][1] self.coor['x'] = x * np.cos(theta) - y * np.sin(theta) + dic['r0'][0] self.coor['y'] = y * np.cos(theta) + x* np.sin(theta) + dic['r0'][1]
def __add__(self, other): """ Overloading operator +. """ error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) coor = np.concatenate([self.coor, other.coor]) tags = np.concatenate([self.tags, other.tags]) lat = lattice(unit_cell=self.unit_cell, prim_vec=self.prim_vec) lat.add_sites(coor) lat.sites = self.sites + other.sites lat.tags = np.unique(tags) return lat
def rotation(self, theta): r""" Rotate the lattice structure by the angle :math:`\theta`. :param theta: Rotation angle in degrees. """ error_handling.empty_coor(self.coor) error_handling.real_number(theta, "theta") theta *= PI / 360 for dic in self.unit_cell: x = self.coor["x"] - dic["r0"][0] y = self.coor["y"] - dic["r0"][1] self.coor["x"] = x * np.cos(theta) - y * np.sin(theta) + dic["r0"][0] self.coor["y"] = y * np.cos(theta) + x * np.sin(theta) + dic["r0"][1]
def boundary_line(self, cx, cy, co): """ Select sites according to :math:`c_yy+c_xx > c_0`. :param cx: Real number. cx value. :param cy: Real number. cy value. :param co: Real number. co value. """ error_handling.empty_coor(self.coor) error_handling.real_number(cx, "cx") error_handling.real_number(cy, "cy") error_handling.real_number(co, "co") self.coor = self.coor[cy * self.coor["y"] + cx * self.coor["x"] > co] self.sites = len(self.coor)
def __add__(self, other): ''' Overloading operator +. ''' error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) coor = np.concatenate([self.coor, other.coor]) tags = np.concatenate([self.tags, other.tags]) lat = lattice(unit_cell=self.unit_cell, prim_vec=self.prim_vec) lat.add_sites(coor) lat.sites = self.sites + other.sites lat.tags = np.unique(tags) return lat
def plot(self, ms=20, fs=20, plt_index=False, axis=False, figsize=None): """ Plot lattice in hopping space. :param ms: Positive number. Default value 20. Markersize. :param fs: Positve number. Default value 20. Fontsize. :param plt_index: Boolean. Default value False. Plot site labels. :param axis: Boolean. Default value False. Plot axis. :param figsize: Tuple. Default value None. Figsize. :returns: * **fig** -- Figure. """ error_handling.empty_coor(self.coor) error_handling.positive_real(ms, "ms") error_handling.positive_real(fs, "fs") error_handling.boolean(plt_index, "plt_index") error_handling.boolean(axis, "axis") if figsize is None: figsize = (5, 5) error_handling.list_tuple_2elem(figsize, "figsize") error_handling.positive_real(figsize[0], "figsize[0]") error_handling.positive_real(figsize[1], "figsize[1]") fig, ax = plt.subplots(figsize=figsize) # plot sites colors = ["b", "r", "g", "y", "m", "k"] for color, tag in zip(colors, self.tags): plt.plot( self.coor["x"][self.coor["tag"] == tag], self.coor["y"][self.coor["tag"] == tag], "o", color=color, ms=ms, markeredgecolor="none", ) ax.set_aspect("equal") ax.set_xlim([np.min(self.coor["x"]) - 1.0, np.max(self.coor["x"]) + 1.0]) ax.set_ylim([np.min(self.coor["y"]) - 1.0, np.max(self.coor["y"]) + 1.0]) if not axis: ax.axis("off") # plot indices if plt_index: indices = ["{}".format(i) for i in range(self.sites)] for l, x, y in zip(indices, self.coor["x"], self.coor["y"]): plt.annotate(l, xy=(x, y), xytext=(0, 0), textcoords="offset points", ha="right", va="bottom", size=fs) plt.draw() return fig
def __isub__(self, other): ''' Overloading operator -=. .. note:: The tags are not considered in the lattice subtraction. ''' error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) ind_remove = [] boo = np.zeros(self.sites, bool) for i, c in enumerate(other.coor): boo += np.isclose(c['x'], self.coor['x']) & np.isclose(c['y'], self.coor['y']) self.coor = self.coor[np.logical_not(boo)] self.sites = sum(np.logical_not(boo)) return self
def __isub__(self, other): """ Overloading operator -=. .. note:: The tags are not considered in the lattice subtraction. """ error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) ind_remove = [] boo = np.zeros(self.sites, bool) for i, c in enumerate(other.coor): boo += np.isclose(c["x"], self.coor["x"]) & np.isclose(c["y"], self.coor["y"]) self.coor = self.coor[np.logical_not(boo)] self.sites = sum(np.logical_not(boo)) return self
def plot(self, ms=20, fs=20, plt_index=False, axis=False, figsize=None): ''' Plot lattice in hopping space. :param ms: Positive number. Default value 20. Markersize. :param fs: Positve number. Default value 20. Fontsize. :param plt_index: Boolean. Default value False. Plot site labels. :param axis: Boolean. Default value False. Plot axis. :param figsize: Tuple. Default value None. Figsize. :returns: * **fig** -- Figure. ''' error_handling.empty_coor(self.coor) error_handling.positive_real(ms, 'ms') error_handling.positive_real(fs, 'fs') error_handling.boolean(plt_index, 'plt_index') error_handling.boolean(axis, 'axis') if figsize is None: figsize = (5, 5) error_handling.list_tuple_2elem(figsize, 'figsize') error_handling.positive_real(figsize[0], 'figsize[0]') error_handling.positive_real(figsize[1], 'figsize[1]') fig, ax = plt.subplots(figsize=figsize) # plot sites colors = ['b', 'r', 'g', 'y', 'm', 'k'] for color, tag in zip(colors, self.tags): plt.plot(self.coor['x'][self.coor['tag'] == tag], self.coor['y'][self.coor['tag'] == tag], 'o', color=color, ms=ms, markeredgecolor='none') ax.set_aspect('equal') ax.set_xlim([np.min(self.coor['x'])-1., np.max(self.coor['x'])+1.]) ax.set_ylim([np.min(self.coor['y'])-1., np.max(self.coor['y'])+1.]) if not axis: ax.axis('off') # plot indices if plt_index: indices = ['{}'.format(i) for i in range(self.sites)] for l, x, y in zip(indices, self.coor['x'], self.coor['y']): plt.annotate(l, xy=(x, y), xytext=(0, 0), textcoords='offset points', ha='right', va='bottom', size=fs) plt.draw() return fig
def ellipse_in(self, rx, ry, x0, y0): """ Select sites according to .. math:: (x-x_0)^2/a^2+(y-y_0)^2/b^2 < 1\, . :param list_hop: List of Dictionary (see set_hopping definition). :param rx: Positive Real number. Radius along :math:`x`. :param ry: Positive Real number. Radius along :math:`y`. :param x0: Real number. :math:`x` center. :param y0: Real number. :math:`y` center. """ error_handling.empty_coor(self.coor) error_handling.positive_real(rx, "rx") error_handling.positive_real(ry, "ry") error_handling.real_number(x0, "x0") error_handling.real_number(y0, "y0") self.coor = self.coor[(self.coor["x"] - x0) ** 2 / rx ** 2 + (self.coor["y"] - y0) ** 2 / ry ** 2 < 1.0] self.sites = len(self.coor)
def __sub__(self, other): """ Overloading operator -. .. note:: The tags are not considered in the lattice subtraction. """ error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) tags = np.unique([self.tags, other.tags]) boo = np.zeros(self.sites, bool) for i, c in enumerate(other.coor): boo += np.isclose(c["x"], self.coor["x"]) & np.isclose(c["y"], self.coor["y"]) coor = self.coor[np.logical_not(boo)] lat = lattice(unit_cell=self.unit_cell, prim_vec=self.prim_vec) lat.add_sites(coor) lat.sites = len(lat.coor) lat.tags = self.tags return lat
def remove_dangling(self): """ Remove dangling sites (sites connected with just another site). """ error_handling.empty_coor(self.coor) while True: dif_x = self.coor["x"] - self.coor["x"].reshape(self.sites, 1) dif_y = self.coor["y"] - self.coor["y"].reshape(self.sites, 1) dis = np.sqrt(dif_x ** 2 + dif_y ** 2) dis_unique = np.unique(dis) len_hop = dis_unique[1] ind = np.argwhere(np.isclose(dis, len_hop)) dang = [] for i in range(self.sites): if (ind[:, 0] == i).sum() == 1: dang.append(i) self.coor = np.delete(self.coor, dang, axis=0) self.sites -= len(dang) if dang == []: break
def remove_dangling(self): ''' Remove dangling sites (sites connected with just another site). ''' error_handling.empty_coor(self.coor) while True: dif_x = self.coor['x'] - self.coor['x'].reshape(self.sites, 1) dif_y = self.coor['y'] - self.coor['y'].reshape(self.sites, 1) dis = np.sqrt(dif_x ** 2 + dif_y ** 2) dis_unique = np.unique(dis) len_hop = dis_unique[1] ind = np.argwhere(np.isclose(dis, len_hop)) dang = [] for i in range(self.sites): if (ind[:, 0] == i).sum() == 1: dang.append(i) self.coor = np.delete(self.coor, dang, axis=0) self.sites -= len(dang) if dang == []: break
def __sub__(self, other): ''' Overloading operator -. .. note:: The tags are not considered in the lattice subtraction. ''' error_handling.lat(other) error_handling.empty_coor(self.coor) error_handling.empty_coor(other.coor) tags = np.unique([self.tags, other.tags]) boo = np.zeros(self.sites, bool) for i, c in enumerate(other.coor): boo += np.isclose(c['x'], self.coor['x']) & np.isclose(c['y'], self.coor['y']) coor = self.coor[np.logical_not(boo)] lat = lattice(unit_cell=self.unit_cell, prim_vec=self.prim_vec) lat.add_sites(coor) lat.sites = len(lat.coor) lat.tags = self.tags return lat
def ellipse_in(self, rx, ry, x0, y0): ''' Select sites according to .. math:: (x-x_0)^2/a^2+(y-y_0)^2/b^2 < 1\, . :param list_hop: List of Dictionary (see set_hopping definition). :param rx: Positive Real number. Radius along :math:`x`. :param ry: Positive Real number. Radius along :math:`y`. :param x0: Real number. :math:`x` center. :param y0: Real number. :math:`y` center. ''' error_handling.empty_coor(self.coor) error_handling.positive_real(rx, 'rx') error_handling.positive_real(ry, 'ry') error_handling.real_number(x0, 'x0') error_handling.real_number(y0, 'y0') self.coor = self.coor[(self.coor['x'] -x0) ** 2 / rx ** 2 + \ (self.coor['y'] -y0) ** 2 / ry ** 2 < 1.] self.sites = len(self.coor)
def remove_sites(self, index): ''' Remove sites defined by their indices (use method lattice.plot(plt_index=True) to get access to the site indices). :param index: List. Site indices to be removed. Example usage:: # Square lattice unit_cell = [{'tag': b'a', r0=(0., 0.)}] prim_vec = [(0, 1), (1, 0)] lat = lattice(unit_cell=unit_cell, prim_vec=prim_vec) lat.get_lattice(n1=2, n2=2) lat.remove_sites([0, 2]) ''' error_handling.empty_coor(self.coor) error_handling.remove_sites(index, self.sites) mask = np.ones(self.sites, bool) mask[index] = False self.coor = self.coor[mask] self.sites = self.coor.size
def remove_sites(self, index): """ Remove sites defined by their indices (use method lattice.plot(plt_index=True) to get access to the site indices). :param index: List. Site indices to be removed. Example usage:: # Square lattice unit_cell = [{'tag': b'a', r0=(0., 0.)}] prim_vec = [(0, 1), (1, 0)] lat = lattice(unit_cell=unit_cell, prim_vec=prim_vec) lat.get_lattice(n1=2, n2=2) lat.remove_sites([0, 2]) """ error_handling.empty_coor(self.coor) error_handling.remove_sites(index, self.sites) mask = np.ones(self.sites, bool) mask[index] = False self.coor = self.coor[mask] self.sites = self.coor.size
def change_sign_y(self): """ Change y coordinates sign. """ error_handling.empty_coor(self.coor) self.coor["y"] *= -1
def change_sign_y(self): ''' Change y coordinates sign. ''' error_handling.empty_coor(self.coor) self.coor['y'] *= -1