Esempio n. 1
0
def parse_scf_conv(scf_out):
    from qharv.reel import ascii_out
    mm = ascii_out.read(scf_out)

    idxl = ascii_out.all_lines_with_tag(mm, 'iteration #')
    data = []
    for idx in idxl:
        mm.seek(idx)

        # read iteration number
        iternow = ascii_out.name_sep_val(mm, 'iteration', sep='#', dtype=int)

        # find total energy and other info (!!!! must be in order)
        try:
            time = ascii_out.name_sep_val(mm,
                                          'cpu time spent up to now',
                                          sep='is')
            enow = ascii_out.name_sep_val(mm, 'total energy')
        except:
            continue

        entry = {'istep': iternow, 'energy': enow, 'time': time}
        data.append(entry)

    return data
Esempio n. 2
0
def get_dsk_amat(floc):                                                         
  """ extract A matrix from qmcfinitesize output
  k->0 behavior of 3D structure factor S(k) is fitted to a Gaussian 
  S(k) = k^T A k

  Args:
    floc (str): location of qmcfinitesize output
  Returns:
    np.array: A matrix (3x3)
  """
  mm = ascii_out.read(floc)                                                     
                                                                                
  amat = np.zeros([3,3])                                                        
                                                                                
  # step 1: fill upper triangular part of amat                                  
  xyzm = {'x':0,'y':1,'z':2}  # map x,y,z to index                              
  keyl = ['a_xx','a_yy','a_zz','a_xy','a_xz','a_yz']                            
  for key in keyl:  # order of key matters!                                     
    val = ascii_out.name_sep_val(mm,key)                                        
    xyz_xyz = key.split('_')[-1]                                                
    idx = tuple([xyzm[xyz] for xyz in xyz_xyz])                                 
    amat[idx] = val                                                             
  # end for                                                                     
                                                                                
  # step 2: symmetrize amat                                                     
  amat[(1,0)] = amat[(0,1)]                                                     
  amat[(2,1)] = amat[(1,2)]                                                     
  amat[(2,0)] = amat[(0,2)]                                                     
                                                                                
  return amat                                                                   
Esempio n. 3
0
def read_kpoints(scf_out):
    from qharv.reel import ascii_out
    mm = ascii_out.read(scf_out)

    # get lattice units
    alat = ascii_out.name_sep_val(mm, 'lattice parameter (alat)')
    blat = 2 * np.pi / alat

    # start parsing k points
    idx = mm.find(b'number of k points')
    mm.seek(idx)

    # read first line
    #  e.g. number of k points=    32  Fermi-Dirac smearing ...
    line = mm.readline().decode()
    nk = int(line.split('=')[1].split()[0])

    # confirm units in second line
    line = mm.readline().decode()
    assert '2pi/alat' in line

    # start parsing kvectors
    data = np.zeros([nk, 4])  # ik, kx, ky, kz, wk
    for ik in range(nk):
        line = mm.readline().decode()
        kvec, wk = parse_kline(line, ik=ik)
        data[ik, :3] = kvec * blat
        data[ik, 3] = wk
    return data
Esempio n. 4
0
def get_elem_pos(nscf_in):
    from qharv.reel import ascii_out
    mm = ascii_out.read(nscf_in)
    natom = ascii_out.name_sep_val(mm, 'nat', '=', dtype=int)
    idx = mm.find(b'ATOMIC_POSITIONS')
    mm.seek(idx)
    header = mm.readline().decode()
    eleml = []
    posl = []
    for iatom in range(natom):
        line = mm.readline()
        tokens = line.split()
        eleml.append(tokens[0])
        posl.append(tokens[1:])
    mm.close()
    elem = np.array(eleml, dtype=str)
    pos = np.array(posl, dtype=float)
    return elem, pos, header
Esempio n. 5
0
def parse_output(floc):
    """ get energy, volume and pressure from QE output """
    etot = read_first_energy(floc)
    entry = {'energy': etot / 2.}  # Ry to ha

    mm = read(floc)

    label_map = {'volume': 'unit-cell volume', 'natom': 'number of atoms/cell'}

    for key in label_map.keys():
        val = name_sep_val(mm, label_map[key])
        entry[key] = val
    # end for
    au_stressl, kbar_stressl = read_stress(floc)
    assert len(au_stressl) == 1
    au_stress = au_stressl[0]
    entry['pressure'] = np.diag(au_stress).mean() / 2.  # Ry to ha
    entry['stress'] = au_stress / 2.  # Ry to ha

    return entry
Esempio n. 6
0
def read_fsc_out(fout, chi2_tol=1e-12, rtol=0.01):
    from qharv.reel import ascii_out
    mm = ascii_out.read(fout)
    # check chi^2
    idxl = ascii_out.all_lines_with_tag(mm, 'fitpn: Chi^2 =')
    for idx in idxl:
        mm.seek(idx)
        chi2 = ascii_out.name_sep_val(mm, 'fitpn: Chi^2', '=')
        assert chi2 < chi2_tol
    # rewind
    mm.seek(0)
    # get nelec
    nelec = ascii_out.name_sep_val(mm, 'nparts', '=', dtype=int)
    # read potential
    idx = mm.find(b'Potential energy correction')
    mm.seek(idx)
    idx = mm.find(b'using optimized potential')
    mm.seek(idx)
    dv = ascii_out.name_sep_val(mm, 'dV/N', '=')
    # check potential
    idx = mm.find(b'interpolating optimized potential')
    mm.seek(idx)
    dv0 = ascii_out.name_sep_val(mm, 'dV/N', '=')
    assert dv > 0
    assert dv0 > 0
    rdv = abs(dv - dv0) / dv0
    assert rdv < rtol
    # read kinetic
    mm = ascii_out.read(fout)
    idx = mm.find(b'Kinetic energy correction')
    mm.seek(idx)
    idx = mm.find(b'using optimized potential')
    mm.seek(idx)
    dt = ascii_out.name_sep_val(mm, 'dT/N', '=')
    # check kinetic
    idx = mm.find(b'interpolating optimized potential')
    mm.seek(idx)
    dt0 = ascii_out.name_sep_val(mm, 'dT/N', '=')
    assert dt > 0
    assert dt0 > 0
    rdt = abs(dt - dt0) / dt0
    assert rdt < rtol
    mm.close()
    return dv * nelec, dt * nelec
Esempio n. 7
0
def get_volume(fout):
  mm = ascii_out.read(fout)
  omega = ascii_out.name_sep_val(mm, 'Vol', pos=1)
  return omega
Esempio n. 8
0
def get_efermi(fout):
    from qharv.reel import ascii_out
    mm = ascii_out.read(fout)
    efermi = ascii_out.name_sep_val(mm, 'the Fermi energy', sep='is')
    return efermi
Esempio n. 9
0
def parse_nscf_bands(nscf_out, span=7, trailer='occupation numbers'):
    data = {}  # build a dictionary as return value

    def scanf_7f(line, n):
        """ implement scanf("%7.*f") """
        numl = []
        for i in range(n):
            token = line[span * i:span * (i + 1)]
            num = float(token)
            numl.append(num)
        return numl

    def parse_float_body(body):
        """ parse a blob of floats """
        lines = body.split('\n')
        numl = []
        for line in lines:
            if len(line) == 0: continue
            numl += map(float, line.split())
        return numl

    from qharv.reel import ascii_out
    ndim = 3
    mm = ascii_out.read(nscf_out)
    alat = ascii_out.name_sep_val(mm, 'lattice parameter (alat)')
    blat = 2 * np.pi / alat

    # find the beginnings of each band
    bhead = ' k ='
    idxl = ascii_out.all_lines_with_tag(mm, bhead)
    nkpt = len(idxl)
    data['nkpt'] = nkpt

    # estimate the end of the last band
    idx1 = ascii_out.all_lines_with_tag(mm, trailer)[-1]

    # trick to use no if statement in the loop
    idxl = idxl + [idx1]

    kvecs = []  # (nkpt, ndim)
    mat = []  # (nkpt, nbnd)
    for ikpt in range(nkpt):
        # specify beginning and end of the band output
        idx0 = idxl[ikpt]
        idx1 = idxl[ikpt + 1]

        # parse band output
        #  first read header
        mm.seek(idx0)
        header = mm.readline().decode()
        if not 'bands (ev)' in header: continue
        kxkykz = ascii_out.lr_mark(header, '=', '(')
        kvec = scanf_7f(kxkykz, ndim)
        kvecs.append(kvec)
        #  then read body
        body = mm[mm.tell():idx1].decode().strip('\n')
        if trailer in body:
            idx2 = mm.find(trailer.encode())
            body = mm[mm.tell():idx2].strip('\n')
        row = parse_float_body(body)
        mat.append(row)
    # end for ikpt
    data['kvecs'] = blat * np.array(kvecs)
    data['bands'] = np.array(mat)
    return data
Esempio n. 10
0
def input_structure(scf_in, put_in_box=True):
    ndim = 3  # assume 3 dimensions
    with open(scf_in, 'r+') as f:
        mm = mmap(f.fileno(), 0)
    # end with

    from qharv.reel.ascii_out import name_sep_val
    ntyp = name_sep_val(mm, 'ntyp', dtype=int)
    if ntyp != 1:
        raise NotImplementedError('only support 1 type of atom for now')
    # end if

    # read lattice
    mm.seek(0)
    idx = mm.find(b'ibrav')
    mm.seek(idx)
    ibrav_line = mm.readline()
    ibrav = int(ibrav_line.split('=')[-1])
    if ibrav != 0:
        raise NotImplementedError('only ibrav = 0 is supported')
    # end if
    idx = mm.find(b'CELL_PARAMETERS')
    mm.seek(idx)
    header = mm.readline()
    unit = header.split()[-1]
    axes = np.zeros([ndim, ndim])
    for idim in range(ndim):
        line = mm.readline()
        axes[idim, :] = map(float, line.split())
    # end for
    cell = {'unit': unit, 'axes': axes}

    # read atomic positions
    mm.seek(0)  # rewind
    idx = mm.find(b'nat')
    mm.seek(idx)
    nat_line = mm.readline()
    nat = int(nat_line.split('=')[-1])

    idx = mm.find(b'ATOMIC_POSITIONS')
    mm.seek(idx)
    header = mm.readline()
    unit = header.split()[-1]

    pos = np.zeros([nat, ndim])
    for iat in range(nat):
        line = mm.readline()
        pos[iat, :] = map(float, line.split()[-3:])
    # end for iat

    try:
        line = mm.readline()
        float(line.split()[-3:])
        raise RuntimeError('next lines looks like positions too!\n%s' % line)
    except:
        pass  # expect to see an empty line
    # end try
    if put_in_box:
        atpos = {
            'pos_unit': unit,
            'pos': pos_in_box(np.array(pos), np.array(axes)).tolist()
        }
    else:
        atpos = {'pos_unit': unit, 'pos': pos}
    # end if

    entry = {'infile': scf_in}
    entry.update(cell)
    entry.update(atpos)

    return entry
Esempio n. 11
0
def read_forces(scf_out, ndim=3, which='total'):
    """ read the forces in a pwscf output, assume only one force block
     'which' decides which block of forces to read, choices are:
         ['total', 'non-local', 'local', 'ionic', 'core', 'Hubbard', 'scf']
     !!!! assuming QE uses Ry, will convert to Ha """
    Ry = 0.5  # Ha
    begin_tag_dict = {
        'total': 'Forces acting on atoms',
        'non-local': 'The non-local contrib.  to forces',
        'ionic': 'The ionic contribution  to forces',
        'local': 'The local contribution  to forces',
        'core': 'The core correction contribution to forces',
        'Hubbard': 'The Hubbard contrib.    to forces',
        'scf': 'The SCF correction term to forces'
    }
    end_tag_dict = {
        'total': 'The non-local contrib.  to forces',
        'non-local': 'The ionic contribution  to forces',
        'ionic': 'The local contribution  to forces',
        'local': 'The core correction contribution to forces',
        'core': 'The Hubbard contrib.    to forces',
        'Hubbard': 'The SCF correction term to forces',
        'scf': 'Total force ='
    }

    fhandle = open(scf_out, 'r+')
    mm = mmap(fhandle.fileno(), 0)

    natom = name_sep_val(mm, 'number of atoms', dtype=int)

    # locate force block
    begin_tag = begin_tag_dict[which]
    end_tag = end_tag_dict[which]

    begin_idx = mm.find(begin_tag.encode())
    end_idx = mm.find(end_tag.encode())
    if begin_idx == -1:
        raise RuntimeError('cannot locate %s' % begin_tag)
    elif end_idx == -1:
        # maybe verbosity='low'
        end_idx = mm.find(b'Total force =')
        if end_idx == -1:
            raise RuntimeError('cannot locate %s' % end_tag)
        # end if
    # end if
    force_block = mm[begin_idx:end_idx]

    # parse force block for forces
    forces = np.zeros([natom, ndim])
    iatom = 0
    for line in force_block.split(b'\n'):
        if line.strip().startswith(b'atom'):
            tokens = line.split()
            if len(tokens) == 9:  # found an atom
                myforce = np.array(tokens[-3:], dtype=float)
                forces[iatom, :] = tokens[-3:]
                iatom += 1
            # end if
        # end if
    # end for
    if iatom != natom:
        raise RuntimeError('found %d forces for %d atoms' % (iatom, natom))
    # end if

    fhandle.close()

    return forces * Ry