Esempio n. 1
0
    def analyze(self):
        path = self.path
        infile_name = self.infile_name
        outfile_name = self.outfile_name
        pw2c_outfile_name = self.pw2c_outfile_name

        nx = 0

        outfile = os.path.join(path, outfile_name)

        try:
            # perform MD analysis
            f = TextFile(outfile)
            n = 0
            md_res = []
            while f.seek('!', 1) != -1:
                E = float(f.readtokens()[-2])
                f.seek('P=', 1)
                P = float(f.readtokens()[-1])
                f.seek('time      =', 1)
                t = float(f.readtokens()[-2])
                f.seek('kinetic energy', 1)
                K = float(f.readtokens()[-2])
                f.seek('temperature', 1)
                T = float(f.readtokens()[-2])
                md_res.append((E, P, t, K, T))
                n += 1
            #end while
            md_res = array(md_res, dtype=float).T
            quantities = ('total_energy', 'pressure', 'time', 'kinetic_energy',
                          'temperature')
            md = obj()
            for i, q in enumerate(quantities):
                md[q] = md_res[i]
            #end for
            md.potential_energy = md.total_energy - md.kinetic_energy
            self.md_data = md
            self.md_stats = self.md_statistics()
            if self.info.md_only:
                return
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('MD analysis failed')
            #end if
        #end try

        try:
            lines = open(outfile, 'r').read().splitlines()
        except:
            nx += 1
            if self.info.warn:
                self.warn('file read failed')
            #end if
        #end try

        try:
            fermi_energies = []
            for l in lines:
                if l.find('Fermi energ') != -1:
                    toks = l.split()[::-1]
                    assert toks[0] == 'ev'
                    for tok in toks[1:]:
                        try:
                            ef1 = float(tok)
                            fermi_energies.append(ef1)
                        except ValueError:
                            fermi_energies = fermi_energies[::-1]
                            break
                        #end try
                    #end for
                #end if
            #end for
            if len(fermi_energies) == 0:
                self.Ef = 0.0
            else:
                self.Ef = fermi_energies[-1]
            #end if
            self.fermi_energies = array(fermi_energies)
        except:
            nx += 1
            if self.info.warn:
                self.warn('fermi energy read failed')
            #end if
        #end try
        try:
            energies = []
            for l in lines:
                if l.find('!  ') != -1:
                    energies.append(float(l.split('=')[1].split()[0]))
                #end if
            #end for
            if len(energies) == 0:
                self.E = 0.0
            else:
                self.E = energies[-1]
            #end if
            self.energies = array(energies)
        except:
            nx += 1
            if self.info.warn:
                self.warn('total energy read failed')
            #end if
        #end try
        try:
            # get bands and occupations
            nfound = 0
            index = -1
            bands = obj()
            bands.up = obj()
            bands.down = obj()
            polarized = False
            if self.input.system.nspin > 1:
                polarized = True
            #end if
            read_kpoints = False
            read_2pi_alat = False
            read_rel = False
            for i in range(len(lines)):
                l = lines[i]
                if 'End of self-consistent calculation' in l:
                    # Initialize each time in case a hybrid functional was used
                    if nfound > 0:
                        nfound = 0
                        index = -1
                        bands = obj()
                        bands.up = obj()
                        bands.down = obj()
                    #end if
                #end if

                if '- SPIN UP -' in l:
                    up_spin = True
                elif '- SPIN DOWN -' in l:
                    up_spin = False
                    index = -1
                #end if

                if 'number of k points=' in l:
                    try:
                        num_kpoints = int(l.strip().split()[4])
                    except:
                        print(
                            "Number of k-points {0} is not an integer".format(
                                num_kpoints))
                    #end try

                    kpoints_2pi_alat = lines[i + 2:i + 2 + num_kpoints]
                    kpoints_rel = lines[i + 4 + num_kpoints:i + 4 +
                                        2 * num_kpoints]
                    kpoints_2pi_alat = array([
                        k.strip().split()[4:6] + [k.strip().split()[6][0:-2]]
                        for k in kpoints_2pi_alat
                    ],
                                             dtype=float)
                    kpoints_rel = array([
                        k.strip().split()[4:6] + [k.strip().split()[6][0:-2]]
                        for k in kpoints_rel
                    ],
                                        dtype=float)
                #end if
                if 'bands (ev)' in l:
                    index += 1
                    nfound += 1
                    i_occ = -1
                    j = i
                    while i_occ == -1:
                        j += 1
                        if 'occupation numbers' in lines[j]:
                            i_occ = j
                        #end if
                    #end while
                    seigs = ''
                    for j in range(i + 1, i_occ):
                        seigs += lines[j]
                    #end for
                    seigs = seigs.replace(
                        '-', ' -'
                    )  # For cases where the eigenvalues "touch", e.g. -144.9938-144.9938 -84.3023
                    seigs = seigs.strip()
                    eigs = array(seigs.split(), dtype=float)

                    soccs = ''
                    for j in range(i_occ + 1, i_occ + 1 + (i_occ - i) - 2):
                        soccs += lines[j]
                    #end for
                    occs = array(soccs.split(), dtype=float)
                    bk = obj(
                        index=index,
                        kpoint_2pi_alat=kpoints_2pi_alat[index],
                        kpoint_rel=kpoints_rel[index],
                        eigs=eigs,
                        occs=occs,
                        pol='none',
                    )
                    band_channel = bands.up
                    if polarized:
                        if up_spin:
                            bk.pol = 'up'
                        elif not up_spin:
                            bk.pol = 'down'
                            band_channel = bands.down
                        #end if
                    else:
                        index = nfound - 1
                    #end if
                    band_channel.append(bk)
                    #if nfound==1:
                    #    bands.up = obj(
                    #        eigs = eigs,
                    #        occs = occs
                    #        )
                    #elif nfound==2:
                    #    bands.down = obj(
                    #        eigs = eigs,
                    #        occs = occs
                    #        )
                    #end if
                #end if
            #end for
            vbm = obj(energy=-1.0e6)
            cbm = obj(energy=1.0e6)
            direct_gap = obj(energy=1.0e6)
            for band_channel in bands:
                for b in band_channel:
                    e_val = max(b.eigs[b.occs > 0.5])
                    e_cond = min(b.eigs[b.occs < 0.5])

                    if e_val > vbm.energy:
                        vbm.energy = e_val
                        vbm.kpoint_rel = b.kpoint_rel
                        vbm.kpoint_2pi_alat = b.kpoint_2pi_alat
                        vbm.index = b.index
                        vbm.pol = b.pol
                        vbm.band_number = max(where(b.occs > 0.5))
                    #end if
                    if e_cond < cbm.energy:
                        cbm.energy = e_cond
                        cbm.kpoint_rel = b.kpoint_rel
                        cbm.kpoint_2pi_alat = b.kpoint_2pi_alat
                        cbm.index = b.index
                        cbm.pol = b.pol
                        cbm.band_number = min(where(b.occs < 0.5))
                    #end if
                    if (e_cond - e_val) < direct_gap.energy:
                        direct_gap.energy = e_cond - e_val
                        direct_gap.kpoint_rel = b.kpoint_rel
                        direct_gap.kpoint_2pi_alat = b.kpoint_2pi_alat
                        direct_gap.index = b.index
                        direct_gap.pol = [vbm.pol, cbm.pol]
                    #end if
                #end for
            #end for
            electronic_structure = ''
            if (vbm.energy + 0.025) >= cbm.energy:
                if vbm.band_number == cbm.band_number:
                    electronic_structure = 'metallic'
                else:
                    electronic_structure = 'semi-metal'
                #end if
            else:
                electronic_structure = 'insulating'
                if not equal(vbm.kpoint_rel, cbm.kpoint_rel).all():
                    indirect_gap = obj(energy=round(cbm.energy - vbm.energy,
                                                    3),
                                       kpoints=obj(vbm=vbm, cbm=cbm))
                    bands.indirect_gap = indirect_gap
            #end if
            bands.electronic_structure = electronic_structure
            bands.vbm = vbm
            bands.cbm = cbm
            bands.direct_gap = direct_gap
            if nfound > 0:
                self.bands = bands
            #end if
            # Kayahan edited --end
        except:
            nx += 1
            if self.info.warn:
                self.warn('band read failed')
            #end if
        #end try

        try:
            # read structures
            structures = obj()
            i = 0
            found = False
            cont = False
            while i < len(lines):
                l = lines[i]
                if l.find('CELL_PARAMETERS') != -1 and l.strip().startswith(
                        'CELL'):
                    conf = obj()
                    axes = []
                    cont = True
                    for d in (0, 1, 2):
                        i += 1
                        axes.append(array(lines[i].split(), dtype=float))
                    #end for
                    conf.axes = array(axes)
                #end if
                if l.find('ATOMIC_POSITIONS') != -1:
                    found = True
                    if not cont:
                        conf = obj()
                    #end if
                    atoms = []
                    positions = []
                    i += 1
                    tokens = lines[i].split()

                    while len(tokens) > 0 and tokens[0].lower() != 'end' and (
                            len(tokens) == 4 or
                        (len(tokens) == 7 and tokens[-1] in '01')):
                        atoms.append(tokens[0])
                        positions.append(array(tokens[1:4], dtype=float))
                        i += 1
                        tokens = lines[i].split()
                    #end while
                    conf.atoms = atoms
                    conf.positions = array(positions)
                    if 'crystal' in l.lower() and 'axes' in conf:
                        conf.positions = dot(conf.positions, conf.axes)
                    #end if
                    nconf = len(structures)
                    structures[nconf] = conf
                    cont = False
                #end if
                i += 1
            #end while
            if found:
                self.structures = structures
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('structure read failed')
            #end if
        #end try

        #begin added by Yubo "Paul" Yang: cell, stress, pressure and volume
        # 01/21/2016: grab cells in a vc-relax run, one at each optimization step
        # 09/29/2016: obselete after rev7131

        # grab stress, pressure and volume
        try:
            press = 0.
            vol = 0.
            for l in lines:
                if l.find('unit-cell volume') != -1:
                    #vol = float( l.split('=')[-1].split()[-2] )
                    vol = l.split('=')[-1].split()[-2]
                # end if
                if (l.find('total') != -1) and (l.find('stress') != -1):
                    press = l.split('=')[-1]
                # end if
            # end for
            self.pressure = float(press)
            self.volume = float(vol)
        except:
            nx += 1
            if self.info.warn:
                self.warn('pressure/volume read failed')
            #end if
        #end try

        try:
            stress = []
            nlines = len(lines)
            i = 0
            while i < nlines:
                l = lines[i]
                if l.find('total   stress') != -1:
                    for j in range(3):
                        i += 1
                        stress.append(
                            list(np.array(lines[i].split(), dtype=float)))
                    #end for
                #end if
                i += 1
            #end while
            self.stress = stress
        except:
            nx += 1
            if self.info.warn:
                self.warn('stress read failed')
            #end if
        #end try
        #end added by Yubo "Paul" Yang

        try:
            forces = []
            tot_forces = []
            i = 0
            found = False
            nlines = len(lines)
            while i < nlines:
                l = lines[i]
                if l.find('Forces acting on atoms') != -1:
                    found = True
                    conf = obj()
                    aforces = []
                    found_atom = False
                    for j in range(10):
                        i += 1
                        if i < nlines and 'atom' in lines[i]:
                            found_atom = True
                            break
                        #end if
                    #end for
                    if found_atom:
                        tokens = lines[i].split()
                        while len(tokens) == 9 and tokens[4] == 'force':
                            aforces.append(tokens[6:])
                            i += 1
                            tokens = lines[i].split()
                        #end while
                    #end if
                    forces.append(aforces)
                    i += 1
                elif 'Total force' in l:
                    tokens = l.split()
                    if len(tokens) == 9 and tokens[1] == 'force':
                        tot_forces.append(float(tokens[3]))
                    #end if
                #end if
                i += 1
            #end while
            if found:
                self.forces = array(forces, dtype=float)
                self.tot_forces = array(tot_forces)
                max_forces = []
                for f in self.forces:
                    if len(f.shape) == 2:
                        max_forces.append((sqrt((f**2).sum(1))).max())
                    #end if
                #end for
                self.max_forces = array(max_forces)
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('force read failed')
            #end if
        #end try

        try:
            tc = 0.
            tw = 0.
            for l in lines:
                if l.find('PWSCF        :') != -1:
                    t1 = l.split(':')[1].split('CPU')
                    tc = pwscf_time(t1[0])
                    tw = pwscf_time(t1[1].replace('WALL', ''))
                    break
                #end if
            #end for
            self.cputime = tc
            self.walltime = tw
        except:
            nx += 1
            if self.info.warn:
                self.warn('time read failed')
            #end if
        #end try

        try:
            # read symmetrized k-points
            nkpoints = None
            i = 0
            for l in lines:
                if 'number of k points' in l:
                    tokens = l.replace('=', ' ').split()
                    nkpoints = int(tokens[4])
                    break
                #end if
                i += 1
            #end for
            if nkpoints is not None:
                i += 2
                klines_cart = lines[i:i + nkpoints]
                i += nkpoints + 2
                klines_unit = lines[i:i + nkpoints]
                kpoints_cart = []
                for l in klines_cart:
                    tokens = l.replace('= (', ':').replace('), wk =',
                                                           ':').split(':')
                    kpoints_cart.append(tokens[1].split())
                #end for
                kpoints_unit = []
                kweights = []
                for l in klines_unit:
                    tokens = l.replace('= (', ':').replace('), wk =',
                                                           ':').split(':')
                    kpoints_unit.append(tokens[1].split())
                    kweights.append(tokens[2])
                #end for
                self.kpoints_cart = array(kpoints_cart, dtype=float)
                self.kpoints_unit = array(kpoints_unit, dtype=float)
                self.kweights = array(kweights, dtype=float)
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('symmetrized kpoint read failed')
            #end if
        #end try

        try:
            if pw2c_outfile_name != None:
                lines = open(os.path.join(path, pw2c_outfile_name),
                             'r').readlines()
                for l in lines:
                    if l.find('Kinetic') != -1:
                        tokens = l.split()
                        self.K = eval(tokens[5])
                        break
                    #end if
                #end for
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('pw2casino read failed')
            #end if
        #end try

        if nx > 0 and self.info.warn:
            self.warn(
                'encountered an exception, some quantities will not be available'
            )
        #end try

        if self.info.xml:
            self.xmldata = obj(data=None, kpoints=None, failed=False)
            try:
                cont = self.input.control
                datadir = os.path.join(self.path, cont.outdir,
                                       cont.prefix + '.save')
                data_file = os.path.join(datadir, 'data-file.xml')
                if not os.path.exists(data_file):
                    datadir = os.path.join(self.path, cont.outdir)
                    data_file = os.path.join(datadir, cont.prefix + '.xml')
                #end if
                data = read_qexml(data_file)
                kpdata = data.root.eigenvalues.k_point
                kpoints = obj()
                for ki, kpd in kpdata.items():
                    kp = obj(kpoint=kpd.k_point_coords, weight=kpd.weight)
                    kpoints[ki] = kp
                    for si, dfile in kpd.datafile.items():
                        efilepath = os.path.join(datadir, dfile.iotk_link)
                        if os.path.exists(efilepath):
                            edata = read_qexml(efilepath)
                            eunits = edata.root.units_for_energies.units.lower(
                            )
                            if eunits.startswith('ha'):
                                units = 'Ha'
                            elif eunits.startswith('ry'):
                                units = 'Ry'
                            elif eunits.startswith('ev'):
                                units = 'eV'
                            else:
                                units = 'Ha'
                            #end if
                            spin = obj(units=units,
                                       eigenvalues=edata.root.eigenvalues,
                                       occupations=edata.root.occupations)
                            if si == 1:
                                kp.up = spin
                            elif si == 2:
                                kp.down = spin
                            #end if
                        else:
                            self.xmldata.failed = True
                        #end if
                    #end for
                #end for
                self.xmldata.set(data=data, kpoints=kpoints)
            except Exception as e:
                if self.info.warn:
                    self.warn(
                        'encountered an exception during xml read, this data will not be available\nexception encountered: '
                        + str(e))
                #end if
                self.xmldata.failed = True
Esempio n. 2
0
    def analyze(self):
        path = self.path
        infile_name = self.infile_name
        outfile_name = self.outfile_name
        pw2c_outfile_name = self.pw2c_outfile_name

        nx = 0

        try:
            lines = open(os.path.join(path, outfile_name),
                         'r').read().splitlines()
        except:
            nx += 1
            if self.info.warn:
                self.warn('file read failed')
            #end if
        #end try

        try:
            energies = []
            for l in lines:
                if l.find('!  ') != -1:
                    energies.append(eval(l.split('=')[1].split()[0]))
                #end if
            #end for
            if len(energies) == 0:
                self.E = 0.0
            else:
                self.E = energies[-1]
            #end if
            self.energies = array(energies)
        except:
            nx += 1
            if self.info.warn:
                self.warn('energy read failed')
            #end if
        #end try

        try:
            # get bands and occupations
            nfound = 0
            bands = obj()
            for i in xrange(len(lines)):
                l = lines[i]
                if 'bands (ev)' in l:
                    nfound += 1
                    i_occ = -1
                    j = i
                    while i_occ == -1:
                        j += 1
                        if 'occupation numbers' in lines[j]:
                            i_occ = j
                        #end if
                    #end while
                    seigs = ''
                    for j in range(i + 1, i_occ):
                        seigs += lines[j]
                    #end for
                    seigs = seigs.strip()
                    eigs = array(seigs.split(), dtype=float)

                    soccs = ''
                    for j in range(i_occ + 1, i_occ + 1 + (i_occ - i) - 2):
                        soccs += lines[j]
                    #end for
                    occs = array(soccs.split(), dtype=float)

                    if nfound == 1:
                        bands.up = obj(eigs=eigs, occs=occs)
                    elif nfound == 2:
                        bands.down = obj(eigs=eigs, occs=occs)
                    #end if
                #end if
            #end for
            if nfound > 0:
                self.bands = bands
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('band read failed')
            #end if
        #end try

        try:
            # read structures
            structures = obj()
            i = 0
            found = False
            cont = False
            while i < len(lines):
                l = lines[i]
                if l.find('CELL_PARAMETERS') != -1 and l.strip().startswith(
                        'CELL'):
                    conf = obj()
                    axes = []
                    cont = True
                    for d in (0, 1, 2):
                        i += 1
                        axes.append(array(lines[i].split(), dtype=float))
                    #end for
                    conf.axes = array(axes)
                #end if
                if l.find('ATOMIC_POSITIONS') != -1:
                    found = True
                    if not cont:
                        conf = obj()
                    #end if
                    atoms = []
                    positions = []
                    i += 1
                    tokens = lines[i].split()

                    while len(tokens) > 0 and tokens[0].lower() != 'end' and (
                            len(tokens) == 4 or
                        (len(tokens) == 7 and tokens[-1] in '01')):
                        atoms.append(tokens[0])
                        positions.append(array(tokens[1:4], dtype=float))
                        i += 1
                        tokens = lines[i].split()
                    #end while
                    conf.atoms = atoms
                    conf.positions = array(positions)
                    if 'crystal' in l.lower() and 'axes' in conf:
                        conf.positions = dot(conf.positions, conf.axes)
                    #end if
                    nconf = len(structures)
                    structures[nconf] = conf
                    cont = False
                #end if
                i += 1
            #end while
            if found:
                self.structures = structures
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('structure read failed')
            #end if
        #end try

        #begin added by Yubo "Paul" Yang: cell, stress, pressure and volume
        # 01/21/2016: grab cells in a vc-relax run, one at each optimization step
        # 09/29/2016: obselete after rev7131

        # grab stress, pressure and volume
        try:
            press = 0.
            vol = 0.
            for l in lines:
                if l.find('unit-cell volume') != -1:
                    #vol = float( l.split('=')[-1].split()[-2] )
                    vol = l.split('=')[-1].split()[-2]
                # end if
                if (l.find('total') != -1) and (l.find('stress') != -1):
                    press = l.split('=')[-1]
                # end if
            # end for
            self.pressure = float(press)
            self.volume = float(vol)
        except:
            nx += 1
            if self.info.warn:
                self.warn('pressure/volume read failed')
            #end if
        #end try

        try:
            stress = []
            nlines = len(lines)
            i = 0
            while i < nlines:
                l = lines[i]
                if l.find('total   stress') != -1:
                    for j in range(3):
                        i += 1
                        tokens = lines[i].split()
                        stress.append(map(float, tokens))
                    # end for j
                # end found
                i += 1
            # end while
            self.stress = stress
        except:
            nx += 1
            if self.info.warn:
                self.warn('stress read failed')
            #end if
        #end
        #end added by Yubo "Paul" Yang

        try:
            forces = []
            tot_forces = []
            i = 0
            found = False
            nlines = len(lines)
            while i < nlines:
                l = lines[i]
                if l.find('Forces acting on atoms') != -1:
                    found = True
                    conf = obj()
                    aforces = []
                    found_atom = False
                    for j in range(10):
                        i += 1
                        if i < nlines and 'atom' in lines[i]:
                            found_atom = True
                            break
                        #end if
                    #end for
                    if found_atom:
                        tokens = lines[i].split()
                        while len(tokens) == 9 and tokens[4] == 'force':
                            aforces.append(tokens[6:])
                            i += 1
                            tokens = lines[i].split()
                        #end while
                    #end if
                    forces.append(aforces)
                    i += 1
                    if i < nlines:
                        tokens = lines[i].split()
                        if len(tokens) == 9 and tokens[1] == 'force':
                            tot_forces.append(float(tokens[3]))
                        #end if
                    #end if
                #end if
                i += 1
            #end while
            if found:
                self.forces = array(forces, dtype=float)
                self.tot_forces = array(tot_forces)
                max_forces = []
                for f in self.forces:
                    if len(f.shape) == 2:
                        max_forces.append((sqrt((f**2).sum(1))).max())
                    #end if
                #end for
                self.max_forces = array(max_forces)
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('force read failed')
            #end if
        #end try

        try:
            tc = 0.
            tw = 0.
            for l in lines:
                if l.find('PWSCF        :') != -1:
                    t1 = l.split(':')[1].split('CPU')
                    tc = pwscf_time(t1[0])
                    tw = pwscf_time(t1[1].replace('WALL', ''))
                    break
                #end if
            #end for
            self.cputime = tc
            self.walltime = tw
        except:
            nx += 1
            if self.info.warn:
                self.warn('time read failed')
            #end if
        #end try

        try:
            # read symmetrized k-points
            nkpoints = None
            i = 0
            for l in lines:
                if 'number of k points' in l:
                    tokens = l.replace('=', ' ').split()
                    nkpoints = int(tokens[4])
                    break
                #end if
                i += 1
            #end for
            if nkpoints is not None:
                i += 2
                klines_cart = lines[i:i + nkpoints]
                i += nkpoints + 2
                klines_unit = lines[i:i + nkpoints]
                kpoints_cart = []
                for l in klines_cart:
                    tokens = l.replace('= (', ':').replace('), wk =',
                                                           ':').split(':')
                    kpoints_cart.append(tokens[1].split())
                #end for
                kpoints_unit = []
                kweights = []
                for l in klines_unit:
                    tokens = l.replace('= (', ':').replace('), wk =',
                                                           ':').split(':')
                    kpoints_unit.append(tokens[1].split())
                    kweights.append(tokens[2])
                #end for
                self.kpoints_cart = array(kpoints_cart, dtype=float)
                self.kpoints_unit = array(kpoints_unit, dtype=float)
                self.kweights = array(kweights, dtype=float)
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('symmetrized kpoint read failed')
            #end if
        #end try

        try:
            if pw2c_outfile_name != None:
                lines = open(os.path.join(path, pw2c_outfile_name),
                             'r').readlines()
                for l in lines:
                    if l.find('Kinetic') != -1:
                        tokens = l.split()
                        self.K = eval(tokens[5])
                        break
                    #end if
                #end for
            #end if
        except:
            nx += 1
            if self.info.warn:
                self.warn('pw2casino read failed')
            #end if
        #end try

        if nx > 0 and self.info.warn:
            self.warn(
                'encountered an exception, some quantities will not be available'
            )
        #end try

        if self.info.xml:
            self.xmldata = obj(data=None, kpoints=None, failed=False)
            try:
                cont = self.input.control
                datadir = os.path.join(self.path, cont.outdir,
                                       cont.prefix + '.save')
                data = read_qexml(os.path.join(datadir, 'data-file.xml'))
                kpdata = data.root.eigenvalues.k_point
                kpoints = obj()
                for ki, kpd in kpdata.iteritems():
                    kp = obj(kpoint=kpd.k_point_coords, weight=kpd.weight)
                    kpoints[ki] = kp
                    for si, dfile in kpd.datafile.iteritems():
                        efilepath = os.path.join(datadir, dfile.iotk_link)
                        if os.path.exists(efilepath):
                            edata = read_qexml(efilepath)
                            eunits = edata.root.units_for_energies.units.lower(
                            )
                            if eunits.startswith('ha'):
                                units = 'Ha'
                            elif eunits.startswith('ry'):
                                units = 'Ry'
                            elif eunits.startswith('ev'):
                                units = 'eV'
                            else:
                                units = 'Ha'
                            #end if
                            spin = obj(units=units,
                                       eigenvalues=edata.root.eigenvalues,
                                       occupations=edata.root.occupations)
                            if si == 1:
                                kp.up = spin
                            elif si == 2:
                                kp.down = spin
                            #end if
                        else:
                            self.xmldata.failed = True
                        #end if
                    #end for
                #end for
                self.xmldata.set(data=data, kpoints=kpoints)
            except Exception, e:
                if self.info.warn:
                    self.warn(
                        'encountered an exception during xml read, this data will not be available\nexception encountered: '
                        + str(e))
                #end if
                self.xmldata.failed = True
Esempio n. 3
0
    def analyze(self):
        try:
            path = self.path
            infile_name = self.infile_name
            outfile_name = self.outfile_name
            pw2c_outfile_name = self.pw2c_outfile_name

            lines = open(os.path.join(path,outfile_name),'r').read().splitlines()

            energies = []
            for l in lines:
                if l.find('!  ')!=-1:
                    energies.append( eval( l.split('=')[1].split()[0] ) )
                #end if
            #end for
            if len(energies)==0:
                self.E = 0.0
            else:
                self.E = energies[-1]
            #end if
            self.energies = array(energies)

            # get bands and occupations
            nfound = 0
            bands = obj()
            for i in range(len(lines)):
                l = lines[i]
                if 'bands (ev)' in l:
                    nfound+=1
                    i_occ = -1
                    j = i
                    while i_occ==-1:
                        j+=1
                        if 'occupation numbers' in lines[j]:
                            i_occ = j
                        #end if
                    #end while
                    try:
                        seigs = ''
                        for j in range(i+1,i_occ):
                            seigs+=lines[j]
                        #end for
                        seigs = seigs.strip()
                        eigs = array(seigs.split(),dtype=float)

                        soccs = ''
                        for j in range(i_occ+1,i_occ+1+(i_occ-i)-2):
                            soccs+= lines[j]
                        #end for
                        occs = array(soccs.split(),dtype=float)
                    except Exception:
                        eigs = array([])
                        occs = array([])
                        if self.info.warn:
                            self.warn('band read failed, line: '+l)
                        #end if
                    #end try
                    

                    if nfound==1:
                        bands.up = obj(
                            eigs = eigs,
                            occs = occs
                            )
                    elif nfound==2:
                        bands.down = obj(
                            eigs = eigs,
                            occs = occs
                            )
                    #end if
                #end if
                #try:
                #    seigs = ''
                #    for j in range(i+1,i_occ):
                #        seigs+=lines[j]
                #    #end for
                #    seigs = seigs.strip()
                #    eigs = array(seigs.split(),dtype=float)
                #
                #    soccs = ''
                #    for j in range(i_occ+1,i_occ+1+(i_occ-i)-2):
                #        soccs+= lines[j]
                #    #end for
                #    occs = array(soccs.split(),dtype=float)
                #except Exception:
                #    eigs = array([])
                #    occs = array([])
                ##end try

                if nfound==1:
                    bands.up = obj(
                        eigs = eigs,
                        occs = occs
                        )
                elif nfound==2:
                    bands.down = obj(
                        eigs = eigs,
                        occs = occs
                        )
                #end if
            #end for
            if nfound>0:
                self.bands = bands
            #end if


            structures = obj()
            i=0
            found = False
            while i<len(lines):
                l = lines[i]
                if l.find('ATOMIC_POSITIONS')!=-1:
                    found = True
                    conf = obj()
                    atoms = []
                    positions = []
                    i+=1
                    tokens = lines[i].split()

                    while len(tokens)>0 and tokens[0] in elements and (len(tokens)==4 or (len(tokens)==7 and tokens[-1] in '01')):
                        atoms.append(tokens[0])
                        positions.append(array(tokens[1:4],dtype=float))
                        i+=1
                        tokens = lines[i].split()
                    #end while
                    conf.atoms = atoms
                    conf.positions = array(positions)
                    nconf = len(structures)
                    structures[nconf]=conf
                #end if
                i+=1
            #end while
            if found:
                self.structures = structures
            #end if

            forces = []
            tot_forces = []
            i=0
            found = False
            nlines = len(lines)
            while i<nlines:
                l = lines[i]
                if l.find('Forces acting on atoms')!=-1:
                    found = True
                    conf = obj()
                    aforces = []
                    found_atom = False
                    for j in range(10):
                        i+=1
                        if i<nlines and 'atom' in lines[i]:
                            found_atom = True
                            break
                        #end if
                    #end for
                    if found_atom:
                        tokens = lines[i].split()
                        while len(tokens)==9 and tokens[4]=='force':
                            aforces.append(tokens[6:])
                            i+=1
                            tokens = lines[i].split()
                        #end while
                    #end if
                    forces.append(aforces)
                    i+=1
                    if i<nlines:
                        tokens = lines[i].split()
                        if len(tokens)==9 and tokens[1]=='force':
                            tot_forces.append(float(tokens[3]))
                        #end if
                    #end if
                #end if
                i+=1
            #end while
            if found:
                self.forces = array(forces,dtype=float)
                self.tot_forces = array(tot_forces)
                max_forces = []
                for f in self.forces:
                    if len(f.shape)==2:
                        max_forces.append((sqrt((f**2).sum(1))).max())
                    #end if
                #end for
                self.max_forces = array(max_forces)
            #end if

            tc= 0.
            tw= 0.
            for l in lines:
                if l.find('PWSCF        :')!=-1:
                    t1 = l.split(':')[1].split('CPU')
                    tc = pwscf_time(t1[0])
                    tw = pwscf_time(t1[1].replace('WALL',''))
                    break
                #end if
            #end for
            self.cputime = tc
            self.walltime= tw

            if pw2c_outfile_name!=None:
                lines = open(os.path.join(path,pw2c_outfile_name),'r').readlines()
                for l in lines:
                    if l.find('Kinetic')!=-1:
                        tokens = l.split()
                        self.K = eval(tokens[5])
                        break
                    #end if
                #end for
            #end if        
        except Exception:
            self.warn('encountered an exception, some quantities will not be available')
        #end try

        if self.info.xml:
            self.xmldata = obj(
                data    = None,
                kpoints = None,
                failed  = False
                )
            try:
                cont = self.input.control
                datadir = os.path.join(self.path,cont.outdir,cont.prefix+'.save')
                data = read_qexml(os.path.join(datadir,'data-file.xml'))
                kpdata = data.root.eigenvalues.k_point
                kpoints = obj()
                for ki,kpd in kpdata.iteritems():
                    kp = obj(
                        kpoint = kpd.k_point_coords,
                        weight = kpd.weight
                        )
                    kpoints[ki]=kp
                    for si,dfile in kpd.datafile.iteritems():
                        efilepath = os.path.join(datadir,dfile.iotk_link)
                        if os.path.exists(efilepath):
                            edata = read_qexml(efilepath)
                            eunits = edata.root.units_for_energies.units.lower()
                            if eunits.startswith('ha'):
                                units = 'Ha'
                            elif eunits.startswith('ry'):
                                units = 'Ry'
                            elif eunits.startswith('ev'):
                                units = 'eV'
                            else:
                                units = 'Ha'
                            #end if
                            spin = obj(
                                units       = units,
                                eigenvalues = edata.root.eigenvalues,
                                occupations = edata.root.occupations
                                )
                            if si==1:
                                kp.up = spin
                            elif si==2:
                                kp.down = spin
                            #end if
                        else:
                            self.xmldata.failed = True
                        #end if
                    #end for
                #end for
                self.xmldata.set(
                    data    = data,
                    kpoints = kpoints
                    )
            except Exception,e:
                self.warn('encountered an exception during xml read, this data will not be available\nexception encountered: '+str(e))
                self.xmldata.failed = True
Esempio n. 4
0
    def analyze(self):
        path = self.path
        infile_name = self.infile_name
        outfile_name = self.outfile_name
        pw2c_outfile_name = self.pw2c_outfile_name

        nx=0

        try:
            lines = open(os.path.join(path,outfile_name),'r').read().splitlines()
        except:
            nx+=1
            if self.info.warn:
                self.warn('file read failed')
            #end if
        #end try

        try:
            energies = []
            for l in lines:
                if l.find('!  ')!=-1:
                    energies.append( eval( l.split('=')[1].split()[0] ) )
                #end if
            #end for
            if len(energies)==0:
                self.E = 0.0
            else:
                self.E = energies[-1]
            #end if
            self.energies = array(energies)
        except:
            nx+=1
            if self.info.warn:
                self.warn('energy read failed')
            #end if
        #end try
        try:
            # get bands and occupations
            nfound = 0
            index = -1
            bands = obj()
            bands.up = []
            bands.down = []
            polarized = False
            if self.input.system.nspin > 1:
                polarized = True
            #end if
            read_kpoints  = False
            read_2pi_alat = False
            read_rel      = False
            for i in xrange(len(lines)):
                l = lines[i]
                if '- SPIN UP -' in l:
                    up_spin   = True
                elif '- SPIN DOWN -' in l:
                    up_spin   = False
                    index = -1
                #end if
                              
                if 'number of k points=' in l:
                    try:
                        num_kpoints      = int(l.strip().split()[4])
                    except:
                        print "Number of k-points {0} is not an integer".format(num_kpoints)

                    kpoints_2pi_alat = lines[i+2:i+2+num_kpoints]
                    kpoints_rel      = lines[i+4+num_kpoints:i+4+2*num_kpoints]
                    kpoints_2pi_alat = array([k.strip().split()[4:6] + [k.strip().split()[6][0:-2]] for k in kpoints_2pi_alat], dtype=float)
                    kpoints_rel      = array([k.strip().split()[4:6] + [k.strip().split()[6][0:-2]] for k in kpoints_rel], dtype=float)
                #end if
                if 'bands (ev)' in l:
                    index+=1
                    nfound+=1
                    i_occ = -1
                    j = i
                    while i_occ==-1:
                        j+=1
                        if 'occupation numbers' in lines[j]:
                            i_occ = j
                        #end if
                    #end while
                    seigs = ''
                    for j in range(i+1,i_occ):
                        seigs+=lines[j]
                    #end for
                    seigs = seigs.strip()
                    eigs = array(seigs.split(),dtype=float)

                    soccs = ''
                    for j in range(i_occ+1,i_occ+1+(i_occ-i)-2):
                        soccs+= lines[j]
                    #end for
                    occs   = array(soccs.split(),dtype=float)
                    if polarized:                  
                        if up_spin:
                            bands.up.append({'index':index, 'kpoint_2pi_alat':kpoints_2pi_alat[index], 'kpoint_rel':kpoints_rel[index], 'eigs':eigs, 'occs':occs, 'pol':'up'})
                        elif not up_spin:
                            bands.down.append({'index':index, 'kpoint_2pi_alat':kpoints_2pi_alat[index], 'kpoint_rel':kpoints_rel[index], 'eigs':eigs, 'occs':occs, 'pol':'up'})
                        #end if
                    else:
                        index = nfound -1 
                        bands.up.append({'index':index, 'kpoint_2pi_alat':kpoints_2pi_alat[index], 'kpoint_rel':kpoints_rel[index], 'eigs':eigs, 'occs':occs, 'pol':'none'})
                    #if nfound==1:
                    #    bands.up = obj(
                    #        eigs = eigs,
                    #        occs = occs
                    #        )
                    #elif nfound==2:
                    #    bands.down = obj(
                    #        eigs = eigs,
                    #        occs = occs
                    #        )
                    #end if
                #end if
            #end for
            vbm        = obj(energy=-1.0e6)
            cbm        = obj(energy=1.0e6)
            direct_gap = obj(energy=1.0e6)
            for b in bands.up + bands.down:
                e_val  = max(b['eigs'][b['occs'] > 0.5])
                e_cond = min(b['eigs'][b['occs'] < 0.5])
                                              
                if e_val > vbm.energy:
                    vbm.energy          = e_val
                    vbm.kpoint_rel      = b['kpoint_rel']
                    vbm.kpoint_2pi_alat = b['kpoint_2pi_alat']
                    vbm.index           = b['index']
                    vbm.pol             = b['pol']
                    vbm.band_number     = max(where(b['occs'] > 0.5))
                #end if
                if e_cond < cbm.energy:
                    cbm.energy          = e_cond
                    cbm.kpoint_rel      = b['kpoint_rel']
                    cbm.kpoint_2pi_alat = b['kpoint_2pi_alat']
                    cbm.index           = b['index']
                    cbm.pol             = b['pol']
                    cbm.band_number     = min(where(b['occs'] < 0.5))
                #end if
                if (e_cond - e_val) < direct_gap.energy:
                    direct_gap.energy          = e_cond - e_val
                    direct_gap.kpoint_rel      = b['kpoint_rel']
                    direct_gap.kpoint_2pi_alat = b['kpoint_2pi_alat']
                    direct_gap.index           = b['index']
                    direct_gap.pol             = [vbm.pol, cbm.pol]
                #end if
            #end for
            electronic_structure = ''
            if (vbm.energy +0.025) >= cbm.energy:
                if vbm.band_number == cbm.band_number:
                    electronic_structure = 'metallic'
                else:
                    electronic_structure = 'semi-metal'
                #end if
            else:
                electronic_structure = 'insulating'
                if not equal(vbm.kpoint_rel, cbm.kpoint_rel).all():
                    indirect_gap = obj(energy=round(cbm.energy-vbm.energy, 3), kpoints=obj(vbm=vbm, cbm=cbm))
                    bands.indirect_gap = indirect_gap
            #end if
            bands.electronic_structure = electronic_structure
            bands.vbm = vbm
            bands.cbm = cbm
            bands.direct_gap = direct_gap
            if nfound>0:
                self.bands = bands
            #end if
            # Kayahan edited --end
        except:
            nx+=1
            if self.info.warn:
                self.warn('band read failed')
            #end if
        #end try

        try:
            # read structures
            structures = obj()
            i=0
            found = False
            cont  = False
            while i<len(lines):
                l = lines[i]
                if l.find('CELL_PARAMETERS')!=-1 and l.strip().startswith('CELL'):
                    conf = obj()
                    axes = []
                    cont = True
                    for d in (0,1,2):
                        i+=1
                        axes.append(array(lines[i].split(),dtype=float))
                    #end for
                    conf.axes = array(axes)
                #end if
                if l.find('ATOMIC_POSITIONS')!=-1:
                    found = True
                    if not cont:
                        conf = obj()
                    #end if
                    atoms = []
                    positions = []
                    i+=1
                    tokens = lines[i].split()

                    while len(tokens)>0 and tokens[0].lower()!='end' and (len(tokens)==4 or (len(tokens)==7 and tokens[-1] in '01')):
                        atoms.append(tokens[0])
                        positions.append(array(tokens[1:4],dtype=float))
                        i+=1
                        tokens = lines[i].split()
                    #end while
                    conf.atoms = atoms
                    conf.positions = array(positions)
                    if 'crystal' in l.lower() and 'axes' in conf:
                        conf.positions = dot(conf.positions,conf.axes)
                    #end if
                    nconf = len(structures)
                    structures[nconf]=conf
                    cont = False
                #end if
                i+=1
            #end while
            if found:
                self.structures = structures
            #end if
        except:
            nx+=1
            if self.info.warn:
                self.warn('structure read failed')
            #end if
        #end try

        #begin added by Yubo "Paul" Yang: cell, stress, pressure and volume
        # 01/21/2016: grab cells in a vc-relax run, one at each optimization step
        # 09/29/2016: obselete after rev7131

        # grab stress, pressure and volume
        try:
            press= 0.
            vol=   0.
            for l in lines:
                if l.find('unit-cell volume')!=-1:
                    #vol = float( l.split('=')[-1].split()[-2] )
                    vol = l.split('=')[-1].split()[-2]
                # end if
                if (l.find('total')!=-1) and (l.find('stress')!=-1):
                    press= l.split('=')[-1]
                # end if
            # end for
            self.pressure = float(press)
            self.volume   = float(vol)
        except:
            nx+=1
            if self.info.warn:
                self.warn('pressure/volume read failed')
            #end if
        #end try

        try:
            stress = []
            nlines = len(lines)
            i=0
            while i<nlines:
                l = lines[i]
                if l.find('total   stress')!=-1:
                    for j in range(3):
                        i+=1
                        tokens = lines[i].split()
                        stress.append(map(float,tokens))
                    # end for j
                # end found
                i += 1
            # end while
            self.stress=stress
        except:
            nx+=1
            if self.info.warn:
                self.warn('stress read failed')
            #end if
        #end
        #end added by Yubo "Paul" Yang

        try:
            forces = []
            tot_forces = []
            i=0
            found = False
            nlines = len(lines)
            while i<nlines:
                l = lines[i]
                if l.find('Forces acting on atoms')!=-1:
                    found = True
                    conf = obj()
                    aforces = []
                    found_atom = False
                    for j in range(10):
                        i+=1
                        if i<nlines and 'atom' in lines[i]:
                            found_atom = True
                            break
                        #end if
                    #end for
                    if found_atom:
                        tokens = lines[i].split()
                        while len(tokens)==9 and tokens[4]=='force':
                            aforces.append(tokens[6:])
                            i+=1
                            tokens = lines[i].split()
                        #end while
                    #end if
                    forces.append(aforces)
                    i+=1
                    if i<nlines:
                        tokens = lines[i].split()
                        if len(tokens)==9 and tokens[1]=='force':
                            tot_forces.append(float(tokens[3]))
                        #end if
                    #end if
                #end if
                i+=1
            #end while
            if found:
                self.forces = array(forces,dtype=float)
                self.tot_forces = array(tot_forces)
                max_forces = []
                for f in self.forces:
                    if len(f.shape)==2:
                        max_forces.append((sqrt((f**2).sum(1))).max())
                    #end if
                #end for
                self.max_forces = array(max_forces)
            #end if
        except:
            nx+=1
            if self.info.warn:
                self.warn('force read failed')
            #end if
        #end try

        try:
            tc= 0.
            tw= 0.
            for l in lines:
                if l.find('PWSCF        :')!=-1:
                    t1 = l.split(':')[1].split('CPU')
                    tc = pwscf_time(t1[0])
                    tw = pwscf_time(t1[1].replace('WALL',''))
                    break
                #end if
            #end for
            self.cputime = tc
            self.walltime= tw
        except:
            nx+=1
            if self.info.warn:
                self.warn('time read failed')
            #end if
        #end try


        try:
            # read symmetrized k-points
            nkpoints = None
            i=0
            for l in lines:
                if 'number of k points' in l:
                    tokens = l.replace('=',' ').split()
                    nkpoints = int(tokens[4])
                    break
                #end if
                i+=1
            #end for
            if nkpoints is not None:
                i+=2
                klines_cart = lines[i:i+nkpoints]
                i+=nkpoints+2
                klines_unit = lines[i:i+nkpoints]
                kpoints_cart = []
                for l in klines_cart:
                    tokens = l.replace('= (',':').replace('), wk =',':').split(':')
                    kpoints_cart.append(tokens[1].split())
                #end for
                kpoints_unit = []
                kweights = []
                for l in klines_unit:
                    tokens = l.replace('= (',':').replace('), wk =',':').split(':')
                    kpoints_unit.append(tokens[1].split())
                    kweights.append(tokens[2])
                #end for
                self.kpoints_cart = array(kpoints_cart,dtype=float)
                self.kpoints_unit = array(kpoints_unit,dtype=float)
                self.kweights     = array(kweights,dtype=float)
            #end if
        except:
            nx+=1
            if self.info.warn:
                self.warn('symmetrized kpoint read failed')
            #end if
        #end try
            

        try:
            if pw2c_outfile_name!=None:
                lines = open(os.path.join(path,pw2c_outfile_name),'r').readlines()
                for l in lines:
                    if l.find('Kinetic')!=-1:
                        tokens = l.split()
                        self.K = eval(tokens[5])
                        break
                    #end if
                #end for
            #end if        
        except:
            nx+=1
            if self.info.warn:
                self.warn('pw2casino read failed')
            #end if
        #end try

        if nx>0 and self.info.warn:
            self.warn('encountered an exception, some quantities will not be available')
        #end try

        if self.info.xml:
            self.xmldata = obj(
                data    = None,
                kpoints = None,
                failed  = False
                )
            try:
                cont = self.input.control
                datadir = os.path.join(self.path,cont.outdir,cont.prefix+'.save')
                data = read_qexml(os.path.join(datadir,'data-file.xml'))
                kpdata = data.root.eigenvalues.k_point
                kpoints = obj()
                for ki,kpd in kpdata.iteritems():
                    kp = obj(
                        kpoint = kpd.k_point_coords,
                        weight = kpd.weight
                        )
                    kpoints[ki]=kp
                    for si,dfile in kpd.datafile.iteritems():
                        efilepath = os.path.join(datadir,dfile.iotk_link)
                        if os.path.exists(efilepath):
                            edata = read_qexml(efilepath)
                            eunits = edata.root.units_for_energies.units.lower()
                            if eunits.startswith('ha'):
                                units = 'Ha'
                            elif eunits.startswith('ry'):
                                units = 'Ry'
                            elif eunits.startswith('ev'):
                                units = 'eV'
                            else:
                                units = 'Ha'
                            #end if
                            spin = obj(
                                units       = units,
                                eigenvalues = edata.root.eigenvalues,
                                occupations = edata.root.occupations
                                )
                            if si==1:
                                kp.up = spin
                            elif si==2:
                                kp.down = spin
                            #end if
                        else:
                            self.xmldata.failed = True
                        #end if
                    #end for
                #end for
                self.xmldata.set(
                    data    = data,
                    kpoints = kpoints
                    )
            except Exception,e:
                if self.info.warn:
                    self.warn('encountered an exception during xml read, this data will not be available\nexception encountered: '+str(e))
                #end if
                self.xmldata.failed = True