Beispiel #1
0
    def print_distances(self, n=1):
        '''
        Print distances and positive angles (in degrees) :math:`\phi_+\in[0, 180)` 
        of the nth shortest edges. Negative angles are given by: 
        :math:`\phi_-= \phi_+-180` and :math:`\phi_+\in[-180, 0)`.

        :param n: Positive integer. Number of shortest edges.
        '''
        error_handling.sites(self.lat.sites)
        self.get_distances()
        self.nmax = len(self.dist_uni) - 1
        error_handling.positive_int_lim(n, 'n', self.nmax)
        print('\n{} different distances between sites:'.format(self.nmax))
        print('\nDistances between sites:')
        for i, d in enumerate(self.dist_uni[1:n + 1]):
            if i == 0:
                hop_name = 'st'
            elif i == 1:
                hop_name = 'nd'
            elif i == 2:
                hop_name = 'rd'
            else:
                hop_name = 'th'
            print('{}{} hopping, length: {:.3f}'.format(i + 1, hop_name, d))
            print('\twith positive angles:')
            positive_ang = self.vec_hop['ang'][
                np.isclose(d, self.vec_hop['dis'], atol=ATOL)
                & (self.vec_hop['ang'] >= 0.) & (self.vec_hop['ang'] < 180.)]
            print('\t', np.unique(positive_ang.round(4)))
Beispiel #2
0
    def print_distances(self, n=1):
        '''
        Print distances and positive angles (in degrees) :math:`\phi_+\in[0, 180)` 
        of the nth shortest edges. Negative angles are given by: 
        :math:`\phi_-= \phi_+-180` and :math:`\phi_+\in[-180, 0)`.

        :param n: Positive integer. Number of shortest edges.
        '''
        error_handling.sites(self.lat.sites)
        self.get_distances()
        self.nmax = len(self.dist_uni) - 1
        error_handling.positive_int_lim(n, 'n', self.nmax)
        print('\n{} different distances between sites:'.format(self.nmax))
        print('\nDistances between sites:')
        for i, d in enumerate(self.dist_uni[1: n+1]):
            if i == 0:
                hop_name = 'st'
            elif i == 1:
                hop_name = 'nd'
            elif i == 2:
                hop_name = 'rd'
            else:
                hop_name = 'th'
            print('{}{} hopping, length: {:.3f}'.format(i+1, hop_name, d))
            print('\twith positive angles:')
            positive_ang = self.vec_hop['ang'][np.isclose(d, self.vec_hop['dis'], atol=ATOL) &
                                                                   (self.vec_hop['ang'] >= 0.) &
                                                                   (self.vec_hop['ang'] < 180.)]
            print('\t', np.unique(positive_ang.round(4)))
Beispiel #3
0
 def get_distances(self):
     '''
     Private method.
     Get distances and angles of the edges.
     '''
     error_handling.sites(self.lat.sites)
     dif_x = self.lat.coor['x'] - self.lat.coor['x'].reshape(self.lat.sites, 1)
     dif_y = self.lat.coor['y'] - self.lat.coor['y'].reshape(self.lat.sites, 1)
     dist = np.sqrt(dif_x ** 2 + dif_y ** 2)
     ang = (180 / PI * np.arctan2(dif_y, dif_x))
     self.vec_hop = np.zeros(dist.shape, dtype=[('dis', 'f8'),  ('ang', 'f8')])
     self.vec_hop['dis'] = dist
     self.vec_hop['ang'] = ang
     self.dist_uni = np.unique(self.vec_hop['dis'].round(4))
Beispiel #4
0
    def set_onsite(self, dict_onsite):
        '''
        Set onsite energies.

        :param on:  Array. Sublattice onsite energies.

        Example usage::

            # Line-Centered Square lattice
            sys.set_onsite({b'a': -1j, {b'b':, -2j}})    
        '''
        error_handling.sites(self.lat.sites)
        error_handling.set_onsite(dict_onsite, self.lat.tags)
        self.onsite = np.zeros(self.lat.sites, 'c16')
        for tag, on in dict_onsite.items():
            self.onsite[self.lat.coor['tag'] ==tag] = on
Beispiel #5
0
    def set_onsite(self, dict_onsite):
        '''
        Set onsite energies.

        :param on:  Array. Sublattice onsite energies.

        Example usage::

            # Line-Centered Square lattice
            sys.set_onsite({b'a': -1j, {b'b':, -2j}})    
        '''
        error_handling.sites(self.lat.sites)
        error_handling.set_onsite(dict_onsite, self.lat.tags)
        self.onsite = np.zeros(self.lat.sites, 'c16')
        for tag, on in dict_onsite.items():
            self.onsite[self.lat.coor['tag'] == tag] = on
Beispiel #6
0
 def get_distances(self):
     '''
     Private method.
     Get distances and angles of the edges.
     '''
     error_handling.sites(self.lat.sites)
     dif_x = self.lat.coor['x'] - self.lat.coor['x'].reshape(
         self.lat.sites, 1)
     dif_y = self.lat.coor['y'] - self.lat.coor['y'].reshape(
         self.lat.sites, 1)
     dist = np.sqrt(dif_x**2 + dif_y**2)
     ang = (180 / PI * np.arctan2(dif_y, dif_x))
     self.vec_hop = np.zeros(dist.shape,
                             dtype=[('dis', 'f8'), ('ang', 'f8')])
     self.vec_hop['dis'] = dist
     self.vec_hop['ang'] = ang
     self.dist_uni = np.unique(self.vec_hop['dis'].round(4))
Beispiel #7
0
    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])
Beispiel #8
0
    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])