예제 #1
0
파일: propagation.py 프로젝트: cpoli/tbee
    def get_propagation(self, ham, psi_init, steps, dz, norm=False):
        """
        Get the time evolution.

        :param ham: sparse.csr_matrix. Tight-Binding Hamilonian.
        :param psi_init: np.ndarray. Initial state.
        :param steps: Positive Integer. Number of steps.
        :param dz: Positive number. Step.
        :param norm: Boolean. Default value True. Normalize the norm to 1 at each step.
        """
        error_handling.empty_ham(ham)
        error_handling.ndarray(psi_init, "psi_init", self.lat.sites)
        error_handling.positive_int(steps, "steps")
        error_handling.positive_real(dz, "dz")
        error_handling.boolean(norm, "norm")
        self.steps = steps
        self.dz = dz
        self.prop = np.empty((self.lat.sites, self.steps), "c16")
        self.prop[:, 0] = psi_init
        diag = 1j * np.ones(self.lat.sites, "c16")
        A = (sparse.diags(diag, 0) - 0.5 * self.dz * ham).toarray()
        B = (sparse.diags(diag, 0) + 0.5 * self.dz * ham).toarray()
        mat = np.dot(LA.inv(A), B)
        for i in range(1, self.steps):
            self.prop[:, i] = np.dot(mat, self.prop[:, i - 1])
            if norm:
                self.prop[:, i] /= np.abs(self.prop[:, i]).sum()
예제 #2
0
    def get_propagation(self, ham, psi_init, steps, dz, norm=False):
        '''
        Get the time evolution.

        :param ham: sparse.csr_matrix. Tight-Binding Hamilonian.
        :param psi_init: np.ndarray. Initial state.
        :param steps: Positive Integer. Number of steps.
        :param dz: Positive number. Step.
        :param norm: Boolean. Default value True. Normalize the norm to 1 at each step.
        '''
        error_handling.empty_ham(ham)
        error_handling.ndarray(psi_init, 'psi_init', self.lat.sites)
        error_handling.positive_int(steps, 'steps')
        error_handling.positive_real(dz, 'dz')
        error_handling.boolean(norm, 'norm')
        self.steps = steps
        self.dz = dz
        self.prop = np.empty((self.lat.sites, self.steps), 'c16')
        self.prop[:, 0] = psi_init
        diag = 1j*np.ones(self.lat.sites, 'c16')
        A = (sparse.diags(diag, 0) - 0.5 * self.dz * ham).toarray()
        B = (sparse.diags(diag, 0) + 0.5 * self.dz * ham).toarray()
        mat = (np.dot(LA.inv(A), B))
        for i in range(1, self.steps):
            self.prop[:, i] = np.dot(mat, self.prop[:, i-1])
            if norm:
                self.prop[:, i] /= np.abs(self.prop[:, i]).sum()
예제 #3
0
파일: plot.py 프로젝트: cpoli/tbee
    def intensity_area(self, intensity, s=1000., lw=1., fs=20., plt_hop=False,
                                  figsize=None, title=r'$|\psi|^2$'):
        '''
        Plot the intensity. Intensity propotional to disk shape.

        :param intensity: np.array. Intensity.
        :param s: Positive Float. Default value 1000. 
            Circle size given by s * intensity.
        :param lw: Positive Float. Default value 1. Hopping linewidths.
        :param fs: Positive Float. Default value 20. Fontsize.
        :param plt_hop: Boolean. Default value False. Plot hoppings.
        :param figsize: Tuple. Default value None. Figure size.
        :param title: String. Default value '$|\psi_{ij}|^2$'. Figure title.

        :returns:
            * **fig** -- Figure.
        '''
        error_handling.empty_ndarray(self.sys.lat.coor, 'sys.get_lattice')
        error_handling.ndarray(intensity, 'intensity', self.sys.lat.sites)
        error_handling.positive_real(s, 's')
        error_handling.positive_real(fs, 'fs')
        error_handling.boolean(plt_hop, 'plt_hop')
        error_handling.tuple_2elem(figsize, 'figsize')
        error_handling.string(title, 'title')
        fig, ax = plt.subplots()
        ax.set_xlabel('$i$', fontsize=fs)
        ax.set_ylabel('$j$', fontsize=fs)
        ax.set_title(title, fontsize=fs)
        if plt_hop:
            plt.plot([self.sys.lat.coor['x'][self.sys.hop['i'][:]], 
                             self.sys.lat.coor['x'][self.sys.hop['j'][:]]],
                            [self.sys.lat.coor['y'][self.sys.hop['i'][:]],
                             self.sys.lat.coor['y'][self.sys.hop['j'][:]]],
                            'k', lw=lw)
        for tag, color in zip(self.sys.lat.tags, self.colors):
            plt.scatter(self.sys.lat.coor['x'][self.sys.lat.coor['tag'] == tag],
                        self.sys.lat.coor['y'][self.sys.lat.coor['tag'] == tag],
                        s=100*s*intensity[self.sys.lat.coor['tag'] == tag],
                        c=color, alpha=0.5)
        ax.set_aspect('equal')
        ax.axis('off')
        x_lim = [np.min(self.sys.lat.coor['x'])-2., np.max(self.sys.lat.coor['x'])+2.]
        y_lim = [np.min(self.sys.lat.coor['y'])-2., np.max(self.sys.lat.coor['y'])+2.]
        ax.set_xlim(x_lim)
        ax.set_ylim(y_lim)
        fig.set_tight_layout(True)
        plt.draw()
        return fig
예제 #4
0
    def get_pumping(self, hams, psi_init, steps, dz, norm=True):
        '''
        Get the time evolution with adiabatic pumpings.

        :param hams: List of sparse.csr_matrices. Tight-Binding Hamilonians.
        :param psi_init: np.ndarray. Initial state.
        :param steps: Positive integer. Number of steps.
        :param dz: Positive number. Step.
        :param norm: Boolean. Default value True. Normalize the norm to 1 at each step.
        '''
        error_handling.get_pump(hams)
        error_handling.ndarray(psi_init, 'psi_init', self.lat.sites)
        error_handling.positive_int(steps, 'steps')
        error_handling.positive_real(dz, 'dz')
        error_handling.boolean(norm, 'norm')
        self.steps = steps
        self.dz = dz
        no = len(hams)
        self.prop = np.empty((self.lat.sites, self.steps), 'c16')
        self.prop[:, 0] = psi_init
        diag = 1j * np.ones(self.lat.sites, 'c16')
        delta = self.steps // (1 + no)
        A = (sparse.diags(diag, 0) - 0.5 * self.dz * hams[0]).toarray()
        B = (sparse.diags(diag, 0) + 0.5 * self.dz * hams[0]).toarray()
        mat = (np.dot(LA.inv(A), B))
        # before pumping
        for i in range(1, delta):
           self.prop[:, i] = np.dot(mat, self.prop[:, i-1])
           if norm:
               self.prop[:, i] /= np.abs(self.prop[:, i]).sum()
      # pumping
        c = np.linspace(0, 1, delta)
        for j in range(0, no-1):
            for i in range(0, delta):
                ham = (1-c[i])*hams[j]+c[i]*hams[j+1]
                A = (sparse.diags(diag, 0) - 0.5 * self.dz * ham).toarray()
                B = (sparse.diags(diag, 0) + 0.5 * self.dz * ham).toarray()
                mat = (np.dot(LA.inv(A), B))
                self.prop[:, (j+1)*delta+i] = np.dot(mat, self.prop[:,  (j+1)*delta+i-1])
                if norm:
                    self.prop[:,  (j+1)*delta+i] /= \
                        np.abs(self.prop[:,  (j+1)*delta+i]).sum() 
      # after pumping
        j = no
        for i in range(0, self.steps - no*delta):
            self.prop[:,  no*delta+i] = np.dot(mat, self.prop[:,  no*delta+i-1])
            if norm:
                self.prop[:,  no*delta+i] /= np.abs(self.prop[:,  no*delta+i]).sum()
예제 #5
0
파일: lattice.py 프로젝트: cpoli/tbee
    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
예제 #6
0
파일: propagation.py 프로젝트: cpoli/tbee
    def get_pumping(self, hams, psi_init, steps, dz, norm=True):
        """
        Get the time evolution with adiabatic pumpings.

        :param hams: List of sparse.csr_matrices. Tight-Binding Hamilonians.
        :param psi_init: np.ndarray. Initial state.
        :param steps: Positive integer. Number of steps.
        :param dz: Positive number. Step.
        :param norm: Boolean. Default value True. Normalize the norm to 1 at each step.
        """
        error_handling.get_pump(hams)
        error_handling.ndarray(psi_init, "psi_init", self.lat.sites)
        error_handling.positive_int(steps, "steps")
        error_handling.positive_real(dz, "dz")
        error_handling.boolean(norm, "norm")
        self.steps = steps
        self.dz = dz
        no = len(hams)
        self.prop = np.empty((self.lat.sites, self.steps), "c16")
        self.prop[:, 0] = psi_init
        diag = 1j * np.ones(self.lat.sites, "c16")
        delta = self.steps // (1 + no)
        A = (sparse.diags(diag, 0) - 0.5 * self.dz * hams[0]).toarray()
        B = (sparse.diags(diag, 0) + 0.5 * self.dz * hams[0]).toarray()
        mat = np.dot(LA.inv(A), B)
        # before pumping
        for i in range(1, delta):
            self.prop[:, i] = np.dot(mat, self.prop[:, i - 1])
            if norm:
                self.prop[:, i] /= np.abs(self.prop[:, i]).sum()
        # pumping
        c = np.linspace(0, 1, delta)
        for j in range(0, no - 1):
            for i in range(0, delta):
                ham = (1 - c[i]) * hams[j] + c[i] * hams[j + 1]
                A = (sparse.diags(diag, 0) - 0.5 * self.dz * ham).toarray()
                B = (sparse.diags(diag, 0) + 0.5 * self.dz * ham).toarray()
                mat = np.dot(LA.inv(A), B)
                self.prop[:, (j + 1) * delta + i] = np.dot(mat, self.prop[:, (j + 1) * delta + i - 1])
                if norm:
                    self.prop[:, (j + 1) * delta + i] /= np.abs(self.prop[:, (j + 1) * delta + i]).sum()
        # after pumping
        j = no
        for i in range(0, self.steps - no * delta):
            self.prop[:, no * delta + i] = np.dot(mat, self.prop[:, no * delta + i - 1])
            if norm:
                self.prop[:, no * delta + i] /= np.abs(self.prop[:, no * delta + i]).sum()
예제 #7
0
파일: lattice.py 프로젝트: cationly/tbee
    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
예제 #8
0
파일: system.py 프로젝트: cationly/tbee
    def get_eig(self, eigenvec=False, left=False):
        '''
        Get the eigenergies, eigenvectors and polarisation.

        :param eigenvec: Boolean. Default value False. 
            If True, get the eigenvectors.
        :param left: Boolean. Default value False. 
            If True, get the left eigenvectors too. 
            Relevant for non-Hermitian matrices.
        '''
        error_handling.empty_ham(self.ham)
        error_handling.boolean(eigenvec, 'eigenvec')
        error_handling.boolean(left, 'left')
        if eigenvec:
            if (self.ham.H != self.ham).nnz:
                if not left:
                    self.en, self.rn = LA.eig(self.ham.toarray())
                else:
                    self.en, self.rn, self.ln = LA.eig(self.ham.toarray(),
                                                       left=left)
                ind = np.argsort(self.en.real)
                self.en = self.en[ind]
                self.rn = self.rn[:, ind]
                if self.ln.size:
                    self.ln = self.ln[:, ind]
            else:
                self.en, self.rn = LA.eigh(self.ham.toarray())
            self.intensity = np.abs(self.rn)**2
            self.pola = np.zeros((self.lat.sites, len(self.lat.tags)))
            for i, tag in enumerate(self.lat.tags):
                self.pola[:, i] = np.sum(
                    self.intensity[self.lat.coor['tag'] == tag, :], axis=0)
        else:
            if (self.ham.H != self.ham).nnz:
                self.en = LA.eigvals(self.ham.toarray())
                ind = np.argsort(self.en.real)
                self.en = self.en[ind]
            else:
                self.en = LA.eigvalsh(self.ham.toarray())
예제 #9
0
 def lattice_generic(self, coor, ms, lw, c, fs, axis, plt_hop, plt_hop_low,
                     plt_index, figsize):
     '''
     Private method called by *lattice* and *lattice_hop*.
     '''
     error_handling.positive_real(ms, 'ms')
     error_handling.positive_real(lw, 'lw')
     error_handling.positive_real(c, 'c')
     error_handling.positive_real(fs, 'fs')
     error_handling.boolean(axis, 'axis')
     error_handling.boolean(plt_hop, 'plt_hop')
     error_handling.boolean(plt_hop_low, 'plt_hop_low')
     error_handling.boolean(plt_index, 'plt_index')
     error_handling.tuple_2elem(figsize, 'figsize')
     fig, ax = plt.subplots(figsize=figsize)
     # hoppings
     if plt_hop:
         error_handling.empty_ndarray(self.sys.hop, 'sys.hop')
         self.plt_hopping(coor, self.sys.hop[self.sys.hop['ang'] >= 0], c)
     if plt_hop_low:
         error_handling.empty_ndarray(self.sys.hop, 'sys.hop')
         self.plt_hopping(coor, self.sys.hop[self.sys.hop['ang'] < 0], c)
     # plot sites
     for color, tag in zip(self.colors, self.sys.lat.tags):
         plt.plot(coor['x'][coor['tag'] == tag],
                  coor['y'][coor['tag'] == tag],
                  'o',
                  color=color,
                  ms=ms,
                  markeredgecolor='none')
     ax.set_aspect('equal')
     ax.set_xlim([np.min(coor['x']) - 1., np.max(coor['x']) + 1.])
     ax.set_ylim([np.min(coor['y']) - 1., np.max(coor['y']) + 1.])
     if not axis:
         ax.axis('off')
     # plot indices
     if plt_index:
         indices = ['{}'.format(i) for i in range(self.sys.lat.sites)]
         for l, x, y in zip(indices, coor['x'], coor['y']):
             plt.annotate(l,
                          xy=(x, y),
                          xytext=(0, 0),
                          textcoords='offset points',
                          ha='right',
                          va='bottom',
                          size=fs)
     plt.draw()
     return fig
예제 #10
0
파일: system.py 프로젝트: cpoli/tbee
    def get_eig(self, eigenvec=False, left=False):
        '''
        Get the eigenergies, eigenvectors and polarisation.

        :param eigenvec: Boolean. Default value False. 
            If True, get the eigenvectors.
        :param left: Boolean. Default value False. 
            If True, get the left eigenvectors too. 
            Relevant for non-Hermitian matrices.
        '''
        error_handling.empty_ham(self.ham)
        error_handling.boolean(eigenvec, 'eigenvec')
        error_handling.boolean(left, 'left')
        if eigenvec:
            if (self.ham.H != self.ham).nnz:
                if not left:
                    self.en, self.rn = LA.eig(self.ham.toarray())
                else:
                    self.en, self.rn, self.ln = LA.eig(self.ham.toarray(), left=left)
                ind = np.argsort(self.en.real)
                self.en = self.en[ind]
                self.rn = self.rn[:, ind]
                if self.ln.size:
                    self.ln = self.ln[:, ind]
            else:
                self.en, self.rn = LA.eigh(self.ham.toarray())
            self.intensity = np.abs(self.rn) ** 2
            self.pola = np.zeros((self.lat.sites, len(self.lat.tags)))
            for i, tag in enumerate(self.lat.tags):
                self.pola[:, i] = np.sum(self.intensity[self.lat.coor['tag'] == tag, :], axis=0)
        else:
            if (self.ham.H != self.ham).nnz:
                self.en = LA.eigvals(self.ham.toarray())
                ind = np.argsort(self.en.real)
                self.en = self.en[ind]
            else:
                self.en = LA.eigvalsh(self.ham.toarray())
예제 #11
0
파일: plot.py 프로젝트: cpoli/tbee
 def lattice_generic(self, coor, ms, lw, c, fs, axis, plt_hop,
                               plt_hop_low, plt_index, figsize):
     '''
     Private method called by *lattice* and *lattice_hop*.
     '''
     error_handling.positive_real(ms, 'ms')
     error_handling.positive_real(lw, 'lw')
     error_handling.positive_real(c, 'c')
     error_handling.positive_real(fs, 'fs')
     error_handling.boolean(axis, 'axis')
     error_handling.boolean(plt_hop, 'plt_hop')
     error_handling.boolean(plt_hop_low, 'plt_hop_low')
     error_handling.boolean(plt_index, 'plt_index')
     error_handling.tuple_2elem(figsize, 'figsize')
     fig, ax = plt.subplots(figsize=figsize)
     # hoppings
     if plt_hop:
         error_handling.empty_ndarray(self.sys.hop, 'sys.hop')
         self.plt_hopping(coor, self.sys.hop[self.sys.hop['ang']>=0], c)
     if plt_hop_low:
         error_handling.empty_ndarray(self.sys.hop, 'sys.hop')
         self.plt_hopping(coor, self.sys.hop[self.sys.hop['ang']<0], c)
     # plot sites
     for color, tag in zip(self.colors, self.sys.lat.tags):
         plt.plot(coor['x'][coor['tag'] == tag],
                    coor['y'][coor['tag'] == tag],
                    'o', color=color, ms=ms, markeredgecolor='none')
     ax.set_aspect('equal')
     ax.set_xlim([np.min(coor['x'])-1., np.max(coor['x'])+1.])
     ax.set_ylim([np.min(coor['y'])-1., np.max(coor['y'])+1.])
     if not axis:
         ax.axis('off')
     # plot indices
     if plt_index:
         indices = ['{}'.format(i) for i in range(self.sys.lat.sites)]
         for l, x, y in zip(indices, coor['x'], coor['y']):
             plt.annotate(l, xy=(x, y), xytext=(0, 0),
                                 textcoords='offset points',
                                 ha='right', va='bottom', size=fs)
     plt.draw()
     return fig
예제 #12
0
파일: system.py 프로젝트: cpoli/tbee
    def set_hopping(self, list_hop, upper_part=True):
        '''
        Set lattice hoppings.

        :param list_hop: List of Dictionaries.
            Dictionary with keys ('n', 'ang', 'tag', 't') where:
                * 'n' Positive integer, type of hoppings:

                    * 'n': 1 for nearest neighbours.
                    * 'n': 2 for next-nearest neighbours.  
                    * 'n': 3 for next-next-nearest neighbours.  
                    * etc...

                * 'ang' value, float, angle, in deg, of the hoppings. (optional).

                    Hopping angles are given by the method *print_distances*.

                        * If :math:`ang \in[0, 180)`, fill the Hamiltonian upper part.
                        * If :math:`ang \in[-180, 0)`, fill the Hamiltonian lower part.

                * 'tag' binary string of length 2  (optional).

                    Hopping tags.

                * 't' Complex number.

                    Hopping value.

        :param upper_part: Boolean. Default value True. 
            
            * True get hoppings with (:math:`i<j`) *i.e.* fill the Hamiltonian lower part.
            * False get hoppings with (:math:`i>j`) *i.e.* fill the Hamiltonian upper part.

        Example usage::

            # fill upper part:
            sys.set_hopping([{'n': 1, t: 1.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, t: 1.}], upper_part=False)
            # fill upper part: specifying the angles:
            sys.set_hopping([{'n': 1, 'ang': 0., t: 1.}, {'n': 1, 'ang': 90,  t: 2.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, 'ang': -180., t: 1.}, {'n': 1, 'ang': -90,  t: 2.}], upper_part=False)
            # fill upper part: specifying the tags:
            sys.set_hopping([{'n': 1, 'tag': b'ab', t: 1.}, {'n': 1, 'tag': b'ba',  t: 2.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, 'tag': b'ab', t: 1.}, {'n': 1, 'tag': b'ba',  t: 2.}], upper_part=False)
            # fill upper part: specifying the angles and tags:
            sys.set_hopping([{'n': 1, 'ang': 0., 'tag': b'ab', t: 1.}, 
                                        {'n': 1, 'ang': 0., 'tag': b'ba',  t: 2.},
                                        {'n': 1, 'ang': 90., 'tag': b'ab', t: 3.}, 
                                        {'n': 1, 'ang': 90., 'tag': b'ba',  t: 4.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, 'ang': 0., 'tag': b'ab', t: 1.}, 
                                        {'n': 1, 'ang': 0., 'tag': b'ba',  t: 2.},
                                        {'n': 1, 'ang': 90., 'tag': b'ab', t: 3.}, 
                                        {'n': 1, 'ang': 90., 'tag': b'ba',  t: 4.}]), upper_part=False)

        .. note::

            A Hermitian hopping matrix can be build-up only using 
            its upper part OR only using its lower part. The full matrix is then
            automatic built by Hermitian conjugaison. 
            
            If both upper AND lower parts are used to build up the hopping matrix.
            non Hermitian conjugaison is not performed *i.e.* non-Hermitian hopping matrix
            can be built.
        '''
        error_handling.sites(self.lat.sites)
        error_handling.boolean(upper_part, 'upper_part')
        self.get_distances()
        self.nmax = len(self.dist_uni) - 1
        error_handling.set_hopping(list_hop, self.nmax)
        list_n = np.unique([dic['n'] for dic in list_hop])
        # fill, if needed self.store_hop
        self.check_sites()
        for n in list_n:
            if n not in self.store_hop:
                self.fill_store_hop(n)
        # fill self.hop
        for dic in list_hop:
            if len(dic) == 2:
                size = len(self.store_hop[dic['n']])
                if upper_part:
                    mask = (self.hop['n'] == dic['n']) & (self.hop['i'] < self.hop['j'])
                else:
                    mask = (self.hop['n'] == dic['n']) & (self.hop['i'] > self.hop['j'])
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = np.ones(size, bool)
                hop = self.set_given_hopping(dic['n'], size, dic, ind, upper_part=upper_part)
            elif len(dic) == 3 and 'ang' in dic:
                error_handling.angle(dic['ang'], np.unique(self.store_hop[dic['n']]['ang']), upper_part)
                if dic['ang'] >= 0:
                    ang_store = dic['ang']
                else:
                    ang_store = dic['ang'] + 180.
                size = np.sum(np.isclose(ang_store, self.store_hop[dic['n']]['ang'], atol=ATOL))
                mask = (self.hop['n'] == dic['n']) & np.isclose(self.hop['ang'], dic['ang'], atol=ATOL)
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = np.isclose(ang_store, self.store_hop[dic['n']]['ang'], atol=ATOL)
                error_handling.index(ind, dic)
                hop = self.set_given_hopping(dic['n'], size, dic, ind, upper_part=upper_part)
            elif len(dic) == 3 and 'tag' in dic:
                if upper_part:
                    tag_store = dic['tag']
                else:
                    tag_store = dic['tag'][::-1]
                size = np.sum(self.store_hop[dic['n']]['tag'] == tag_store)
                mask = (self.hop['n'] == dic['n']) & (self.hop['tag'] == dic['tag'])
                if upper_part:
                    mask = self.hop['n'] == dic['n'] & (self.hop['tag'] == dic['tag']) & (self.hop['i'] < self.hop['j'])
                else:
                    mask = self.hop['n'] == dic['n'] & (self.hop['tag'] == dic['tag']) & (self.hop['i'] > self.hop['j'])
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = self.store_hop[dic['n']]['tag'] == tag_store
                error_handling.index(ind, dic)
                hop = self.set_given_hopping(dic['n'], size, dic, ind, upper_part=upper_part)
            else:
                error_handling.angle(dic['ang'], np.unique(self.store_hop[dic['n']]['ang']), upper_part=upper_part)
                error_handling.tag(dic['tag'], np.unique(self.store_hop[dic['n']]['tag']))
                if dic['ang'] >= 0:
                    ang_store = dic['ang']
                else:
                    ang_store = dic['ang'] + 180.
                if upper_part:
                    tag_store = dic['tag']
                else:
                    tag_store = dic['tag'][::-1]
                size = np.sum((self.store_hop[dic['n']]['tag'] == tag_store) & 
                                       (np.isclose(ang_store, self.store_hop[dic['n']]['ang'], atol=ATOL)))
                bool1 = (self.hop['n'] == dic['n']) & (self.hop['tag'] == dic['tag'])
                bool2 = np.isclose(self.hop['ang'], dic['ang'], atol=ATOL)
                mask = bool1 & bool2
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = ((self.store_hop[dic['n']]['tag'] == tag_store) & 
                          (np.isclose(ang_store, self.store_hop[dic['n']]['ang'], atol=1)))
                error_handling.index(ind, dic)
                hop = self.set_given_hopping(dic['n'], size, dic, ind, upper_part=upper_part)
            self.hop = np.concatenate([self.hop, hop])
예제 #13
0
파일: system.py 프로젝트: cationly/tbee
    def set_hopping(self, list_hop, upper_part=True):
        '''
        Set lattice hoppings.

        :param list_hop: List of Dictionaries.
            Dictionary with keys ('n', 'ang', 'tag', 't') where:
                * 'n' Positive integer, type of hoppings:

                    * 'n': 1 for nearest neighbours.
                    * 'n': 2 for next-nearest neighbours.  
                    * 'n': 3 for next-next-nearest neighbours.  
                    * etc...

                * 'ang' value, float, angle, in deg, of the hoppings. (optional).

                    Hopping angles are given by the method *print_distances*.

                        * If :math:`ang \in[0, 180)`, fill the Hamiltonian upper part.
                        * If :math:`ang \in[-180, 0)`, fill the Hamiltonian lower part.

                * 'tag' binary string of length 2  (optional).

                    Hopping tags.

                * 't' Complex number.

                    Hopping value.

        :param upper_part: Boolean. Default value True. 
            
            * True get hoppings with (:math:`i<j`) *i.e.* fill the Hamiltonian lower part.
            * False get hoppings with (:math:`i>j`) *i.e.* fill the Hamiltonian upper part.

        Example usage::

            # fill upper part:
            sys.set_hopping([{'n': 1, t: 1.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, t: 1.}], upper_part=False)
            # fill upper part: specifying the angles:
            sys.set_hopping([{'n': 1, 'ang': 0., t: 1.}, {'n': 1, 'ang': 90,  t: 2.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, 'ang': -180., t: 1.}, {'n': 1, 'ang': -90,  t: 2.}], upper_part=False)
            # fill upper part: specifying the tags:
            sys.set_hopping([{'n': 1, 'tag': b'ab', t: 1.}, {'n': 1, 'tag': b'ba',  t: 2.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, 'tag': b'ab', t: 1.}, {'n': 1, 'tag': b'ba',  t: 2.}], upper_part=False)
            # fill upper part: specifying the angles and tags:
            sys.set_hopping([{'n': 1, 'ang': 0., 'tag': b'ab', t: 1.}, 
                                        {'n': 1, 'ang': 0., 'tag': b'ba',  t: 2.},
                                        {'n': 1, 'ang': 90., 'tag': b'ab', t: 3.}, 
                                        {'n': 1, 'ang': 90., 'tag': b'ba',  t: 4.}])
            # fill lower part:
            sys.set_hopping([{'n': 1, 'ang': 0., 'tag': b'ab', t: 1.}, 
                                        {'n': 1, 'ang': 0., 'tag': b'ba',  t: 2.},
                                        {'n': 1, 'ang': 90., 'tag': b'ab', t: 3.}, 
                                        {'n': 1, 'ang': 90., 'tag': b'ba',  t: 4.}]), upper_part=False)

        .. note::

            A Hermitian hopping matrix can be build-up only using 
            its upper part OR only using its lower part. The full matrix is then
            automatic built by Hermitian conjugaison. 
            
            If both upper AND lower parts are used to build up the hopping matrix.
            non Hermitian conjugaison is not performed *i.e.* non-Hermitian hopping matrix
            can be built.
        '''
        error_handling.sites(self.lat.sites)
        error_handling.boolean(upper_part, 'upper_part')
        self.get_distances()
        self.nmax = len(self.dist_uni) - 1
        error_handling.set_hopping(list_hop, self.nmax)
        list_n = np.unique([dic['n'] for dic in list_hop])
        # fill, if needed self.store_hop
        self.check_sites()
        for n in list_n:
            if n not in self.store_hop:
                self.fill_store_hop(n)
        # fill self.hop
        for dic in list_hop:
            if len(dic) == 2:
                size = len(self.store_hop[dic['n']])
                if upper_part:
                    mask = (self.hop['n']
                            == dic['n']) & (self.hop['i'] < self.hop['j'])
                else:
                    mask = (self.hop['n']
                            == dic['n']) & (self.hop['i'] > self.hop['j'])
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = np.ones(size, bool)
                hop = self.set_given_hopping(dic['n'],
                                             size,
                                             dic,
                                             ind,
                                             upper_part=upper_part)
            elif len(dic) == 3 and 'ang' in dic:
                error_handling.angle(
                    dic['ang'], np.unique(self.store_hop[dic['n']]['ang']),
                    upper_part)
                if dic['ang'] >= 0:
                    ang_store = dic['ang']
                else:
                    ang_store = dic['ang'] + 180.
                size = np.sum(
                    np.isclose(ang_store,
                               self.store_hop[dic['n']]['ang'],
                               atol=ATOL))
                mask = (self.hop['n'] == dic['n']) & np.isclose(
                    self.hop['ang'], dic['ang'], atol=ATOL)
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = np.isclose(ang_store,
                                 self.store_hop[dic['n']]['ang'],
                                 atol=ATOL)
                error_handling.index(ind, dic)
                hop = self.set_given_hopping(dic['n'],
                                             size,
                                             dic,
                                             ind,
                                             upper_part=upper_part)
            elif len(dic) == 3 and 'tag' in dic:
                if upper_part:
                    tag_store = dic['tag']
                else:
                    tag_store = dic['tag'][::-1]
                size = np.sum(self.store_hop[dic['n']]['tag'] == tag_store)
                mask = (self.hop['n'] == dic['n']) & (self.hop['tag']
                                                      == dic['tag'])
                if upper_part:
                    mask = self.hop['n'] == dic['n'] & (
                        self.hop['tag']
                        == dic['tag']) & (self.hop['i'] < self.hop['j'])
                else:
                    mask = self.hop['n'] == dic['n'] & (
                        self.hop['tag']
                        == dic['tag']) & (self.hop['i'] > self.hop['j'])
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = self.store_hop[dic['n']]['tag'] == tag_store
                error_handling.index(ind, dic)
                hop = self.set_given_hopping(dic['n'],
                                             size,
                                             dic,
                                             ind,
                                             upper_part=upper_part)
            else:
                error_handling.angle(dic['ang'],
                                     np.unique(
                                         self.store_hop[dic['n']]['ang']),
                                     upper_part=upper_part)
                error_handling.tag(dic['tag'],
                                   np.unique(self.store_hop[dic['n']]['tag']))
                if dic['ang'] >= 0:
                    ang_store = dic['ang']
                else:
                    ang_store = dic['ang'] + 180.
                if upper_part:
                    tag_store = dic['tag']
                else:
                    tag_store = dic['tag'][::-1]
                size = np.sum((self.store_hop[dic['n']]['tag'] == tag_store)
                              & (np.isclose(ang_store,
                                            self.store_hop[dic['n']]['ang'],
                                            atol=ATOL)))
                bool1 = (self.hop['n'] == dic['n']) & (self.hop['tag']
                                                       == dic['tag'])
                bool2 = np.isclose(self.hop['ang'], dic['ang'], atol=ATOL)
                mask = bool1 & bool2
                if np.sum(mask):
                    self.hop = self.hop[np.logical_not(mask)]
                ind = (
                    (self.store_hop[dic['n']]['tag'] == tag_store) &
                    (np.isclose(
                        ang_store, self.store_hop[dic['n']]['ang'], atol=1)))
                error_handling.index(ind, dic)
                hop = self.set_given_hopping(dic['n'],
                                             size,
                                             dic,
                                             ind,
                                             upper_part=upper_part)
            self.hop = np.concatenate([self.hop, hop])
예제 #14
0
    def intensity_area(self,
                       intensity,
                       s=1000.,
                       lw=1.,
                       fs=20.,
                       plt_hop=False,
                       figsize=None,
                       title=r'$|\psi|^2$'):
        '''
        Plot the intensity. Intensity propotional to disk shape.

        :param intensity: np.array. Intensity.
        :param s: Positive Float. Default value 1000. 
            Circle size given by s * intensity.
        :param lw: Positive Float. Default value 1. Hopping linewidths.
        :param fs: Positive Float. Default value 20. Fontsize.
        :param plt_hop: Boolean. Default value False. Plot hoppings.
        :param figsize: Tuple. Default value None. Figure size.
        :param title: String. Default value '$|\psi_{ij}|^2$'. Figure title.

        :returns:
            * **fig** -- Figure.
        '''
        error_handling.empty_ndarray(self.sys.lat.coor, 'sys.get_lattice')
        error_handling.ndarray(intensity, 'intensity', self.sys.lat.sites)
        error_handling.positive_real(s, 's')
        error_handling.positive_real(fs, 'fs')
        error_handling.boolean(plt_hop, 'plt_hop')
        error_handling.tuple_2elem(figsize, 'figsize')
        error_handling.string(title, 'title')
        fig, ax = plt.subplots()
        ax.set_xlabel('$i$', fontsize=fs)
        ax.set_ylabel('$j$', fontsize=fs)
        ax.set_title(title, fontsize=fs)
        if plt_hop:
            plt.plot([
                self.sys.lat.coor['x'][self.sys.hop['i'][:]],
                self.sys.lat.coor['x'][self.sys.hop['j'][:]]
            ], [
                self.sys.lat.coor['y'][self.sys.hop['i'][:]],
                self.sys.lat.coor['y'][self.sys.hop['j'][:]]
            ],
                     'k',
                     lw=lw)
        for tag, color in zip(self.sys.lat.tags, self.colors):
            plt.scatter(
                self.sys.lat.coor['x'][self.sys.lat.coor['tag'] == tag],
                self.sys.lat.coor['y'][self.sys.lat.coor['tag'] == tag],
                s=100 * s * intensity[self.sys.lat.coor['tag'] == tag],
                c=color,
                alpha=0.5)
        ax.set_aspect('equal')
        ax.axis('off')
        x_lim = [
            np.min(self.sys.lat.coor['x']) - 2.,
            np.max(self.sys.lat.coor['x']) + 2.
        ]
        y_lim = [
            np.min(self.sys.lat.coor['y']) - 2.,
            np.max(self.sys.lat.coor['y']) + 2.
        ]
        ax.set_xlim(x_lim)
        ax.set_ylim(y_lim)
        fig.set_tight_layout(True)
        plt.draw()
        return fig