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,
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
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)
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
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