Exemplo n.º 1
0
def test_mgo_sto3g_scf():
    content = read_resource_text("crystal", "mgo_sto3g_scf", "INPUT")
    output_dict, basis_sets, atom_props = extract_data(content)

    assert len(basis_sets) == 2

    assert atom_props == {}

    assert output_dict == {"scf": {"k_points": (8, 8)}, "title": "MgO bulk"}
Exemplo n.º 2
0
def stdin(input_file, keys, fmt):
    """Parse an existing stdin (d12) file, created from a crystal run."""
    from aiida_crystal17.parsers.raw.inputd12_read import extract_data

    with io.open(input_file) as handle:
        data, bases, atom_props = extract_data(handle.read())
    if keys is not None:
        data = {k: v for k, v in data.items() if k in keys}
    options.echo_dictionary(data, fmt=fmt)
Exemplo n.º 3
0
def test_mgo_sto3g_opt():
    content = read_resource_text("crystal", "mgo_sto3g_opt", "INPUT")
    output_dict, basis_sets, atom_props = extract_data(content)

    assert len(basis_sets) == 2

    assert atom_props == {}

    assert output_dict == {
        "geometry": {
            "optimise": {
                "type": "FULLOPTG"
            }
        },
        "scf": {
            "k_points": (8, 8)
        },
        "title": "MgO bulk",
    }
Exemplo n.º 4
0
def test_nio_sto3g_afm():
    content = read_resource_text("crystal", "nio_sto3g_afm_scf", "INPUT")
    output_dict, basis_sets, atom_props = extract_data(content)

    assert len(basis_sets) == 2

    assert atom_props == {"spin_alpha": [1], "spin_beta": [2]}

    assert output_dict == {
        "scf": {
            "single": "UHF",
            "numerical": {
                "FMIXING": 30
            },
            "post_scf": ["PPAN"],
            "spinlock": {
                "SPINLOCK": [0, 15]
            },
            "k_points": (8, 8),
        },
        "title": "NiO Bulk with AFM spin",
    }
Exemplo n.º 5
0
def populate_builder(remote_data, code=None, metadata=None):
    """create ``crystal17.main`` input nodes from an existing run

    NB: none of the nodes are stored, also
    existing basis will be retrieved if availiable

    Parameters
    ----------
    folder: aiida.common.folders.Folder or str
        folder containing the input and output files
    remote_data: aiida.orm.RemoteData
        containing the input and output files required for parsing
    code: str or aiida.orm.nodes.data.code.Code or None
    metadata: dict or None
        calculation metadata

    Returns
    -------
    aiida.engine.processes.ProcessBuilder

    """
    calc_cls = CalculationFactory("crystal17.main")
    basis_cls = DataFactory("crystal17.basisset")
    struct_cls = DataFactory("structure")
    symmetry_cls = DataFactory("crystal17.symmetry")
    kind_cls = DataFactory("crystal17.kinds")

    # get files
    in_file_name = calc_cls.spec_options.get("input_file_name").default
    out_file_name = calc_cls.spec_options.get("output_main_file_name").default
    if metadata and "options" in metadata:
        in_file_name = metadata["options"].get("input_file_name", in_file_name)
        out_file_name = metadata["options"].get("output_main_file_name",
                                                out_file_name)

    remote_files = remote_data.listdir()

    if in_file_name not in remote_files:
        raise IOError(
            "The input file '{}' is not contained in the remote_data folder. "
            "If it has a different name, change "
            "metadata['options]['input_file_name']".format(in_file_name))
    if out_file_name not in remote_files:
        raise IOError(
            "The output file '{}' is not contained in the remote_data folder. "
            "If it has a different name, change "
            "metadata['options]['output_main_file_name']".format(
                out_file_name))

    with SandboxFolder() as folder:
        remote_data.getfile(in_file_name,
                            os.path.join(folder.abspath, in_file_name))

        with folder.open(in_file_name, mode="r") as handle:
            param_dict, basis_sets, atom_props = extract_data(handle.read())

        remote_data.getfile(out_file_name,
                            os.path.join(folder.abspath, out_file_name))

        with folder.open(out_file_name, mode="r") as handle:
            try:
                data = crystal_stdout.read_crystal_stdout(handle.read())
            except IOError as err:
                raise OutputParsingError(
                    "Error in CRYSTAL 17 run output: {}".format(err))

    # we retrieve the initial primitive geometry and symmetry
    atoms = _create_atoms(data, "initial_geometry")

    # convert fragment (i.e. unfixed) to fixed
    if "fragment" in atom_props:
        frag = atom_props.pop("fragment")
        atom_props["fixed"] = [
            i + 1 for i in range(atoms.get_number_of_atoms())
            if i + 1 not in frag
        ]

    atoms.set_tags(_create_tags(atom_props, atoms))

    structure = struct_cls(ase=atoms)

    if atom_props:
        kind_names = structure.get_kind_names()
        kinds_dict = {"kind_names": kind_names}
        for key, atom_indexes in atom_props.items():
            kv_map = {
                kn: i + 1 in atom_indexes
                for i, kn in enumerate(structure.get_site_kindnames())
            }
            kinds_dict[key] = [kv_map[kn] for kn in kind_names]
        kinds = kind_cls(data=kinds_dict)
    else:
        kinds = None

    symmetry = symmetry_cls(
        data={
            "operations": data["initial_geometry"]["primitive_symmops"],
            "basis": "fractional",
            "hall_number": None,
        })

    bases = {}
    for bset in basis_sets:

        bfile = tempfile.NamedTemporaryFile(delete=False)
        try:
            with open(bfile.name, "w") as f:
                f.write(bset)
            bdata, _ = basis_cls.get_or_create(bfile.name,
                                               use_first=False,
                                               store_basis=False)
            # TODO report if bases created or retrieved
        finally:
            os.remove(bfile.name)

        bases[bdata.element] = bdata

    builder = calc_cls.create_builder(
        param_dict,
        structure,
        bases,
        symmetry=symmetry,
        kinds=kinds,
        code=code,
        metadata=metadata,
    )

    return builder
Exemplo n.º 6
0
def test_full_read(cry_stdin_str):
    output_dict, basis_sets, atom_props = extract_data(cry_stdin_str)

    assert len(basis_sets) == 2

    assert atom_props == {
        "fragment": [1, 3],
        "ghosts": [5, 6],
        "spin_alpha": [1, 3],
        "spin_beta": [2, 4],
    }

    expected = {
        "title": "a title",
        "geometry": {
            "info_print": ["ATOMSYMM", "SYMMOPS"],
            "info_external": ["STRUCPRT"],
            "ROTCRY": [[1.0, 0, 0], [0, 1, 0], [0, 0, -1]],
            "optimise": {
                "type": "FULLOPTG",
                "hessian": "HESSIDEN",
                "gradient": "NUMGRATO",
                "info_print": ["PRINTOPT", "PRINTFORCES"],
                "convergence": {
                    "TOLDEG": 0.0003,
                    "TOLDEX": 0.0012,
                    "TOLDEE": 7,
                    "MAXCYCLE": 50,
                    "FINALRUN": 4,
                },
            },
        },
        "basis_set": {
            "CHARGED": True,
        },
        "scf": {
            "dft": {
                "xc": ["LDA", "PZ"],
                # or
                # "xc": "HSE06",
                # or
                # "xc": {
                #     "LSRSH-PBE": [0.11, 0.25, 0.00001]
                # },
                "SPIN": True,
                "grid": "XLGRID",
                "grid_weights": "BECKE",
                "numerical": {
                    "TOLLDENS": 6,
                    "TOLLGRID": 14,
                    "LIMBEK": 400
                },
            },
            # or
            # "single": "UHF",
            "k_points": [8, 8],
            "numerical": {
                "BIPOLAR": [18, 14],
                "BIPOSIZE": 4000000,
                "EXCHSIZE": 4000000,
                "EXCHPERM": True,
                "ILASIZE": 6000,
                "INTGPACK": 0,
                "MADELIND": 50,
                "POLEORDR": 4,
                "TOLINTEG": [6, 6, 6, 6, 12],
                "TOLPSEUD": 6,
                "FMIXING": 0,
                "MAXCYCLE": 50,
                "TOLDEE": 6,
                "LEVSHIFT": [2, 1],
                "SMEAR": 0.1,
            },
            "fock_mixing": "DIIS",
            # or
            # "fock_mixing": ["BROYDEN", 0.0001, 50, 2],
            "spinlock": {
                "SPINLOCK": [1, 10]
            },
            "post_scf": ["GRADCAL", "PPAN"],
        },
    }

    assert edict.diff(output_dict, expected) == {}
Exemplo n.º 7
0
def test_read_fail(cry_stdin_str):
    cry_stdin_str = cry_stdin_str.replace("PPAN", "WRONG")
    with pytest.raises(NotImplementedError):
        extract_data(cry_stdin_str)