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 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') 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') 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): """ 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. """ # 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