コード例 #1
0
    def get_kpointsdata_ncf(self, name=None, index=None, only_used=False):
        """
        This routine returns an AiiDA :class:`~aiida.orm.KpointsData` type produced from the
        ``inp.xml`` file. This only works if the kpoints are listed in the in inpxml.
        This is NOT a calcfunction and does not keep the provenance!

        :param name: str, optional, if given only the kpoint set with the given name
                     is returned
        :param index: int, optional, if given only the kpoint set with the given index
                      is returned

        :returns: :class:`~aiida.orm.KpointsData` node
        """
        from aiida.orm import KpointsData
        from masci_tools.util.xml.xml_getters import get_kpoints_data

        # HINT, TODO:? in this routine, the 'cell' you might get in an other way
        # exp: StructureData.cell, but for this you have to make a structureData Node,
        # which might take more time for structures with lots of atoms.
        # then just parsing the cell from the inp.xml
        # as in the routine get_structureData

        xmltree, schema_dict = self.load_inpxml()

        if name is None and index is None:
            kpoints, weights, cell, pbc = get_kpoints_data(xmltree,
                                                           schema_dict,
                                                           only_used=only_used)
        else:
            kpoints, weights, cell, pbc = get_kpoints_data(xmltree,
                                                           schema_dict,
                                                           name=name,
                                                           index=index,
                                                           only_used=only_used)

        if isinstance(kpoints, dict):
            kpoints_data = {}
            for (label,
                 kpoints_set), weights_set in zip(kpoints.items(),
                                                  weights.values()):
                kps = KpointsData()
                kps.set_cell(cell)
                kps.pbc = pbc
                kps.set_kpoints(kpoints_set,
                                cartesian=False,
                                weights=weights_set)
                #kpoints_data.add_link_from(self, label='fleurinp.kpts', link_type=LinkType.CREATE)
                kps.label = 'fleurinp.kpts'
                kpoints_data[label] = kps
        else:
            kpoints_data = KpointsData()
            kpoints_data.set_cell(cell)
            kpoints_data.pbc = pbc
            kpoints_data.set_kpoints(kpoints, cartesian=False, weights=weights)
            #kpoints_data.add_link_from(self, label='fleurinp.kpts', link_type=LinkType.CREATE)
            kpoints_data.label = 'fleurinp.kpts'

        return kpoints_data
コード例 #2
0
    def get_kpointsdata_ncf(self):
        """
        This routine returns an AiiDA :class:`~aiida.orm.KpointsData` type produced from the
        ``inp.xml`` file. This only works if the kpoints are listed in the in inpxml.
        This is NOT a calcfunction and does not keep the provenance!

        :returns: :class:`~aiida.orm.KpointsData` node
        """
        from aiida.orm import KpointsData

        # HINT, TODO:? in this routine, the 'cell' you might get in an other way
        # exp: StructureData.cell, but for this you have to make a structureData Node,
        # which might take more time for structures with lots of atoms.
        # then just parsing the cell from the inp.xml
        # as in the routine get_structureData

        # Disclaimer: this routine needs some xpath expressions.
        # these are hardcoded here, therefore maintainance might be needed,
        # if you want to circumvent this, you have
        # to get all the paths from somewhere.

        #######
        # all hardcoded xpaths used and attributes names:
        bravaismatrix_bulk_xpath = '/fleurInput/cell/bulkLattice/bravaisMatrix/'
        bravaismatrix_film_xpath = '/fleurInput/cell/filmLattice/bravaisMatrix/'
        kpointlist_xpath = '/fleurInput/calculationSetup/bzIntegration/kPointList/'

        kpoint_tag = 'kPoint'
        kpointlist_attrib_posscale = 'posScale'
        kpointlist_attrib_weightscale = 'weightScale'
        #kpointlist_attrib_count = 'count'
        kpoint_attrib_weight = 'weight'
        row1_tag_name = 'row-1'
        row2_tag_name = 'row-2'
        row3_tag_name = 'row-3'
        ########

        if 'inp.xml' not in self.files:
            print(
                'cannot get a KpointsData because fleurinpdata has no inp.xml file yet'
            )
            # TODO what to do in this case?
            return False

        # else read in inpxml

        if self._schema_file_path:  # Schema there, parse with schema
            xmlschema_doc = etree.parse(self._schema_file_path)
            xmlschema = etree.XMLSchema(xmlschema_doc)
            parser = etree.XMLParser(attribute_defaults=True, encoding='utf-8')
            with self.open(path='inp.xml', mode='r') as inpxmlfile:
                tree = etree.parse(inpxmlfile, parser)
            tree.xinclude()
            # remove comments from inp.xml
            comments = tree.xpath('//comment()')
            for c in comments:
                p = c.getparent()
                p.remove(c)
            if not xmlschema.validate(tree):
                raise ValueError(
                    'Input file is not validated against the schema.')
        else:  # schema not there, parse without
            print('parsing inp.xml without XMLSchema')
            with self.open(path='inp.xml', mode='r') as inpxmlfile:
                tree = etree.parse(inpxmlfile)
            tree.xinclude()
            # remove comments from inp.xml
            comments = tree.xpath('//comment()')
            for c in comments:
                p = c.getparent()
                p.remove(c)
        root = tree.getroot()

        # get cell matrix from inp.xml
        cell = None
        row1 = root.xpath(bravaismatrix_bulk_xpath +
                          row1_tag_name)  # [0].text.split()

        if row1:  # bulk calculation
            row1 = row1[0].text.split()
            row2 = root.xpath(bravaismatrix_bulk_xpath +
                              row2_tag_name)[0].text.split()
            row3 = root.xpath(bravaismatrix_bulk_xpath +
                              row3_tag_name)[0].text.split()
            # TODO? allow math?
            for i, cor in enumerate(row1):
                row1[i] = float(cor) * BOHR_A
            for i, cor in enumerate(row2):
                row2[i] = float(cor) * BOHR_A
            for i, cor in enumerate(row3):
                row3[i] = float(cor) * BOHR_A

            cell = [row1, row2, row3]
            # set boundary conditions
            pbc1 = [True, True, True]

        elif root.xpath(bravaismatrix_film_xpath + row1_tag_name):
            # film calculation
            row1 = root.xpath(bravaismatrix_film_xpath +
                              row1_tag_name)[0].text.split()
            row2 = root.xpath(bravaismatrix_film_xpath +
                              row2_tag_name)[0].text.split()
            row3 = root.xpath(bravaismatrix_film_xpath +
                              row3_tag_name)[0].text.split()
            for i, cor in enumerate(row1):
                row1[i] = float(cor) * BOHR_A
            for i, cor in enumerate(row2):
                row2[i] = float(cor) * BOHR_A
            for i, cor in enumerate(row3):
                row3[i] = float(cor) * BOHR_A
            # row3 = [0, 0, 0]#? TODO:what has it to be in this case?
            cell = [row1, row2, row3]
            pbc1 = [True, True, False]

        if cell is None:
            print('Could not extract Bravias matrix out of inp.xml. Is the '
                  'Bravias matrix explicitly given? i.e Latnam definition '
                  'not supported.')
            return None
        # get kpoints only works if kpointlist in inp.xml
        kpoints = root.xpath(kpointlist_xpath + kpoint_tag)

        if kpoints:
            posscale = root.xpath(kpointlist_xpath + '@' +
                                  kpointlist_attrib_posscale)
            weightscale = root.xpath(kpointlist_xpath + '@' +
                                     kpointlist_attrib_weightscale)
            #count = root.xpath(kpointlist_xpath + '@' + kpointlist_attrib_count)

            kpoints_pos = []
            kpoints_weight = []

            for kpoint in kpoints:
                kpoint_pos = kpoint.text.split()
                for i, kval in enumerate(kpoint_pos):
                    kpoint_pos[i] = float(kval) / float(posscale[0])
                    kpoint_weight = float(
                        kpoint.get(kpoint_attrib_weight)) / float(
                            weightscale[0])
                kpoints_pos.append(kpoint_pos)
                kpoints_weight.append(kpoint_weight)
            totalw = 0
            for weight in kpoints_weight:
                totalw = totalw + weight
            kps = KpointsData()
            kps.set_cell(cell)
            kps.pbc = pbc1

            kps.set_kpoints(kpoints_pos,
                            cartesian=False,
                            weights=kpoints_weight)
            #kps.add_link_from(self, label='fleurinp.kpts', link_type=LinkType.CREATE)
            kps.label = 'fleurinp.kpts'
            # return {label: kps}
            return kps
        else:  # TODO parser other kpoints formats, if they fit in an AiiDA node
            print('No kpoint list in inp.xml')
            return None