Example #1
0
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 == []
Example #2
0
def test_fleurxml_modifier_modify_xmlfile_simple():
    """Tests if fleurinp_modifier with various modifations on species"""
    from masci_tools.io.fleurxmlmodifier import FleurXMLModifier, ModifierTask

    fm = FleurXMLModifier()
    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.xml_set_attrib_value_no_create('/fleurInput/calculationSetup/cutoffs',
                                      'Gmax', '14.0')

    assert fm.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'}),
        ModifierTask(name='set_species',
                     args=('all', {
                         'mtSphere': {
                             'radius': 3.333
                         }
                     }),
                     kwargs={}),
        ModifierTask(name='xml_set_attrib_value_no_create',
                     args=(
                         '/fleurInput/calculationSetup/cutoffs',
                         'Gmax',
                         '14.0',
                     ),
                     kwargs={})
    ]

    #The underlying methods are tested in the specific tests for the setters
    #We only want to ensure that the procedure finishes without error
    xmltree = fm.modify_xmlfile(TEST_INPXML_PATH)

    assert xmltree is not None
    def set_file(self, filename, dst_filename=None, node=None):
        """
        Appends a :py:func:`~aiida_fleur.data.fleurinp.FleurinpData.set_file()` to
        the list of tasks that will be done on the FleurinpData instance.

        :param filename: absolute path to the file or a filename of node is specified
        :param dst_filename: str of the filename, which should be used instead of the real filename
                             to store it
        :param node: a :class:`~aiida.orm.FolderData` node containing the file
        """
        from aiida.orm import FolderData, load_node

        node_uuid = None
        if node is not None:
            if isinstance(node, FolderData):
                node_uuid = node.uuid

            num_nodes = sum('folder' in label
                            for label in self._other_nodes) + 1
            node_label = f'folder_{num_nodes}'
            # Be more careful? Needs to be stored, otherwise we cannot load it
            self._other_nodes[node_label] = load_node(node_uuid)

        self._tasks.append(
            ModifierTask('set_file',
                         args=(filename, ),
                         kwargs={
                             'dst_filename': dst_filename,
                             'node': node_uuid
                         }))
    def del_file(self, filename):
        """
        Appends a :py:func:`~aiida_fleur.data.fleurinp.FleurinpData.del_file()` to
        the list of tasks that will be done on the FleurinpData instance.

        :param filename: name of the file to be removed from FleurinpData instance
        """
        self._tasks.append(
            ModifierTask('del_file', args=(filename, ), kwargs={}))
    def set_kpointsdata(self, kpointsdata_uuid, name=None, switch=False):
        """
        Appends a :py:func:`~aiida_fleur.tools.xml_aiida_modifiers.set_kpointsdata_f()` to
        the list of tasks that will be done on the FleurinpData.

        :param kpointsdata_uuid: an :class:`aiida.orm.KpointsData` or node uuid, since the node is self cannot be be serialized in tasks.
        """
        from aiida.orm import KpointsData, load_node

        if isinstance(kpointsdata_uuid, KpointsData):
            kpointsdata_uuid = kpointsdata_uuid.uuid
        # Be more careful? Needs to be stored, otherwise we cannot load it

        num_nodes = sum('kpoints' in label for label in self._other_nodes) + 1
        node_label = f'kpoints_{num_nodes}'

        self._other_nodes[node_label] = load_node(kpointsdata_uuid)
        self._tasks.append(
            ModifierTask('set_kpointsdata',
                         args=(kpointsdata_uuid, ),
                         kwargs={
                             'name': name,
                             'switch': switch
                         }))
def modify_fleurinpdata(original, modifications, **kwargs):
    """
    A CalcFunction that performs the modification of the given FleurinpData and stores
    the result in a database.

    :param original: a FleurinpData to be modified
    :param modifications: a python dictionary of modifications in the form of {'task': ...}
    :param kwargs: dict of other aiida nodes to be linked to the modifications
    :returns new_fleurinp: a modified FleurinpData that is stored in a database
    """
    # copy
    # get schema
    # read in inp.xml
    # add modifications
    # validate
    # save inp.xml
    # store new fleurinp (copy)
    import tempfile
    from masci_tools.util.xml.common_functions import reverse_xinclude

    new_fleurinp = original.clone()

    modification_tasks = modifications.get_dict()['tasks']

    #We need to rebuild the namedtuples since the serialization for the calcufunction inputs
    #converts the namedtuples into lists
    modification_tasks = [ModifierTask(*task) for task in modification_tasks]

    FleurinpModifier.apply_fleurinp_modifications(new_fleurinp,
                                                  modification_tasks)

    xmltree, schema_dict, included_tags = new_fleurinp.load_inpxml(
        remove_blank_text=True, return_included_tags=True)

    try:
        with new_fleurinp.open(path='n_mmp_mat', mode='r') as n_mmp_file:
            nmmplines = n_mmp_file.read().split('\n')
    except FileNotFoundError:
        nmmplines = None

    new_fleurtree, new_nmmplines = FleurinpModifier.apply_modifications(xmltree=xmltree,\
                                                                        nmmp_lines=nmmplines,\
                                                                        modification_tasks=modification_tasks,
                                                                        validate_changes=False)

    # To include object store storage this prob has to be done differently

    inpxmltree, includedtrees = reverse_xinclude(new_fleurtree, schema_dict,
                                                 included_tags)

    new_fleurinp.del_file('inp.xml')
    with tempfile.TemporaryDirectory() as td:
        inpxml_path = os.path.join(td, 'inp.xml')
        inpxmltree.write(inpxml_path, encoding='utf-8', pretty_print=True)
        new_fleurinp.set_file(inpxml_path, 'inp.xml')

        for file_name, tree in includedtrees.items():
            file_path = os.path.join(td, file_name)
            tree.write(file_path, encoding='utf-8', pretty_print=True)
            new_fleurinp.set_file(file_path, file_name)

        if new_nmmplines is not None:
            n_mmp_path = os.path.join(td, 'n_mmp_mat')
            with open(n_mmp_path, 'w') as n_mmp_file:
                n_mmp_file.write('\n'.join(new_nmmplines))
            new_fleurinp.set_file(n_mmp_path, 'n_mmp_mat')

    # default label and description
    new_fleurinp.label = 'mod_fleurinp'
    new_fleurinp.description = 'Fleurinpdata with modifications (see inputs of modify_fleurinpdata)'

    return new_fleurinp
Example #7
0
def test_fleurxml_modifier_from_list():
    """Tests if fleurinp_modifier with various modifations on species"""
    from masci_tools.io.fleurxmlmodifier import FleurXMLModifier, ModifierTask

    fm = FleurXMLModifier.fromList([('set_inpchanges', {
        'change_dict': {
            'dos': True,
            'Kmax': 3.9
        }
    }), ('shift_value', {
        'change_dict': {
            'Kmax': 0.1
        },
        'mode': 'rel'
    }),
                                    ('shift_value_species_label', {
                                        'atom_label': '                 222',
                                        'attributename': 'radius',
                                        'value_given': 3,
                                        'mode': 'abs'
                                    }),
                                    ('set_kpointlist', {
                                        'kpoints': [[0, 0, 0]],
                                        'weights': [1]
                                    }),
                                    ('set_species', {
                                        'species_name': 'all',
                                        'attributedict': {
                                            'mtSphere': {
                                                'radius': 3.333
                                            }
                                        }
                                    })])

    assert fm.changes() == [
        ModifierTask(name='set_inpchanges',
                     args=(),
                     kwargs={'change_dict': {
                         'dos': True,
                         'Kmax': 3.9
                     }}),
        ModifierTask(name='shift_value',
                     args=(),
                     kwargs={
                         'change_dict': {
                             'Kmax': 0.1
                         },
                         'mode': 'rel'
                     }),
        ModifierTask(name='shift_value_species_label',
                     args=(),
                     kwargs={
                         'atom_label': '                 222',
                         'attributename': 'radius',
                         'value_given': 3,
                         'mode': 'abs'
                     }),
        ModifierTask(name='set_kpointlist',
                     args=(),
                     kwargs={
                         'kpoints': [[0, 0, 0]],
                         'weights': [1]
                     }),
        ModifierTask(name='set_species',
                     args=(),
                     kwargs={
                         'species_name': 'all',
                         'attributedict': {
                             'mtSphere': {
                                 'radius': 3.333
                             }
                         }
                     })
    ]

    #The underlying methods are tested in the specific tests for the setters
    #We only want to ensure that the procedure finishes without error
    xmltree = fm.modify_xmlfile(TEST_INPXML_PATH)

    assert xmltree is not None