Ejemplo n.º 1
0
def test_roundtrip_simplified():
    cp2k_parser = CP2KInputParserSimplified(DEFAULT_CP2K_INPUT_XML)
    with open(TEST_DIR.joinpath("inputs/test01.inp"), "r") as fhandle:
        ref_tree = cp2k_parser.parse(fhandle)

    cp2k_generator = CP2KInputGenerator(DEFAULT_CP2K_INPUT_XML)
    fhandle = io.StringIO("\n".join(cp2k_generator.line_iter(ref_tree)))

    # reinitialize parser and generators to clear any internal state they might have
    cp2k_parser = CP2KInputParserSimplified(DEFAULT_CP2K_INPUT_XML)
    fhandle.name = "StringIO"  # add a filename (required by parser for context)

    assert cp2k_parser.parse(fhandle) == ref_tree
Ejemplo n.º 2
0
def test_repeated_kinds_simplified_clash():
    cp2k_parser = CP2KInputParserSimplified(DEFAULT_CP2K_INPUT_XML)

    with open(
            TEST_DIR.joinpath("inputs/keyword_parameter_clash_simplified.inp"),
            "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    # the BS parameter clashes with the BS (broken symmetry) keyword of the KIND section
    assert tree["force_eval"]["subsys"]["kind"] == [
        {
            "_": "BS",
            "element": "O",
            "potential": "GTH-PBE-q6",
            "basis_set": ("ORB", "TZVP-MOLOPT-SR-GTH")
        },
        {
            "_": "C",
            "element": "C",
            "potential": "GTH-PBE-q4",
            "basis_set": ("ORB", "TZVP-MOLOPT-SR-GTH")
        },
        {
            "_": "Ti",
            "element": "Ti",
            "potential": "GTH-PBE-q12",
            "basis_set": ("ORB", "TZVP-MOLOPT-SR-GTH")
        },
    ]
Ejemplo n.º 3
0
def cp2kget(fhandle, paths, base_dir, var_values, canonical):
    """Get values by path from a CP2K input file

    Examples for paths:

        force_eval/dft/mgrid/cutoff
    """

    if canonical:
        cp2k_parser = CP2KInputParser(base_dir=base_dir, key_trafo=str.lower)
    else:
        cp2k_parser = CP2KInputParserSimplified(base_dir=base_dir,
                                                key_trafo=str.lower)

    tree = cp2k_parser.parse(fhandle, dict(var_values))

    def _(val):
        if isinstance(val, list):
            return ", ".join(str(v) for v in val)

        return val

    for path in paths:
        sections = path.split("/")
        ref = tree
        for section in sections:
            if isinstance(ref, (list, tuple)):
                section = int(
                    section
                )  # if we encounter a list, convert the respective path element
            ref = ref[
                section]  # exploit Python using references into dicts/lists

        print(f"{path}: {_(ref)}")
Ejemplo n.º 4
0
def test_simple_simplified():
    cp2k_parser = CP2KInputParserSimplified(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/test01.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert "global" in tree
Ejemplo n.º 5
0
def test_conditional_inclusion():
    cp2k_parser = CP2KInputParserSimplified(
        DEFAULT_CP2K_INPUT_XML, base_dir=TEST_DIR.joinpath("inputs/"))

    with open(TEST_DIR.joinpath("inputs/test03.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert "global" in tree
    assert "force_eval" not in tree
def test_repeated_keywords_tuples():
    """Verify bug https://github.com/cp2k/cp2k-input-tools/issues/32 for repeated BASIS_SET is fixed"""
    cp2k_parser = CP2KInputParserSimplified(key_trafo=str.lower)

    with (TEST_DIR / "inputs" /
          "repeated_keywords_tuples.inp").open("r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree["force_eval"]["subsys"]["kind"]["H"]["basis_set"] == [
        ("AUX_FIT", "pFIT3"), "TZV2P-MOLOPT-GTH"
    ]
Ejemplo n.º 7
0
def test_simple_simplified_inclusion():
    cp2k_parser = CP2KInputParserSimplified(
        DEFAULT_CP2K_INPUT_XML, base_dir=TEST_DIR.joinpath("inputs/"))

    with open(TEST_DIR.joinpath("inputs/test02.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert "global" in tree
    assert "force_eval" in tree
    # the simplified parser collapses repeated sections containing a single element
    assert isinstance(tree["force_eval"], dict)
def test_simplified_no_unpack():
    cp2k_parser = CP2KInputParserSimplified(key_trafo=str.upper,
                                            multi_value_unpack=False,
                                            repeated_section_unpack=False)

    with (TEST_DIR / "inputs" / "deltatest_C_0.98.inp").open("r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert isinstance(tree, dict)
    assert tree["FORCE_EVAL"]["SUBSYS"]["KIND"] == {
        "_": "C",
        "ELEMENT": "C",
        "POTENTIAL": "GTH-PBE-q4",
        "BASIS_SET": "ORB TZVP-MOLOPT-SR-GTH",
    }
Ejemplo n.º 9
0
def test_simple_simplified_unitconv():
    """
    Testing the unit conversion from CP2K supported units (also custom defined ones) using pint
    to CP2K's default units (which is what will be used to store them in the tree representation.
    """
    cp2k_parser = CP2KInputParserSimplified(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/test01_units.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree["force_eval"]["subsys"]["cell"]["a"][0] == pytest.approx(
        4.07419, 1e-3)
    assert tree["force_eval"]["dft"]["mgrid"]["cutoff"] == pytest.approx(
        1000, 1e-3)
    assert tree["force_eval"]["dft"]["scf"]["smear"][
        "electronic_temperature"] == pytest.approx(300, 1e-3)
Ejemplo n.º 10
0
def fromcp2k(fhandle, oformat, canonical, base_dir, trafo, var_values):
    """Convert CP2K input to JSON (default), YAML or an aiida-cp2k run script template"""

    if oformat == "aiida-cp2k-calc":
        if canonical:
            print(
                "The --canonical argument is ignored when generating an aiida-cp2k run script template",
                file=sys.stderr)
        if trafo != Trafos.auto:
            print(
                "Any key transformation function other than 'auto' is ignored when generating an aiida-cp2k run script template",
                file=sys.stderr,
            )
        cp2k_parser = CP2KInputParserAiiDA(base_dir=base_dir)
    elif canonical:
        cp2k_parser = CP2KInputParser(base_dir=base_dir, key_trafo=trafo.value)
    else:
        cp2k_parser = CP2KInputParserSimplified(base_dir=base_dir,
                                                key_trafo=trafo.value)

    tree = cp2k_parser.parse(fhandle, dict(var_values))

    if oformat == "json":
        print(json.dumps(tree, indent=2))

    elif oformat == "yaml":
        from ruamel.yaml import YAML

        yaml = YAML()
        yaml.dump(tree, sys.stdout)

    elif oformat == "aiida-cp2k-calc":
        from jinja2 import Environment, PackageLoader

        env = Environment(
            loader=PackageLoader("cp2k_input_tools", "templates"))
        env.globals.update({
            "isinstance": isinstance,
            "Mapping": Mapping,
            "MutableSequence": MutableSequence
        })
        env.filters["quoted"] = lambda item: f'"{item}"' if isinstance(
            item, str) else item
        template = env.get_template("aiida_cp2k_calc.py.j2")
        print(template.render(tree=tree))
Ejemplo n.º 11
0
def test_repeated_kinds_simplified():
    cp2k_parser = CP2KInputParserSimplified(DEFAULT_CP2K_INPUT_XML)

    with open(TEST_DIR.joinpath("inputs/test04.inp"), "r") as fhandle:
        tree = cp2k_parser.parse(fhandle)

    assert tree["force_eval"]["subsys"]["kind"] == {
        "O": {
            "element": "O",
            "potential": "GTH-PBE-q6",
            "basis_set": ("ORB", "TZVP-MOLOPT-SR-GTH")
        },
        "C": {
            "element": "C",
            "potential": "GTH-PBE-q4",
            "basis_set": ("ORB", "TZVP-MOLOPT-SR-GTH")
        },
        "Ti": {
            "element": "Ti",
            "potential": "GTH-PBE-q12",
            "basis_set": ("ORB", "TZVP-MOLOPT-SR-GTH")
        },
    }
Ejemplo n.º 12
0
def cp2kgen(fhandle, expressions, base_dir, canonical, var_values):
    """
    Generates variations of the given CP2K input file

    Examples for generator expressions:

    "force_eval/dft/mgrid/cutoff=[300,400,500,800]", "force_eval/subsys/cell/a/0=10.0"
    """

    if canonical:
        cp2k_parser = CP2KInputParser(base_dir=base_dir, key_trafo=str.lower)
    else:
        cp2k_parser = CP2KInputParserSimplified(base_dir=base_dir,
                                                key_trafo=str.lower)

    tree = cp2k_parser.parse(fhandle, dict(var_values))

    # list of substitutions/transformations to apply
    substitutions = []

    for expression in expressions:
        try:
            kpath, value = expression.split("=", maxsplit=1)
        except ValueError:
            raise ValueError(
                "an expression must be of the form 'path/to/key=...'"
            ) from None

        if re.match(r"^\[.+\]$", value):
            values = [v.strip() for v in value.strip("[]").split(",")]
            substitutions += [(kpath, values)]
        else:
            substitutions += [(kpath, [value])]

    fpath = pathlib.Path(fhandle.name)
    onameprefix = fpath.stem
    onamesuffix = fpath.suffix

    # first generate a list of list of tuples [ [(key/a, 10), (key/a, 20), ...], [(key/b, 100), ...], ...]
    for substtuple in itertools.product(*[[(k, v) for v in values]
                                          for k, values in substitutions]):
        # ... then iterate over the cartesian product
        curr_tree = deepcopy(tree)  # create a full copy of the initial tree
        onameparts = []  # output name parts
        for kpath, value in substtuple:
            ref = curr_tree

            sections = kpath.split("/")
            for section in sections[:-1]:
                if isinstance(ref, list):
                    section = int(
                        section
                    )  # if we encounter a list, convert the respective path element
                ref = ref[
                    section]  # exploit Python using references into dicts/lists

            attr = sections[-1]
            if isinstance(ref, (list, tuple)):
                attr = int(attr)

            if isinstance(ref, tuple):
                # we only get tuples for keywords which can take multiple words, hence this should be safe
                lref = list(ref)
                lref[attr] = value
                ref = tuple(lref)
            else:
                ref[attr] = value

            # take only the attribute name
            onameparts += [f"{attr}_{value}"]

        opath = pathlib.Path(
            f"{onameprefix}-{'-'.join(onameparts)}{onamesuffix}")
        print(f"Writing '{opath}'...")

        with opath.open("w") as fouthandle:
            fouthandle.write(
                f"! Generated with the CP2K input tool cp2kgen v{__version__}\n! "
            )
            fouthandle.write(" \\\n!   ".join(f"'{arg}'" for arg in sys.argv))
            fouthandle.write("\n")
            cp2k_generator = CP2KInputGenerator()
            for line in cp2k_generator.line_iter(curr_tree):
                fouthandle.write(f"{line}\n")