bandskpoints = result['explicit_kpoints']

#
# Pseudopotentials ----------------------------------------------
#
# This exemplifies the handling of pseudos for different species
# Those sharing the same pseudo should be indicated.
#
pseudos_dict = {}
raw_pseudos = [("Fe.psf", ['Fe'])]

for fname, kinds, in raw_pseudos:
    absname = os.path.realpath(
        os.path.join(os.path.dirname(__file__), "data/sample-psf-family",
                     fname))
    pseudo, created = PsfData.get_or_create(absname, use_first=True)
    if created:
        print("Created the pseudo for {}".format(kinds))
    else:
        print("Using the pseudo for {} from DB: {}".format(kinds, pseudo.pk))
    for j in kinds:
        pseudos_dict[j] = pseudo

#
#--All the inputs of a Siesta calculations are listed in a dictionary--
#
inputs = {
    'structure': newstructure,
    'parameters': parameters,
    'code': code,
    'basis': basis,
basis = Dict(dict=basis_dict)

#-------------------------------------------
kpoints = KpointsData()

# method mesh
kpoints_mesh = 4
kpoints.set_kpoints_mesh([kpoints_mesh, kpoints_mesh, kpoints_mesh])

#------------------------------------------------
pseudos_dict = {}
raw_pseudos = [("Si.psf", ['Si'])]
for fname, kinds in raw_pseudos:
    absname = op.realpath(
        op.join(op.dirname(__file__), "../../fixtures/sample_psf", fname))
    pseudo = PsfData.get_or_create(absname)
    if not pseudo.is_stored:
        print("\nCreated the pseudo for {}".format(kinds))
    else:
        print("\nUsing the pseudo for {} from DB: {}".format(kinds, pseudo.pk))
    for j in kinds:
        pseudos_dict[j] = pseudo

#---------------------------------------------

inputs = {
    'structure': s,
    'parameters': parameters,
    'code': code,
    'basis': basis,
    'kpoints': kpoints,
Exemplo n.º 3
0
def get_or_create_pseudo_family():
    """Check if the pseudos are already in the DB, create them otherwise.
    
    Then create (if needed) also a pseudopotential family including it (or pick any already existing)
    and return the name.
    If the family does not exist, it will be created with name 'GaAs-Wannier-example' and a possible prefix.
    """
    UpfData = DataFactory('upf')

    # Get absolute filenames
    pseudos_filenames = [
        'As.pbe-n-rrkjus_psl.0.2.UPF', 'Ga.pbe-dn-kjpaw_psl.1.0.0.UPF'
    ]
    this_script_folder = os.path.dirname(os.path.realpath(__file__))
    pseudos_full_path = [
        os.path.join(this_script_folder, 'pseudos', filename)
        for filename in pseudos_filenames
    ]

    # Will collect pseudopotential nodes that either were created or were found
    pseudo_nodes = []

    # set of family names that include both pseudos
    family_names = None
    # Create the UpfData node if there is no pseudo with that MD5, otherwise reuse it
    # Also, get a set of all family names that include both pseudos
    for fname in pseudos_full_path:
        pseudo_node, _ = UpfData.get_or_create(fname,
                                               use_first=True,
                                               store_upf=True)
        pseudo_nodes.append(pseudo_node)
        if family_names is None:
            family_names = set(pseudo_node.get_upf_family_names())
        else:
            family_names = family_names.intersection(
                pseudo_node.get_upf_family_names())

    if family_names:
        # return any of the available family names (in practice, the first in alphabetical order)
        family_name = sorted(family_names)[0]
        print("Using existing UPF group '{}'".format(family_name))
        return family_name

    # no family found: I create one and return its name
    family_name_prefix = 'GaAs-Wannier-example'

    # Try to create the group
    family_name = family_name_prefix
    group, group_created = Group.objects.get_or_create(
        label=family_name, type_string=upf.UPFGROUP_TYPE)

    # continue trying creating the group if the previous one existed
    safe_counter = 0
    while not group_created:
        safe_counter += 1
        if safe_counter > 10:
            raise ValueError("Too many groups existing, stopping...")

        family_name = "{}-{}".format(family_name_prefix, safe_counter)
        group, group_created = Group.objects.get_or_create(
            label=family_name, type_string=upf.UPFGROUP_TYPE)

    # Update description of the group
    group.description = "Automatic group created by the aiida-Wannier90 minimal workflow example"
    # Put the pseudos in the group
    group.add_nodes(pseudo_nodes)

    print("Created new UPF group '{}' with nodes {}".format(
        family_name, ", ".join(str(node.pk) for node in pseudo_nodes)))
    return family_name
Exemplo n.º 4
0
def main():
    """Main function to be called to run the test."""
    # pylint: disable=too-many-statements

    # If set to True, will ask AiiDA to run in serial mode (i.e., AiiDA will not
    # invoke the mpirun command in the submission script)
    run_in_serial_mode = False
    codename = 'qe-pw@torquessh'
    # If it takes > 5 min, I decide I failed (e.g., no daemon is running)
    timeout_secs = 5 * 60
    queue = None

    expected_energy = -3700.91106342615

    ################################################################

    UpfData = DataFactory('upf')
    Dict = DataFactory('dict')
    KpointsData = DataFactory('array.kpoints')
    StructureData = DataFactory('structure')
    Code = DataFactory('code')

    code = Code.get_from_string(codename)

    alat = 4.  # angstrom
    cell = [
        [
            alat,
            0.,
            0.,
        ],
        [
            0.,
            alat,
            0.,
        ],
        [
            0.,
            0.,
            alat,
        ],
    ]

    # BaTiO3 cubic structure
    structure = StructureData(cell=cell)
    structure.append_atom(position=(0., 0., 0.), symbols=['Ba'])
    structure.append_atom(position=(alat / 2., alat / 2., alat / 2.),
                          symbols=['Ti'])
    structure.append_atom(position=(alat / 2., alat / 2., 0.), symbols=['O'])
    structure.append_atom(position=(alat / 2., 0., alat / 2.), symbols=['O'])
    structure.append_atom(position=(0., alat / 2., alat / 2.), symbols=['O'])

    parameters = Dict(
        dict={
            'CONTROL': {
                'calculation': 'scf',
                'restart_mode': 'from_scratch',
                'wf_collect': True,
                'tstress': True,
                'tprnfor': True,
            },
            'SYSTEM': {
                'ecutwfc': 40.,
                'ecutrho': 320.,
            },
            'ELECTRONS': {
                'conv_thr': 1.e-10,
            }
        })

    kpoints = KpointsData()
    kpoints_mesh = 2
    kpoints.set_kpoints_mesh([kpoints_mesh, kpoints_mesh, kpoints_mesh])

    # to retrieve the bands
    # (the object settings is optional)
    settings_dict = {}
    settings = Dict(dict=settings_dict)

    calc = code.new_calc()
    calc.label = 'Test QE pw.x'
    calc.description = 'Test calculation with the Quantum ESPRESSO pw.x code'
    calc.set_option('max_wallclock_seconds', 30 * 60)  # 30 min
    # Valid only for Slurm and PBS (using default values for the
    # number_cpus_per_machine), change for SGE-like schedulers
    calc.set_option('resources', {'num_machines': 1})
    if run_in_serial_mode:
        calc.set_option('withmpi', False)

    if queue is not None:
        calc.set_option('queue_name', queue)

    calc.use_structure(structure)
    calc.use_parameters(parameters)

    raw_pseudos = [
        ('Ba.pbesol-spn-rrkjus_psl.0.2.3-tot-pslib030.UPF', 'Ba', 'pbesol'),
        ('Ti.pbesol-spn-rrkjus_psl.0.2.3-tot-pslib030.UPF', 'Ti', 'pbesol'),
        ('O.pbesol-n-rrkjus_psl.0.1-tested-pslib030.UPF', 'O', 'pbesol')
    ]

    pseudos_to_use = {}
    for fname, elem, _ in raw_pseudos:
        absname = os.path.realpath(
            os.path.join(os.path.dirname(__file__), 'data', fname))
        pseudo, created = UpfData.get_or_create(absname, use_first=True)
        if created:
            print('Created the pseudo for {}'.format(elem))
        else:
            print('Using the pseudo for {} from DB: {}'.format(
                elem, pseudo.pk))
        pseudos_to_use[elem] = pseudo

    for kind, pseudo in six.iteritems(pseudos_to_use):
        calc.use_pseudo(pseudo, kind=kind)

    calc.use_kpoints(kpoints)

    if settings is not None:
        calc.use_settings(settings)

    calc.store_all()
    print("created calculation; calc=Calculation(uuid='{}') # ID={}".format(
        calc.uuid, calc.dbnode.pk))
    calc.submit()
    print("submitted calculation; calc=Calculation(uuid='{}') # ID={}".format(
        calc.uuid, calc.dbnode.pk))

    print('Wating for end of execution...')
    start_time = time.time()
    exited_with_timeout = True
    while time.time() - start_time < timeout_secs:
        time.sleep(15)  # Wait a few seconds

        # print some debug info, both for debugging reasons and to avoid
        # that the test machine is shut down because there is no output

        print('#' * 78)
        print('####### TIME ELAPSED: {} s'.format(time.time() - start_time))
        print('#' * 78)
        print("Output of 'verdi calculation list':")
        try:
            print(
                subprocess.check_output(
                    ['verdi', 'calculation', 'list'],
                    stderr=subprocess.STDOUT,
                ))
        except subprocess.CalledProcessError as exception:
            print('Note: the command failed, message: {}'.format(
                str(exception)))

        if calc.is_terminated:
            print('Calculation terminated its execution')
            exited_with_timeout = False
            break

    if exited_with_timeout:
        print('Timeout!! Calculation did not complete after {} seconds'.format(
            timeout_secs))
        sys.exit(2)
    else:
        if abs(calc.res.energy - expected_energy) < 1.e-3:
            print('OK, energy has the expected value')
            sys.exit(0)
        else:
            print('ERROR!')
            print('Expected energy value: {}'.format(expected_energy))
            print('Actual energy value: {}'.format(calc.res.energy))
            sys.exit(3)
Exemplo n.º 5
0
def read_cif_folder(path=os.getcwd(),
                    recursive=True,
                    store=False,
                    log=False,
                    comments='',
                    extras='',
                    logfile_name='read_cif_folder_logfile'):
    """
    Method to read in cif files from a folder and its subfolders.
    It can convert them into AiiDA structures and store them.

    defaults input parameter values are:
    path=".", recursive=True, store=False, log=False, comments='', extras=''

    :params: path: Path to the dictionary with the files (default, where this method is called)
    :params: recursive: bool, If True: looks aso in subfolders, if False: just given dir
    :params: store: bool, if True: stores structures in database
    :params: log: bool, if True, writes a logfile with information (pks, and co)
    :params: comments: string: comment to add to the structures
    :params: extras: dir/string/arb: extras added to the structures stored in the db

    """
    # TODO check for duplicates in the database, so that reruning the functions
    # won't import anything else in the database
    cifdata = DataFactory('cif')
    ############ parameters for the user to set ########

    parent_cif_folder = path  # folder path
    store_db = store  # True # store stuff in database?
    write_log = log  # write a logfiles on what was saved
    comment = comments  # comments and extras to add to the structure nodes.
    extra = extras  # helpfull for finding them again in the db
    rek = recursive  # search also in subfolders or only given folder

    #####################
    filenames = []
    filepaths = []
    infofilestring = (
        'Structure Formula, Structuredata pk, Structure Data uuid, cif-file-path, comment, extras \n'
    )

    #1. get all the files
    if rek:
        for root, dirs, files in os.walk(parent_cif_folder):
            for file1 in files:
                if file1.endswith('.cif'):
                    filenames.append(file1)
                    filepath = os.path.join(root, file1)
                    filepaths.append(filepath)
    else:
        dir_list = os.listdir(parent_cif_folder)
        for filename in dir_list:
            if filename.endswith('.cif'):
                filenames.append(filename)
                filepath = os.path.join(parent_cif_folder, filename)
                filepaths.append(filepath)

    nfiles = len(filenames)
    print('{} cif-files found in folder "{}" '.format(nfiles,
                                                      parent_cif_folder))

    structuredatas = []

    #2. read all the files and store stuff.
    saved_count = 0
    saved_count_cif = 0
    filenames2 = []
    structuredatas2 = []
    for i in range(nfiles):
        try:
            new_cif = cifdata.get_or_create(filepaths[i], store_cif=True)
        except (ValueError, AttributeError, ImportError) as emessage:
            print(('invalid cif file: {}, the error message was {} '.format(
                filepaths[i], emessage)))
            continue
        #print new_cif
        if new_cif[1]:
            saved_count_cif = saved_count_cif + 1
        # do we want to save the structures again, or do we also continue
        #else:
        #    continue
        #asecell = new_cif[0].get_ase()
        #structuredatas.append(DataFactory('structure'))
        filenames2.append(filenames[i])
        #struc = structuredatas[-1](ase=asecell)
        #formula = struc.get_formula()
        if store_db:
            struc = wf_struc_from_cif(new_cif[0])
            formula = struc.get_formula()
            #new_cif.store()
            #struc.store()
            saved_count = saved_count + 1

            # add comment or extras, only possible after storing
            if comment:
                user = struc.user  # we are the creator
                struc.add_comment(comment, user)
            if extra:
                if isinstance(extra, dict):
                    struc.set_extra_many(extra)
                else:
                    struc.set_extra('specification', extra)
            struc.set_extra('formula', formula)
            structuredatas2.append(struc)
        else:
            struc = struc_from_cif(new_cif[0])
            structuredatas2.append(struc)
            formula = struc.get_formula()
        if write_log:
            # This file is a logfile/info file created by 'read_cif_folder'
            # Structure Formula, structuredata pk, Structure Data uuid,
            #'cif-file-path', comment, extras
            # TODO? if not stored write not stored
            if store_db:
                infofilestring = infofilestring + '{} {} {} {} {} {} \n'.format(
                    formula, struc.pk, struc.uuid, filepaths[i],
                    struc.get_comments(), struc.extras)
            else:
                infofilestring = (infofilestring + '{} notstored notstored {}'
                                  'notstored notstored \n'
                                  ''.format(formula, filepaths[i]))

    # write a logfile
    if write_log:
        file1 = os.open(logfile_name, os.O_RDWR | os.O_CREAT)
        os.write(file1, bytes(infofilestring, 'UTF8'))
        os.close(file1)
    print('{} cif-files and {} structures were saved in the database'.format(
        saved_count_cif, saved_count))

    return structuredatas2, filenames2
Exemplo n.º 6
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