Esempio n. 1
0
    def __init__(self, qe_input, qe_dyn, ff, new_supercell_name,
                 new_dynmat_name):  # ff stands for folding factor

        print(" \n\n\n * * * Map phonons in a supercell * * *\n")
        print(" This code works only without symmetries!!! \n")

        self.qe_input = qe_input

        if not qe_input.is_it_true(qe_input.system['noinv']):
            #self.qe_input.system['noinv']='.true.'
            print(" WARNING! noinv flag set to .true. !!! \n")

        if not qe_input.is_it_true(qe_input.system['nosym']):
            #self.qe_input.system['nosym']='.true.'
            print(" WARNING! nosym flag set to .true. !!! \n")

        self.qe_dyn = qe_dyn
        self.ff = ff
        self.new_supercell_name = new_supercell_name
        self.new_dynmat_name = new_dynmat_name
        superc = supercell(qe_input, R=ff, mode='diagonal')
        self.qe_s = superc.write()
        self.qe_s.write(new_supercell_name)
Esempio n. 2
0
from QEplayground.pwscf import *
from QEplayground.supercell import *

scf_filename = "hBN.supercell.scf.in"
qe_input = Pwscf(scf_filename)

super_c = supercell(qe_input, [2, 2, 1])

qe_s = super_c.write()

qe_s.write("hBN.supercellx2.scf.in")
Esempio n. 3
0
    def build_mapping(self):
        n_qpoints=self.q_grid[0]*self.q_grid[1]*self.q_grid[2]
        print(" Q grid "+str(self.q_grid))
        print(" Number of q-points "+str(n_qpoints))

        if(self.qe_dyn.nqpoints != n_qpoints):
            print("\n ERROR! number of q-points in matdyn.modes different from the input q-grid!! \n")
            exit(0)

        #
        # Check orthogonality 
        #
        if(not self.qe_dyn.check_orthogonality()):
            print(" ERROR ERROR ERROR!! ")
            print(" Use the dynamical matrix eigenvectors as input!! ")
            print(" Not the one normalized with the masses!! ")
            exit(1)
        #
        #
        # Build the supercell
        #
        superc=supercell(self.qe_input,R=self.q_grid,mode='diagonal')
        self.qe_s=superc.write()
        self.qe_s.write(self.qe_input.filename+"_supercell")
        print(" Supercell scf file: "+self.qe_input.filename+"_supercell")
        self.qe_dyn_s=Matdyn(self.qe_s)
        #
        # Mapping the phonons
        #
        nmodes_old=self.qe_dyn.nmodes
        nmodes_new=self.qe_dyn_s.nmodes
        #
        self.qe_dyn_s.nqpoints=1
        self.qe_dyn_s.qpoints =np.zeros([1,3])
        self.qe_dyn_s.eig     =np.zeros([1,nmodes_new])
        self.qe_dyn_s.eiv     =np.zeros([1,nmodes_new,nmodes_new],dtype=complex)
        #
        # Copy old eivenvalues and eigenvectors (no phase yet)
        #
        for iq in range(n_qpoints):
            for im in range(nmodes_old):
                im_q=im+iq*nmodes_old
                self.qe_dyn_s.eig[0,im_q]=self.qe_dyn.eig[iq,im]
                for iq2 in range(n_qpoints):
                    self.qe_dyn_s.eiv[0,im_q,iq2*nmodes_old:(iq2+1)*nmodes_old]=self.qe_dyn.eiv[iq,im,:]

        # 
        # Add phases to the eigenvectors
        #
        new_atoms =self.qe_s.get_atoms(units="bohr")
        new_natoms=int(self.qe_s.system["nat"])
        #
        tpiba=2.0*math.pi/float(self.qe_input.system['celldm(1)'])
        #
        phases=np.zeros([n_qpoints,new_natoms],dtype=float)

        eps=1e-5

        for iq in range(n_qpoints):
            for a in range(new_natoms):
                sprod=np.dot(self.qe_dyn.qpoints[iq][:],new_atoms[a][:]*tpiba)
                phases[iq,a]=np.real(np.exp(1j*sprod))  # equivalent to cos(q*r)
                print(" Phase [q= %d, a= %d ] = %lf " % (iq,a,phases[iq,a]))
                if iq !=0 and abs(phases[iq,a])<=eps:
                    print("Zero phase for atom %d at q= %iq ! Please check the code! ")
                    exit(0)

        for im in range(nmodes_old):
            for iq in range(n_qpoints):
                im_q=im+iq*nmodes_old
                for a in range(new_natoms):
                    self.qe_dyn_s.eiv[0,im_q,a*3:(a+1)*3]=self.qe_dyn_s.eiv[0,im_q,a*3:(a+1)*3]*phases[iq,a]

        #
        # Sort phonons
        #
        sort_idx=np.argsort(self.qe_dyn_s.eig,axis=1)
        self.qe_dyn_s.eig=np.sort(self.qe_dyn_s.eig,axis=1)
        new_eig=np.empty_like(self.qe_dyn_s.eiv)
        for im in range(nmodes_new):
            new_eig[0,im,:]=self.qe_dyn_s.eiv[0,sort_idx[0][im],:]
        self.qe_dyn_s.eiv=new_eig
        #
        # Normalize eigevectors again
        #
        self.qe_dyn_s.normalize()
        #
        # Write output
        #
        self.qe_dyn_s.write_modes(filename="dynmat_supercell.out")
Esempio n. 4
0
from QEplayground.pwscf  import *
from QEplayground.supercell  import *

scf_filename    ="hBN.scf.in"
qe_input =Pwscf(scf_filename)

super_c = supercell(qe_input,R=[[1,-1,0],[6,3,1]],mode='nondiagonal')

qe_s = super_c.write()

qe_s.write("hBN.supercell.scf.in")
Esempio n. 5
0
    def build_mapping(self, sort_ph=True, print_eig=False, norm_eig=True):
        #
        # Select all the q points to be folded
        #
        qpoints_all = self.qe_dyn.qpoints
        tr = self.get_translation_vectors()
        #
        print(" Translation vectors in alat ")
        for it in range(self.ff[2] * self.ff[1] * self.ff[0]):
            print(str(tr[it, :]))

        print("\n Q-points in 2 pi/alat ")
        for qpoint in qpoints_all:
            print(str(qpoint))
        #
        #folded_qpoints = [np.array([0.0, 0.0, 0.0])]
        #index_folded_qpoints = [0]
        #ffinv = np.reciprocal(self.ff, dtype = float)
        #ffinv = np.around(ffinv,decimals=4)
        #
        #
        ##for ind,q in enumerate(qpoints_all) :
        #    if np.any(np.greater_equal(q,ffinv)):
        #        folded_qpoints.append(q)
        #        index_folded_qpoints.append(ind)
        #n_qpoints = len(folded_qpoints)
        #

        # Check orthogonality
        #
        #print(str(n_qpoints))
        #exit(0)
        if (not self.qe_dyn.check_orthogonality()):
            print(" ERROR ERROR ERROR!! ")
            print(" Use the dynamical matrix eigenvectors as input!! ")
            print(" Not the one normalized with the masses!! ")
            sys.exit(1)
        #
        #
        # Build the supercell
        #
        superc = supercell(self.qe_input, R=self.ff)
        self.qe_s = superc.write()
        self.qe_s.write(self.new_supercell_name)
        print("\nSupercell scf file: " + self.new_supercell_name + "\n")
        #
        self.qe_dyn_s = Matdyn(self.qe_s)
        #
        # Mapping the phonons
        #
        nmodes_old = self.qe_dyn.nmodes
        nmodes_new = self.qe_dyn_s.nmodes
        #
        self.qe_dyn_s.nqpoints = 1
        self.qe_dyn_s.qpoints = np.zeros([1, 3])
        self.qe_dyn_s.eig = np.zeros([1, nmodes_new])
        self.qe_dyn_s.eiv = np.zeros([1, nmodes_new, nmodes_new],
                                     dtype=complex)
        #
        # Copy old eivenvalues and eigenvectors (no phase yet) (phase is exp(1j*q.T) where q is 0)
        #
        #        for iq,ifolded in enumerate(index_folded_qpoints):
        #            for im in range(nmodes_old):
        #                im_q=im+iq*nmodes_old
        #                self.qe_dyn_s.eig[0,im_q]=self.qe_dyn.eig[ifolded,im]
        #                for iq2 in range(n_qpoints):
        #                    self.qe_dyn_s.eiv[0,im_q,iq2*nmodes_old:(iq2+1)*nmodes_old]=self.qe_dyn.eiv[ifolded,im,:]
        #
        n_qpoints = self.qe_dyn.nqpoints
        #
        # Print eigenvalues and eigenvectors
        #
        if (print_eig):
            self.qe_dyn.write_modes()

        for iq in range(n_qpoints):
            for im in range(nmodes_old):
                im_q = im + iq * nmodes_old
                self.qe_dyn_s.eig[0, im_q] = self.qe_dyn.eig[iq, im]
                for iq2 in range(n_qpoints):
                    self.qe_dyn_s.eiv[0, im_q, iq2 * nmodes_old:(iq2 + 1) *
                                      nmodes_old] = self.qe_dyn.eiv[iq, im, :]
        #
        #
        if (print_eig):
            self.qe_dyn_s.write_modes()
        #
        # Add phases to the eigenvectors
        #
        tpiba = 2.0 * math.pi / np.linalg.norm(
            self.qe_input.cell_parameters[0])
        #
        # I assume that the number of cell is equal to the number of q-points
        # this code can be generalized to map only particular q-points
        #
        for iq in range(n_qpoints):
            for im in range(nmodes_old):
                im_q = im + iq * nmodes_old
                for cell in range(n_qpoints):
                    # q in units of 2pi/alat, Tr in units of alat
                    sprod = np.dot(tr[cell][:],
                                   self.qe_dyn.qpoints[iq][:] * 2.0 * math.pi)
                    phase = np.exp(1j * sprod)
                    #                    # Add phase
                    if abs(phase) < 1e-5:
                        print("Error phase is zero!!! ")
                        exit(0)
                    self.qe_dyn_s.eiv[0, im_q, cell * nmodes_old:(cell + 1) *
                                      nmodes_old] *= phase

        #new_atoms =self.qe_s.get_atoms(units="alat")
        #new_natoms=int(self.qe_s.system["nat"])
        #
        #
        #
        #phases=np.zeros([n_qpoints,new_natoms],dtype=float)
        #
        #
        #eps=1e-5
        #tr = self.get_translation_vectors()
        #print("translation vectors :",tr)
        #for iq,ifolded in enumerate(index_folded_qpoints):
        #    for a in range(new_natoms):
        #        sprod=np.dot(self.qe_dyn.qpoints[ifolded][:],tr[a][:]*2.0*math.pi) # q in units of 2pi/alat, Tr in units of alat
        #        print("scalar product =",sprod)
        #        print("exponential value :",np.exp(1j*sprod))
        #        phases[iq,a]=np.real(np.exp(1j*sprod))
        #        print(f" Phase [q= {iq}, a= {a} ] = {phases[iq,a]}\n ")
        #        if iq !=0 and abs(phases[iq,a])<=eps:
        #            print("Zero phase for atom %d at q= %iq ! Please check the code! ")
        #            sys.exit(1)
        #
        #for im in range(nmodes_old):
        #     for iq in range(n_qpoints):
        #         im_q=im+iq*nmodes_old
        #         for a in range(new_natoms):
        #             self.qe_dyn_s.eiv[0,im_q,a*3:(a+1)*3] *= phases[iq,a]
        #
        if (sort_ph):
            #
            # Sort phonons
            #
            sort_idx = np.argsort(self.qe_dyn_s.eig, axis=1)
            self.qe_dyn_s.eig = np.sort(self.qe_dyn_s.eig, axis=1)
            new_eig = np.empty_like(self.qe_dyn_s.eiv)
            for im in range(nmodes_new):
                new_eig[0, im, :] = self.qe_dyn_s.eiv[0, sort_idx[0][im], :]
            self.qe_dyn_s.eiv = new_eig
        #
        # Normalize eigenvectors again
        #
        if (norm_eig):
            print("Normalize the new eigenvectors ")
            self.qe_dyn_s.normalize()
            print("Check normalization...", end="  ")
            if (not self.qe_dyn_s.check_orthogonality()):
                print("NO")
                exit(0)
            else:
                print("YES")
        else:
            for n in range(nmodes_new):
                print("New norm " +
                      str(np.linalg.norm(self.qe_dyn_s.eiv[0, n])))
        #
        print("Make eigenvectors real this break orthogonality!! ")
        for iq in range(n_qpoints):
            for im in range(nmodes_old):
                im_q = im + iq * nmodes_old
                for cell in range(n_qpoints):
                    # Make it real
                    self.qe_dyn_s.eiv[0, im_q, cell * nmodes_old:(cell + 1) *
                                      nmodes_old] = np.real(
                                          self.qe_dyn_s.eiv[0, im_q, cell *
                                                            nmodes_old:(cell +
                                                                        1) *
                                                            nmodes_old])
        self.qe_dyn_s.normalize()
        # Write output
        self.qe_dyn_s.check_orthogonality()
        #
        self.qe_dyn_s.write_modes(filename=self.new_dynmat_name)
Esempio n. 6
0
    def build_mapping(self, sort_ph=True, print_eig=False, norm_eig=True):
        #
        # Select all the q points to be folded
        #
        qpoints_all = self.qe_dyn.qpoints
        tr = self.get_translation_vectors()
        #
        print(" Translation vectors in alat ")
        for it in range(self.ff[2] * self.ff[1] * self.ff[0]):
            print(str(tr[it, :]))

        print("\n Q-points in 2 pi/alat ")
        for qpoint in qpoints_all:
            print(str(qpoint))

        #
        # Check orthogonality
        #
        if (not self.qe_dyn.check_orthogonality()):
            print(" ERROR ERROR ERROR!! ")
            print(" Use the dynamical matrix eigenvectors as input!! ")
            print(" Not the one normalized with the masses!! ")
            sys.exit(1)

        #
        # Build the supercell
        #
        superc = supercell(self.qe_input, R=self.ff, mode='keep_kpoints')
        self.qe_s = superc.write()
        self.qe_s.write(self.new_supercell_name)
        print("\nSupercell scf file: " + self.new_supercell_name + "\n")
        #
        self.qe_dyn_s = Matdyn(self.qe_s)
        #
        # Mapping the phonons
        #
        nmodes_old = self.qe_dyn.nmodes
        nmodes_new = self.qe_dyn_s.nmodes
        #
        self.qe_dyn_s.nqpoints = 1
        self.qe_dyn_s.qpoints = np.zeros([1, 3])
        self.qe_dyn_s.eig = np.zeros([1, nmodes_new])
        self.qe_dyn_s.eiv = np.zeros([1, nmodes_new, nmodes_new],
                                     dtype=complex)
        #
        # Selecting q-points
        #
        # I assume there is an unknown number of q-points
        # I order the q points in the same way than the translation vectors for simplicity reasons
        #
        qpoints_all_sorted = sorted(qpoints_all, key=lambda q: q[2])
        heights = [
            list(el) for _, el in groupby(qpoints_all, key=lambda q: q[2])
        ]
        depths = []
        for i in range(len(heights)):
            depths.append([
                list(el) for _, el in groupby(heights[i], key=lambda q: q[1])
            ])
        q_ordered = []
        for i in range(self.ff[2]):
            for j in range(self.ff[1]):
                for k in range(self.ff[0]):
                    q_ordered.append(depths[-i][-j][-k])
        #
        print("Selected q-points")
        for el in q_ordered:
            print(el)

        #
        # Copy old eivenvalues and eigenvectors (no phase yet) (phase is exp(1j*q.T) where q is 0)
        #
        #
        #
        n_qpoints = self.qe_dyn.nqpoints
        #
        # Print eigenvalues and eigenvectors
        #
        if (print_eig):
            self.qe_dyn.write_modes()

        N = self.ff[0] * self.ff[1] * self.ff[2]

        for iq in range(len(q_ordered)):
            for im in range(nmodes_old):
                im_q = im + iq * nmodes_old
                self.qe_dyn_s.eig[0, im_q] = self.qe_dyn.eig[iq, im]
                for iq2 in range(len(q_ordered)):
                    self.qe_dyn_s.eiv[0, im_q, iq2 * nmodes_old:(iq2 + 1) *
                                      nmodes_old] = self.qe_dyn.eiv[iq, im, :]
        #
        #
        if (print_eig):
            self.qe_dyn_s.write_modes()
        #
        # Add phases to the eigenvectors
        #
        tpiba = 2.0 * math.pi / np.linalg.norm(
            self.qe_input.cell_parameters[0])
        #
        #
        phases = np.zeros((len(q_ordered), len(tr)), dtype=complex)
        #
        for iq in range(len(q_ordered)):
            for cell in range(len(tr)):
                sprod = np.dot(q_ordered[iq][:], tr[cell][:] * 2. * math.pi)
                phases[iq, cell] = np.exp(1j * sprod)
        #
        natoms = int(nmodes_old / 3.)  # number of atoms per unit cell
        #
        for im in range(nmodes_new):
            for cell in range(len(tr)):
                # Add phase
                self.qe_dyn_s.eiv[0, im, cell * natoms:(cell + 1) *
                                  natoms] *= phases[im // nmodes_old, cell]
                # Make it real
                self.qe_dyn_s.eiv[0, im,
                                  cell * natoms:(cell + 1) * natoms] = np.real(
                                      self.qe_dyn_s.eiv[0, im, cell *
                                                        natoms:(cell + 1) *
                                                        natoms])

        #
        if (sort_ph):
            #
            # Sort phonons
            #
            sort_idx = np.argsort(self.qe_dyn_s.eig, axis=1)
            self.qe_dyn_s.eig = np.sort(self.qe_dyn_s.eig, axis=1)
            new_eig = np.empty_like(self.qe_dyn_s.eiv)
            for im in range(nmodes_new):
                new_eig[0, im, :] = self.qe_dyn_s.eiv[0, sort_idx[0][im], :]
            self.qe_dyn_s.eiv = new_eig
        #
        # Normalize eigenvectors again
        #
        if (norm_eig):
            print("Normalize the new eigenvectors ")
            self.qe_dyn_s.normalize()
            print("Check normalization...")
            print("Are the new eigenvectors orthogonal ?",
                  self.qe_dyn_s.check_orthogonality())
        else:
            for n in range(nmodes_new):
                print("New norm " +
                      str(np.linalg.norm(self.qe_dyn_s.eiv[0, n])))
        #
        # Write output
        #
        self.qe_dyn_s.write_modes(filename=self.new_dynmat_name)