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
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