Source code for hzdplugins.aiidaplugins.utilities

from .constants import slurm_options
from copy import deepcopy

[docs]def pwInputToDict(loc_file, atomic_species_list): """ Create the input dictionary from the INP_PWSCF :param loc_file: The location of the input file for pw.x :type loc_file: Python string :param atomic_species_list: contains the order of the atomic species, very useful for the hubbard_u, etc. :type atomic_species_list: Python dictionary :returns: a python dictionary that contains all the relevant information """ # reverse the atomic_species_list r_asl = {v:k for k,v in atomic_species_list.items()} # read the file line by line f = open(loc_file,'r') # some basic keywords levelOneParameters = ['&CONTROL', '&SYSTEM', '&ELECTRONS', '&IONS', '&CELL', 'ATOMIC_SPECIES', 'K_POINTS', 'CELL_PARAMETERS', 'ATOMIC_POSITIONS'] # process each line, and add them to the dictionary input_dict = {} for line in f.readlines(): line = line.rstrip() keyword = line.split(' ')[0].upper() # face /, just move to the next line if keyword == '/': continue # if meet keyword, then start a new key if keyword in levelOneParameters: if '&' in keyword: keyword = keyword.split('&')[1] input_dict[keyword] = {} currentKeyword = keyword # current keyword else: input_dict[keyword] = {} currentKeyword = keyword if keyword in 'CELL_PARAMETERS': input_dict[keyword] = [] elif keyword in 'ATOMIC_POSITIONS': input_dict[keyword] = [] # if it is not the keyword else: lineContent = line.split(' ') tmp_list = [] for item in lineContent: if item != '': tmp_list.append(item) if currentKeyword in ['CONTROL', 'SYSTEM', 'ELECTRONS', 'IONS', 'CELL']: if 'hubbard_u' in tmp_list[0]: if 'hubbard_u' not in list(input_dict[currentKeyword].keys()): input_dict[currentKeyword]['hubbard_u'] = {} input_dict[currentKeyword]['hubbard_u'][r_asl[int(tmp_list[0][-2])]] = tmp_list[2] else: input_dict[currentKeyword]['hubbard_u'][r_asl[int(tmp_list[0][-2])]] = tmp_list[2] elif 'starting_magnetization' in tmp_list[0]: if 'starting_magnetization' not in list(input_dict[currentKeyword].keys()): input_dict[currentKeyword]['starting_magnetization'] = {} input_dict[currentKeyword]['starting_magnetization'][r_asl[int(tmp_list[0][-2])]] = tmp_list[2] else: input_dict[currentKeyword]['starting_magnetization'][r_asl[int(tmp_list[0][-2])]] = tmp_list[2] elif 'starting_ns_eigenvalue' in tmp_list[0]: if 'starting_ns_eigenvalue' not in list(input_dict[currentKeyword].keys()): input_dict[currentKeyword]['starting_ns_eigenvalue'] = [] snm_list = [ int(tmp_list[0][-6]), int(tmp_list[0][-4]), r_asl[int(tmp_list[0][-2])], tmp_list[2] ] input_dict[currentKeyword]['starting_ns_eigenvalue'].append(snm_list) else: snm_list = [ int(tmp_list[0][-6]), int(tmp_list[0][-4]), r_asl[int(tmp_list[0][-2])], tmp_list[2] ] input_dict[currentKeyword]['starting_ns_eigenvalue'].append(snm_list) else: input_dict[currentKeyword][tmp_list[0]] = tmp_list[2] elif currentKeyword in 'ATOMIC_SPECIES': input_dict[currentKeyword][tmp_list[0]] = { 'atomic_weight': tmp_list[1], 'pseudopotential': tmp_list[2] } elif currentKeyword in 'K_POINTS': input_dict[currentKeyword] = { 'kpoints': [int(item) for item in tmp_list[0:3]], 'displacement': [int(item) for item in tmp_list[3:]] } elif currentKeyword in 'CELL_PARAMETERS': tmp_list = [float(item) for item in tmp_list] input_dict[currentKeyword].append(tmp_list) elif currentKeyword in 'ATOMIC_POSITIONS': tmp_list = [tmp_list[0]] + [float(item) for item in tmp_list[1:]] input_dict[currentKeyword].append(tmp_list) f.close() return input_dict
[docs]def listToStr(l, separator): """ :param l: the list that we want to print :type l: Python list :param separator: the separator that we want to add, e.g. ' ' (space), etc. :type separator: Python string """ tmp_str = str(l[0]) for i in l[1:-1]: tmp_str += separator + str(i) tmp_str += separator + str(l[-1]) return tmp_str
[docs]def dictToPwInput(dict_input, location, atomic_species_list): """ To convert the dictionary to the input file for pw.x :param dict_input: contains all the information about the structure :type dict_input: Python dictionary :param location: contains the location of the output file :type location: Python string :param atomic_species_list: contains the order of the atomic species, very useful for the hubbard_u, etc. :type atomic_species_list: Python dictionary :returns: a file named in location """ f = open(location, 'w') for key, value in dict_input.items(): if key.upper() in ['CONTROL', 'SYSTEM', 'ELECTRONS', 'IONS', 'CELL']: f.write('&{}\n'.format(key)) for param, p_v in value.items(): if 'hubbard_u' in param: for k, v in p_v.items(): f.write(' hubbard_u({}) = {}\n'.format(atomic_species_list[k], v)) elif 'starting_magnetization' in param: for k, v in p_v.items(): f.write(' starting_magnetization({}) = {}\n'.format(atomic_species_list[k], v)) elif 'starting_ns_eigenvalue' in param: for l in p_v: f.write(' starting_ns_eigenvalue({},{},{}) = {}\n'.format(l[0], l[1], atomic_species_list[l[2]], l[3])) else: f.write(' {} = {}\n'.format(param, p_v)) f.write('/\n') elif key.upper() in ['ATOMIC_SPECIES']: f.write('{}\n'.format(key)) for element, e_v in value.items(): f.write('{} {} {}\n'.format(element, e_v['atomic_weight'], e_v['pseudopotential'])) elif key.upper() in ['K_POINTS']: kpts = value['kpoints'] disp = value['displacement'] f.write('K_POINTS automatic\n') f.write('{} {} {} {} {} {}\n'.format( kpts[0], kpts[1], kpts[2],\ disp[0], disp[1], disp[2] )) elif key.upper() in ['CELL_PARAMETERS']: f.write('CELL_PARAMETERS (angstrom)\n') tmp_str = '' for l in value: f.write('{}\n'.format(listToStr(l, ' '))) elif key.upper() in ['ATOMIC_POSITIONS']: f.write('ATOMIC_POSITIONS (angstrom)\n') for l in value: f.write('{}\n'.format(listToStr(l, ' '))) else: pass f.close()
[docs]def getSubmitFile(filename, computer, typeCalculation, inpDict): """ This function can help us generate the submitting file for the supercomputer. :param location: the filename of the submitting script :type location: Python string :param computer: the name of the computer that we want to run on, the options are: ['rwth-claix', 'juwels-mac', 'jureca-dc-mac', 'jureca-booster-mac'] (currently) :type computer: Pythong string :param typeCalculation: the type of the simulation that we want to conduct :type typeCalculation: Python string (e.g. ['qe'] or others) :param inpDict: The dictionary that contains all the information that we need for constructing the input file. All the keywords are: ['job_name', 'scheduler_stdout', 'scheduler_stderr', 'queue_name', 'account', 'resources', 'max_wallclock_seconds', 'modules', 'cmd', 'ntasks_per_node'] :type inpDict: Python dictionary :return: a file named filename, no other return """ f = open(filename, 'w') tmpDict = deepcopy(slurm_options[computer+'-mac'][typeCalculation]) for k, v in inpDict.items(): if k == 'resources': for k1, v1 in v.items(): tmpDict[k][k1] = v1 else: tmpDict[k] = v f.write('#!/bin/bash\n') for k, v in tmpDict.items(): # choose different things to f.write if k == 'job_name': f.write('#SBATCH --job-name={}\n'.format(v)) if k == 'scheduler_stdout': f.write('#SBATCH --output={}\n'.format(v)) if k == 'scheduler_stderr': f.write('#SBATCH --error={}\n'.format(v)) if k == 'queue_name': f.write('#SBATCH --partition={}\n'.format(v)) if k == 'account': f.write('#SBATCH --account={}\n'.format(v)) if k == 'resources': f.write('#SBATCH --nodes={}\n'.format(v['num_machines'])) if 'gpus' in list(v.keys()): f.write('#SBATCH --gres:gpu={}\n'.format(v['gpus'])) if k == 'ntasks_per_node': f.write('#SBATCH --ntasks-per-node={}\n'.format(v)) if k == 'max_wallclock_seconds': hours = v // 3600 minutes = v % 3600 // 60 seconds = v % 3600 % 60 f.write('#SBATCH --time={:02d}:{:02d}:{:02d}\n'.format(hours,minutes,seconds)) if k == 'use': for item in v: f.write('module use {}\n'.format(item)) if k == 'modules': for item in v: f.write('module load {}\n'.format(item)) if k == 'cmd': f.write('{}\n'.format(v)) f.close()