def test_get_value(self): p = kkrparams(LMAX=3) # check for KeyError if wrong key is checked known_error = False try: p.get_value('something_wrong') except KeyError: known_error = True assert known_error # check for returning unset value npol = p.get_value('NPOL') assert npol == None # check correct LMAX value lmax = p.get_value('LMAX') assert lmax == 3 # check for returning lists for RUNOPT and TESTOPT runopt = p.get_value('RUNOPT') testopt = p.get_value('TESTOPT') assert runopt == [] assert testopt == [] p = kkrparams(TESTOPT=['test1', 'test2'], RUNOPT=['NEWSOSOL']) runopt = p.get_value('RUNOPT') testopt = p.get_value('TESTOPT') assert runopt == ['NEWSOSOL'] assert set(testopt) == set(['test1', 'test2'])
def test_read_unsorted_inputfile(self): p = kkrparams(ZATOM=26., LMAX=2, NAEZ=1, BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], RCLUSTZ=1.5, NSPIN=2, RBASIS=[0, 0, 0], ALATBASIS=1, RMAX=7, GMAX=65) p.fill_keywords_to_inputfile(output='input.temp.txt') txt = open('input.temp.txt', 'r').readlines() # exchange some lines tmp = txt[0] txt[0] = txt[5] txt[5] = tmp tmp = txt[-1] txt[-1] = txt[-2] txt[-2] = tmp tmp = txt[-2] txt[-2] = txt[-4] txt[-4] = tmp tmp = txt[-3] txt[-3] = txt[-1] txt[-1] = tmp open('input.temp_unsorted.txt', 'w').writelines(txt) p2 = kkrparams() p2.read_keywords_from_inputcard(inputcard='input.temp_unsorted.txt') print(p2.get_dict()) print(dict(p2.get_set_values())) check_full_dict(p, p2)
def _extract_and_write_config(self, parent_calc_folder, params_host, parameters, tempfolder): """ fill kkr params for KKRimp and write config file """ # initialize kkrimp parameter set with default values params_kkrimp = kkrparams(params_type='kkrimp', NPAN_LOGPANELFAC=2, RADIUS_MIN=-1, NCOLL=0, SPINORBIT=0, SCFSTEPS=1, IMIX=0, MIXFAC=0.05, ITDBRY=20, BRYMIX=0.05, QBOUND=10**-7, RUNFLAG=[], TESTFLAG=[], HFIELD=[0.0, 0], CALCFORCE=0, CALCJIJMAT=0, CALCORBITALMOMENT=0, ICST=2) # keys that are being overwritten from host calculation settings keys_overwrite = ['NSPIN', 'KVREL', 'XC', 'INS', 'ICST', 'RADIUS_LOGPANELS', 'NPAN_EQ', 'NPAN_LOG', 'NCHEB', 'QBOUND'] for key in keys_overwrite: if key=='XC': key0 = 'KEXCOR' elif key=='RADIUS_LOGPANELS': key0 = 'R_LOG' elif key=='MIXFAC': key0 = 'STRMIX' else: key0 = key val = params_host.get_value(key0) if val is not None: params_kkrimp.set_value(key, val) # settings for SOC solver runopts = params_host.get_value('RUNOPT') if 'NEWSOSOL' in runopts: params_kkrimp.set_multiple_values(NCOLL=1, SPINORBIT=1, CALCORBITALMOMENT=1, TESTFLAG=['tmatnew']) else: params_kkrimp.set_multiple_values(NCOLL=0, SPINORBIT=0, CALCORBITALMOMENT=0, TESTFLAG=[]) # special settings runopts = params_host.get_value('RUNOPT') if 'SIMULASA' in runopts or (params_kkrimp.get_value('NCOLL')>0 and params_kkrimp.get_value('INS')>0): params_kkrimp.set_value('RUNFLAG', ['SIMULASA']) else: params_kkrimp.set_value('RUNFLAG', []) # overwrite keys if found in parent_calc if parent_calc_folder is not None: params_parent = parent_calc_folder.get_inputs_dict().get('parameters', None) else: params_parent = None if params_parent is not None: params_parent = kkrparams(params_type='kkr', **params_parent.get_dict()) for (key, val) in params_parent.get_set_values(): self._check_key_setting_consistency(params_kkrimp, key, val) params_kkrimp.set_value(key, val) # overwrite from input parameters if parameters is not None: for (key, val) in parameters.get_set_values(): self._check_key_setting_consistency(params_kkrimp, key, val) params_kkrimp.set_value(key, val) # write config.cfg config_filename = tempfolder.get_abs_path(self._CONFIG) params_kkrimp.fill_keywords_to_inputfile(output=config_filename)
def test_read_minimal_inputfile(self): p = kkrparams(ZATOM=26., LMAX=2, NAEZ=1, BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], RCLUSTZ=1.5, NSPIN=2, RBASIS=[0, 0, 0], ALATBASIS=1) p.fill_keywords_to_inputfile(is_voro_calc=True) p2 = kkrparams(params_type='voronoi') p2.read_keywords_from_inputcard() check_full_dict(p, p2)
def test_get_mandatory(self): p = kkrparams() manlist = p.get_all_mandatory() assert set(manlist) == set([ 'LMAX', 'NAEZ', 'BRAVAIS', 'RMAX', 'GMAX', 'NSPIN', '<RBASIS>', 'ALATBASIS', '<ZATOM>' ])
def test_set_rmtcore(self): #test rmtcore from numpy import array from aiida_kkr.tools.common_functions import search_string para_dict = dict([ (u'INS', 0), (u'RCLUSTZ', 1.69), (u'LMAX', 2), (u'GMAX', 65.0), (u'<RMTCORE>', [0.3535533906, 0.3535533906, 0.3535533906, 0.3535533906]), (u'RMAX', 7.0), (u'NSPIN', 1) ]) zatom = array([47., 47., 47., 47.]) alat = 7.8692316414074615 natom = 4 positions = array([[0., 0., 0.], [0., 0.5, 0.5], [0.5, 0., 0.5], [0.5, 0.5, 0.]]) bravais = array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) k = kkrparams(**para_dict) k.set_multiple_values(ZATOM=zatom, NAEZ=natom, ALATBASIS=alat, RBASIS=positions, BRAVAIS=bravais) k.fill_keywords_to_inputfile() txt = open('inputcard').readlines() naez = int(txt[search_string('NAEZ', txt)].split()[-1]) rmtcore = [] l_offset = search_string('RMTCORE', txt) for iatom in range(naez): rmtcore_at = float(txt[l_offset + 1 + iatom].split()[-1]) rmtcore.append(rmtcore_at) maxdiff = (max(abs(array(para_dict['<RMTCORE>']) - array(rmtcore)))) assert maxdiff < 10**-6
def test_fill_inputfile_KKR(self): reffile = [ 'ALATBASIS= 1.00000000000000\n', 'BRAVAIS\n', '1.00000000000000 0.00000000000000 0.00000000000000\n', '<ZATOM>\n', '29.00000000000000\n', '0.00000000000000 1.00000000000000 0.00000000000000\n', '0.00000000000000 0.00000000000000 1.00000000000000\n', 'NAEZ= 1\n', '<RBASIS>\n', '0.00000000000000 0.00000000000000 0.00000000000000\n', 'NSPIN= 2\n', 'LMAX= 2\n', 'RCLUSTZ= 1.50000000000000\n', 'RMAX= 7.00000000000000\n', 'GMAX= 65.00000000000000\n' ] p = kkrparams(ZATOM=29., LMAX=2, NAEZ=1, BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], RMAX=7, GMAX=65, RCLUSTZ=1.5, NSPIN=2, RBASIS=[0, 0, 0], ALATBASIS=1) p.fill_keywords_to_inputfile() txt = open('inputcard').readlines() done = False while not done: try: txt.remove('\n') except ValueError: done = True assert len(txt) == len(reffile) txt.sort() reffile.sort() for i in range(len(txt)): assert set(txt[i].split()) == set(reffile[i].split())
def test_fill_inputfile_minimal_Voronoi(self): p = kkrparams(ZATOM=29., LMAX=2, NAEZ=1, BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], RCLUSTZ=1.5, NSPIN=2, RBASIS=[0, 0, 0], ALATBASIS=1) p.fill_keywords_to_inputfile(is_voro_calc=True) txt = open('inputcard').readlines() ref = [ 'ALATBASIS= 1.00000000000000\n', 'BRAVAIS\n', '1.00000000000000 0.00000000000000 0.00000000000000\n', '0.00000000000000 1.00000000000000 0.00000000000000\n', '0.00000000000000 0.00000000000000 1.00000000000000\n', 'NAEZ= 1\n', '<RBASIS>\n', '0.00000000000000 0.00000000000000 0.00000000000000\n', '<ZATOM>\n', '29.00000000000000\n', 'NSPIN= 2\n', 'LMAX= 2\n', 'RCLUSTZ= 1.50000000000000\n' ] done = False while not done: try: txt.remove('\n') except ValueError: done = True assert len(txt) == len(ref) txt.sort() ref.sort() print(txt, ref) for i in range(len(txt)): print(i, txt[i], ref[i]) assert set(txt[i].split()) == set(ref[i].split())
def test_get_set_values2(self): from numpy import array p = kkrparams() p.set_multiple_values(EMIN=1, EMAX=2) setlist = p.get_set_values() assert set(array(setlist).flatten()) == set( array([['EMIN', 1.], ['EMAX', 2.]]).flatten())
def test_get_missing_keys(self): p = kkrparams() missing = p.get_missing_keys() assert set(missing) == set([ '<ZATOM>', 'BRAVAIS', 'LMAX', 'GMAX', 'RMAX', 'NAEZ', '<RBASIS>', 'NSPIN', 'ALATBASIS' ]) missing = p.get_missing_keys(use_aiida=True) assert set(missing) == set(['LMAX', 'GMAX', 'RMAX', 'NSPIN']) p = kkrparams(params_type='voronoi', EMIN=-2, LMAX=3) missing = p.get_missing_keys() assert set(missing) == set([ '<ZATOM>', 'BRAVAIS', 'RCLUSTZ', 'NAEZ', '<RBASIS>', 'NSPIN', 'ALATBASIS' ])
def test_fill_inputfile_empty_check(self): p = kkrparams(LMAX=2, NAEZ=1) known_error = False try: p.fill_keywords_to_inputfile() except ValueError: known_error = True assert known_error
def test_set_value_None(self): p = kkrparams() p.set_value('EMIN', -1) assert p.values['EMIN'] == -1 p.set_value('EMIN', None) assert p.values['EMIN'] == -1 p.remove_value('EMIN') assert p.values['EMIN'] is None
def test_wrong_input_type(self): p = kkrparams() known_error = False try: p.set_value('EMIN', '2') except TypeError: known_error = True assert known_error known_error = False try: p.set_value('EMIN', False) except TypeError: known_error = True assert known_error
def test_inconsistency_bulk_mode_bravais(self): p = kkrparams(LMAX=2, NAEZ=1, BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 0]], NSPIN=2, RBASIS=[0, 0, 0], ALATBASIS=1, RMAX=7, GMAX=65, ZATOM=29.) knownError = False try: p.fill_keywords_to_inputfile() except ValueError: knownError = True assert knownError
def test_input_consistency_check_fail(self): knownError = False try: p = kkrparams(ZATOM=29., LMAX=2, NAEZ=1, BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], RMAX=7, GMAX=65, NSPIN=2, RBASIS=[0, 0, 0], ALATBASIS=1) p.set_value('LDAU_PARA', [1, 2]) p._check_input_consistency() except TypeError: knownError = True assert knownError
def test_wrong_input_array_dimension(self): p = kkrparams() from numpy import array, sqrt bravais = array([[0.7071067812, -0.5, 0.0], [0.7071067812, 0.5, 0.0], [sqrt(2), 0.0, 0.866025404]]) # atom positions in relative coordinates basis_vectors = [] for iatom in range(6): tmp = array([0, 0, 0]) + iatom * array([0.5, 0.5, bravais[2, 2]]) tmp[0] = tmp[0] % 1 tmp[1] = tmp[1] % 1 print(iatom, tmp) basis_vectors.append(tmp) basis_vectors = array(basis_vectors) p.set_value('INTERFACE', True) p.set_value('<RBLEFT>', array([[1, 1], [0, 1]]))
def test_update_params_wf(self): from aiida_kkr.tools.common_workfunctions import update_params_wf from aiida_kkr.tools.kkr_params import kkrparams from aiida.orm import DataFactory ParameterData = DataFactory('parameter') k = kkrparams(LMAX=2) node1 = ParameterData(dict=k.values) node2 = ParameterData( dict={ 'nodename': 'my_changed_name', 'nodedesc': 'My description text', 'EMIN': -1, 'RMAX': 10. }) unode = update_params_wf(node1, node1) assert unode == node1 unode = update_params_wf(node1, node2) d0 = node1.get_dict() for i in d0.keys(): if d0[i] is None: d0.pop(i) d1 = unode.get_dict() for i in d1.keys(): if d1[i] is None: d1.pop(i) l_identical, l_diff = [], [] for i in d0.keys(): if i in d1.keys(): l_identical.append([i, d0[i], d1[i]]) else: l_diff.append([0, i, d0[i]]) for i in d1.keys(): if i not in d0.keys(): l_diff.append([1, i, d1[i]]) assert l_identical == [[u'LMAX', 2, 2]] assert l_diff == [[1, u'RMAX', 10.0], [1, u'EMIN', -1.0]] return node1, node2, unode
def test_set_kkrimp_params_full(self): p = kkrparams(params_type='kkrimp') p.set_multiple_values(CALCORBITALMOMENT=0, RUNFLAG='', QBOUND=10**-7, NSPIN=1, TESTFLAG='', NPAN_EQ=7, CALCFORCE=0, NPAN_LOGPANELFAC=2, SPINORBIT=0, ITDBRY=20, NPAN_LOG=5, INS=1, ICST=2, CALCJIJMAT=0, NCHEB=10, HFIELD=[0.00, 0], BRYMIX=0.05, KVREL=1, IMIX=0, RADIUS_MIN=-1, NCOLL=0, RADIUS_LOGPANELS=0.6, MIXFAC=0.05, SCFSTEPS=1, XC='LDA-VWN') p.fill_keywords_to_inputfile(output='config.cfg') reftxt = [ 'RUNFLAG=\n', 'TESTFLAG=\n', '\n', 'INS= 1\n', 'KVREL= 1\n', 'NSPIN= 1\n', '\n', 'SCFSTEPS= 1\n', 'IMIX= 0\n', 'ITDBRY= 20\n', 'MIXFAC= 0.05000000000000\n', 'BRYMIX= 0.05000000000000\n', 'QBOUND= 1.000000e-07\n', '\n', 'XC= LDA-VWN\n', 'ICST= 2\n', 'SPINORBIT= 0\n', 'NCOLL= 0\n', 'NPAN_LOGPANELFAC= 2\n', 'RADIUS_LOGPANELS= 0.60000000000000\n', 'RADIUS_MIN= -1\n', 'NPAN_LOG= 5\n', 'NPAN_EQ= 7\n', 'NCHEB= 10\n', '\n', 'HFIELD= 0.00000000000000 0\n', '\n', 'CALCORBITALMOMENT= 0\n', 'CALCFORCE= 0\n', 'CALCJIJMAT= 0\n' ] txt = open('config.cfg').readlines() assert txt == reftxt
def test_set_potname_empty(self): p = kkrparams() p.set_multiple_values(RMAX=1, GMAX=1, NSPIN=1, RBASIS=[0, 0, 0], LMAX=2, RCLUSTZ=1.2, NAEZ=1, ZATOM=[0], BRAVAIS=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], ALATBASIS=1, FILES=['', 'shapenew']) p.fill_keywords_to_inputfile() from aiida_kkr.tools.common_functions import search_string txt = open('inputcard').readlines() itmp = search_string('FILES', txt) potname = txt[itmp + 2].split()[0] shapename = txt[itmp + 4].split()[0] assert 'potential' == potname assert 'shapenew' == shapename
# initial structure ################################################### # create Copper bulk aiida Structure alat = 3.61 # lattice constant in Angstroem bravais = alat * array([[0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5] ]) # Bravais matrix in Ang. units Cu = StructureData(cell=bravais) Cu.append_atom(position=[0, 0, 0], symbols='Cu') ################################################### # Voronoi step (preparation of starting potential) ################################################### # create empty set of KKR parameters (LMAX cutoff etc. ) for voronoi code params = kkrparams(params_type='voronoi') # and set at least the mandatory parameters params.set_multiple_values(LMAX=2, NSPIN=1, RCLUSTZ=2.3) # finally create an aiida ParameterData node and fill with the dictionary of parameters ParaNode = ParameterData(dict=params.get_dict()) # choose a valid installation of the voronoi code ### !!! adapt to your code name !!! ### codename = 'voronoi@my_mac' code = Code.get_from_string(codename) # create new instance of a VoronoiCalculation voro_calc = code.new_calc()
def create_input_nodes(self, open_transport, input_file_names=None, output_file_names=None, remote_workdir=None): """ Create calculation input nodes based on the job's files. :param open_transport: An open instance of the transport class of the calculation's computer. See the tutorial for more information. :type open_transport: aiida.transport.plugins.local.LocalTransport or aiida.transport.plugins.ssh.SshTransport This method parses the files in the job's remote working directory to create the input nodes that would exist if the calculation were submitted using AiiDa. These nodes are: * a ``'parameters'`` ParameterData node, based on the namelists and their variable-value pairs; * ...; and can be retrieved as a dictionary using the ``get_inputs_dict()`` method. *These input links are cached-links; nothing is stored by this method (including the calculation node itself).* **Keyword arguments** .. note:: These keyword arguments can also be set when instantiating the class or using the ``set_`` methods (e.g. ``set_remote_workdir``). Offering to set them here simply offers the user an additional place to set their values. *Only the values that have not yet been set need to be specified.* :param input_file_names: The file name of the job's input files (inputcard, shapefun). :type input_file_names: dict of str values :param output_file_names: The file name of the job's output files (i.e. the files containing the stdout of KKR, the output.000.txt, output.0.txt, output.2.txt, out_timing.txt, output potential, output nonco_angle file). :type output_file_names: dict of str values :param remote_workdir: Absolute path to the directory where the job was run. The transport of the computer you link ask input to the calculation is the transport that will be used to retrieve the calculation's files. Therefore, ``remote_workdir`` should be the absolute path to the job's directory on that computer. :type remote_workdir: str :raises aiida.common.exceptions.InputValidationError: if ``open_transport`` is a different type of transport than the computer's. :raises aiida.common.exceptions.InvalidOperation: if ``open_transport`` is not open. :raises aiida.common.exceptions.InputValidationError: if ``remote_workdir``, ``input_file_names``, and/or ``output_file_names`` are not set prior to or during the call of this method. :raises aiida.common.exceptions.FeatureNotAvailable: if the input file uses anything which is not currently implimented in aiida-kkr. :raises aiida.common.exceptions.ParsingError: if there are issues parsing the input file. :raises IOError: if there are issues reading the input file. """ # Make sure the remote workdir and input + output file names were # provided either before or during the call to this method. If they # were just provided during this method call, store the values. if remote_workdir is not None: self.set_remote_workdir(remote_workdir) elif self.get_attr('remote_workdir', None) is None: raise InputValidationError( 'The remote working directory has not been specified.\n' 'Please specify it using one of the following...\n ' '(a) pass as a keyword argument to create_input_nodes\n' ' [create_input_nodes(remote_workdir=your_remote_workdir)]\n' '(b) pass as a keyword argument when instantiating\n ' ' [calc = KkrImporterCalculation(remote_workdir=your_remote_workdir)]\n' '(c) use the set_remote_workdir method\n' ' [calc.set_remote_workdir(your_remote_workdir)]') # check if necessary input file names are given and set filenames from dict self.set_input_file_names(input_file_names) # set output file names instead of using defaults self.set_output_file_names(output_file_names) # Check that open_transport is the correct transport type. if type(open_transport) is not self.get_computer().get_transport_class( ): raise InputValidationError( "The transport passed as the `open_transport` parameter is " "not the same transport type linked to the computer. Please " "obtain the correct transport class using the " "`get_transport_class` method of the calculation's computer. " "See the tutorial for more information.") # Check that open_transport is actually open. if not open_transport._is_open: raise InvalidOperation( "The transport passed as the `open_transport` parameter is " "not open. Please execute the open the transport using it's " "`open` method, or execute the call to this method within a " "`with` statement context guard. See the tutorial for more " "information.") # Copy the input file and psuedo files to a temp folder for parsing. with SandboxFolder() as folder: # Copy the input file to the temp folder. remote_path = os.path.join(self._get_remote_workdir(), self._INPUT_FILE_NAME) open_transport.get(remote_path, folder.abspath) # Parse the input file. local_path = os.path.join(folder.abspath, self._INPUT_FILE_NAME) parameters = kkrparams(params_type='kkr') parameters.read_keywords_from_inputcard(inputcard=local_path) # Create ParameterData node based on the namelist and link as input. aiida_parameters = ParameterData(dict=parameters.get_dict()) self.use_parameters(aiida_parameters) # Create a StructureData node from inputs success, structuredata = structure_from_params(parameters) if not success: raise InputValidationError( 'Something went wrong when creating the an aiida structure from your input file. Check you input' ) self.use_structure(structuredata) self._set_attr('input_nodes_created', True)
def set_params_dos(self): """ take input parameter node and change to DOS contour according to input from wf_parameter input internally calls the update_params work function to keep track of provenance """ params = self.ctx.input_params_KKR input_dict = params.get_dict() para_check = kkrparams() # step 1 try to fill keywords try: for key, val in input_dict.iteritems(): para_check.set_value(key, val, silent=True) except: error = 'ERROR: calc_parameters given are not consistent! Hint: did you give an unknown keyword?' self.ctx.errors.append(error) self.control_end_wc(error) # step 2: check if all mandatory keys are there label = '' descr = '' missing_list = para_check.get_missing_keys(use_aiida=True) if missing_list != []: kkrdefaults = kkrparams.get_KKRcalc_parameter_defaults()[0] kkrdefaults_updated = [] for key_default, val_default in kkrdefaults.items(): if key_default in missing_list: para_check.set_value(key_default, kkrdefaults.get(key_default), silent=True) kkrdefaults_updated.append(key_default) missing_list.remove(key_default) if len(missing_list) > 0: error = 'ERROR: calc_parameters misses keys: {}'.format( missing_list) self.ctx.errors.append(error) self.control_end_wc(error) else: self.report( 'updated KKR parameter node with default values: {}'. format(kkrdefaults_updated)) label = 'add_defaults_' descr = 'added missing default keys, ' # overwrite energy contour to DOS contour no matter what is in input parameter node. # Contour parameter given as input to workflow. econt_new = self.ctx.dos_params_dict # always overwrite NPOL, N1, N3, thus add these to econt_new econt_new['NPOL'] = 0 econt_new['NPT1'] = 0 econt_new['NPT3'] = 0 try: for key, val in econt_new.iteritems(): if key == 'kmesh': key = 'BZDIVIDE' elif key == 'nepts': key = 'NPT2' elif key == 'emin': key = 'EMIN' elif key == 'emax': key = 'EMAX' elif key == 'tempr': key = 'TEMPR' # set params para_check.set_value(key, val, silent=True) except: error = 'ERROR: dos_params given in wf_params are not valid!' self.ctx.errors.append(error) self.control_end_wc(error) updatenode = ParameterData(dict=para_check.get_dict()) updatenode.label = label + 'KKRparam_DOS' updatenode.description = descr + 'KKR parameter node extracted from parent parameters and wf_parameter input node.' paranode_dos = update_params_wf(self.ctx.input_params_KKR, updatenode) self.ctx.dos_kkrparams = paranode_dos
N = 0 print 'start waiting for calculation to finish' while not calc.has_finished() and N < (maxwait / 2.): N += 1 if N % 5 == 0: print('.') sleep(2.) print('waiting done after {} seconds: {} {}'.format( N * 2, calc.has_finished(), calc.has_finished_ok())) ################################################################################################ # first host GF with DOS contour from aiida_kkr.tools.kkr_params import kkrparams params = kkrparams(**GF_host_calc.inp.parameters.get_dict()) params.set_multiple_values(EMIN=emin, EMAX=GF_host_calc.res.fermi_energy + dE_emax, NPOL=0, NPT1=0, NPT2=npt, NPT3=0) ParaNode = ParameterData(dict=params.get_dict()) code = GF_host_calc.get_code( ) # take the same code as in the calculation before GF_host_doscalc = code.new_calc() resources = GF_host_calc.get_resources() GF_host_doscalc.set_resources(resources) GF_host_doscalc.use_parameters(ParaNode) GF_host_doscalc.use_parent_folder(kkr_converged_parent_folder)
def generate_inputcard_from_structure(parameters, structure, input_filename, parent_calc=None, shapes=None, isvoronoi=False, use_input_alat=False, vca_structure=False): """ Takes information from parameter and structure data and writes input file 'input_filename' :param parameters: input parameters node containing KKR-related input parameter :param structure: input structure node containing lattice information :param input_filename: input filename, typically called 'inputcard' optional arguments :param parent_calc: input parent calculation node used to determine if EMIN parameter is automatically overwritten (from voronoi output) or not :param shapes: input shapes array (set automatically by aiida_kkr.calculations.Kkrcaluation and shall not be overwritten) :param isvoronoi: tell whether or not the parameter set is for a voronoi calculation or kkr calculation (have different lists of mandatory keys) :param use_input_alat: True/False, determines whether the input alat value is taken or the new alat is computed from the Bravais vectors :note: assumes valid structure and parameters, i.e. for 2D case all necessary information has to be given. This is checked with function 'check_2D_input' called in aiida_kkr.calculations.Kkrcaluation """ from aiida.common.constants import elements as PeriodicTableElements from numpy import array from aiida_kkr.tools.kkr_params import kkrparams from aiida_kkr.tools.common_functions import get_Ang2aBohr, get_alat_from_bravais from aiida_kkr.calculations.voro import VoronoiCalculation #list of globally used constants a_to_bohr = get_Ang2aBohr() # Get the connection between coordination number and element symbol # maybe do in a differnt way _atomic_numbers = { data['symbol']: num for num, data in PeriodicTableElements.iteritems() } # KKR wants units in bohr bravais = array(structure.cell) * a_to_bohr alat_input = parameters.get_dict().get('ALATBASIS') if use_input_alat and alat_input is not None: alat = alat_input else: alat = get_alat_from_bravais(bravais, is3D=structure.pbc[2]) bravais = bravais / alat sites = structure.sites naez = len(sites) positions = [] charges = [] weights = [] # for CPA isitelist = [] # counter sites array for CPA isite = 0 for site in sites: pos = site.position #TODO maybe convert to rel pos and make sure that type is right for script (array or tuple) abspos = array(pos) * a_to_bohr / alat # also in units of alat positions.append(abspos) isite += 1 sitekind = structure.get_kind(site.kind_name) for ikind in range(len(sitekind.symbols)): site_symbol = sitekind.symbols[ikind] if sitekind.is_alloy(): wght = sitekind.weights[ikind] else: wght = 1. if not sitekind.has_vacancies(): zatom_tmp = _atomic_numbers[site_symbol] else: zatom_tmp = 0.0 if vca_structure and ikind > 0 and not isvoronoi: # for VCA case take weighted average (only for KKR code, voronoi code uses zatom of first site for dummy calculation) zatom = zatom * wght_last + zatom_tmp * wght # also reset weight to 1 wght = 1. else: zatom = zatom_tmp if vca_structure and isvoronoi: wght = 1. wght_last = wght # for VCA mode # make sure that for VCA only averaged position is written (or first for voronoi code) if ((vca_structure and ((len(sitekind.symbols) == 1) or (not isvoronoi and ikind == 1) or (isvoronoi and ikind == 0))) or (not vca_structure)): charges.append(zatom) weights.append(wght) isitelist.append(isite) weights = array(weights) isitelist = array(isitelist) charges = array(charges) positions = array(positions) # workaround for voronoi calculation with Zatom=83 (Bi potential not there!) if isvoronoi: from numpy import where mask_replace_Bi_Pb = where(charges == 83) charges[mask_replace_Bi_Pb] = 82 print('WARNING: Bi potential not available, using Pb instead!!!') ###################################### # Prepare keywords for kkr from input structure # get parameter dictionary input_dict = parameters.get_dict() # remove special keys that are used for special cases but are not part of the KKR parameter set for key in _ignored_keys: if input_dict.get(key) is not None: print('WARNING: automatically removing value of key', key) input_dict.pop(key) # get rid of structure related inputs that are overwritten from structure input for key in [ 'BRAVAIS', 'ALATBASIS', 'NAEZ', '<ZATOM>', '<RBASIS>', 'CARTESIAN' ]: if input_dict.get(key) is not None: print('WARNING: automatically removing value of key', key) input_dict.pop(key) # automatically rescale RMAX, GMAX, RCLUSTZ, RCLUSTXY which are scaled with the lattice constant if alat_input is not None: if input_dict.get('RMAX') is not None: print('rescale RMAX', alat_input / alat) input_dict['RMAX'] = input_dict['RMAX'] * alat_input / alat if input_dict.get('GMAX') is not None: print('rescale GMAX', 1 / (alat_input / alat)) input_dict['GMAX'] = input_dict['GMAX'] * 1 / (alat_input / alat) if input_dict.get('RCLUSTZ') is not None: print('rescale RCLUSTZ', alat_input / alat) input_dict['RCLUSTZ'] = input_dict['RCLUSTZ'] * alat_input / alat if input_dict.get('RCLUSTXY') is not None: print('rescale RCLUSTXY', alat_input / alat) input_dict['RCLUSTXY'] = input_dict['RCLUSTXY'] * alat_input / alat # empty kkrparams instance (contains formatting info etc.) if not isvoronoi: params = kkrparams() else: params = kkrparams(params_type='voronoi') # for KKR calculation set EMIN automatically from parent_calc (ausways in res.emin of voronoi and kkr) if ('EMIN' not in input_dict.keys() or input_dict['EMIN'] is None) and parent_calc is not None: print('Overwriting EMIN with value from parent calculation') if isinstance(parent_calc, VoronoiCalculation): emin = parent_calc.res.emin else: emin = parent_calc.res.energy_contour_group['emin'] print('Setting emin:', emin, 'is emin None?', emin is None) params.set_value('EMIN', emin) # overwrite keywords with input parameter for key in input_dict.keys(): params.set_value(key, input_dict[key], silent=True) # Write input to file (the parameters that are set here are not allowed to be modfied externally) params.set_multiple_values(BRAVAIS=bravais, ALATBASIS=alat, NAEZ=naez, ZATOM=charges, RBASIS=positions, CARTESIAN=True) # for CPA case: if len(weights) > naez: natyp = len(weights) params.set_value('NATYP', natyp) params.set_value('<CPA-CONC>', weights) params.set_value('<SITE>', isitelist) else: natyp = naez # write shapes (extracted from voronoi parent automatically in kkr calculation plugin) if shapes is not None: params.set_value('<SHAPE>', shapes) # change input values of 2D input to new alat: rbl = params.get_value('<RBLEFT>') rbr = params.get_value('<RBRIGHT>') zper_l = params.get_value('ZPERIODL') zper_r = params.get_value('ZPERIODR') if rbl is not None: params.set_value('<RBLEFT>', array(rbl) * a_to_bohr / alat) if rbr is not None: params.set_value('<RBRIGHT>', array(rbr) * a_to_bohr / alat) if zper_l is not None: params.set_value('ZPERIODL', array(zper_l) * a_to_bohr / alat) if zper_r is not None: params.set_value('ZPERIODR', array(zper_r) * a_to_bohr / alat) # write inputfile params.fill_keywords_to_inputfile(output=input_filename) nspin = params.get_value('NSPIN') newsosol = False if 'NEWSOSOL' in params.get_value('RUNOPT'): newsosol = True return natyp, nspin, newsosol
def update_params(node, nodename=None, nodedesc=None, **kwargs): """ Update parameter node given with the values given as kwargs. Returns new node. :param node: Input parameter node (needs to be valid KKR input parameter node). :param **kwargs: Input keys with values as in kkrparams. :param linkname: Input linkname string. Give link from old to new node a name . If no linkname is given linkname defaults to 'updated parameters' :return: parameter node :example usage: OutputNode = KkrCalculation.update_params(InputNode, EMIN=-1, NSTEPS=30) :note: Keys are set as in kkrparams class. Check documentation of kkrparams for further information. :note: By default nodename is 'updated KKR parameters' and description contains list of changed """ # check if node is a valid KKR parameters node if not isinstance(node, ParameterData): print('Input node is not a valid ParameterData node') raise InputValidationError( 'update_params needs valid parameter node as input') #initialize temporary kkrparams instance containing all possible KKR parameters params = kkrparams() # extract input dict from node inp_params = node.get_dict() # check if input dict contains only values for KKR parameters for key in inp_params: if key not in params.values.keys() and key not in _ignored_keys: print('Input node contains unvalid key "{}"'.format(key)) raise InputValidationError( 'unvalid key "{}" in input parameter node'.format(key)) # copy values from input node for key in inp_params: value = inp_params[key] params.set_value(key, value, silent=True) # to keep track of changed values: changed_params = {} # check if values are given as **kwargs (otherwise return input node) if len(kwargs) == 0: print('No additional input keys given, return input node') return node else: for key in kwargs: if kwargs[key] != inp_params[key]: params.set_value(key, kwargs[key], silent=True) changed_params[key] = kwargs[key] if len(changed_params.keys()) == 0: print('No keys have been changed, return input node') return node # set linkname with input or default value if nodename is None or type(nodename) is not str: nodename = 'updated KKR parameters' if nodedesc is None or type(nodedesc) is not str: nodedesc = 'changed parameters: {}'.format(changed_params) # create new node ParaNode = ParameterData(dict=params.values) ParaNode.label = nodename ParaNode.description = nodedesc return ParaNode
kkr_calc_converged.out.remote_folder) from aiida.tools.data.array.kpoints import get_explicit_kpoints_path kpts = get_explicit_kpoints_path(struc).get('explicit_kpoints') # run bandstructure calculation # create bandstructure calculation reusing old settings (including same computer and resources in this example) kkrcode = kkr_calc_converged.get_code() kkrcalc = kkrcode.new_calc() kkrcalc.use_kpoints(kpts) # pass kpoints as input kkrcalc.use_parent_folder(kkr_calc_converged.out.remote_folder) kkrcalc.set_resources(kkr_calc_converged.get_resources()) # change parameters to qdos settings (E range and number of points) from aiida_kkr.tools.kkr_params import kkrparams qdos_params = kkrparams( **kkr_calc_converged.inp.parameters.get_dict()) # reuse old settings # reuse the same emin/emax settings as in DOS run (extracted from input parameter node) qdos_params.set_multiple_values( EMIN=host_dos_calc.inp.parameters.get_dict().get('EMIN'), EMAX=host_dos_calc.inp.parameters.get_dict().get('EMAX'), NPT2=100) kkrcalc.use_parameters(ParameterData(dict=qdos_params.get_dict())) # store and submit calculation kkrcalc.store_all() kkrcalc.submit() wait_for_it(kkrcalc, maxwait=600) # plot results
#!/usr/bin/env python from aiida_kkr.tools.kkr_params import kkrparams p = kkrparams(params_type='kkr') p.read_keywords_from_inputcard()
def test_scf_wc_Cu_simple(self): """ simple Cu noSOC, FP, lmax2 full example using scf workflow """ from aiida.orm import Code, load_node, DataFactory from aiida.work import run from aiida_kkr.tools.kkr_params import kkrparams from aiida_kkr.workflows.kkr_scf import kkr_scf_wc from pprint import pprint from scipy import array ParameterData = DataFactory('parameter') StructureData = DataFactory('structure') alat = 6.83 # in a_Bohr abohr = 0.52917721067 # conversion factor to Angstroem units # bravais vectors bravais = array([[0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5]]) a = 0.5 * alat * abohr Cu = StructureData(cell=[[a, a, 0.0], [a, 0.0, a], [0.0, a, a]]) Cu.append_atom(position=[0.0, 0.0, 0.0], symbols='Cu') Cu.store() print(Cu) # here we create a parameter node for the workflow input (workflow specific parameter) and adjust the convergence criterion. wfd = kkr_scf_wc.get_wf_defaults() wfd['convergence_criterion'] = 10**-4 wfd['check_dos'] = False wfd['kkr_runmax'] = 5 wfd['nsteps'] = 50 wfd['queue_name'] = '' wfd['resources']['num_machines'] = 1 wfd['use_mpi'] = False #True wfd['num_rerun'] = 2 wfd['natom_in_cls_min'] = 20 KKRscf_wf_parameters = ParameterData(dict=wfd) # The scf-workflow needs also the voronoi and KKR codes to be able to run the calulations VoroCode = Code.get_from_string('voronoi@my_mac') KKRCode = Code.get_from_string('KKRcode@my_mac') # Finally we use the kkrparams class to prepare a valid set of KKR parameters that are stored as a ParameterData object for the use in aiida ParaNode = ParameterData(dict=kkrparams( LMAX=2, RMAX=7, GMAX=65, NSPIN=1, RCLUSTZ=1.9).get_dict()) label = 'KKR-scf for Cu bulk' descr = 'KKR self-consistency workflow for Cu bulk' try: out = run(kkr_scf_wc, structure=Cu, calc_parameters=ParaNode, voronoi=VoroCode, kkr=KKRCode, wf_parameters=KKRscf_wf_parameters, _label=label, _description=descr) except: print 'some Error occured in run of kkr_scf_wc' # load node of workflow print out n = load_node(out[1]) print '\noutputs of workflow\n-------------------------------------------------' pprint(n.get_outputs_dict()) # get output dictionary n = n.get_outputs()[-1] out = n.get_dict() print '\n\noutput dictionary:\n-------------------------------------------------' pprint(out) # finally check some output print '\n\ncheck values ...\n-------------------------------------------------' print 'voronoi_step_success', out['voronoi_step_success'] assert out['voronoi_step_success'] print 'kkr_step_success', out['kkr_step_success'] assert out['kkr_step_success'] print 'successful', out['successful'] assert out['successful'] print 'error', out['errors'] assert out['errors'] == [] print 'warning', out['warnings'] assert out['warnings'] == [] print 'convergence_reached', out['convergence_reached'] assert out['convergence_reached'] print 'convergence_value', out['convergence_value'] assert out['convergence_value'] < 10**-4 print 'charge_neutrality', abs(out['charge_neutrality']) assert abs(out['charge_neutrality']) < 5 * 10**-4 print 'used_higher_accuracy', out['used_higher_accuracy'] assert out['used_higher_accuracy'] print '\ndone with checks\n'
def _get_and_verify_hostfiles(self, inputdict): """ Check inputdict for host_Greenfunction_folder and extract impurity_info, paths to kkrflex-files and path of shapefun file :param inputdict: input dictionary containing all input nodes to KkrimpCalculation :returns: * imp_info: ParameterData node containing impurity information like position, Z_imp, cluster size, etc. * kkrflex_file_paths: dict of absolute file paths for the kkrflex files * shapefun_path: absolute path of the shapefunction file in the host calculation (needed to construct shapefun_imp) * shapes: mapping array of atoms to shapes (<SHAPE> input) :note: shapefun_path is None if host_Greenfunction calculation was not full-potential :raises: * InputValidationError, if inputdict does not contain 'host_Greenfunction' * InputValidationError, if host_Greenfunction_folder not of right type * UniquenessError, if host_Greenfunction_folder does not have exactly one parent * InputValidationError, if host_Greenfunction does not have an input node impurity_info * InputValidationError, if host_Greenfunction was not a KKRFLEX calculation """ # get host_parent node and check consistency try: host_parent = inputdict.pop(self.get_linkname('host_Greenfunction_folder')) except KeyError: raise InputValidationError("No host_Greenfunction_folder specified for this calculation") # check host parent type if not isinstance(host_parent, RemoteData): raise InputValidationError("host_Greenfunction_folder not of type RemoteData") # extract parent calculation parent_calcs = host_parent.get_inputs(node_type=JobCalculation) n_parents = len(parent_calcs) if n_parents != 1: raise UniquenessError( "Input RemoteData is child of {} " "calculation{}, while it should have a single parent" "".format(n_parents, "" if n_parents == 0 else "s")) else: parent_calc = parent_calcs[0] # extract impurity_info imp_info = parent_calc.get_inputs_dict().get('impurity_info', None) if imp_info is None: raise InputValidationError("host_Greenfunction calculation does not have an input node impurity_info") # check if host parent was KKRFLEX calculation hostfolderpath = parent_calc.out.retrieved.folder.abspath hostfolderpath = os.path.join(hostfolderpath, 'path') input_file = os.path.join(hostfolderpath, KkrCalculation()._DEFAULT_INPUT_FILE) params_host_calc = kkrparams(params_type='kkr') # initialize kkrparams instance to use read_keywords_from_inputcard params_host_calc.read_keywords_from_inputcard(inputcard=input_file) if 'RUNOPT' not in params_host_calc.get_dict().keys(): host_ok = False elif 'KKRFLEX' not in params_host_calc.get_dict().get('RUNOPT', []): host_ok = False else: host_ok = True if not host_ok: raise InputValidationError("host_Greenfunction calculation was not a KKRFLEX run") # extract absolute paths of kkrflex_* files kkrflex_file_paths = {} for file in self._ALL_KKRFLEX_FILES: file_abspath = os.path.join(hostfolderpath, file) if os.path.exists(file_abspath): kkrflex_file_paths[file] = file_abspath # extract absolute path of host shapefun file_abspath = os.path.join(hostfolderpath, KkrCalculation()._SHAPEFUN) if os.path.exists(file_abspath): shapefun_path = file_abspath else: shapefun_path = None # extract shapes array from parameters read from inputcard shapes = params_host_calc.get_dict().get('<SHAPE>', None) if type(shapes)==int: shapes = [shapes] # extract input structure try: structure, voro_parent = VoronoiCalculation.find_parent_structure(parent_calc) except: structure, voro_parent = None, None if structure is None: raiseInputValidationError("No structure node found from host GF parent") return imp_info, kkrflex_file_paths, shapefun_path, shapes, parent_calc, params_host_calc, structure
def _check_and_extract_input_nodes(self, inputdict): """ Extract input nodes from inputdict and check consitency of input nodes :param inputdict: dict of inputnodes :returns: * parameters (aiida_kkr.tools.kkr_params.kkrparams), optional: parameters of KKRimp that end up in config.cfg * code (KKRimpCodeNode): code of KKRimp on some machine * imp_info (ParameterDataNode): parameter node of the impurity information, extracted from host_parent_calc * kkrflex_file_paths (dict): dictionary of {filenames: absolute_path_to_file} for the kkrflex-files * shapfun_path (str): absolute path of the shapefunction of the host parent calculation * host_parent_calc (KkrCalculation): node of the parent host calculation where the kkrflex-files were created * impurity_potential (SinglefileData): single file data node containing the starting potential for the impurity calculation * parent_calc_folder (RemoteData): remote directory of a parent KKRimp calculation """ # 1. extract parameters, optional (defaults extracted from host calculation) try: parameters = inputdict.pop(self.get_linkname('parameters')) if not isinstance(parameters, ParameterData): raise InputValidationError("parameters not of type ParameterData") except KeyError: self.logger.info("No parameters specified for this calculation, use defaults") parameters = None if parameters is not None: # convert to kkrparams instance parameters = kkrparams(params_type='kkrimp', **parameters.get_dict()) # 2. extract code try: code = inputdict.pop(self.get_linkname('code')) except KeyError: raise InputValidationError("No code specified for this calculation") # 3. get hostfiles imp_info, kkrflex_file_paths, shapfun_path, shapes, host_parent_calc, params_host, structure = self._get_and_verify_hostfiles(inputdict) # 4. check impurity potential or parent calc input # imp potential try: impurity_potential = inputdict.pop(self.get_linkname('impurity_potential')) if not isinstance(impurity_potential, SinglefileData): raise InputValidationError("impurity_potential not of type SinglefileData") found_imp_pot = True except KeyError: impurity_potential = None found_imp_pot = False # parent calc folder try: parent_calc_folder = inputdict.pop(self.get_linkname('parent_calc_folder')) if not isinstance(parent_calc_folder, RemoteData): raise InputValidationError("parent_calc_folder not of type RemoteData") found_parent_calc = True except KeyError: parent_calc_folder = None found_parent_calc = False # consistency checks if not found_parent_calc and not found_imp_pot: raise InputValidationError("Neither impurity_potential nor parent_calc_folder specified for this calculation.\n" "Please provide either impurity_potential or parent_calc_folder.") elif found_parent_calc and found_imp_pot: raise InputValidationError("Both impurity_potential and parent_calc_folder specified for this calculation.\n" "Please provide one one, i.e. either impurity_potential or parent_calc_folder.") # 5. anything left that is unknown? if inputdict: raise ValidationError("Unknown inputs: {}".format(inputdict)) # Done checking inputdict, returning ... return parameters, code, imp_info, kkrflex_file_paths, shapfun_path, shapes, host_parent_calc, params_host, impurity_potential, parent_calc_folder, structure