Пример #1
0
def make_berry_parser():
    import re
    from pwproc.util import parser_one_line

    def parse_vector(vec, *, num_re=re.compile(r"-?[.\d]+")):
        return tuple(map(float, num_re.findall(vec)))

    gdir_re = re.compile(r"^[ \w]* direction of vector ([123])$")
    phase_re = re.compile(r"^ +TOTAL PHASE: +(-?[.\d]+) \(mod (1|2)\)$")
    vec_re = re.compile(r"^ +The polarization direction is: +\(( *(?:-?[.\d]+[ ,]*){3})\)$")
    pol_re = re.compile(r"^ +P = +(-?[.\d]+) +\(mod +([.\d]+)\) +C/m\^2$")

    g_parser = parser_one_line(gdir_re, lambda m: int(m.group(1)))
    phase_parser = parser_one_line(phase_re, lambda m: (float(m.group(1)), int(m.group(2))))
    vec_parser = parser_one_line(vec_re, lambda m: parse_vector(m.group(1)))
    pol_parser = parser_one_line(pol_re, lambda m: tuple(map(float, m.group(1, 2))))

    def berry_parser(f_name):
        # type: (Path) -> Polarization
        with open(f_name) as f:
            gdir = g_parser(f)
            f.seek(0)
            phase = phase_parser(f)
            f.seek(0)
            vec = vec_parser(f)
            f.seek(0)
            pol = pol_parser(f)
        return Polarization(gdir, phase, vec, pol)

    return berry_parser
Пример #2
0
def get_init_basis(path):
    # type: (Path) -> Tuple[float, Basis]
    """Extracts the initial basis in angstrom from pw.x output."""
    from scipy import constants
    from pwproc.util import parser_one_line, parser_with_header

    bohr_to_ang = constants.value('Bohr radius') / constants.angstrom
    alat_re = re.compile(
        r"[ \t]+lattice parameter \(alat\)[ \t]+=[ \t]+([\d.]+)[ \t]+a\.u\.")
    basis_head_re = re.compile(
        r"[ \t]+crystal axes: \(cart. coord. in units of alat\)")
    basis_line_re = re.compile(
        r"[ \t]+a\([\d]\) = \(((?:[ \t]+[-.\d]+){3}[ \t]+)\)")

    alat_parser = parser_one_line(alat_re, lambda m: float(m.group(1)))
    basis_parser = parser_with_header(basis_head_re, basis_line_re,
                                      lambda m: parse_vector(m.group(1)))

    with open(path) as f:
        alat: float = alat_parser(f)
        # TODO: Remove seek and run parsers in correct order
        f.seek(0)
        basis = basis_parser(f)

    # Convert basis from alat to angstrom
    assert len(basis) == 3
    basis = Basis(np.array(basis))
    basis *= alat * bohr_to_ang

    return alat, basis
Пример #3
0
def get_scf_energy(path):
    # type: (str) -> float
    """Get the energy in Ry from pw.x output."""
    import re
    from pwproc.util import parser_one_line

    energy_re = re.compile(r"![\s]+total energy[\s]+=[\s]+(-[\d.]+) Ry")
    energy_parser = parser_one_line(energy_re, lambda m: float(m.group(1)))

    with open(path) as f:
        return energy_parser(f)
Пример #4
0
def find_fermi(path):
    # type: (Path) -> Iterable[float]
    """Extract all records of the Fermi energy from pw.x output."""
    import re
    from pwproc.util import parser_one_line

    fermi_re = re.compile(r"[ \t]+the Fermi energy is[ \t]+(-?[.\d]+) ev")
    fermi_parser = parser_one_line(fermi_re,
                                   lambda m: float(m.group(1)),
                                   find_multiple=True)

    with open(path) as f:
        fe = fermi_parser(f)

    return fe
Пример #5
0
def get_save_file(path):
    # type: (Path) -> str
    """Extract the prefix from pw.x output."""
    from pwproc.util import parser_one_line

    save_re = re.compile(
        r"^[ \t]+Writing output data file (?:\./)?([-.\w]+).save/?$")
    save_parser = parser_one_line(save_re, lambda m: m.group(1))

    with open(path) as f:
        prefix = save_parser(f)

    if prefix is None:
        raise ParserError("Could not find calculation prefix")

    return prefix