Пример #1
0
 def plot_optical_indices(self, opp=None):
     project = self.projects[self.currentprojectid]
     if project.object_str_type(self.currentitemid) == 'cell':
         cell = project.cells[self.currentitemid]
         # check if cell already has OpticalIndices attribute
         try:
             len(cell.optical_indices.components)
         except AttributeError as e:
             if bf.grep(cell.outcar,
                        "DIELECTRIC FUNCTION") is not None or bf.grep(
                            cell.outcar, "DIELECTRIC TENSOR") is not None:
                 cell.optical_indices = oi.OpticalIndices(cell.outcar)
             else:
                 message = 'Warning! There is no dielectric function to plot in this file! '
                 message += '\nSee https://cms.mpi.univie.ac.at/wiki/index.php/Dielectric_properties_of_SiC for VASP help'
                 print(message)
                 return None
         if opp is None:
             fig = cell.optical_indices.plot(
                 pp=cell.optical_indices.lastopp)
         else:
             fig = cell.optical_indices.plot(pp=opp)
         frame = tk.Frame(self.work_frame, bd=2, bg='white', relief=RAISED)
         self.fig_to_canvas(fig, frame)
         self.update_work_frame(frame, cell.treetitle)
Пример #2
0
def get_band_occupation(outcar, nkpts, functional):
    """ Retrieve the bands occupation for each kpoint
    :param outcar: content of the outcar file (list of strings)
    :param nkpts: number of kpoints (int)
    :param functional: functional used (string)
    :return: last energy and occupation of the bands for each kpoint
    """

    if functional == 'GW0@GGA':
        str_beg = "  band No. old QP-enery  QP-energies   sigma(KS)   T+V_ion+V_H  V^pw_x(r,r')   Z            occupation"
        indices_beg = np.array([f[1] for f in bf.grep(outcar, str_beg)
                                ])[-nkpts:] + 2
        col_index = 2
    elif functional == 'G0W0@GGA':
        str_beg = "  band No.  KS-energies  QP-energies   sigma(KS)   V_xc(KS)     V^pw_x(r,r')   Z            occupation"
        indices_beg = np.array([f[1] for f in bf.grep(outcar, str_beg)]) + 2
        col_index = 2
    else:
        str_beg = '  band No.  band energies     occupation'
        indices_beg = np.array([f[1] for f in bf.grep(outcar, str_beg)]) + 1
        col_index = 1

    indices_end = np.array([outcar[f:].index('') for f in indices_beg])
    raw_data = [
        outcar[f:g] for f, g in zip(indices_beg, indices_end + indices_beg)
    ]
    data = [bf.convert_stringcolumn_to_array(f) for f in raw_data]

    return [[f[col_index], f[-1]] for f in data]
Пример #3
0
def extract_rpa(content):
    index_beg = bf.grep(content, 'INVERSE MACROSCOPIC DIELECTRIC TENSOR')[0][1] + 2
    index_end = bf.grep(content, 'screened Coulomb potential')[0][1] - 4

    blocks_indices = list(range(index_beg, index_end, 7))
    data = [read_block(content[index: index+4]) for index in blocks_indices]
    energy = np.array([d[0] for d in data])
    eps1, eps2 = np.transpose([d[1:] for d in data], axes=(1, 2, 0))
    return energy, eps1, eps2
Пример #4
0
def extract_ipa_gw(content):
    index_beg = bf.grep(content, 'HEAD OF MICROSCOPIC DIELECTRIC TENSOR (INDEPENDENT PARTICLE)')[0][1] + 2
    index_end = bf.grep(content, 'XI_LOCAL:  cpu time')[0][1] - 4
    
    blocks_indices = list(range(index_beg, index_end, 7))
    data = [read_block(content[index: index+4]) for index in blocks_indices]
    energy = np.array([d[0] for d in data])
    eps1, eps2 = np.transpose([d[1:] for d in data], axes=(1, 2, 0))
    return energy, eps1, eps2
Пример #5
0
    def __init__(self, outcar_file):
        
        if type(outcar_file) == str:
            content = bf.read_file(outcar_file)
        elif type(outcar_file) == list:
            content = outcar_file
        
        self.components = ['XX', 'YY', 'ZZ', 'XY', 'YZ', 'ZX']
        self.quantities = ['epsilon 1', 'epsilon 2', 'n', 'k', 'R', 'abs', 'L', 'sigma1', 'sigma2']
        self.quantities_labels = ('\epsilon_1', '\epsilon_2', 'n', 'k', 'R' , 'abs', 'L', 'sigma1', 'sigma2')
        self.components_labels = self.components

        algo = bf.grep(content, 'ALGO    =', 0, 'execute GW part')
        if algo == 'CHI':
            self._energy, self._eps1, self._eps2 = extract_rpa(content)
        elif algo is not None and algo.find('GW') > -1:
            self._energy, self._eps1, self._eps2 = extract_ipa_gw(content)
        else:
            self._energy, self._eps1, self._eps2 = extract_ipa(content)

        self._n, self._k, self._r, self._abs, self._L, self._sigma1, self._sigma2 = np.transpose([get_nkr(e1, e2, self._energy) for e1, e2 in zip(self._eps1, self._eps2)], axes=(1, 0, 2))
        # self._abs, self._L, self._sigma1, self._sigma2

        self.data = np.array([self._eps1, self._eps2, self._n, self._k, self._r,self._abs,self._L,self._sigma1,self._sigma2])
        self.data_dict = dict(list(zip(self.quantities, self.data)))
        self.data_dict_t = dict(list(zip(self.components, np.transpose(self.data, axes=(1, 0, 2)))))
        self.quantities_dict = dict(list(zip(self.quantities, self.quantities_labels)))
        self.components_dict = dict(list(zip(self.components, self.components_labels)))
        self.lastopp = OpticalPlotParameters(self)
Пример #6
0
def get_cell_parameters(outcar):
    """ Retrieve the cell parameters from the OUTCAR file content
    :param outcar: content of the outcar file (list of strings, each one for a line)
    :return: cristallographic parameters of the cell
    """
    index = bf.grep(outcar, 'direct lattice vectors')[-1][
        1]  # location of the cristallographic parameters in the OUTCAR
    raw_data = outcar[index + 1:index +
                      4]  # direct and reciprocal lattice vectors
    return [[float(f) for f in g.split()[:3]] for g in raw_data]
Пример #7
0
def extract_ipa(content):

    tensor_headers = bf.grep(content, "frequency dependent")
    if tensor_headers is not None:
        if len(tensor_headers) == 2:
            index1 = bf.grep(content, "frequency dependent IMAGINARY DIELECTRIC FUNCTION")[0][1]
            index2 = bf.grep(content, "frequency dependent      REAL DIELECTRIC FUNCTION")[0][1]
            index3 = bf.grep(content, "The outermost node ")[0][1]
        elif len(tensor_headers) == 4:
            index1 = tensor_headers[0][1]
            index2 = tensor_headers[1][1]
            index3 = tensor_headers[2][1]
        else:
            print('Warning! Case not programmed! Are you sure your file is ok?')
        eps2 = bf.fast_stringcolumn_to_array(content[index1 + 3: index2 - 1])
        eps1 = bf.fast_stringcolumn_to_array(content[index2 + 3: index3 - 1])
        return eps1[0], eps1[1:], eps2[1:]
    else:
        print('Warning! Could not find tensor header in OUTCAR file')
Пример #8
0
def get_functional(outcar):
    """ Retrieve the functional used from the outcar data
    :param outcar: content of the OUTCAR file (list of strings)
    :return: functional of used
    """

    # Default values
    functional = 'other'  # used for display inline
    functional_title = 'other'  # used for display in matplotlib

    lexch = bf.grep(outcar, 'LEXCH   =', 0, 'internal', 'str', 1)
    lhfcalc = bf.grep(outcar, 'LHFCALC =', 0, 'Hartree', 'str', 1)
    hfscreen = bf.grep(outcar, 'HFSCREEN=', 0, 'screening', 'float', 1)
    gw = bf.grep(outcar,
                 'Response functions by sum over occupied states:',
                 nb_found=2)

    if lexch == '2' and lhfcalc == 'F':
        functional = 'LDA'
        functional_title = 'LDA'
    if lexch == '8' and lhfcalc == 'F':
        functional = 'GGA'
        functional_title = 'GGA'
    if lexch == '8' and lhfcalc == 'T':
        if hfscreen == 0.2:
            functional = 'HSE'
            functional_title = 'HSE'
        if hfscreen == 0.0:
            functional = 'PBE0'
            functional_title = 'PBE0'
    if gw is not None:
        nelm = bf.grep(outcar, 'NELM    =', 0, 'number', 'int', 1)
        if nelm == 1:
            functional = 'G0W0@GGA'
            functional_title = 'G_0W_0@GGA'
        elif nelm > 1:
            functional = 'GW0@GGA'
            functional_title = 'GW_0@GGA'

    return functional, functional_title
Пример #9
0
def get_kpoints_reciprocal_coords(outcar, nkpts):

    index_beg = bf.grep(outcar,
                        ' k-points in units of 2pi/SCALE and weight:',
                        nb_found=1)[0][1] + 1
    index_end = outcar[index_beg:].index(' ')

    data_str = outcar[index_beg:index_beg + index_end]
    coordinates = np.transpose(bf.convert_stringcolumn_to_array(data_str)[:3])

    if len(coordinates) != nkpts:
        raise bf.PydefImportError(
            'Number of kpoint coordinates in reciprocal space retrieved '
            'and number of kpoints are not consistent')
    else:
        return coordinates
Пример #10
0
def get_kpoints_weights_and_coords(outcar, nkpts):
    """ Retrieve the kpoints weights from the OUTCAR file content
    :param outcar: content of the OUTCAR file (list of strings)
    :param nkpts: number of kpoints (int)
    :return: numpy array """

    index_beg = bf.grep(outcar,
                        'k-points in reciprocal lattice and weights',
                        nb_found=1)[0][1] + 1
    index_end = outcar[index_beg:].index(' ')

    data_str = outcar[index_beg:index_beg + index_end]
    x, y, z, weights = bf.convert_stringcolumn_to_array(data_str)
    coordinates = [[f, g, h] for f, g, h in zip(x, y, z)]

    if len(weights) != nkpts:
        raise bf.PydefImportError(
            'Number of kpoint weights retrieved and number of kpoints are not consistent'
        )
    else:
        return coordinates, weights
Пример #11
0
def get_atoms_positions(outcar, atoms):
    """
    :param outcar: content of the outcar file (list of strings)
    :param atoms: number of atoms of each atomic species (list of integers)
    :return: position of each atom as a dictionary
    """

    str_beg = 'position of ions in cartesian coordinates  (Angst):'
    index_beg = bf.grep(
        outcar, str_beg,
        nb_found=1)[0][1] + 1  # index of the first atom position
    index_end = outcar[index_beg:].index('') - 1
    atoms_positions = [[float(f) for f in g.split()]
                       for g in outcar[index_beg:index_end + index_beg]]

    # Check that the number of positions retrieved is equal to the number of atoms
    if len(atoms_positions) != len(atoms):
        raise bf.PydefImportError(
            "The number of atoms positions is not consistent with the total number of atoms"
        )
    else:
        return dict(zip(atoms, atoms_positions))
Пример #12
0
def get_electrostatic_potentials(outcar, atoms):
    """ Retrieve the electrostatic averaged potentials from the OUTCAR file
    :param outcar: content of the OUTCAR file (list of strings)
    :param atoms: number of atoms of each atomic species (list of integers)
    :return: dictionary with the electrostatic potential for each atom """

    index_beg = bf.grep(outcar,
                        'average (electrostatic) potential at core',
                        nb_found=1)[0][1] + 3
    index_end = outcar[index_beg:].index(' ')

    potentials_str = outcar[index_beg:index_beg + index_end]
    potentials_raw = np.concatenate(
        [[float(f) for f in re.split('     |-', q)[1:]]
         for q in potentials_str])
    potentials = np.array(
        [-f[1] for f in np.split(potentials_raw, len(atoms))])

    if len(potentials) != len(atoms):
        raise bf.PydefImportError(
            'Number of electrostatic potentials retrieved and number are not consistent'
        )

    return dict(zip(list(atoms), potentials))
Пример #13
0
    def __init__(self, outcar_file, doscar_file):
        """ Read the OUTCAR and DOSCAR output files of a VASP calculation
        :param outcar_file: location of the OUTCAR file (string)
        :param doscar_file: location of the DOSCAR file (string) """

        # --------------------------------------------------- OUTCAR ---------------------------------------------------

        self.OUTCAR = outcar_file
        self.DOSCAR = doscar_file

        self.outcar = bf.read_file(outcar_file)  # content of the OUTCAR file

        if self.outcar[0][:6] != ' vasp.':
            raise bf.PydefOutcarError(
                'The given file appears to not be a valid OUTCAR file.')

        # ------------------------------------------- CALCULATION PROPERTIES -------------------------------------------

        self.functional, self.functional_title = get_functional(
            self.outcar)  # functional used
        self.nedos = bf.grep(self.outcar, 'NEDOS =', 0, 'number of ions',
                             'int', 1)  # number of point in the DOS
        self.encut = bf.grep(self.outcar, 'ENCUT  =', 0, 'eV', 'float',
                             1)  # ENCUT used
        self.ediff = bf.grep(self.outcar, 'EDIFF  =', 0, 'stopping', 'float',
                             1)  # EDIFF value
        self.emin = bf.grep(self.outcar, 'EMIN   =', 0, ';', 'float',
                            1)  # minimum energy for the DOS
        self.emax = bf.grep(self.outcar, 'EMAX   =', 0, 'energy-range',
                            'float', 1)  # maximum energy for the DOS
        self.ismear = bf.grep(self.outcar, 'ISMEAR =', 0, ';', 'int',
                              1)  # ISMEAR tag
        self.lorbit = bf.grep(self.outcar, 'LORBIT =', 0, '0 simple, 1 ext',
                              'int', 1)  # LORBIT tag
        self.isym = bf.grep(self.outcar, 'ISYM   =', 0, '0-nonsym', 'int',
                            1)  # ISYM tag
        self.istart = bf.grep(self.outcar, 'ISTART =', 0, 'job', 'int',
                              1)  # ISTART tag
        self.ispin = bf.grep(self.outcar, 'ISPIN  =', 0, 'spin', 'int',
                             1)  # ISPIN tag
        self.icharg = bf.grep(self.outcar, 'ICHARG =', 0, 'charge:', 'int',
                              1)  # ICHARG tag

        # --------------------------------------------- SYSTEM PROPERTIES ----------------------------------------------

        self.nb_atoms_tot = bf.grep(self.outcar, 'NIONS =', 0, False, 'int',
                                    1)  # total number of atoms
        self.nb_atoms = [
            int(f) for f in bf.grep(self.outcar, 'ions per type =', 0).split()
        ]  # population of each atomic species
        self.atoms_types = [
            bf.grep(self.outcar, 'VRHFIN =', f, ':')
            for f in range(len(bf.grep(self.outcar, 'VRHFIN =')))
        ]  # atomic species
        self.population = dict(zip(self.atoms_types, self.nb_atoms))
        self.atoms_valence = [
            int(float(f))
            for f in bf.grep(self.outcar, 'ZVAL   =', -1).split()
        ]  # valence of each atomic species
        self.atoms = np.concatenate(
            [[f + ' (' + str(g) + ')' for g in range(1, q + 1)]
             for f, q in zip(self.atoms_types, self.nb_atoms)])  # atoms list
        self.nb_electrons = bf.grep(self.outcar, 'NELECT =', 0, 'total number',
                                    'float', 1)  # total number of electrons
        self.charge = sum(
            np.array(self.nb_atoms) *
            np.array(self.atoms_valence)) - self.nb_electrons
        self.orbitals = [
            f for f in bf.grep(self.outcar, '# of ion', 0, 'tot').split(' ')
            if f != ''
        ]

        # verification of the consistence of the data retrieved
        if self.nb_atoms_tot != sum(self.nb_atoms) or \
                len(self.nb_atoms) != len(self.atoms_types) or \
                len(self.nb_atoms) != len(self.atoms_valence):
            raise bf.PydefImportError(
                'Numbers of atoms retrieved are not consistent')

        self.name, self.display_name = get_system_name(self.atoms_types,
                                                       self.nb_atoms, False)
        self.rname, self.display_rname = get_system_name(
            self.atoms_types, self.nb_atoms, True)

        # --------------------------------------------- CALCULATION RESULT ---------------------------------------------

        # Number of electronic steps
        if self.functional != 'G0W0@GGA' and self.functional != 'GW0@GGA':
            self.nb_iterations = len(bf.grep(
                self.outcar, 'Iteration'))  # for non GW calculations
        else:
            self.nb_iterations = bf.grep(self.outcar, 'NELM    =', 0, 'number',
                                         'int', 1)  # for GW calculations

        # Cristallographic properties
        self.cell_parameters = get_cell_parameters(
            self.outcar)  # cristallographic parameters
        self.atoms_positions = get_atoms_positions(
            self.outcar, self.atoms)  # atoms positions

        # Energy & Density of states
        self.energy = bf.grep(self.outcar, 'free energy    TOTEN  =', -1, 'eV',
                              'float', self.nb_iterations)  # total energy
        self.fermi_energy = bf.grep(self.outcar, ' BZINTS: Fermi energy:', -1,
                                    ';', 'float')  # fermi energy
        if self.ismear == 0:
            self.fermi_energy = bf.grep(self.outcar,
                                        'E-fermi :',
                                        0,
                                        'XC(G=0)',
                                        'float',
                                        nb_found=1)
        self.nkpts = bf.grep(self.outcar, 'NKPTS =', 0, 'k-points in BZ',
                             'int', 1)  # number of k-points
        self.kpoints_coords, self.kpoints_weights = get_kpoints_weights_and_coords(
            self.outcar, self.nkpts)
        self.kpoints_coords_r = get_kpoints_reciprocal_coords(
            self.outcar, self.nkpts)
        self.nbands = bf.grep(self.outcar, 'NBANDS=', 0, False, 'int',
                              1)  # number of bands
        self.bands_data = get_band_occupation(
            self.outcar, self.nkpts,
            self.functional)  # bands energy and occupation
        self.VBM, self.CBM = get_band_extrema(
            self.bands_data)  # VBM and CBM energies
        self.gap = self.CBM - self.VBM  # electronic gap
        if self.functional != 'G0W0@GGA' and self.functional != 'GW0@GGA':
            self.potentials = get_electrostatic_potentials(
                self.outcar, self.atoms)  # electrostatic averaged potentials
        else:
            self.potentials = None

        # --------------------------------------------------- OTHERS ---------------------------------------------------

        self.ID = ''.join([f + str(g) for f, g in zip(self.atoms_types, self.nb_atoms)]) + '_' + self.functional\
                  + '_q' + str(int(self.charge))
        self.title = self.display_name + ' ' + self.functional_title + ' q=%.0f' % self.charge  # title of the

        # --------------------------------------------------- DOSCAR ---------------------------------------------------

        if self.DOSCAR != '':
            self.doscar = bf.read_file(
                doscar_file)  # content of the DOSCAR file

            self.dos_energy, self.total_dos, self.total_dos_up, self.total_dos_down, self.dos_opa, self.dos_opa_up, \
            self.dos_opa_down, self.dos_opas, self.dos_opas_up, self.dos_opas_down = self.analyse_dos()

            # Maximum value of each DOS excluding the first value
            self.dosmax = np.max(self.total_dos[1:])
            if self.ispin == 2:
                self.dosmax_up = np.max(self.total_dos_up[1:])
                self.dosmax_down = np.max(self.total_dos_down[1:])

            self.dpp = DosPlotParameters(self)  # DOS plot parameters

        if self.icharg == 11:
            self.bpp = BandDiagramPlotParameters(self)
Пример #14
0
eps1, eps2, n, k, r = c.plot()
# eps1.show()
n.show()
k.show()
r.show()

c = cc.Cell('D:/OUTCAR.LOPTICS')

import sys

sys.exit()

import pydef_core.basic_functions as bf

content = bf.read_file('D:/OUTCAR.LOPTICS')
test0 = bf.grep(content, "frequency dependent IMAGINARY DIELECTRIC FUNCTION")
index1 = bf.grep(content,
                 "frequency dependent IMAGINARY DIELECTRIC FUNCTION")[0][1]
index2 = bf.grep(content,
                 "frequency dependent      REAL DIELECTRIC FUNCTION")[0][1]
index3 = bf.grep(
    content, "The outermost node ")[0][1]  # This can be a problem sometime!
test1 = content[index1 + 4:index2 - 1]
test2 = content[index2 + 4:index3 - 1]


def check(arg, index):
    i = index - 1
    for elt in arg:
        i += 1
        j = -1