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()
Example #2
0
    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
Example #3
0
    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