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()
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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
示例#5
0
    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
示例#6
0
    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