def StripeGenerator(cluster, config="StripeX"): """ Generate stripe ordered state on the given cluster. Parameters ---------- cluster : Lattice The cluster on which to generate the stripe ordered state. config : ["StripeX" | "StripeY", | "StripeZ"], str, optional The type of the stripe order to generate. If set to "StripeX", the spins along the x-bond direction are parallel; If set to "StripeY", the spins along the y-bond direction are parallel; If set to "StripeZ", the spins along the z-bond direction are parallel. Default: "StripeX". Returns ------- spin_up_indices : list of int The indices of the lattice sites which are in spin-up state. spin_down_indices : list of int The indices of the lattice sites which are in spin-down state. """ if config == "StripeX": points = np.array([[0.0, 0.0], [0.5, np.sqrt(3) / 2]]) vectors = np.array([[1.0, 0.0], [1.0, np.sqrt(3)]]) elif config == "StripeY": points = np.array([[0.0, 0.0], [0.5, np.sqrt(3) / 2]]) vectors = np.array([[1.5, np.sqrt(3) / 2], [1.0, np.sqrt(3)]]) elif config == "StripeZ": points = np.array([[0.0, 0.0], [1.0, 0.0]]) vectors = np.array([[2.0, 0.0], [0.5, np.sqrt(3) / 2]]) else: raise ValueError("Invalid `config`: {0}".format(config)) cell = Lattice(points, vectors) spin_up_indices = [] spin_down_indices = [] for point in cluster.points: index_cell = cell.getIndex(point, fold=True) index_cluster = cluster.getIndex(point, fold=False) if index_cell == 0: spin_up_indices.append(index_cluster) else: spin_down_indices.append(index_cluster) return spin_up_indices, spin_down_indices
def __init__(self): points = np.array([ [0.0, 0.0], [1.0, 0.0], [2.0, 0.0], [3.0, 0.0], [4.0, 0.0], [5.0, 0.0], [0.5, np.sqrt(3) / 2], [1.5, np.sqrt(3) / 2], [2.5, np.sqrt(3) / 2], [3.5, np.sqrt(3) / 2], [4.5, np.sqrt(3) / 2], [5.5, np.sqrt(3) / 2], ], dtype=np.float64) vectors = np.array([[6.0, 0.0], [3.0, np.sqrt(3)]], dtype=np.float64) cluster = Lattice(points, vectors) intra, inter = cluster.bonds(nth=1) x_bonds = [] y_bonds = [] z_bonds = [] for bond in intra + inter: p0, p1 = bond.endpoints index0 = cluster.getIndex(site=p0, fold=True) index1 = cluster.getIndex(site=p1, fold=True) bond_index = (index0, index1) azimuth = bond.getAzimuth(ndigits=0) if azimuth in (-180, 0, 180): x_bonds.append(bond_index) elif azimuth in (-120, 60): z_bonds.append(bond_index) elif azimuth in (-60, 120): y_bonds.append(bond_index) else: raise RuntimeError("Invalid bond azimuth: {0}".format(azimuth)) self._identity = "Triangle12" self._cluster = cluster self._x_bonds = tuple(x_bonds) self._y_bonds = tuple(y_bonds) self._z_bonds = tuple(z_bonds)
t0 = 0.0 t1 = -1.00 t2 = -0.25 id = "t0={0:.2f}_t1={1:.2f}_t2={2:.2f}".format(t0, t1, t2) cluster = Lattice(POINTS, VECTORS) intra_bonds_1st, inter_bonds_1st = cluster.bonds(nth=1) intra_bonds_2nd, inter_bonds_2nd = cluster.bonds(nth=2) intra_bonds_6th, inter_bonds_6th = cluster.bonds(nth=6) HTerms = [] for bond in intra_bonds_1st + inter_bonds_1st: p0, p1 = bond.endpoints p0_eqv, dR0 = cluster.decompose(p0) p1_eqv, dR1 = cluster.decompose(p1) index0 = cluster.getIndex(p0_eqv) index1 = cluster.getIndex(p1_eqv) HTerms.append((index0, index1, t0, dR0 - dR1)) for bond in intra_bonds_2nd + inter_bonds_2nd: p0, p1 = bond.endpoints p0_eqv, dR0 = cluster.decompose(p0) p1_eqv, dR1 = cluster.decompose(p1) index0 = cluster.getIndex(p0_eqv) index1 = cluster.getIndex(p1_eqv) HTerms.append((index0, index1, t1, dR0 - dR1)) for bond in intra_bonds_6th + inter_bonds_6th: p0, p1 = bond.endpoints p0_eqv, dR0 = cluster.decompose(p0) p1_eqv, dR1 = cluster.decompose(p1)
[1, 74], [8, 74], [14, 81], [14, 88], [13, 89], [15, 89], [17, 42], [17, 44], [16, 43], [18, 43], ] all_hopping_indices = intra_hopping_indices + inter_hopping_indices fig, ax = plt.subplots(num=model) for index, point in enumerate(points_collection): cell_index = cell.getIndex(point, fold=True) if cell_index in (0, 10): color = "tab:red" marker_size = 12 else: color = "tab:green" marker_size = 10 ax.plot( point[0], point[1], ls="", marker="o", color=color, ms=marker_size, zorder=1,
ax.plot([x0 + x_delta, x1 + x_delta], [y0, y1], color="black", zorder=0) # Draw the StripeX order StripeXCell = Lattice( np.array([[0.0, 0.0], [0.5, np.sqrt(3) / 2]]), np.array([[1.0, 0.0], [1.0, np.sqrt(3)]]), ) StripeXCellSpinColors = ("tab:orange", "tab:purple") StripeXCellSpinVectors = np.array([[0.0, 1.0], [0.0, -1.0]]) x_delta = x_deltas[0] spin_colors = [] spin_vectors = [] points = StripeXCluster.points for point in points: index = StripeXCell.getIndex(site=point, fold=True) spin_vectors.append(StripeXCellSpinVectors[index]) spin_colors.append(StripeXCellSpinColors[index]) spin_vectors = np.array(spin_vectors) Show2DVectors( ax, points[:, 0] + x_delta, points[:, 1], spin_vectors, spin_colors ) # Draw the StripeY order StripeYCell = Lattice( np.array([[0.0, 0.0], [1.0, 0.0]]), np.array([[2.0, 0.0], [-0.5, np.sqrt(3) / 2]]), ) StripeYCellSpinColors = ("tab:orange", "tab:purple") StripeYCellSpinVectors = np.array([[0.0, 1.0], [0.0, -1.0]])
[12, 45], [18, 90], [21, 110], [22, 58], [1, 136], [4, 45], [7, 89], [20, 99], [21, 139], [22, 50], ] ALL_HOPPING_INDICES = INTRA_HOPPING_INDICES + INTER_HOPPING_INDICES fig, ax = plt.subplots(num="ModelDefinition") for index, point in enumerate(POINTS_COLLECTION): cell_index = CELL.getIndex(point, fold=True) if cell_index in (0, 10): color = "tab:red" marker_size = 18 elif cell_index in (20, 21, 22): color = "tab:green" marker_size = 15 else: color = "tab:blue" marker_size = 12 ax.plot( point[0], point[1], ls="", marker="o",
def __init__(self, num1=4, num2=6, direction="xy"): """ On triangular lattice, the nearest-neighbor (NN) bonds along the zero-degree direction is defined as the x-type bond (x-bond); NN bonds along the 120-degree direction is defined as the y-type bond (y-bond); NN bonds along the 60-degree direction is defined as the z-type bond (z-bond). The definition of the x, y, z bond is counterclockwise. Parameters ---------- num1, num2 : int, optional The number of lattice site along the 1st and 2nd translation vector. The default values for `num1` and `num2` are 4 and 6 respectively. direction : ["xy" | "xz" | "yx" | "yz" | "zx" | "zy"], optional Define the direction of the cluster. This parameter determine the interpretation of the `num1` and `num2` parameters. For example, if `direction` is set to "xy", then there are `num1` lattice sites along the x-bond direction and `num2` lattice sites along the y-bond direction. Default: "xy". """ assert isinstance(num1, int) and num1 > 0 assert isinstance(num2, int) and num2 > 0 assert direction in ("xy", "xz", "yx", "yz", "zx", "zy") identity = "num1={0}_num2={1}_direction={2}".format( num1, num2, direction ) RX = np.array([1.0, 0.0], dtype=np.float64) RY = np.array([-0.5, np.sqrt(3) / 2], dtype=np.float64) RZ = np.array([0.5, np.sqrt(3) / 2], dtype=np.float64) AS = { "xy": np.array([RX, RY], dtype=np.float64), "xz": np.array([RX, RZ], dtype=np.float64), "yx": np.array([RY, RX], dtype=np.float64), "yz": np.array([RY, RZ], dtype=np.float64), "zx": np.array([RZ, RX], dtype=np.float64), "zy": np.array([RZ, RY], dtype=np.float64), } As = AS[direction] vectors = As * np.array([[num1], [num2]]) points = np.dot([[i, j] for i in range(num1) for j in range(num2)], As) cluster = Lattice(points=points, vectors=vectors, name=identity) intra, inter = cluster.bonds(nth=1) x_bonds = [] y_bonds = [] z_bonds = [] for bond in intra + inter: p0, p1 = bond.endpoints index0 = cluster.getIndex(site=p0, fold=True) index1 = cluster.getIndex(site=p1, fold=True) bond_index = (index0, index1) azimuth = bond.getAzimuth(ndigits=0) # The definition of x, y, z bond in a trio is counterclockwise. if azimuth in (-180, 0, 180): x_bonds.append(bond_index) elif azimuth in (-120, 60): z_bonds.append(bond_index) elif azimuth in (-60, 120): y_bonds.append(bond_index) else: raise RuntimeError("Invalid bond azimuth: {0}".format(azimuth)) self._num1 = num1 self._num2 = num2 self._direction = direction self._identity = identity self._cluster = cluster self._x_bonds = tuple(x_bonds) self._y_bonds = tuple(y_bonds) self._z_bonds = tuple(z_bonds)
import matplotlib.pyplot as plt import numpy as np from HamiltonianPy import Lattice from database import POINTS, VECTORS cluster_points = np.append(POINTS, [[0.0, 0.0]], axis=0) cluster = Lattice(cluster_points, VECTORS) intra_bonds_1st, inter_bonds_1st = cluster.bonds(nth=1) intra_bonds_3rd, inter_bonds_3rd = cluster.bonds(nth=3) fig, ax = plt.subplots() for point in cluster_points: cluster_index = cluster.getIndex(point, fold=True) if cluster_index == 12: color = "tab:red" marker_size = 25 else: color = "black" marker_size = 20 ax.plot(point[0], point[1], marker="o", ms=marker_size, color=color, zorder=2) ax.text(point[0], point[1] - 0.2, str(cluster_index), ha="center", va="top",
def TightBinding(kpoints, model="Model1", return_vectors=True, **model_params): actual_model_params = dict(DEFAULT_MODEL_PARAMETERS) actual_model_params.update(model_params) t0 = actual_model_params["t0"] t1 = actual_model_params["t1"] cell = Lattice(points=POINTS, vectors=VECTORS) ids = [[0, 0], [1, -1], [0, -1], [-1, 0], [-1, 1], [0, 1], [1, 0]] points_collection = np.concatenate( [np.dot([i, j], VECTORS) + POINTS for i, j in ids]) inter_hopping_indices = [ [5, 83], [5, 82], [6, 82], [6, 81], [6, 63], [7, 63], [7, 71], [8, 71], [8, 53], [8, 52], [9, 52], [9, 51], ] if model == "Model1": intra_hopping_indices0 = [[0, 4], [4, 5], [1, 7], [7, 8], [2, 10], [10, 11]] intra_hopping_indices1 = [ [0, 1], [1, 2], [2, 0], [0, 3], [0, 10], [0, 11], [1, 4], [1, 5], [1, 6], [2, 7], [2, 8], [2, 9], [3, 4], [3, 11], [6, 5], [6, 7], [9, 8], [9, 10], ] else: intra_hopping_indices0 = [ [0, 4], [4, 5], [5, 6], [1, 7], [7, 8], [8, 9], [2, 10], [10, 11], [11, 3], ] intra_hopping_indices1 = [ [0, 1], [1, 2], [2, 0], [0, 3], [0, 10], [0, 11], [1, 4], [1, 5], [1, 6], [2, 7], [2, 8], [2, 9], [3, 4], [6, 7], [9, 10], ] terms = [] for coeff, hopping_indices in [ (t0, intra_hopping_indices0), (t1, intra_hopping_indices1), (t1, inter_hopping_indices), ]: for ij in hopping_indices: p0, p1 = points_collection[ij] p0_eqv, dR0 = cell.decompose(p0) p1_eqv, dR1 = cell.decompose(p1) index0 = cell.getIndex(p0_eqv, fold=False) index1 = cell.getIndex(p1_eqv, fold=False) terms.append((index0, index1, coeff, dR0 - dR1)) site_num = cell.point_num kpoint_num = kpoints.shape[0] HMs = np.zeros((kpoint_num, site_num, site_num), dtype=np.complex128) for i, j, coeff, dR in terms: HMs[:, i, j] += coeff * np.exp(1j * np.matmul(kpoints, dR)) HMs += np.transpose(HMs, (0, 2, 1)).conj() if return_vectors: return np.linalg.eigh(HMs) else: return np.linalg.eigvalsh(HMs)
def TightBinding(kpoints, model="Model1", return_vectors=True, **model_params): actual_model_params = dict(DEFAULT_MODEL_PARAMETERS) actual_model_params.update(model_params) t0 = actual_model_params["t0"] t1 = actual_model_params["t1"] mu0 = actual_model_params["mu0"] / 2 mu1 = actual_model_params["mu1"] / 2 ids = ([0, 0], [-1, 0], [1, 0], [0, -1], [0, 1]) cell = Lattice(ALL_POINTS[0:20], TRANSLATION_VECTORS) points_collection = np.concatenate( [np.dot(ij, TRANSLATION_VECTORS) + ALL_POINTS[0:20] for ij in ids] ) intra_hopping_indices0 = [ [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [10, 11], [10, 12], [10, 13], [10, 14], [10, 15], [10, 16], [10, 17], [10, 18], [10, 19], ] intra_hopping_indices1 = [ [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 1], [11, 12], [12, 13], [13, 14], [14, 15], [15, 16], [16, 17], [17, 18], [18, 19], [19, 11], [6, 11] ] inter_hopping_indices = [[3, 37], [9, 74]] if model == "Model2": intra_hopping_indices1 += [[6, 12], [6, 19], [5, 11], [7, 11]] inter_hopping_indices += [ [3, 36], [3, 38], [2, 37], [4, 37], [9, 73], [9, 75], [1, 74], [8, 74], ] terms = [] zero_dr = np.array([0.0, 0.0], dtype=np.float64) for point in cell.points: index = cell.getIndex(point, fold=False) mu = mu0 if index in (0, 10) else mu1 terms.append((2 * index, 2 * index, mu, zero_dr)) terms.append((2 * index + 1, 2 * index + 1, mu, zero_dr)) for t, ijs in [(t0, intra_hopping_indices0), (t1, intra_hopping_indices1)]: for ij in ijs: p0, p1 = points_collection[ij] coeff = t / np.dot(p1 - p0, p1 - p0) index0 = cell.getIndex(p0, fold=False) index1 = cell.getIndex(p1, fold=False) terms.append((2 * index0, 2 * index1, coeff, zero_dr)) terms.append((2 * index0 + 1, 2 * index1 + 1, coeff, zero_dr)) for ij in inter_hopping_indices: p0, p1 = points_collection[ij] coeff = t1 / np.dot(p1 - p0, p1 - p0) p0_eqv, dR0 = cell.decompose(p0) p1_eqv, dR1 = cell.decompose(p1) index0 = cell.getIndex(p0_eqv, fold=False) index1 = cell.getIndex(p1_eqv, fold=False) terms.append((2 * index0, 2 * index1, coeff, dR1 - dR0)) terms.append((2 * index0 + 1, 2 * index1 + 1, coeff, dR1 - dR0)) # msg = "({0:2d},{1:2d}), t={2:.8f}, dR=({3:.8f}, {4:.8f})" # print("Hamiltonian Terms:") # for i, j, coeff, dR in terms: # print(msg.format(i, j, coeff, dR[0], dR[1])) point_num = cell.point_num shape = (kpoints.shape[0], 2 * point_num, 2 * point_num) HMs = np.zeros(shape, dtype=np.complex128) for i, j, coeff, dR in terms: HMs[:, i, j] += coeff * np.exp(1j * np.matmul(kpoints, dR)) HMs += np.transpose(HMs, (0, 2, 1)).conj() if return_vectors: return np.linalg.eigh(HMs) else: return np.linalg.eigvalsh(HMs)
zorder=0) # Draw the StripeX order StripeXCell = Lattice( np.array([[0.0, 0.0], [0.5, np.sqrt(3) / 2]]), np.array([[1.0, 0.0], [1.0, np.sqrt(3)]]), ) StripeXCellSpinColors = ("tab:orange", "tab:purple") StripeXCellSpinVectors = np.array([[0.0, 1.0], [0.0, -1.0]]) x_delta = x_deltas[0] spin_colors = [] spin_vectors = [] points = StripeXCluster.points for point in points: index = StripeXCell.getIndex(site=point, fold=True) spin_vectors.append(StripeXCellSpinVectors[index]) spin_colors.append(StripeXCellSpinColors[index]) spin_vectors = np.array(spin_vectors) Show2DVectors(ax, points[:, 0] + x_delta, points[:, 1], spin_vectors, spin_colors) # Draw the StripeY order StripeYCell = Lattice( np.array([[0.0, 0.0], [1.0, 0.0]]), np.array([[2.0, 0.0], [-0.5, np.sqrt(3) / 2]]), ) StripeYCellSpinColors = ("tab:orange", "tab:purple") StripeYCellSpinVectors = np.array([[0.0, 1.0], [0.0, -1.0]]) x_delta = x_deltas[1]