示例#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
示例#2
0
def get_ekmap(scf_out):
    """Obtain the internal variable 'equiv' from kpoint_grid.f90 in QE/PW

  store the maps between full BZ (fBZ) and irreducible BZ (iBZ)

  Args:
    scf_out (str): output file
  Return:
    (dict, dict): (fBZ->iBZ, iBZ->fBZ) maps
  """
    from qharv.reel import ascii_out
    mm = ascii_out.read(scf_out)
    text = ascii_out.block_text(mm, 'equivalent kpoints begin', 'end')
    lines = text.split('\n')
    emap = {}  # full kgrid to irreducible wedge
    kmap = {}  # irreducible wedge to full kgrid
    for line in lines:
        tokens = line.split('equiv')
        if len(tokens) != 2: continue
        left, right = map(int, tokens)
        emap[left] = right
        if right in kmap:
            kmap[right].append(left)
        else:
            kmap[right] = [left]
    mm.close()
    return emap, kmap
示例#3
0
def get_axsf_normal_mode(faxsf, imode):
    """ extract the first normal mode labeled by 'PRIMCOORD {imode:d}' 
  assume the following format:

  PRIMCOORD  1
    16   1
  H      0.00000   0.00000   1.50303  -0.00000   0.00000   0.02501
  H      0.63506   0.63506   0.00000   0.00000  -0.00000   0.02500
  ...

  Args:
    faxsf (str): name of axsf file
    imode (int): index of normal mode
  Return:
    tuple: (elem,data), elem is a list of atomic symbols,
     data is a np.array of floats (6 columns in above example).
  """
    from qharv.reel import ascii_out
    mm = ascii_out.read(faxsf)

    # search through all modes for requested imode
    all_idx = ascii_out.all_lines_with_tag(mm, 'PRIMCOORD')
    found = False
    for idx in all_idx:
        mm.seek(idx)
        line = mm.readline()
        myi = int(line.split()[1])
        if myi != imode: continue

        # found imode
        found = True

        # get number of atoms
        line = mm.readline()
        natom = int(line.split()[0])

        # get atomic symbols, positions and normal mode
        elem = []
        data = []
        for iatom in range(natom):
            line = mm.readline()
            tokens = line.split()
            elem.append(tokens[0])
            data.append(map(float, tokens[1:]))
        # end for iatom

        # check that the next line is either next mode or empty
        line = mm.readline()
        expected = (line == '') or (line.startswith('PRIMCOORD'))
        if not expected:
            raise RuntimeError('failed to read mode %d correctly' % imode)
        # end if
        break
    # end for idx

    if not found:
        raise RuntimeError('failed to find mode %d in %s' % (imode, faxsf))
    # end if

    return elem, np.array(data)
示例#4
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                                                                   
示例#5
0
def read_lammps_log(flog, header='Per MPI rank memory', trailer='Loop time'):
  import pandas as pd
  from qharv.reel import ascii_out, scalar_dat
  mm = ascii_out.read(flog)
  blocks = ascii_out.all_lines_with_tag(mm, header)
  dfl = []
  if len(blocks) < 1:
    return pd.DataFrame(dfl)
  for iblock, idx in enumerate(blocks):
    mm.seek(idx)
    pre = '# '  # !!!! assume first line is header
    try:  # clean run from start to finish
      text1 = ascii_out.block_text(mm, header, trailer)
      text1 = strip_warnings(text1)
      df1 = scalar_dat.parse(pre+text1).astype(float)
    except Exception as err:
      mm.seek(idx)  # !!!! decorator "stay" does not finish if Exception
      if type(err) is ValueError:  # unfinished restart run
        text1 = ascii_out.block_text(mm, header, trailer='restart')
        text1 = strip_warnings(text1)
        df1 = scalar_dat.parse(pre+text1).astype(float)
      elif type(err) is RuntimeError:  # unfinished final run
        text1 = ascii_out.block_text(mm, header, trailer, force_tail=True)
        text1 = strip_warnings(text1)
        df1 = scalar_dat.parse(pre+text1).astype(float)
      else:  # give up
        raise err
    dfl.append(df1)
  mm.close()
  df = pd.concat(dfl, sort=False).reset_index(drop=True)
  return df
示例#6
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
示例#7
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
示例#8
0
def get_data_block(floc, name, nhead=0):
  start_tag = '#'+name + '_START#'
  stop_tag  = '#'+name + '_STOP#'

  mm = ascii_out.read(floc)                                                     
  text = ascii_out.block_text(mm,start_tag,stop_tag)
  lines= text.split('\n')[nhead:-1]  # empty after the last \n
  data   = np.array(
    [map(float,line.split()) for line in lines]
  ,dtype=float)
  return data
示例#9
0
def get_tgrid_tshift(nscf_in):
    from qharv.reel import ascii_out
    mm = ascii_out.read(nscf_in)
    idx = mm.find(b'K_POINTS automatic')
    mm.seek(idx)
    mm.readline()
    kline = mm.readline()
    mm.close()

    nums = list(map(int, kline.split()))
    tgrid = np.array(nums[:3])
    tshift = np.array(nums[3:])
    return tgrid, tshift
示例#10
0
def read_out_cell(scf_out, ndim=3):
    axes = np.zeros([ndim, ndim])
    from qharv.reel import ascii_out
    mm = ascii_out.read(scf_out)
    idx = mm.find(b'crystal axes')
    mm.seek(idx)
    mm.readline()
    for idim in range(ndim):
        line = mm.readline()
        right = line.split('=')[-1]
        text = ascii_out.lr_mark(right, '(', ')')
        axes[idim, :] = map(float, text.split())
    return axes
def read_cfg(fcfg):
    mm = ascii_out.read(fcfg)

    idxl = ascii_out.all_lines_with_tag(mm, 'ITEM:')
    data = {}
    for idx in idxl:
        mm.seek(idx)
        header = mm.readline()
        item_name = header.split(':')[-1].strip()

        entry = parse_item(mm, item_name)
        data.update(entry)
    return data
示例#12
0
def get_axes(nscf_in, ndim=3):
    from qharv.reel import ascii_out
    mm = ascii_out.read(nscf_in)
    idx = mm.find(b'CELL_PARAMETERS')
    mm.seek(idx)
    mm.readline()
    cell = []
    for idim in range(ndim):
        line = mm.readline().decode()
        nums = list(map(float, line.split()))
        cell.append(nums)
    mm.close()
    axes = np.array(cell)
    return axes
示例#13
0
def get_weights(nscf_out, remove_copy=False, atol=1e-10):
    from qharv.reel import ascii_out
    mm = ascii_out.read(nscf_out)
    idx = ascii_out.all_lines_with_tag(mm, 'wk =')
    lines = ascii_out.all_lines_at_idx(mm, idx)
    weights = []
    for line in lines:
        wt = float(line.strip('\n').split('wk =')[-1])
        weights.append(wt)
    mm.close()
    nt = len(weights)
    if remove_copy:
        weights = weights[:nt / 2]
    wtot = sum(weights)
    if not np.isclose(wtot, 2.0, atol=atol):
        raise RuntimeError('wrong weight sum %3.2f; expected 2.0' % wtot)
    return np.array(weights)
示例#14
0
def get_occupation_numbers(nscf_out, nmax=1024):
    from qharv.reel import ascii_out
    mm = ascii_out.read(nscf_out)
    idx = ascii_out.all_lines_with_tag(mm, 'occupation numbers')
    occl = []
    for i in idx:
        mm.seek(i)
        mm.readline()
        occ = []
        for j in range(nmax):
            line = mm.readline()
            tokens = line.split()
            if len(tokens) == 0:
                break
            occ += map(float, tokens)
        next_line = mm.readline()
        occl.append(occ)
    return np.array(occl)
示例#15
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
示例#16
0
def get_jk_kvecs(fout,
                 header='kSpace coefficient groups',
                 trailer='QMCHamiltonian::addOperator'):
    """ parse QMCPACK output for kSpace Jastrow kvecs """
    from qharv.reel import ascii_out

    mm = ascii_out.read(fout)
    text = ascii_out.block_text(mm, header, trailer)

    data = []
    for line in text.split('\n'):
        tokens = line.split()
        if len(tokens) != 4: continue
        data.append(map(float, tokens))

    data = np.array(data)
    kvecs = data[:, :3]
    kmags = data[:, 3]
    return kvecs
def get_supertwists(qmc_out):
    """ read supercell twists from QMCPACK output

  Args:
    qmc_out (str): QMCPACK output, must contain "Super twist #"
  Return:
    np.array: an array of twist vectors (ntwist, ndim)
  """
    from qharv.reel import ascii_out
    mm = ascii_out.read(qmc_out)
    idxl = ascii_out.all_lines_with_tag(mm, 'Super twist #')
    lines = ascii_out.all_lines_at_idx(mm, idxl)
    data = []
    for line in lines:
        text = ascii_out.lr_mark(line, '[', ']')
        vec = np.array(text.split(), dtype=float)
        data.append(vec)
    mat = np.array(data)
    return mat
示例#18
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
示例#19
0
def read_kfracs(scf_out):
    from qharv.reel import ascii_out
    mm = ascii_out.read(scf_out)
    # get number of kpoints
    idx = mm.find(b'number of k points')
    mm.seek(idx)
    line = mm.readline().decode()
    nk = int(line.split('=')[1].split()[0])
    # find first line
    idx = mm.find(b'cryst. coord.')
    mm.seek(idx)
    mm.readline()
    # read kpoints and weights
    data = np.zeros([nk, 4])
    for ik in range(nk):
        line = mm.readline().decode()
        kvec, wk = parse_kline(line)
        data[ik, :3] = kvec
        data[ik, 3] = wk
    return data
示例#20
0
def read_ipi_xyz(fxyz):
  from ase import io
  from ase.cell import Cell
  from qharv.reel import ascii_out
  mm = ascii_out.read(fxyz)
  idxl = ascii_out.all_lines_with_tag(mm, '# ')
  traj = io.read(fxyz, ':', format='extxyz')
  nhead = len(idxl)
  nbody = len(traj)
  if nhead != nbody:
    msg = 'found %d headers for %d bodies' % (nhead, nbody)
    raise RuntimeError(msg)
  headers = []
  for idx in idxl:
    mm.seek(idx)
    header = mm.readline().decode()
    headers.append(header)
  mm.close()

  for header, atoms in zip(headers, traj):
    tokens = header.strip('#').split()
    # read cell
    i0 = tokens.index('CELL(abcABC):')
    cellpart = tokens[i0+1:i0+7]
    cellpar = np.array(cellpart, dtype=float)
    cell = Cell.fromcellpar(cellpar)
    atoms.set_cell(cell)
    atoms.set_pbc(True)
    # read info
    atoms.info = {}
    for i, tok in enumerate(tokens):
      if (i >= i0) and (i < i0+7):
        continue
      if tok.endswith(':'):  # key-val pair
        atoms.info[tok[:-1]] = tokens[i+1]
      if ('{' in tok) and ('}' in tok):  # unit
        key, val = tok.split('{')
        atoms.info[key+'_unit'] = val[:-1]
  return traj
示例#21
0
def get_volume(fout):
  mm = ascii_out.read(fout)
  omega = ascii_out.name_sep_val(mm, 'Vol', pos=1)
  return omega
示例#22
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
示例#23
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
示例#24
0
def read_sym_ops(scf_out, ndim=3):
    """ read symmetry operators

  Args:
    scf_out (str): QE output file
    ndim (int, optional): number of spatial dimensions, default is 3
  Return:
    list: all symmetry operators, each is represented as a dictionary
      isym is index, name is description, vec is shift, mat is rotation
  """
    from qharv.reel import ascii_out
    mm = ascii_out.read(scf_out)

    # find starting location of symmetry operator output
    idx = mm.find(b'Sym. Ops.')
    if idx == -1:
        msg = 'no symmetry operations printed in %s. Is verbosity high?' % scf_out
        raise RuntimeError(msg)
    # rewind to beginning of line
    idx0 = mm.rfind(b'\n', 0, idx)
    mm.seek(idx0 + 1)
    header = mm.readline().decode()
    nsym = int(header.split()[0])

    # check the number of symmetry outputs
    idxl = ascii_out.all_lines_with_tag(mm, 'isym = ')
    if len(idxl) != nsym:
        raise RuntimeError('found %d symm. expected %d' % (len(idxl), nsym))

    # parse symmetry operators
    symops = []
    for idx in idxl:
        mm.seek(idx)

        # read symmetry index and name: isym, name
        line0 = mm.readline().decode()
        text0 = line0.split('=')[1]
        tokens0 = text0.split()
        isym = int(tokens0[0])
        name = ' '.join(tokens0[1:])

        # read translation vector: vec
        vec = [0] * ndim
        if 'cart. axis' in name:
            vect = ascii_out.lr_mark(line0, '[', ']')
            vec[:] = list(map(float, vect.split(',')))

        # read rotation matrix: mat
        mat = []
        idx = mm.find(b'cryst.')
        mm.readline()  # skip empty line
        for idim in range(ndim):
            line = mm.readline().decode()
            if 'cryst.' in line:
                line = line.split('=')[1]
            text = ascii_out.lr_mark(line, '(', ')')
            mat.append(list(map(float, text.split())))
        entry = {'isym': isym, 'name': name, 'vec': vec, 'mat': mat}
        symops.append(entry)
    mm.close()
    return symops