def test_fleurinp_modifier_set_kpointsdata(create_fleurinp): """Test if setting a kpoints list to a fleurinp data node works""" from aiida.orm import KpointsData fleurinp_tmp = create_fleurinp(inpxmlfilefolder) fleurinp_tmp.store() # needed? struc = fleurinp_tmp.get_structuredata_ncf() kps = KpointsData() kps.set_cell(struc.cell) kps.pbc = struc.pbc kpoints_pos = [[0.0, 0.0, 0.0], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.0, 0.5], [0.5, 0.5, 0.5], [1.0, 1.0, 1.0]] kpoints_weight = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] # Fleur renormalizes kps.set_kpoints(kpoints_pos, cartesian=False, weights=kpoints_weight) kps.store() # needed, because node has to be loaded... #print(fleurinp_tmp) fm = FleurinpModifier(fleurinp_tmp) fm.set_kpointsdata(kps) fm.show(validate=True, display=False) fm.freeze() # check if kpoint node is input into modification # uuid of node show also work fm = FleurinpModifier(fleurinp_tmp) fm.set_kpointsdata(kps.uuid) fm.freeze()
def test_fleurinp_modifier1(create_fleurinp): """Tests if fleurinp_modifier with various modifations on species""" fleurinp_tmp = create_fleurinp(inpxmlfilefolder) fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.shift_value({'Kmax': 0.1}, 'rel') fm.shift_value_species_label(' 222', 'radius', 3, mode='abs') fm.set_species('all', {'mtSphere': {'radius': 3.333}}) fm.undo() changes = fm.changes() assert changes == [('set_inpchanges', { 'Kmax': 3.9, 'dos': True }), ('shift_value', { 'Kmax': 0.1 }, 'rel'), ('shift_value_species_label', ' 222', 'radius', 3, 'abs')] fm.show(validate=True) fm.freeze() fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.undo(revert_all=True) changes = fm.changes() assert changes == []
def test_fleurinp_modifier2(create_fleurinp, inpxml_etree): """Tests if fleurinp_modifier with various other modifations methods, the detailed tests for method functionality is tested elsewhere.""" from aiida_fleur.tools.xml_util import eval_xpath fleurinp_tmp = create_fleurinp(inpxmlfilefolder) etree = inpxml_etree(inpxmlfilefolder) fm = FleurinpModifier(fleurinp_tmp) actions = fm.get_avail_actions() assert isinstance(actions, dict) new_tag = eval_xpath(etree, '/fleurInput/calculationSetup/scfLoop') fm.delete_tag('/fleurInput/calculationSetup/scfLoop') fm.replace_tag('/fleurInput/calculationSetup/cutoffs', new_tag) fm.delete_att('/fleurInput/calculationSetup/soc', 'theta') fm.create_tag('/fleurInput/calculationSetup/soc', 'theta') fm.xml_set_all_text('/fleurInput/cell/symmetryOperations/symOp/row-1', 'test text') fm.xml_set_text_occ('/fleurInput/cell/symmetryOperations/symOp/row-1', 'test text') fm.xml_set_text('/fleurInput/cell/symmetryOperations/symOp/row-1', 'test text') fm.xml_set_all_attribv('/fleurInput/calculationSetup/soc', 'theta', 12) fm.xml_set_first_attribv('/fleurInput/calculationSetup/soc', 'theta', 12) fm.xml_set_attribv_occ('/fleurInput/calculationSetup/soc', 'theta', 12) fm.set_species_label(' 222', {'mtSphere': {'radius': 3.333}}) fm.set_atomgr_att_label(attributedict={'force': [('relaxXYZ', 'FFF')]}, atom_label=' 222') fm.set_atomgr_att(attributedict={'force': [('relaxXYZ', 'TFF')]}, species='Fe-1') fm.set_nkpts(500, gamma='T') fm.set_kpath({'gamma': (0, 0, 0), 'L': (0.1, 0.1, 0.1)}, 300) fm.add_num_to_att('/fleurInput/calculationSetup/soc', 'theta', 4) #fm.set_species1 fm.show()
def create_new_fleurinp(self): """ create a new fleurinp from the old with certain parameters """ # TODO allow change of kpoint mesh?, tria? wf_dict = self.inputs.wf_parameters.get_dict() nkpts = wf_dict.get('nkpts', 500) # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0 sigma = wf_dict.get('sigma', 0.005) emin = wf_dict.get('emin', -0.30) emax = wf_dict.get('emax', 0.80) fleurmode = FleurinpModifier(self.inputs.fleurinp) #change_dict = {'band': True, 'ndir' : -1, 'minEnergy' : self.inputs.wf_parameters.get_dict().get('minEnergy', -0.30000000), #'maxEnergy' : self.inputs.wf_parameters.get_dict().get('manEnergy','0.80000000'), #'sigma' : self.inputs.wf_parameters.get_dict().get('sigma', '0.00500000')} change_dict = {'band': True, 'ndir' : 0, 'minEnergy' : emin, 'maxEnergy' : emax, 'sigma' : sigma} #'ndir' : 1, 'pot8' : True fleurmode.set_inpchanges(change_dict) if nkpts: fleurmode.set_nkpts(count=nkpts) #fleurinp_new.replace_tag() fleurmode.show(validate=True, display=False) # needed? fleurinp_new = fleurmode.freeze() self.ctx.fleurinp1 = fleurinp_new
def test_fleurinp_modifier1(create_fleurinp): """Tests if fleurinp_modifier with various modifations on species""" from masci_tools.io.fleurxmlmodifier import ModifierTask fleurinp_tmp = create_fleurinp(inpxmlfilefolder) fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.shift_value({'Kmax': 0.1}, 'rel') fm.shift_value_species_label(' 222', 'radius', 3, mode='abs') fm.set_species('all', {'mtSphere': {'radius': 3.333}}) fm.undo() changes = fm.changes() assert changes == [ ModifierTask(name='set_inpchanges', args=({ 'dos': True, 'Kmax': 3.9 },), kwargs={}), ModifierTask(name='shift_value', args=({ 'Kmax': 0.1 }, 'rel'), kwargs={}), ModifierTask(name='shift_value_species_label', args=(' 222', 'radius', 3), kwargs={'mode': 'abs'}) ] fm.show(validate=True) fm.freeze() fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.undo(revert_all=True) changes = fm.changes() assert changes == []
def test_fleurinp_modifier_set_nmmpmat(create_fleurinp): """Tests if set_nmmpmat works on fleurinp modifier works, with right interface""" fleurinp_tmp = create_fleurinp(inpxmlfilefolder2) fm = FleurinpModifier(fleurinp_tmp) fm.set_nmmpmat('Ga-1', orbital=2, spin=1, occStates=[1, 2, 3, 4, 5]) fm.set_nmmpmat('As-2', orbital=1, spin=1, denmat=[[1, -2, 3], [4, -5, 6], [7, -8, 9]]) # Does not validate # Found invalid diagonal element for species Ga-1, spin 1 and l=2 with pytest.raises(ValueError): fm.show(validate=True, display=False) new_fleurinp = fm.freeze() assert 'n_mmp_mat' in new_fleurinp.files
def test_fleurinp_single_value_modification(create_fleurinp, inpxmlfilepath): """ set kmax, itmax, minDistance in inp.xml input file of fleurinpdata to 10.2, 99, 0.000001, then check if it everything set """ from aiida_fleur.data.fleurinpmodifier import FleurinpModifier fleurinp_tmp = create_fleurinp(inpxmlfilepath) fleurinpmode = FleurinpModifier(fleurinp_tmp) fleurinpmode.set_inpchanges({ 'itmax': 99, 'minDistance': 0.01, 'Kmax': 10.2 }) fleurinpmode.show(display=False, validate=True) out = fleurinpmode.freeze() assert isinstance(out, type(fleurinp_tmp))
def test_fleurinp_modifier_regression(create_fleurinp, inpxml_etree, file_regression): """Tests if fleurinp_modifier with various other modifations methods, the detailed tests for method functionality is tested elsewhere.""" fleurinp_tmp = create_fleurinp(inpxmlfilefolder) fm = FleurinpModifier(fleurinp_tmp) fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.shift_value({'Kmax': 0.1}, 'rel') fm.shift_value_species_label(' 222', 'radius', 3, mode='abs') fm.set_species('all', {'mtSphere': {'radius': 3.333}}) #fm.set_nkpts(500, gamma='T') #fm.set_kpath({'gamma': (0, 0, 0), 'L': (0.1, 0.1, 0.1)}, 300) with pytest.deprecated_call(): fm.add_num_to_att('/fleurInput/calculationSetup/scfLoop', 'minDistance', 4) #fm.set_species1 fm.show() new_fleurinp = fm.freeze() file_regression.check(new_fleurinp.get_content('inp.xml'), extension='.xml')
def test_fleurinp_modifier_included_files(create_fleurinp, inpxml_etree, file_regression): """Tests if fleurinp_modifier with various other modifations methods, the detailed tests for method functionality is tested elsewhere.""" TEST_FOLDER = os.path.dirname(os.path.abspath(__file__)) TEST_FOLDER = os.path.abspath(os.path.join(TEST_FOLDER, '../files/included_xml_files')) INPXML_FILE = os.path.join(TEST_FOLDER, 'inp.xml') KPTSXML_FILE = os.path.join(TEST_FOLDER, 'kpts.xml') SYMXML_FILE = os.path.join(TEST_FOLDER, 'sym.xml') fleurinp_tmp = create_fleurinp(INPXML_FILE, additional_files=[KPTSXML_FILE, SYMXML_FILE]) fm = FleurinpModifier(fleurinp_tmp) #Modify main inp.xml file fm.set_inpchanges({'dos': True, 'Kmax': 3.9}) fm.shift_value({'Kmax': 0.1}, 'rel') #Modify included xml files fm.delete_tag('symmetryOperations') fm.create_tag('symmetryOperations') fm.create_tag('kPointList') fm.create_tag('kPoint', occurrences=0) fm.set_attrib_value('name', 'TEST', contains='kPointList', occurrences=0) fm.set_text('kPoint', [0.0, 0.0, 0.0], complex_xpath="/fleurInput/cell/bzIntegration/kPointLists/kPointList[@name='TEST']/kPoint") fm.show() new_fleurinp = fm.freeze() assert new_fleurinp.files == ['kpts.xml', 'sym.xml', 'inp.xml'] file_content = [ new_fleurinp.get_content('inp.xml'), new_fleurinp.get_content('kpts.xml'), new_fleurinp.get_content('sym.xml') ] file_regression.check('\n'.join(file_content), extension='.xml')
def create_new_fleurinp(self): """ create a new fleurinp from the old with certain parameters """ # TODO allow change of kpoint mesh?, tria? wf_dict = self.ctx.wf_dict if 'fleurinp' not in self.inputs: for i in self.inputs.remote.get_incoming(): if isinstance(i.node, CalcJobNode): self.ctx.fleurinp_scf = load_node(i.node.pk).get_incoming().get_node_by_label('fleurinpdata') else: self.ctx.fleurinp_scf = self.inputs.fleurinp # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0 fleurmode = FleurinpModifier(self.ctx.fleurinp_scf) nkpts = wf_dict.get('nkpts', 500) sigma = wf_dict.get('sigma', 0.005) emin = wf_dict.get('emin', -0.30) emax = wf_dict.get('emax', 0.80) if wf_dict.get('mode') == 'dos': change_dict = {'dos': True, 'ndir': -1, 'minEnergy': emin, 'maxEnergy': emax, 'sigma': sigma} else: change_dict = {'band': True, 'ndir': 0, 'minEnergy': emin, 'maxEnergy': emax, 'sigma': sigma} fleurmode.set_inpchanges(change_dict) if wf_dict.get('kpath') != 'auto': fleurmode.set_kpath(wf_dict.get('kpath'), nkpts) # if nkpts: # fleurmode.set_nkpts(count=nkpts) #fleurinp_new.replace_tag() fleurmode.show(validate=True, display=False) # needed? fleurinp_new = fleurmode.freeze() self.ctx.fleurinp_banddos = fleurinp_new
def change_fleurinp(self): """ This routine sets somethings in the fleurinp file before running a fleur calculation. """ self.report('INFO: run change_fleurinp') if self.ctx.scf_needed: # use fleurinp from scf wc try: fleurin = self.ctx.reference.outputs.fleurinp except NotExistent: error = 'Fleurinp generated in the reference calculation is not found.' self.control_end_wc(error) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED else: if 'fleurinp' in self.inputs: # use the given fleurinp fleurin = self.inputs.fleurinp else: # or generate a new one from inp.xml located in the remote folder remote_node = self.inputs.remote for link in remote_node.get_incoming().all(): if isinstance(link.node, CalcJobNode): parent_calc_node = link.node retrieved_node = parent_calc_node.get_outgoing().get_node_by_label('retrieved') fleurin = FleurinpData(files=['inp.xml'], node=retrieved_node) # copy inpchanges from wf parameters fchanges = self.ctx.wf_dict.get('inpxml_changes', []) # create forceTheorem tags fchanges.extend([('create_tag', { 'xpath': '/fleurInput', 'newelement': 'forceTheorem' }), ('create_tag', { 'xpath': '/fleurInput/forceTheorem', 'newelement': 'spinSpiralDispersion' })]) for i, vectors in enumerate(self.ctx.wf_dict['q_vectors']): fchanges.append(('create_tag', { 'xpath': '/fleurInput/forceTheorem/spinSpiralDispersion', 'newelement': 'q' })) fchanges.append(('xml_set_text_occ', { 'xpathn': '/fleurInput/forceTheorem/spinSpiralDispersion/q', 'text': ' '.join(six.moves.map(str, vectors)), 'create': False, 'occ': i })) changes_dict = {'itmax': 1, 'l_noco': True, 'ctail': False, 'l_ss': True} fchanges.append(('set_inpchanges', {'change_dict': changes_dict})) # change beta parameter for key, val in six.iteritems(self.ctx.wf_dict.get('beta')): fchanges.append(('set_atomgr_att_label', { 'attributedict': { 'nocoParams': [('beta', val)] }, 'atom_label': key })) if fchanges: # change inp.xml file fleurmode = FleurinpModifier(fleurin) avail_ac_dict = fleurmode.get_avail_actions() # apply further user dependend changes for change in fchanges: function = change[0] para = change[1] method = avail_ac_dict.get(function, None) if not method: error = ("ERROR: Input 'inpxml_changes', function {} " 'is not known to fleurinpmodifier class, ' 'please check/test your input. I abort...' ''.format(function)) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED else: # apply change method(**para) # validate try: fleurmode.show(display=False, validate=True) except etree.DocumentInvalid: error = ('ERROR: input, user wanted inp.xml changes did not validate') self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE # apply out = fleurmode.freeze() self.ctx.fleurinp = out return else: # otherwise do not change the inp.xml self.ctx.fleurinp = fleurin return
def change_fleurinp(self): """ This routine sets somethings in the fleurinp file before running a fleur calculation. """ self.report('INFO: run change_fleurinp') if self.ctx.scf_needed: try: fleurin = self.ctx.reference.outputs.fleurinp except NotExistent: error = 'Fleurinp generated in the reference calculation is not found.' self.control_end_wc(error) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED else: if 'fleurinp' in self.inputs: fleurin = self.inputs.fleurinp else: # In this case only remote is given # fleurinp data has to be generated from the remote inp.xml file fleurin = get_fleurinp_from_remote_data(self.inputs.remote) # copy inpchanges from wf parameters fchanges = self.ctx.wf_dict.get('inpxml_changes', []) # create forceTheorem tags fchanges.extend([ ('create_tag', { 'xpath': '/fleurInput', 'newelement': 'forceTheorem' }), ('create_tag', { 'xpath': '/fleurInput/forceTheorem', 'newelement': 'DMI' }), ('create_tag', { 'xpath': '/fleurInput/forceTheorem/DMI', 'newelement': 'qVectors' }), ('xml_set_attribv_occ', { 'xpathn': '/fleurInput/forceTheorem/DMI', 'attributename': 'theta', 'attribv': ' '.join(six.moves.map(str, self.ctx.wf_dict.get('sqas_theta'))) }), ('xml_set_attribv_occ', { 'xpathn': '/fleurInput/forceTheorem/DMI', 'attributename': 'phi', 'attribv': ' '.join(six.moves.map(str, self.ctx.wf_dict.get('sqas_phi'))) }) ]) for i, vectors in enumerate(self.ctx.wf_dict['q_vectors']): fchanges.append(('create_tag', { 'xpath': '/fleurInput/forceTheorem/DMI/qVectors', 'newelement': 'q' })) fchanges.append(('xml_set_text_occ', { 'xpathn': '/fleurInput/forceTheorem/DMI/qVectors/q', 'text': ' '.join(six.moves.map(str, vectors)), 'create': False, 'occ': i })) changes_dict = { 'itmax': 1, 'l_noco': True, 'ctail': False, 'spav': True, # 'l_soc': True, 'l_ss': True } fchanges.append(('set_inpchanges', {'change_dict': changes_dict})) # change beta parameter for key, val in six.iteritems(self.ctx.wf_dict.get('beta')): fchanges.append(('set_atomgr_att_label', { 'attributedict': { 'nocoParams': { 'beta': val } }, 'atom_label': key })) # switch off SOC on an atom specie for atom_label in self.ctx.wf_dict['soc_off']: fchanges.append(('set_species_label', { 'at_label': atom_label, 'attributedict': { 'special': { 'socscale': 0.0 } }, 'create': True })) if fchanges: # change inp.xml file fleurmode = FleurinpModifier(fleurin) avail_ac_dict = fleurmode.get_avail_actions() # apply further user dependend changes for change in fchanges: function = change[0] para = change[1] method = avail_ac_dict.get(function, None) if not method: error = ("ERROR: Input 'inpxml_changes', function {} " 'is not known to fleurinpmodifier class, ' 'please check/test your input. I abort...' ''.format(function)) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED else: # apply change method(**para) # validate? try: fleurmode.show(display=False, validate=True) except etree.DocumentInvalid: error = ( 'ERROR: input, user wanted inp.xml changes did not validate' ) self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE # apply out = fleurmode.freeze() self.ctx.fleurinp = out return else: # otherwise do not change the inp.xml self.ctx.fleurinp = fleurin return
def change_fleurinp(self): """ This routine sets somethings in the fleurinp file before running a fleur calculation. """ self.report('INFO: run change_fleurinp') inputs = self.inputs # Has to never crash because corresponding check was done in validate function if self.ctx.fleurinp: # something was already changed return elif 'fleurinp' in inputs: fleurin = self.inputs.fleurinp elif 'structure' in inputs: if not self.ctx['inpgen'].is_finished_ok: error = 'Inpgen calculation failed' self.control_end_wc(error) return self.exit_codes.ERROR_INPGEN_CALCULATION_FAILED fleurin = self.ctx['inpgen'].outputs.fleurinpData elif 'remote_data' in inputs: # In this case only remote_data for input structure is given # fleurinp data has to be generated from the remote inp.xml file to use change_fleurinp remote_node = self.inputs.remote_data for link in remote_node.get_incoming().all(): if isinstance(link.node, CalcJobNode): parent_calc_node = link.node retrieved_node = parent_calc_node.get_outgoing().get_node_by_label('retrieved') try: if self.ctx.wf_dict['use_relax_xml']: fleurin = FleurinpData(files=['inp.xml', 'relax.xml'], node=retrieved_node) self.report('INFO: generated FleurinpData from inp.xml and relax.xml') else: raise ValueError except ValueError: fleurin = FleurinpData(files=['inp.xml'], node=retrieved_node) self.report('INFO: generated FleurinpData from inp.xml') fleurin.store() wf_dict = self.ctx.wf_dict force_dict = wf_dict.get('force_dict') converge_mode = wf_dict.get('mode') fchanges = wf_dict.get('inpxml_changes', []) fleurmode = FleurinpModifier(fleurin) # set proper convergence parameters in inp.xml if converge_mode == 'density': dist = wf_dict.get('density_converged') fleurmode.set_inpchanges({'itmax': self.ctx.default_itmax, 'minDistance': dist}) elif converge_mode == 'force': force_converged = wf_dict.get('force_converged') dist = wf_dict.get('density_converged') fleurmode.set_inpchanges({ 'itmax': self.ctx.default_itmax, 'minDistance': dist, 'force_converged': force_converged, 'l_f': True, 'qfix': force_dict.get('qfix'), 'forcealpha': force_dict.get('forcealpha'), 'forcemix': force_dict.get('forcemix') }) elif converge_mode == 'energy': dist = 0.0 fleurmode.set_inpchanges({'itmax': self.ctx.default_itmax, 'minDistance': dist}) avail_ac_dict = fleurmode.get_avail_actions() # apply further user dependend changes if fchanges: for change in fchanges: function = change[0] para = change[1] method = avail_ac_dict.get(function, None) if not method: error = ("ERROR: Input 'inpxml_changes', function {} " 'is not known to fleurinpmodifier class, ' 'please check/test your input. I abort...' ''.format(function)) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED else: # apply change try: method(**para) except ValueError as vale: error = ('ERROR: Changing the inp.xml file failed. Tried to apply {}' ', which failed with {}. I abort, good luck next time!' ''.format(change, vale)) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED # validate? try: fleurmode.show(display=False, validate=True) except etree.DocumentInvalid: error = ('ERROR: input, user wanted inp.xml changes did not validate') self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE # apply out = fleurmode.freeze() self.ctx.fleurinp = out return
def change_fleurinp(self): """ create a new fleurinp from the old with certain parameters """ # TODO allow change of kpoint mesh?, tria? wf_dict = self.ctx.wf_dict if self.ctx.scf_needed: try: fleurin = self.ctx.scf.outputs.fleurinp except NotExistent: error = 'Fleurinp generated in the SCF calculation is not found.' self.control_end_wc(error) return self.exit_codes.ERROR_SCF_CALCULATION_FAILED else: if 'fleurinp' not in self.inputs: fleurin = get_fleurinp_from_remote_data(self.inputs.remote) else: fleurin = self.inputs.fleurinp # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0 fleurmode = FleurinpModifier(fleurin) fchanges = wf_dict.get('inpxml_changes', []) # apply further user dependend changes if fchanges: try: fleurmode.add_task_list(fchanges) except (ValueError, TypeError) as exc: error = ( 'ERROR: Changing the inp.xml file failed. Tried to apply inpxml_changes' f', which failed with {exc}. I abort, good luck next time!' ) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED kpath = wf_dict['kpath'] explicit = wf_dict['kpoints_explicit'] distance = wf_dict['kpoints_distance'] nkpts = wf_dict['kpoints_number'] listname = wf_dict['klistname'] if explicit is not None: try: fleurmode.set_kpointlist(**explicit) except (ValueError, TypeError) as exc: error = ( 'ERROR: Changing the inp.xml file failed. Tried to apply kpoints_explicit' f', which failed with {exc}. I abort, good luck next time!' ) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED if listname is None: if wf_dict.get('mode') == 'band': listname = 'path-2' if nkpts is None and distance is None: nkpts = 500 if 'kpoints' in self.inputs: fleurmode.set_kpointsdata(self.inputs.kpoints, switch=True) if kpath == 'auto': if fleurin.inp_version >= '0.32' and listname is not None: fleurmode.switch_kpointset(listname) elif isinstance(kpath, dict): if fleurin.inp_version < '0.32': if distance is not None: raise ValueError( 'set_kpath only supports specifying the number of points for the kpoints' ) fleurmode.set_kpath(kpath, nkpts) else: raise ValueError( 'set_kpath is only supported for inputs up to Max4') elif kpath == 'seek': #Use aiida functionality struc = fleurin.get_structuredata() if distance is not None: output = get_explicit_kpoints_path(struc, reference_distance=distance) else: output = get_explicit_kpoints_path(struc) primitive_struc = output['primitive_structure'] #check if primitive_structure and input structure are identical: maxdiff_cell = sum( abs(np.array(primitive_struc.cell) - np.array(struc.cell))).max() if maxdiff_cell > 3e-9: self.report(f'Error in cell : {maxdiff_cell}') self.report( 'WARNING: The structure data from the fleurinp is not the primitive structure type, which is mandatory in some cases' ) output['explicit_kpoints'].store() fleurmode.set_kpointsdata(output['explicit_kpoints'], switch=True) elif kpath == 'skip': return else: #Use ase struc = fleurin.get_structuredata() path = bandpath(kpath, cell=struc.cell, npoints=nkpts, density=distance) special_points = path.special_points labels = [] for label, special_kpoint in special_points.items(): for index, kpoint in enumerate(path.kpts): if sum(abs(np.array(special_kpoint) - np.array(kpoint))).max() < 1e-12: labels.append((index, label)) labels = sorted(labels, key=lambda x: x[0]) kpts = KpointsData() kpts.set_cell(struc.cell) kpts.pbc = struc.pbc weights = np.ones(len(path.kpts)) / len(path.kpts) kpts.set_kpoints(kpoints=path.kpts, cartesian=False, weights=weights, labels=labels) kpts.store() fleurmode.set_kpointsdata(kpts, switch=True) sigma = wf_dict['sigma'] emin = wf_dict['emin'] emax = wf_dict['emax'] if fleurin.inp_version < '0.32': if wf_dict.get('mode') == 'dos': fleurmode.set_inpchanges({'ndir': -1}) if wf_dict.get('mode') == 'dos': change_dict = { 'dos': True, 'minEnergy': emin, 'maxEnergy': emax, 'sigma': sigma } else: change_dict = { 'band': True, 'minEnergy': emin, 'maxEnergy': emax, 'sigma': sigma } fleurmode.set_inpchanges(change_dict) try: fleurmode.show(display=False, validate=True) except etree.DocumentInvalid: error = ( 'ERROR: input, user wanted inp.xml changes did not validate') self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE except ValueError as exc: error = ( 'ERROR: input, user wanted inp.xml changes could not be applied.' f'The following error was raised {exc}') self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED fleurinp_new = fleurmode.freeze() self.ctx.fleurinp_banddos = fleurinp_new
def get_inputs_fixed_configurations(self, index, config): """ Sets up the input for the fixed density matrix calculation. """ remote_data = None if self.ctx.scf_no_ldau_needed: try: fleurinp = self.ctx.scf_no_ldau.outputs.fleurinp remote_data = load_node( self.ctx.scf_no_ldau.outputs.output_scf_wc_para['last_calc_uuid']).outputs.remote_folder except NotExistent: error = 'Fleurinp generated in the SCF calculation is not found.' self.control_end_wc(error) return {}, self.exit_codes.ERROR_SCF_NOLDAU_FAILED else: remote_data = self.inputs.remote if 'fleurinp' not in self.inputs: fleurinp = get_fleurinp_from_remote_data(remote_data, store=True) self.report(f'INFO: generated FleurinpData from {fleurinp.files}') else: fleurinp = self.inputs.fleurinp inputs = self.inputs label = f'Fixed_{index}' description = f'LDA+U with fixed nmmpmat for config {index}' if 'settings' not in inputs: settings = {} else: settings = inputs.settings.get_dict() if 'remove_from_remotecopy_list' not in settings: settings['remove_from_remotecopy_list'] = [] settings['remove_from_remotecopy_list'].append('mixing_history*') self.report(f'INFO: create fleurinp for config {index}') fm = FleurinpModifier(fleurinp) fm.set_inpchanges({'itmax': self.ctx.wf_dict['iterations_fixed'], 'l_linMix': True, 'mixParam': 0.0}) for atom_species, ldau_dict in self.ctx.wf_dict['ldau_dict'].items(): fm.set_species(species_name=atom_species, attributedict={'ldaU': ldau_dict}) for config_index, config_species in config.items(): orbital = config_index.split('-')[-1] atom_species = '-'.join(config_index.split('-')[:-1]) for spin, config_spin in enumerate(config_species): if self.ctx.wf_dict['use_orbital_occupation']: fm.set_nmmpmat(species_name=atom_species, orbital=int(orbital), spin=spin + 1, orbital_occupations=config_spin) else: fm.set_nmmpmat(species_name=atom_species, orbital=int(orbital), spin=spin + 1, state_occupations=config_spin) try: fm.show(display=False, validate=True) except etree.DocumentInvalid: error = ('ERROR: input, inp.xml changes did not validate') self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE except ValueError as exc: error = ('ERROR: input, inp.xml changes could not be applied.' f'The following error was raised {exc}') self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED fleurinp_fixed = fm.freeze() input_fixed = get_inputs_fleur(inputs.fleur, remote_data, fleurinp_fixed, self.ctx.options, label, description, settings=settings) return input_fixed, None
def change_fleurinp(self): """ This routine sets somethings in the fleurinp file before running a fleur calculation. """ # TODO recongize inpgen fail, then no fleurin exists... if self.ctx.fleurinp: #something was already changed #print('Fleurinp already exists') return elif 'fleurinp' in self.inputs: fleurin = self.inputs.fleurinp else: try: fleurin = self.ctx['inpgen'].out.fleurinpData except AttributeError: error = 'No fleurinpData found, inpgen failed' self.control_end_wc(error) wf_dict = self.inputs.wf_parameters.get_dict() converge_te = wf_dict.get('converge_energy', False) fchanges = wf_dict.get('inpxml_changes', []) if not converge_te or fchanges: # change inp.xml file fleurmode = FleurinpModifier(fleurin) if not converge_te: dist = wf_dict.get('density_criterion', 0.00002) fleurmode.set_inpchanges({'itmax': 30, 'minDistance': dist}) avail_ac_dict = fleurmode.get_avail_actions() # apply further user dependend changes if fchanges: for change in fchanges: function = change[0] para = change[1] method = avail_ac_dict.get(function, None) if not method: error = ("ERROR: Input 'inpxml_changes', function {} " "is not known to fleurinpmodifier class, " "plaese check/test your input. I abort..." "".format(method)) self.control_end_wc(error) else: # apply change method(**para) # validate? apply_c = True try: fleurmode.show(display=False, validate=True) except XMLSyntaxError: error = ( 'ERROR: input, user wanted inp.xml changes did not validate' ) #fleurmode.show(display=True)#, validate=True) self.control_end_wc(error) apply_c = False # apply if apply_c: out = fleurmode.freeze() self.ctx.fleurinp = out return else: # otherwise do not change the inp.xml self.ctx.fleurinp = fleurin return
def change_fleurinp(self): """ This routine sets somethings in the fleurinp file before running a fleur calculation. """ if self.ctx.scf_needed: try: fleurin = self.ctx.reference.outputs.fleurinp except NotExistent: error = 'Fleurinp generated in the reference calculation is not found.' self.control_end_wc(error) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED else: if 'fleurinp' in self.inputs: fleurin = self.inputs.fleurinp else: # In this case only remote is given # fleurinp data has to be generated from the remote inp.xml file fleurin = get_fleurinp_from_remote_data(self.inputs.remote) # copy default changes fchanges = self.ctx.wf_dict.get('inpxml_changes', []) # add forceTheorem tag into inp.xml fchanges.extend([ ('create_tag', { 'xpath': '/fleurInput', 'newelement': 'forceTheorem' }), ('create_tag', { 'xpath': '/fleurInput/forceTheorem', 'newelement': 'MAE' }), ('xml_set_attribv_occ', { 'xpathn': '/fleurInput/forceTheorem/MAE', 'attributename': 'theta', 'attribv': ' '.join(six.moves.map(str, self.ctx.wf_dict.get('sqas_theta'))) }), ('xml_set_attribv_occ', { 'xpathn': '/fleurInput/forceTheorem/MAE', 'attributename': 'phi', 'attribv': ' '.join(six.moves.map(str, self.ctx.wf_dict.get('sqas_phi'))) }), ('set_inpchanges', { 'change_dict': { 'itmax': 1, 'l_soc': True } }), ]) if fchanges: # change inp.xml file fleurmode = FleurinpModifier(fleurin) avail_ac_dict = fleurmode.get_avail_actions() # apply further user dependend changes for change in fchanges: function = change[0] para = change[1] method = avail_ac_dict.get(function, None) if not method: error = ("ERROR: Input 'inpxml_changes', function {} " 'is not known to fleurinpmodifier class, ' 'please check/test your input. I abort...' ''.format(function)) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED else: # apply change method(**para) # validate? try: fleurmode.show(display=False, validate=True) except etree.DocumentInvalid: error = ( 'ERROR: input, user wanted inp.xml changes did not validate' ) self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE # apply out = fleurmode.freeze() self.ctx.fleurinp = out return else: # otherwise do not change the inp.xml self.ctx.fleurinp = fleurin return
def change_fleurinp(self): """ This routine sets somethings in the fleurinp file before running a fleur calculation. """ self.report('INFO: run change_fleurinp') inputs = self.inputs # Has to never crash because corresponding check was done in validate function if self.ctx.fleurinp: # something was already changed return elif 'fleurinp' in inputs: fleurin = self.inputs.fleurinp elif 'structure' in inputs: if not self.ctx['inpgen'].is_finished_ok: error = 'Inpgen calculation failed' self.control_end_wc(error) return self.exit_codes.ERROR_INPGEN_CALCULATION_FAILED fleurin = self.ctx['inpgen'].outputs.fleurinpData elif 'remote_data' in inputs: # In this case only remote_data for input structure is given # fleurinp data has to be generated from the remote inp.xml file to use change_fleurinp fleurin = get_fleurinp_from_remote_data(self.inputs.remote_data, store=True) self.report(f'INFO: generated FleurinpData from files {fleurin}') wf_dict = self.ctx.wf_dict force_dict = wf_dict.get('force_dict') converge_mode = wf_dict.get('mode') fchanges = wf_dict.get('inpxml_changes', []) fleurmode = FleurinpModifier(fleurin) # set proper convergence parameters in inp.xml if converge_mode == 'density': dist = wf_dict.get('density_converged') fleurmode.set_inpchanges({ 'itmax': self.ctx.default_itmax, 'minDistance': dist }) elif converge_mode == 'force': force_converged = wf_dict.get('force_converged') dist = wf_dict.get('density_converged') fleurmode.set_inpchanges({ 'itmax': self.ctx.default_itmax, 'minDistance': dist, 'force_converged': force_converged, 'l_f': True, 'qfix': force_dict.get('qfix'), 'forcealpha': force_dict.get('forcealpha'), 'forcemix': force_dict.get('forcemix') }) elif converge_mode == 'energy': dist = 0.0 fleurmode.set_inpchanges({ 'itmax': self.ctx.default_itmax, 'minDistance': dist }) elif converge_mode == 'gw': dist = 0.0 fleurmode.set_inpchanges({ 'itmax': self.ctx.default_itmax, 'minDistance': dist, 'gw': 1 }) if 'settings' in self.inputs: self.inputs.settings.append({ 'additional_retrieve_list': ['basis.hdf', 'pot.hdf', 'ecore'] }) self.inputs.settings.append({ 'additional_remotecopy_list': ['basis.hdf', 'pot.hdf', 'ecore'] }) else: self.inputs.settings = { 'additional_retrieve_list': ['basis.hdf', 'pot.hdf', 'ecore'], 'additional_remotecopy_list': ['basis.hdf', 'pot.hdf', 'ecore'] } # apply further user dependend changes if fchanges: try: fleurmode.add_task_list(fchanges) except (ValueError, TypeError) as exc: error = ( 'ERROR: Changing the inp.xml file failed. Tried to apply inpxml_changes' f', which failed with {exc}. I abort, good luck next time!' ) self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED # validate? try: fleurmode.show(display=False, validate=True) except etree.DocumentInvalid: error = ( 'ERROR: input, user wanted inp.xml changes did not validate') self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE except ValueError as exc: error = ( 'ERROR: input, user wanted inp.xml changes could not be applied.' f'The following error was raised {exc}') self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED # apply out = fleurmode.freeze() self.ctx.fleurinp = out return
# fleurmode.set_species('W-2', {'electronConfig' : {'coreConfig' : '[Xe] (4f5/2) (4f7/2)', 'valenceConfig' : '(6s1/2) (5d3/2) (5d5/2) (6p1/2) (6p3/2)'}}, create=True)#, 'stateOccupation' : [{'state' : "(6p3/2)", 'spinUp' : "1.00000000", 'spinDown' : "1.00000000"}, {'state' : "(6p1/2)", 'spinUp' : "1.00000000", 'spinDown' : "1.00000000"}]}}, create=True) xpathn = '/fleurInput/atomSpecies/species[@name = "{}"]'.format(name)# 'radius': xpathn2 = '/fleurInput/atomSpecies/species[@name = "{}"]/electronConfig3/e/d/g/f/yeah'.format(name) new_e = etree.Element('lo') new_e.set('type', "SCLO") #fleurmode.create_tag(xpathn, new_e, True) #fleurmode.create_tag(xpathn,'electronConfig2', True) #eval_xpath3(root, xpathn2, create=True) #fleurmode.set_species('W-2', {'lo': {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 1}}, True) #fleurmode.set_species('W-2', {'lo': [{'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 2}]}, True) #fleurmode.set_species('W-2', {'lo': [{'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 3}, {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 4}, {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 5}, {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 6}]}, True) ''' #fleurmode.changes() fleurmode.show(validate=True)#, display=False) print fleurmode._original print fleurmode._tasks out=''#fleurmode.freeze() print 'out: {}'.format(out) print 'in: {}'.format(new_fleurinpData)