Ejemplo n.º 1
0
    def set_positions(self, spos_ac, atom_partition=None):
        move_wfs = (self.kpt_u[0].psit_nG is not None
                    and self.spos_ac is not None)

        if move_wfs:
            paste_wfs = self.wfs_mover.cut_wfs(self, spos_ac)

        # This will update the positions -- and transfer, if necessary --
        # the projection matrices which may be necessary for updating
        # the wavefunctions.
        WaveFunctions.set_positions(self, spos_ac, atom_partition)

        if move_wfs and paste_wfs is not None:
            paste_wfs()

        self.set_orthonormalized(False)
        self.pt.set_positions(spos_ac, atom_partition)
        self.allocate_arrays_for_projections(self.pt.my_atom_indices)
        self.positions_set = True
Ejemplo n.º 2
0
Archivo: fdpw.py Proyecto: qsnake/gpaw
 def set_positions(self, spos_ac):
     WaveFunctions.set_positions(self, spos_ac)
     self.set_orthonormalized(False)
     self.pt.set_positions(spos_ac)
     self.allocate_arrays_for_projections(self.pt.my_atom_indices)
     self.positions_set = True
Ejemplo n.º 3
0
    def set_positions(self, spos_ac):
        self.timer.start('Basic WFS set positions')
        WaveFunctions.set_positions(self, spos_ac)
        self.timer.stop('Basic WFS set positions')
        self.timer.start('Basis functions set positions')
        self.basis_functions.set_positions(spos_ac)
        self.timer.stop('Basis functions set positions')
        if self.ksl is not None:
            self.basis_functions.set_matrix_distribution(self.ksl.Mstart,
                                                         self.ksl.Mstop)

        nq = len(self.kd.ibzk_qc)
        nao = self.setups.nao
        mynbands = self.bd.mynbands
        
        Mstop = self.ksl.Mstop
        Mstart = self.ksl.Mstart
        mynao = Mstop - Mstart

        if self.ksl.using_blacs: # XXX
            # S and T have been distributed to a layout with blacs, so
            # discard them to force reallocation from scratch.
            #
            # TODO: evaluate S and T when they *are* distributed, thus saving
            # memory and avoiding this problem
            self.S_qMM = None
            self.T_qMM = None
        
        S_qMM = self.S_qMM
        T_qMM = self.T_qMM
        
        if S_qMM is None: # XXX
            # First time:
            assert T_qMM is None
            if self.ksl.using_blacs: # XXX
                self.tci.set_matrix_distribution(Mstart, mynao)
                
            S_qMM = np.empty((nq, mynao, nao), self.dtype)
            T_qMM = np.empty((nq, mynao, nao), self.dtype)
        
        for kpt in self.kpt_u:
            if kpt.C_nM is None:
                kpt.C_nM = np.empty((mynbands, nao), self.dtype)

        self.allocate_arrays_for_projections(
            self.basis_functions.my_atom_indices)
            
        self.P_aqMi = {}
        for a in self.basis_functions.my_atom_indices:
            ni = self.setups[a].ni
            self.P_aqMi[a] = np.empty((nq, nao, ni), self.dtype)

        for kpt in self.kpt_u:
            q = kpt.q
            kpt.P_aMi = dict([(a, P_qMi[q])
                              for a, P_qMi in self.P_aqMi.items()])

        self.timer.start('TCI: Calculate S, T, P')
        # Calculate lower triangle of S and T matrices:
        self.tci.calculate(spos_ac, S_qMM, T_qMM, self.P_aqMi)
        add_paw_correction_to_overlap(self.setups, self.P_aqMi, S_qMM,
                                      self.ksl.Mstart, self.ksl.Mstop)
        self.timer.stop('TCI: Calculate S, T, P')

        S_MM = None # allow garbage collection of old S_qMM after redist
        S_qMM = self.ksl.distribute_overlap_matrix(S_qMM)
        T_qMM = self.ksl.distribute_overlap_matrix(T_qMM)

        for kpt in self.kpt_u:
            q = kpt.q
            kpt.S_MM = S_qMM[q]
            kpt.T_MM = T_qMM[q]

        if (debug and self.band_comm.size == 1 and self.gd.comm.rank == 0 and
            nao > 0 and not self.ksl.using_blacs):
            # S and T are summed only on comm master, so check only there
            from numpy.linalg import eigvalsh
            self.timer.start('Check positive definiteness')
            for S_MM in S_qMM:
                tri2full(S_MM, UL='L')
                smin = eigvalsh(S_MM).real.min()
                if smin < 0:
                    raise RuntimeError('Overlap matrix has negative '
                                       'eigenvalue: %e' % smin)
            self.timer.stop('Check positive definiteness')
        self.positions_set = True
        self.S_qMM = S_qMM
        self.T_qMM = T_qMM
Ejemplo n.º 4
0
    def set_positions(self, spos_ac):
        self.timer.start('Basic WFS set positions')
        WaveFunctions.set_positions(self, spos_ac)
        self.timer.stop('Basic WFS set positions')
        self.timer.start('Basis functions set positions')
        self.basis_functions.set_positions(spos_ac)
        self.timer.stop('Basis functions set positions')
        if self.ksl is not None:
            self.basis_functions.set_matrix_distribution(self.ksl.Mstart,
                                                         self.ksl.Mstop)

        nq = len(self.kd.ibzk_qc)
        nao = self.setups.nao
        mynbands = self.mynbands
        
        Mstop = self.ksl.Mstop
        Mstart = self.ksl.Mstart
        mynao = Mstop - Mstart

        if self.ksl.using_blacs: # XXX
            # S and T have been distributed to a layout with blacs, so
            # discard them to force reallocation from scratch.
            #
            # TODO: evaluate S and T when they *are* distributed, thus saving
            # memory and avoiding this problem
            self.S_qMM = None
            self.T_qMM = None
        
        S_qMM = self.S_qMM
        T_qMM = self.T_qMM
        
        if S_qMM is None: # XXX
            # First time:
            assert T_qMM is None
            if self.ksl.using_blacs: # XXX
                self.tci.set_matrix_distribution(Mstart, mynao)
                
            S_qMM = np.empty((nq, mynao, nao), self.dtype)
            T_qMM = np.empty((nq, mynao, nao), self.dtype)
        
        for kpt in self.kpt_u:
            if kpt.C_nM is None:
                kpt.C_nM = np.empty((mynbands, nao), self.dtype)

        self.allocate_arrays_for_projections(
            self.basis_functions.my_atom_indices)
            
        self.P_aqMi = {}
        for a in self.basis_functions.my_atom_indices:
            ni = self.setups[a].ni
            self.P_aqMi[a] = np.empty((nq, nao, ni), self.dtype)

        for kpt in self.kpt_u:
            q = kpt.q
            kpt.P_aMi = dict([(a, P_qMi[q])
                              for a, P_qMi in self.P_aqMi.items()])

        self.timer.start('TCI: Calculate S, T, P')
        # Calculate lower triangle of S and T matrices:
        self.tci.calculate(spos_ac, S_qMM, T_qMM, self.P_aqMi)
        add_paw_correction_to_overlap(self.setups, self.P_aqMi, S_qMM,
                                      self.ksl.Mstart, self.ksl.Mstop)
        self.timer.stop('TCI: Calculate S, T, P')

        S_MM = None # allow garbage collection of old S_qMM after redist
        S_qMM = self.ksl.distribute_overlap_matrix(S_qMM)
        T_qMM = self.ksl.distribute_overlap_matrix(T_qMM)

        for kpt in self.kpt_u:
            q = kpt.q
            kpt.S_MM = S_qMM[q]
            kpt.T_MM = T_qMM[q]


        if (debug and self.band_comm.size == 1 and self.gd.comm.rank == 0 and
            nao > 0 and not self.ksl.using_blacs):
            # S and T are summed only on comm master, so check only there
            from numpy.linalg import eigvalsh
            self.timer.start('Check positive definiteness')
            for S_MM in S_qMM:
                tri2full(S_MM, UL='L')
                smin = eigvalsh(S_MM).real.min()
                if smin < 0:
                    raise RuntimeError('Overlap matrix has negative '
                                       'eigenvalue: %e' % smin)
            self.timer.stop('Check positive definiteness')
        self.positions_set = True
        self.S_qMM = S_qMM
        self.T_qMM = T_qMM
Ejemplo n.º 5
0
    def set_positions(self, spos_ac, atom_partition=None, move_wfs=False):
        oldspos_ac = self.spos_ac
        with self.timer('Basic WFS set positions'):
            WaveFunctions.set_positions(self, spos_ac, atom_partition)

        with self.timer('Basis functions set positions'):
            self.basis_functions.set_positions(spos_ac)

        if self.ksl is not None:
            self.basis_functions.set_matrix_distribution(self.ksl.Mstart,
                                                         self.ksl.Mstop)

        nq = len(self.kd.ibzk_qc)
        nao = self.setups.nao
        mynbands = self.bd.mynbands
        Mstop = self.ksl.Mstop
        Mstart = self.ksl.Mstart
        mynao = Mstop - Mstart

        #if self.ksl.using_blacs:  # XXX
        #     S and T have been distributed to a layout with blacs, so
        #     discard them to force reallocation from scratch.
        #
        #     TODO: evaluate S and T when they *are* distributed, thus saving
        #     memory and avoiding this problem
        for kpt in self.kpt_u:
            kpt.S_MM = None
            kpt.T_MM = None

        # Free memory in case of old matrices:
        self.S_qMM = self.T_qMM = self.P_aqMi = None

        if self.dtype == complex and oldspos_ac is not None:
            update_phases([kpt.C_nM for kpt in self.kpt_u],
                          [kpt.q for kpt in self.kpt_u],
                          self.kd.ibzk_qc, spos_ac, oldspos_ac,
                          self.setups, Mstart)

        for kpt in self.kpt_u:
            if kpt.C_nM is None:
                kpt.C_nM = np.empty((mynbands, nao), self.dtype)

        if 0:#self.debug_tci:
            #if self.ksl.using_blacs:
            #    self.tci.set_matrix_distribution(Mstart, mynao)
            oldS_qMM = np.empty((nq, mynao, nao), self.dtype)
            oldT_qMM = np.empty((nq, mynao, nao), self.dtype)


            oldP_aqMi = {}
            for a in self.basis_functions.my_atom_indices:
                ni = self.setups[a].ni
                oldP_aqMi[a] = np.empty((nq, nao, ni), self.dtype)

            # Calculate lower triangle of S and T matrices:
            self.timer.start('tci calculate')
            #self.tci.calculate(spos_ac, oldS_qMM, oldT_qMM,
            #                   oldP_aqMi)
            self.timer.stop('tci calculate')


        self.timer.start('mktci')
        manytci = self.tciexpansions.get_manytci_calculator(
            self.setups, self.gd, spos_ac, self.kd.ibzk_qc, self.dtype,
            self.timer)
        self.timer.stop('mktci')
        self.manytci = manytci
        self.newtci = manytci.tci

        my_atom_indices = self.basis_functions.my_atom_indices
        self.timer.start('ST tci')
        newS_qMM, newT_qMM = manytci.O_qMM_T_qMM(self.gd.comm,
                                                 Mstart, Mstop,
                                                 self.ksl.using_blacs)
        self.timer.stop('ST tci')
        self.timer.start('P tci')
        P_qIM = manytci.P_qIM(my_atom_indices)
        self.timer.stop('P tci')
        self.P_aqMi = newP_aqMi = manytci.P_aqMi(my_atom_indices)
        self.P_qIM = P_qIM  # XXX atomic correction

        # TODO
        #   OK complex/conj, periodic images
        #   OK scalapack
        #   derivatives/forces
        #   sparse
        #   use symmetry/conj tricks to reduce calculations
        #   enable caching of spherical harmonics

        #if self.atomic_correction.name != 'dense':
        #from gpaw.lcao.newoverlap import newoverlap
        #self.P_neighbors_a, self.P_aaqim = newoverlap(self, spos_ac)
        self.atomic_correction.gobble_data(self)

        #if self.atomic_correction.name == 'scipy':
        #    Pold_qIM = self.atomic_correction.Psparse_qIM
        #    for q in range(nq):
        #        maxerr = abs(Pold_qIM[q] - P_qIM[q]).max()
        #        print('sparse maxerr', maxerr)
        #        assert maxerr == 0

        self.atomic_correction.add_overlap_correction(self, newS_qMM)
        if self.debug_tci:
            self.atomic_correction.add_overlap_correction(self, oldS_qMM)

        if self.atomic_correction.implements_distributed_projections():
            my_atom_indices = self.atomic_correction.get_a_values()
        else:
            my_atom_indices = self.basis_functions.my_atom_indices
        self.allocate_arrays_for_projections(my_atom_indices)

        #S_MM = None  # allow garbage collection of old S_qMM after redist
        if self.debug_tci:
            oldS_qMM = self.ksl.distribute_overlap_matrix(oldS_qMM, root=-1)
            oldT_qMM = self.ksl.distribute_overlap_matrix(oldT_qMM, root=-1)

        newS_qMM = self.ksl.distribute_overlap_matrix(newS_qMM, root=-1)
        newT_qMM = self.ksl.distribute_overlap_matrix(newT_qMM, root=-1)

        #if (debug and self.bd.comm.size == 1 and self.gd.comm.rank == 0 and
        #    nao > 0 and not self.ksl.using_blacs):
        #    S and T are summed only on comm master, so check only there
        #    from numpy.linalg import eigvalsh
        #    self.timer.start('Check positive definiteness')
        #    for S_MM in S_qMM:
        #        tri2full(S_MM, UL='L')
        #        smin = eigvalsh(S_MM).real.min()
        #        if smin < 0:
        #            raise RuntimeError('Overlap matrix has negative '
        #                               'eigenvalue: %e' % smin)
        #    self.timer.stop('Check positive definiteness')
        self.positions_set = True

        if self.debug_tci:
            Serr = np.abs(newS_qMM - oldS_qMM).max()
            Terr = np.abs(newT_qMM - oldT_qMM).max()
            print('S maxerr', Serr)
            print('T maxerr', Terr)
            try:
                assert Terr < 1e-15, Terr
            except AssertionError:
                np.set_printoptions(precision=6)
                if self.world.rank == 0:
                    print(newT_qMM)
                    print(oldT_qMM)
                    print(newT_qMM - oldT_qMM)
                raise
            assert Serr < 1e-15, Serr

            assert len(oldP_aqMi) == len(newP_aqMi)
            for a in oldP_aqMi:
                Perr = np.abs(oldP_aqMi[a] - newP_aqMi[a]).max()
                assert Perr < 1e-15, (a, Perr)

        for kpt in self.kpt_u:
            q = kpt.q
            kpt.S_MM = newS_qMM[q]
            kpt.T_MM = newT_qMM[q]
        self.S_qMM = newS_qMM
        self.T_qMM = newT_qMM

        # Elpa wants to reuse the decomposed form of S_qMM.
        # We need to keep track of the existence of that object here,
        # since this is where we change S_qMM.  Hence, expect this to
        # become arrays after the first diagonalization:
        self.decomposed_S_qMM = [None] * len(self.S_qMM)
Ejemplo n.º 6
0
 def set_positions(self, spos_ac):
     WaveFunctions.set_positions(self, spos_ac)
     self.set_orthonormalized(False)
     self.pt.set_positions(spos_ac)
     self.allocate_arrays_for_projections(self.pt.my_atom_indices)
     self.positions_set = True