Beispiel #1
0
 def analyze(self, guard=True):
     if not self.initialized:
         return
     #end if
     log_filepath = os.path.join(self.path, self.outfile_name)
     if not os.path.exists(log_filepath):
         self.error(
             'RMG analysis cannot be completed.\nLog file does not exist at path provided.\nPath provided: {}'
             .format(log_filepath))
     #end if
     logfile = TextFile(log_filepath)
     self.setup_info = obj()
     self.results = obj()
     if guard:
         try:
             self.read_setup_info(logfile)
         except:
             None
         #end try
         try:
             self.read_results(logfile)
         except:
             None
         #end try
     else:
         self.read_setup_info(logfile)
         self.read_results(logfile)
Beispiel #2
0
 def read(self, filepath=None):
     if filepath is None:
         filepath = self.location
     #end if
     if not os.path.exists(filepath):
         self.error('file does not exist: {0}'.format(filepath))
     #end if
     file = TextFile(filepath)
     self.read_file(file)
Beispiel #3
0
 def get_output(self, filetag):
     filename = self.info.files[filetag]
     outfile = os.path.join(self.info.path, filename)
     if os.path.exists(outfile):
         filepath = outfile
     elif os.path.exists(filename):
         filepath = filename
     elif self.info.exit:
         self.error(
             'output file does not exist at either of the locations below:\n  {0}\n  {1}'
             .format(outfile, filename))
     else:
         return None
     #end if
     try:
         return TextFile(filepath)
     except:
         return None
Beispiel #4
0
def test_textfile():
    from fileio import TextFile

    files = get_files()

    # test empty initialization
    empty = TextFile()

    # test read
    f = TextFile(files['scf.in'])

    assert(len(f.read())==1225)
    assert(len(f.lines())==55)
    assert(len(f.tokens())==125)

    assert(f.readline()=='&CONTROL\n')
    assert(f.readline()=="   calculation     = 'scf'\n")

    assert(f.readline('celldm')=='celldm(1)       = 1.0\n')

    assert(f.readtokens('ecutwfc')==['ecutwfc', '=', '272'])

    val = f.readtokensf('CELL_PARAMETERS',float,float,float)
    ref = [28.34589199, 0.0, 0.0]
    assert(value_eq(val,ref))

    f.close()
Beispiel #5
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
 def open_log(self):
     logfile = os.path.join(self.info.path, self.info.outfile)
     self.log = TextFile(logfile)