Commits (1)
......@@ -18,28 +18,32 @@ import gzip
import bz2
import lzma
from nomadcore.baseclasses import ParserInterface
import nomadcore.baseclasses
from vaspparser.parser_vasprun import parserInfo
from vaspparser.parser_vasprun import VasprunContext, XmlParser, parserInfo
from .metainfo import m_env
from vaspparser.parser_vasprun import VasprunContext, XmlParser, parser_info
from nomad.parsing.parser import MatchingParser
from vaspparser.parser_outcar import VaspOutcarParser
from nomad.parsing.legacy import CoEInterfaceParser
class VASPRunMainParser:
"""
The main parser class that is called for all run types. Parses the VASP
.xml output files.
"""
def __init__(self, parser_context):
self.parser_context = parser_context
class VASPParser(MatchingParser):
def __init__(self):
super().__init__(
name='parsers/vasp', code_name='VASP', code_homepage='https://www.vasp.at/',
mainfile_mime_re=r'(application/.*)|(text/.*)',
mainfile_contents_re=(
r'^\s*<\?xml version="1\.0" encoding="ISO-8859-1"\?>\s*'
r'?\s*<modeling>'
r'?\s*<generator>'
r'?\s*<i name="program" type="string">\s*vasp\s*</i>'
r'?'),
supported_compressions=['gz', 'bz2', 'xz']
)
def run(self, filepath, logger=None):
self._metainfo_env = m_env
super_context = VasprunContext(logger=logger)
def parse(self, filepath):
# the nomadcore.baseclasses.logger is set for each parsing run
superContext = VasprunContext(logger=nomadcore.baseclasses.logger)
parser = XmlParser(parserInfo, superContext)
backend = self.parser_context.super_backend
parser = XmlParser(parser_info, super_context, metainfo_env=m_env)
open_file = open
if filepath.endswith('.gz'):
......@@ -49,46 +53,5 @@ class VASPRunMainParser:
elif filepath.endswith('.xz'):
open_file = lzma.open
parser.parse(os.path.abspath(filepath), open_file(filepath, 'rt'), backend)
class VASPRunParserInterface(ParserInterface):
"""
This class handles the initial setup before any parsing can happen. It
determines which version of BigDFT was used to generate the output and then
sets up a correct main parser.
After the implementation has been setup, you can parse the files with
parse().
"""
def __init__(
self,
metainfo_to_keep=None, backend=None, default_units=None,
metainfo_units=None, debug=True, log_level=logging.ERROR, store=True):
super(VASPRunParserInterface, self).__init__(
metainfo_to_keep, backend, default_units, metainfo_units, debug, log_level, store)
def setup_version(self):
"""
Setups the version by looking at the output file and the version
specified in it.
"""
# Setup the root folder to the fileservice that is used to access files
dirpath, filename = os.path.split(self.parser_context.main_file)
dirpath = os.path.abspath(dirpath)
self.parser_context.file_service.setup_root_folder(dirpath)
self.parser_context.file_service.set_file_id(filename, "output")
self.main_parser = VASPRunMainParser(self.parser_context)
def get_metainfo_filename(self):
return "vasp.nomadmetainfo.json"
def get_parser_info(self):
return parserInfo
class VASPRunParser(CoEInterfaceParser):
def __init__(self):
super().__init__(VASPRunParserInterface)
parser.parse(os.path.abspath(filepath), open_file(filepath, 'rt'))
return parser.root_section
......@@ -17,23 +17,39 @@ from builtins import range
from builtins import object
import xml.etree.ElementTree
from xml.etree.ElementTree import ParseError
import sys
import bisect
from datetime import datetime
import os
import re
import traceback
import numpy as np
import ase.geometry
import ase.data
from math import pi
import xml.etree.ElementTree as ET
import logging
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
from nomadcore.unit_conversion.unit_conversion import convert_unit_function
from nomadcore.unit_conversion.unit_conversion import convert_unit
from nomad.metainfo import Quantity
from nomad.datamodel.metainfo.public import section_run as msection_run
from nomad.datamodel.metainfo.public import section_method as msection_method
from nomad.datamodel.metainfo.public import section_sampling_method as msection_sampling_method
from nomad.datamodel.metainfo.public import section_frame_sequence as msection_frame_sequence
from nomad.datamodel.metainfo.public import section_workflow as msection_workflow
from nomad.datamodel.metainfo.public import section_single_configuration_calculation as msection_single_configuration_calculation
from nomad.datamodel.metainfo.public import section_basis_set as msection_basis_set
from nomad.datamodel.metainfo.public import section_XC_functionals as msection_XC_functionals
from nomad.datamodel.metainfo.public import section_system as msection_system
from nomad.datamodel.metainfo.public import section_k_band as msection_k_band
from nomad.datamodel.metainfo.public import section_k_band_segment as msection_k_band_segment
from nomad.datamodel.metainfo.public import section_k_band_normalized as msection_k_band_normalized
from nomad.datamodel.metainfo.public import section_k_band_segment_normalized as msection_k_band_segment_normalized
from nomad.datamodel.metainfo.public import section_eigenvalues as msection_eigenvalues
from nomad.datamodel.metainfo.public import section_method_atom_kind as msection_method_atom_kind
from nomad.datamodel.metainfo.public import section_basis_set_cell_dependent as msection_basis_set_cell_dependent
from nomad.datamodel.metainfo.public import section_dos as msection_dos
from nomad.datamodel.metainfo.common import section_method_basis_set as msection_method_basis_set
eV2J = convert_unit_function("eV", "J")
eV2JV = np.vectorize(eV2J)
......@@ -53,10 +69,10 @@ special_paths = {
'monoclinic': 'ΓYHCEM1AXH1,MDZ,YD'}
def secondsFromEpoch(date):
def seconds_from_epoch(date):
epoch = datetime(1970, 1, 1)
ts = date-epoch
return ts.seconds + ts.microseconds/1000.0
ts = date - epoch
return ts.seconds + ts.microseconds / 1000.0
trueRe = re.compile(
......@@ -65,20 +81,20 @@ falseRe = re.compile(
r"\s*(?:\.?[fF](?:[Aa][Ll][Ss][Ee])?\.?|0|[Nn](?:[Oo]|[Ee][Ii][Nn])?)\s*$")
def toBool(value):
def to_bool(value):
if falseRe.match(value):
return False
elif trueRe.match(value):
return True
else:
backend.pwarn("Unexpected value for boolean field: %s" % (value))
return None
metaTypeTransformers = {
meta_type_transformers = {
'C': lambda x: x.strip(),
'i': lambda x: int(float(x.strip())),
'f': lambda x: float(x.strip()),
'b': toBool,
'b': to_bool,
}
......@@ -94,8 +110,9 @@ class MyXMLParser(ET.XMLParser):
num = int(target)
else:
num = int(m.group(2), 16)
if not(num in (0x9, 0xA, 0xD) or 0x20 <= num <= 0xD7FF
or 0xE000 <= num <= 0xFFFD or 0x10000 <= num <= 0x10FFFF):
if not(
num in (0x9, 0xA, 0xD) or 0x20 <= num <= 0xD7FF or 0xE000 <= num <= 0xFFFD
or 0x10000 <= num <= 0x10FFFF):
# is invalid xml character, cut it out of the stream
mstart, mend = m.span()
mydata = data[:mstart] + data[mend:]
......@@ -111,7 +128,7 @@ def transform2(y):
return y
def getVector(el, transform=float, field="v"):
def get_vector(el, transform=float, field="v"):
""" returns the vasp style vector contained in the element el (using field v).
single elements are converted using the function convert"""
#
......@@ -127,7 +144,7 @@ class VasprunContext(object):
logger = logging.getLogger(__name__)
self.logger = logger
self.parser = None
self._parser = None
self.bands = None
self.kpoints = None
self.weights = None
......@@ -135,124 +152,132 @@ class VasprunContext(object):
self.tetrahedronVolume = None
self.ispin = None
self.ibrion = None
self.lastSystemDescription = None
self.labels = None
self.singleConfCalcs = []
self.vbTopE = None
self.ebMinE = None
self.eFermi = None
self.e_fermi = None
self.cell = None
self.angstrom_cell = None
self.unknown_incars = {}
self._energies = []
sectionMap = {
section_map = {
"modeling": ["section_run", "section_method"],
"structure": ["section_system"],
"calculation": ["section_single_configuration_calculation"]
}
def startedParsing(self, parser):
self.parser = parser
@property
def parser(self):
return self._parser
def onEnd_generator(self, parser, event, element, pathStr):
backend = parser.backend
@parser.setter
def parser(self, name):
self._parser = name
def on_end_generator(self, element, path_str):
root_section = self.parser.root_section
program_name = g(element, "i/[@name='program']")
if program_name.strip().upper() == "VASP":
backend.addValue("program_name", "VASP")
if program_name.strip().upper() == 'VASP':
root_section.program_name = 'VASP'
else:
raise Exception("unexpected program name: %s" % program_name)
version = (g(element, "i/[@name='version']", "") + " " +
g(element, "i/[@name='subversion']", "") + " " +
g(element, "i/[@name='platform']", ""))
raise Exception('unexpected program name: %s' % program_name)
version = (
g(element, "i/[@name='version']", "") + " " +
g(element, "i/[@name='subversion']", "") + " " +
g(element, "i/[@name='platform']", ""))
if not version.isspace():
backend.addValue("program_version", version)
backend.addValue("program_basis_set_type", "plane waves")
root_section.program_version = version
root_section.program_basis_set_type = "plane waves"
date = g(element, "i/[@name='date']")
pdate = None
time = g(element, "i/[@name='time']")
if date:
pdate = datetime.strptime(date.strip(), "%Y %m %d")
if pdate and time:
pdate = datetime.combine(pdate.date(), datetime.strptime(
time.strip(), "%H:%M:%S").timetz())
if pdate:
backend.addValue("program_compilation_datetime",
secondsFromEpoch(pdate))
root_section.program_compilation_datetime = seconds_from_epoch(pdate)
for i in element:
if i.tag != "i" or not i.attrib.get("name") in set(["program", "version", "subversion", "platform", "program_version", "date", "time"]):
backend.pwarn("unexpected tag %s %s %r in generator" %
(i.tag, i.attrib, i.text))
if i.tag != "i" or not i.attrib.get("name") in set(
[
'program', 'version', 'subversion', 'platform', 'program_version',
'date', 'time']):
pass
def onEnd_incar(self, parser, event, element, pathStr):
backend = parser.backend
metaEnv = parser.backend.metaInfoEnv()
def on_end_incar(self, element, path_str):
root_section = self.parser.root_section
m_env = self.parser.metainfo_env
section_method = root_section.m_create(msection_method)
dft_plus_u = False
ibrion = None
nsw = 0
for el in element:
if el.tag == "v":
name = el.attrib.get("name", None)
meta = metaEnv['x_vasp_incar_' + name]
meta = m_env.resolve_definition('x_vasp_incar_' + name, Quantity)
if not meta:
backend.pwarn("Unknown INCAR parameter (not registered in the meta data): %s %s %r" % (
el.tag, el.attrib, el.text))
self.logger.warn(
"Unknown INCAR parameter (not registered in the meta data): %s %s %r" % (
el.tag, el.attrib, el.text))
continue
#- -
vector_val = np.asarray(getVector(el))
backend.addArrayValues(meta.get('name'), vector_val)
vector_val = np.asarray(get_vector(el))
setattr(section_method, meta.get('name'), vector_val)
elif el.tag == "i":
name = el.attrib.get("name", None)
meta = metaEnv['x_vasp_incar_' + name]
valType = el.attrib.get("type")
meta = m_env.resolve_definition('x_vasp_incar_' + name, Quantity)
val_type = el.attrib.get("type")
if not meta:
backend.pwarn("Unknown INCAR parameter (not registered in the meta data): %s %s %r" % (
el.tag, el.attrib, el.text))
elif valType:
expectedMetaType = {
self.logger.warn(
"Unknown INCAR parameter (not registered in the meta data): %s %s %r" % (
el.tag, el.attrib, el.text))
elif val_type:
expected_meta_type = {
'string': ['C'],
'int': ['i'],
'logical': ['b', 'C']
}.get(valType)
if not expectedMetaType:
backend.pwarn("Unknown value type %s encountered in INCAR: %s %s %r" % (
valType, el.tag, el.attrib, el.text))
elif not meta.get('dtypeStr') in expectedMetaType:
backend.pwarn("type mismatch between meta data %s and INCAR type %s for %s %s %r" % (
meta.get('dtypeStr'), valType, el.tag, el.attrib, el.text))
}.get(val_type)
metainfo_type = self._metainfo_type(meta)
if not expected_meta_type:
self.logger.warn("Unknown value type %s encountered in INCAR: %s %s %r" % (
val_type, el.tag, el.attrib, el.text))
elif not metainfo_type in expected_meta_type:
self.logger.warn("type mismatch between meta data %s and INCAR type %s for %s %s %r" % (
metainfo_type, val_type, el.tag, el.attrib, el.text))
else:
shape = meta.get("shape", None)
dtypeStr = meta.get("dtypeStr", None)
converter = metaTypeTransformers.get(dtypeStr)
shape = meta.get("shape")
converter = meta_type_transformers.get(metainfo_type)
if not converter:
backend.pwarn(
"could not find converter for dtypeStr %s when handling meta info %s" % (dtypeStr, ))
self.logger.warn(
"could not find converter for %s when handling meta info %s" % (
metainfo_type, meta))
elif shape:
vals = re.split("\s+", el.text.strip())
backend.addValue(
meta["name"], [converter(x) for x in vals])
vals = re.split(r"\s+", el.text.strip())
setattr(section_method, meta['name'], [converter(x) for x in vals])
else:
backend.addValue(meta["name"], converter(el.text))
setattr(section_method, meta["name"], converter(el.text))
if name == 'GGA':
# FIXME tmk: many options are not coded yet. See
# https://www.vasp.at/wiki/index.php/GGA
fMap = {
f_map = {
'91': ['GGA_X_PW91', 'GGA_C_PW91'],
'PE': ['GGA_X_PBE', 'GGA_C_PBE'],
'RP': ['GGA_X_RPBE', 'GGA_C_PBE'],
'PS': ['GGA_C_PBE_SOL', 'GGA_X_PBE_SOL'],
'MK': ['GGA_X_OPTB86_VDW']
}
functs = fMap.get(el.text.strip(), None)
functs = f_map.get(el.text.strip(), None)
if not functs:
backend.pwarn("Unknown XC functional %s" %
el.text.strip())
self.logger.warn("Unknown XC functional %s" % el.text.strip())
else:
for f in functs:
backend.openNonOverlappingSection(
"section_XC_functionals")
backend.addValue("XC_functional_name", f)
backend.closeNonOverlappingSection(
"section_XC_functionals")
section_XC_functionals = section_method.m_create(msection_XC_functionals)
section_XC_functionals.XC_functional_name = f
elif name == "ISPIN":
self.ispin = int(el.text.strip())
elif name == "LDAU":
......@@ -263,35 +288,32 @@ class VasprunContext(object):
elif name == "NSW":
nsw = int(el.text.strip())
else:
backend.pwarn("unexpected tag %s %s %r in incar" %
(el.tag, el.attrib, el.text))
self.logger.warn(
"unexpected tag %s %s %r in incar" % (el.tag, el.attrib, el.text))
if ibrion is None:
ibrion = -1 if nsw == 0 or nsw == 1 else 0
if nsw == 0:
ibrion = -1
self.ibrion = ibrion
if dft_plus_u:
backend.addValue("electronic_structure_method", "DFT+U")
else:
backend.addValue("electronic_structure_method", "DFT")
section_method.electronic_structure_method = 'DFT+U' if dft_plus_u else 'DFT'
def onEnd_kpoints(self, parser, event, element, pathStr):
backend = parser.backend
def on_end_kpoints(self, element, path_str):
root_section = self.parser.root_section
self.bands = None
self.kpoints = None
self.weights = None
for el in element:
if el.tag == "generation":
param = el.attrib.get("param", None) # eg. listgenerated, Monkhorst-Pack, Gamma
param = el.attrib.get("param", None) # eg. listgenerated, Monkhorst-Pack, Gamma
if param:
backend.addValue(
"x_vasp_k_points_generation_method", param)
root_section.section_method[-1].x_vasp_k_points_generation_method = param
if param == "listgenerated":
# This implies a path on k-space, potentially a bandstructure calculation
# Save k-path info into a dictionary
self.bands = {
"divisions": g(el, "i/[@name='divisions']", None),
"points": getVector(el)
"points": get_vector(el)
}
elif param in ["Monkhorst-Pack", "Gamma"]:
......@@ -299,22 +321,20 @@ class VasprunContext(object):
# Hence, do nothing: k-points will be stored in the `varray` if-block
pass
else:
backend.pwarn("Unknown k point generation method '%s'" %(param))
self.logger.warn("Unknown k point generation method '%s'" % param)
elif el.tag == "varray":
name = el.attrib.get("name", None)
if name == "kpointlist":
self.kpoints = np.asarray(getVector(el))
backend.addArrayValues("k_mesh_points", self.kpoints)
self.kpoints = np.asarray(get_vector(el))
root_section.section_method[-1].k_mesh_points = self.kpoints
elif name == "weights":
self.weights = np.asarray(getVector(el))
backend.addArrayValues(
"k_mesh_weights", self.weights.flatten())
self.weights = np.asarray(get_vector(el))
root_section.section_method[-1].k_mesh_weights = self.weights.flatten()
elif name == "tetrahedronlist":
self.tetrahedrons = np.asarray(getVector(el), dtype=np.int)
backend.addArrayValues(
"x_vasp_tetrahedrons_list", self.tetrahedrons)
self.tetrahedrons = np.asarray(get_vector(el), dtype=np.int)
root_section.section_method[-1].x_vasp_tetrahedrons_list = self.tetrahedrons
else:
backend.pwarn("Unknown array %s in kpoints" % name)
self.logger.warn("Unknown array %s in kpoints" % name)
elif el.tag == "i":
name = el.attrib.get("name", None)
if name == "volumeweight":
......@@ -324,105 +344,98 @@ class VasprunContext(object):
vol_cubic_angs = float(el.text.strip())
vol_cubic_meters = ang2m(ang2m(ang2m(vol_cubic_angs)))
backend.addArrayValues("x_vasp_tetrahedron_volume",
vol_cubic_meters)
root_section.section_method[-1].x_vasp_tetrahedron_volume = vol_cubic_meters
else:
backend.pwarn("Unknown tag %s in kpoints" % el.tag)
self.logger.pwarn("Unknown tag %s in kpoints" % el.tag)
def onEnd_structure(self, parser, event, element, pathStr):
backend = parser.backend
gIndexes = parser.tagSections[pathStr]
self.lastSystemDescription = gIndexes["section_system"]
def on_end_structure(self, element, path_str):
root_section = self.parser.root_section
section_system = root_section.m_create(msection_system)
self.cell = None
for el in element:
if (el.tag == "crystal"):
for cellEl in el:
if cellEl.tag == "varray":
name = cellEl.attrib.get("name", None)
for cell_el in el:
if cell_el.tag == "varray":
name = cell_el.attrib.get("name", None)
if name == "basis":
conv = convert_unit_function("angstrom", "m")
self.cell = getVector(
cellEl, lambda x: conv(float(x)))
self.angstrom_cell = np.array(getVector(cellEl))
backend.addArrayValues(
"simulation_cell", np.asarray(self.cell))
backend.addArrayValues(
"configuration_periodic_dimensions", np.ones(3, dtype=bool))
self.cell = get_vector(
cell_el, lambda x: conv(float(x)))
self.angstrom_cell = np.array(get_vector(cell_el))
section_system.simulation_cell = np.asarray(self.cell)
section_system.configuration_periodic_dimensions = np.ones(3, dtype=bool)
elif name == "rec_basis":
pass
else:
backend.pwarn(
self.logger.warn(
"Unexpected varray %s in crystal" % name)
elif cellEl.tag == "i":
if cellEl.attrib.get("name") != "volume":
backend.pwarn(
"Unexpected i value %s in crystal" % cellEl.attrib)
elif cell_el.tag == "i":
if cell_el.attrib.get("name") != "volume":
self.logger.warn(
"Unexpected i value %s in crystal" % cell_el.attrib)
else:
backend.pwarn("Unexpected tag %s %s %r in crystal" % (
cellEl.tag, cellEl.attrib, cellEl.text))
self.logger.warn("Unexpected tag %s %s %r in crystal" % (
cell_el.tag, cell_el.attrib, cell_el.text))
elif el.tag == "varray":
name = el.attrib.get("name", None)
if name == "positions":
pos = getVector(el)
backend.addArrayValues(
"atom_positions", np.dot(np.asarray(pos), self.cell))
pos = get_vector(el)
section_system.atom_positions = np.dot(np.asarray(pos), self.cell)
elif name == "selective":
atom_sel = getVector(el, transform=lambda item: item == 'T')
backend.addArrayValues(
"x_vasp_selective_dynamics", np.asarray(atom_sel, dtype=np.bool))
atom_sel = get_vector(el, transform=lambda item: item == 'T')
section_system.x_vasp_selective_dynamics = np.asarray(atom_sel, dtype=np.bool)
else:
backend.pwarn(
self.logger.warn(
"Unexpected varray in structure %s" % el.attrib)
elif el.tag == "nose":
nose = getVector(el)
backend.addArrayValues("x_vasp_nose_thermostat", nose)
nose = get_vector(el)
section_system.x_vasp_nose_thermostat = nose
else:
backend.pwarn("Unexpected tag in structure %s %s %r" %
(el.tag, el.attrib, el.text))
self.logger.warn(
"Unexpected tag in structure %s %s %r" % (el.tag, el.attrib, el.text))
if self.labels is not None:
backend.addArrayValues("atom_labels", self.labels)
section_system.atom_labels = self.labels
def onEnd_eigenvalues(self, parser, event, element, pathStr):
if pathStr != "modeling/calculation/eigenvalues":
def on_end_eigenvalues(self, element, path_str):
if path_str != "modeling/calculation/eigenvalues":
return True
backend = parser.backend
root_section = self.parser.root_section
eigenvalues = None
occupation = None
for el in element:
if el.tag == "array":
for arrEl in el:
if arrEl.tag == "dimension":
for arrray_el in el:
if arrray_el.tag == "dimension":
pass
elif arrEl.tag == "field":
elif arrray_el.tag == "field":
pass
elif arrEl.tag == "set":
elif arrray_el.tag == "set":
isp = -1
for spinEl in arrEl:
if spinEl.tag == "set":
for spin_el in arrray_el:
if spin_el.tag == "set":
ik = -1
isp += 1
for kEl in spinEl:
for kEl in spin_el:
if kEl.tag == "set":
ik += 1
bands = np.asarray(
getVector(kEl, field="r"))
get_vector(kEl, field="r"))
if eigenvalues is None:
eigenvalues = np.zeros(
(self.ispin, self.kpoints.shape[0], bands.shape[0]), dtype=float)
(self.ispin, self.kpoints.shape[0], bands.shape[0]), dtype=float)
occupation = np.zeros(
(self.ispin, self.kpoints.shape[0], bands.shape[0]), dtype=float)
(self.ispin, self.kpoints.shape[0], bands.shape[0]), dtype=float)
eigenvalues[isp, ik] = bands[:, 0]
occupation[isp, ik] = bands[:, 1]
else:
backend.pwarn(
self.logger.warn(
"unexpected tag %s in k array of the eigenvalues" % kEl.tag)
else:
backend.pwarn(
"unexpected tag %s in spin array of the eigenvalues" % spinEl.tag)
self.logger.warn(
"unexpected tag %s in spin array of the eigenvalues" % spin_el.tag)
else:
backend.pwarn(
"unexpected tag %s in array of the eigenvalues" % arrEl.tag)
self.logger.warn(
"unexpected tag %s in array of the eigenvalues" % arrray_el.tag)
if eigenvalues is not None:
ev = eV2JV(eigenvalues)
......@@ -445,13 +458,11 @@ class VasprunContext(object):
ebMinE[ispin] = ebMinK
self.vbTopE = vbTopE
self.ebMinE = ebMinE
backend.addArrayValues(
"energy_reference_highest_occupied", np.array(vbTopE))
backend.addArrayValues(
"energy_reference_lowest_unoccupied", np.array(ebMinE))
root_section.section_single_configuration_calculation[-1].energy_reference_highest_occupied = np.array(vbTopE)
root_section.section_single_configuration_calculation[-1].energy_reference_lowest_unoccupied = np.array(ebMinE)
if self.bands:
divisions = int(self.bands['divisions'])
backend.openNonOverlappingSection("section_k_band")
section_k_band = root_section.section_single_configuration_calculation[-1].m_create(msection_k_band)
nsegments = self.kpoints.shape[0] // divisions
kpt = np.reshape(
self.kpoints, (nsegments, divisions, 3))
......@@ -460,257 +471,230 @@ class VasprunContext(object):
occ = np.reshape(
occupation, (self.ispin, nsegments, divisions, bands.shape[0]))
for isegment in range(nsegments):
backend.openNonOverlappingSection(
"section_k_band_segment")
backend.addArrayValues(
"band_energies", energies[:, isegment, :, :])
backend.addArrayValues(
"band_occupations", occ[:, isegment, :, :])
backend.addArrayValues(
"band_k_points", kpt[isegment])
section_k_band_segment = section_k_band.m_create(msection_k_band_segment)
section_k_band_segment.band_energies = energies[:, isegment, :, :]
section_k_band_segment.band_occupations = occ[:, isegment, :, :]
section_k_band_segment.band_k_points = kpt[isegment]
# "band_segm_labels"
backend.addArrayValues("band_segm_start_end", np.asarray(
[kpt[isegment, 0], kpt[isegment, divisions - 1]]))
backend.closeNonOverlappingSection(
"section_k_band_segment")
backend.closeNonOverlappingSection("section_k_band")
backend.openNonOverlappingSection(
"section_k_band_normalized")
section_k_band_segment.band_segm_start_end = np.asarray(
[kpt[isegment, 0], kpt[isegment, divisions - 1]])
section_k_band_normalized = root_section.section_single_configuration_calculation[-1].m_create(msection_k_band_normalized)
for isegment in range(nsegments):
backend.openNonOverlappingSection(
"section_k_band_segment_normalized")
backend.addArrayValues(
"band_energies_normalized", energies[:, isegment, :, :] - max(self.vbTopE))
backend.addArrayValues(
"band_occupations_normalized", occ[:, isegment, :, :])
backend.addArrayValues(
"band_k_points_normalized", kpt[isegment])
backend.addArrayValues("band_segm_start_end_normalized", np.asarray(
[kpt[isegment, 0], kpt[isegment, divisions - 1]]))
backend.closeNonOverlappingSection(
"section_k_band_segment_normalized")
backend.closeNonOverlappingSection(
"section_k_band_normalized")
section_k_band_segment_normalized = section_k_band_normalized.m_create(msection_k_band_segment_normalized)
section_k_band_segment_normalized.band_energies_normalized = energies[:, isegment, :, :] - max(self.vbTopE)
section_k_band_segment_normalized.band_occupations_normalized = occ[:, isegment, :, :]
section_k_band_segment_normalized.band_k_points_normalized = kpt[isegment]
section_k_band_segment_normalized.band_segm_start_end_normalized = np.asarray(
[kpt[isegment, 0], kpt[isegment, divisions - 1]])
else:
backend.openNonOverlappingSection(
"section_eigenvalues")
backend.addArrayValues("eigenvalues_values", ev)
backend.addArrayValues(
"eigenvalues_occupation", occupation)
backend.closeNonOverlappingSection(
"section_eigenvalues")
section_eigenvalues = root_section.section_single_configuration_calculation[-1].m_create(msection_eigenvalues)
section_eigenvalues.eigenvalues_values = ev
section_eigenvalues.eigenvalues_occupation = occupation
else:
backend.pwarn("unexpected tag %s in the eigenvalues" % el.tag)
def onEnd_scstep(self, parser, event, element, pathStr):
pass
self.logger.warn("unexpected tag %s in the eigenvalues" % el.tag)
def onStart_calculation(self, parser, event, element, pathStr):
backend = parser.backend
gIndexes = parser.tagSections[pathStr]
self.singleConfCalcs.append(
gIndexes["section_single_configuration_calculation"])
def on_start_calculation(self, element, path_str):
root_section = self.parser.root_section
sscc = root_section.m_create(msection_single_configuration_calculation)
if self.waveCut:
backend.openNonOverlappingSection("section_basis_set")
backend.addValue(
"mapping_section_basis_set_cell_dependent", self.waveCut)
backend.closeNonOverlappingSection("section_basis_set")
def onEnd_modeling(self, parser, event, element, pathStr):
backend = parser.backend
backend.addValue("x_vasp_unknown_incars", self.unknown_incars)
section_basis_set = sscc.m_create(msection_basis_set)
section_basis_set.mapping_section_basis_set_cell_dependent = self.waveCut
def on_end_modeling(self, element, path_str):
root_section = self.parser.root_section
root_section.section_method[-1].x_vasp_unknown_incars = self.unknown_incars
if self.ibrion is None or self.ibrion == -1:
return
samplingGIndex = backend.openSection("section_sampling_method")
section_sampling_method = root_section.m_create(msection_sampling_method)
if self.ibrion == 0:
sampling_method = "molecular_dynamics"
else:
sampling_method = "geometry_optimization"
backend.addValue("sampling_method", sampling_method)
backend.closeSection("section_sampling_method", samplingGIndex)
frameSequenceGIndex = backend.openSection("section_frame_sequence")
backend.addValue("frame_sequence_to_sampling_ref", samplingGIndex)
backend.addArrayValues(
"frame_sequence_local_frames_ref", np.asarray(self.singleConfCalcs))
backend.closeSection("section_frame_sequence", frameSequenceGIndex)
def onEnd_calculation(self, parser, event, element, pathStr):
eConv = eV2J
fConv = convert_unit_function("eV/angstrom", "N")
pConv = convert_unit_function("eV/angstrom^3", "Pa")
backend = parser.backend
backend.addValue(
"single_configuration_calculation_to_system_ref", self.lastSystemDescription)
gIndexes = parser.tagSections["/modeling"]
backend.addValue(
"single_configuration_to_calculation_method_ref", gIndexes["section_method"])
section_sampling_method.sampling_method = sampling_method
section_frame_sequence = root_section.m_create(msection_frame_sequence)
section_frame_sequence.frame_sequence_to_sampling_ref = section_sampling_method
section_frame_sequence.frame_sequence_local_frames_ref = root_section.section_single_configuration_calculation[-1]
section_workflow = root_section.m_create(msection_workflow)
section_workflow.workflow_type = sampling_method
section_workflow.workflow_final_calculation_ref = root_section.section_single_configuration_calculation[-1]
if len(self._energies) > 1:
delta_energy = abs(self._energies[-1] - self._energies[-2])
section_workflow.relaxation_energy_tolerance = delta_energy
def on_end_calculation(self, element, path_str):
e_conv = eV2J
f_conv = convert_unit_function("eV/angstrom", "N")
p_conv = convert_unit_function("eV/angstrom^3", "Pa")
root_section = self.parser.root_section
sscc = root_section.section_single_configuration_calculation[-1]
sscc.single_configuration_calculation_to_system_ref = root_section.section_system[-1]
sscc.single_configuration_to_calculation_method_ref = root_section.section_method[-1]
for el in element:
if el.tag == "energy":
for enEl in el:
if enEl.tag == "i":
name = enEl.attrib.get("name", None)
for en_el in el:
if en_el.tag == "i":
name = en_el.attrib.get("name", None)
if name == "e_fr_energy":
value = eConv(float(enEl.text.strip()))
backend.addValue("energy_free", value)
value = e_conv(float(en_el.text.strip()))
sscc.energy_free = value
elif name == "e_wo_entrp":
value = eConv(float(enEl.text.strip()))
backend.addValue("energy_total", value)
value = e_conv(float(en_el.text.strip()))
sscc.energy_total = value
elif name == "e_0_energy":
value = eConv(float(enEl.text.strip()))
backend.addValue("energy_total_T0", value)
else:
backend.pwarn(
"Unexpected i tag with name %s in energy section" % name)
elif enEl.tag == "varray":
name = enEl.attrib.get("name", None)
value = e_conv(float(en_el.text.strip()))
sscc.energy_total_T0 = value
self._energies.append(value)
elif en_el.tag == "varray":
name = en_el.attrib.get("name", None)
if name == "forces":
f = getVector(enEl, lambda x: fConv(float(x)))
backend.addValue("atom_forces", f)
f = get_vector(en_el, lambda x: f_conv(float(x)))
sscc.atom_forces = f
elif name == 'stress':
f = getVector(enEl, lambda x: pConv(float(x)))
backend.addValue("stress_tensor", f)
f = get_vector(en_el, lambda x: p_conv(float(x)))
sscc.stress_tensor = f
def onEnd_atominfo(self, parser, event, element, pathStr):
nAtoms = None
nAtomTypes = None
atomTypes = []
def on_end_atominfo(self, element, path_str):
root_section = self.parser.root_section
atom_types = []
labels = []
labels2 = None
atomTypesDesc = []
backend = parser.backend
atom_types_desc = []
for el in element:
if el.tag == "atoms":
nAtoms = int(el.text.strip())
elif el.tag == "types":
nAtomTypes = int(el.text.strip())
if el.tag in ['atoms', 'types']:
pass
elif el.tag == "array":
name = el.attrib.get("name", None)
if name == "atoms":
for atomsEl in el:
if atomsEl.tag == "dimension":
for atoms_el in el:
if atoms_el.tag == "dimension":
pass
elif atomsEl.tag == "field":
elif atoms_el.tag == "field":
pass
elif atomsEl.tag == "set":
for atomsLine in atomsEl:
if atomsLine.tag != "rc":
backend.pwarn(
"unexpected tag %s in atoms array in atominfo" % atomsLine.tag)
elif atoms_el.tag == "set":
for atoms_line in atoms_el:
if atoms_line.tag != "rc":
self.logger.warn(
"unexpected tag %s in atoms array in atominfo" % atoms_line.tag)
else:
line = atomsLine.findall("c")
line = atoms_line.findall("c")
labels.append(line[0].text.strip())
atomTypes.append(int(line[1].text.strip()))
atom_types.append(int(line[1].text.strip()))
else:
backend.pwarn(
"unexpected tag %s in atoms array in atominfo" % atomsEl.tag)
self.logger.warn(
"unexpected tag %s in atoms array in atominfo" % atoms_el.tag)
elif name == "atomtypes":
keys = []
fieldTypes = []
for atomsEl in el:
if atomsEl.tag == "dimension":
field_types = []
for atoms_el in el:
if atoms_el.tag == "dimension":
pass
elif atomsEl.tag == "field":
keys.append(atomsEl.text.strip())
fieldTypes.append(
atomsEl.attrib.get("type", "float"))
elif atomsEl.tag == "set":
expectedKeys = ["atomspertype", "element",
"mass", "valence", "pseudopotential"]
if keys != expectedKeys:
backend.pwarn(
"unexpected fields in atomtype: %s vs %s" % (keys, expectedKeys))
for atomsLine in atomsEl:
if atomsLine.tag != "rc":
backend.pwarn(
"unexpected tag %s in atoms array in atominfo" % atomsLine.tag)
elif atoms_el.tag == "field":
keys.append(atoms_el.text.strip())
field_types.append(
atoms_el.attrib.get("type", "float"))
elif atoms_el.tag == "set":
expected_keys = [
"atomspertype", "element", "mass", "valence", "pseudopotential"]
if keys != expected_keys:
self.logger.warn(
"unexpected fields in atomtype: %s vs %s" % (keys, expected_keys))
for atoms_line in atoms_el:
if atoms_line.tag != "rc":
self.logger.warn(
"unexpected tag %s in atoms array in atominfo" % atoms_line.tag)
else:
line = atomsLine.findall("c")
typeDesc = {}
line = atoms_line.findall("c")
type_desc = {}
for i, k in enumerate(keys):
fieldType = fieldTypes[i]
field_type = field_types[i]
value = line[i].text
if fieldType == "float":
if field_type == "float":
value = float(value)
elif fieldType == "int":
elif field_type == "int":
value = int(value)
else:
pass
typeDesc[k] = value
atomTypesDesc.append(typeDesc)
type_desc[k] = value
atom_types_desc.append(type_desc)
else:
backend.pwarn(
"unexpected tag %s in atomtypes array in atominfo" % atomsEl.tag)
kindIds = []
nEl = {}
kindLabels = []
for atomDesc in atomTypesDesc:
kindId = backend.openSection(
"section_method_atom_kind")
if 'element' in atomDesc:
elName = atomDesc['element'].strip()
self.logger.warn(
"unexpected tag %s in atomtypes array in atominfo" % atoms_el.tag)
n_el = {}
kind_labels = []
for atom_desc in atom_types_desc:
section_method_atom_kind = root_section.section_method[-1].m_create(msection_method_atom_kind)
if 'element' in atom_desc:
elName = atom_desc['element'].strip()
try:
elNr = ase.data.chemical_symbols.index(elName)
backend.addValue(
"method_atom_kind_atom_number", elNr)
section_method_atom_kind.method_atom_kind_atom_number = elNr
except Exception as e:
self.logger.error(
"error finding element number for %r" % atomDesc['element'].strip(),
"error finding element number for %r" % atom_desc['element'].strip(),
exc_info=e)
nElNow = 1 + nEl.get(elName, 0)
nEl[elName] = nElNow
elLabel = elName + \
(str(nElNow) if nElNow > 1 else "")
kindLabels.append(elLabel)
backend.addValue("method_atom_kind_label", elLabel)
if "mass" in atomDesc:
backend.addValue(
"method_atom_kind_mass", atomDesc["mass"])
if "valence" in atomDesc:
backend.addValue(
"method_atom_kind_explicit_electrons", atomDesc["valence"])
if "pseudopotential" in atomDesc:
backend.addValue(
"method_atom_kind_pseudopotential_name", atomDesc["pseudopotential"])
kindIds.append(kindId)
backend.closeSection(
"section_method_atom_kind", kindId)
backend.addArrayValues("x_vasp_atom_kind_refs", np.asarray(
[kindIds[i-1] for i in atomTypes]))
labels2 = [kindLabels[i-1] for i in atomTypes]
n_el_now = 1 + n_el.get(elName, 0)
n_el[elName] = n_el_now
el_label = elName + \
(str(n_el_now) if n_el_now > 1 else "")
kind_labels.append(el_label)
section_method_atom_kind.method_atom_kind_label = el_label
if "mass" in atom_desc:
section_method_atom_kind.method_atom_kind_mass = atom_desc["mass"]
if "valence" in atom_desc:
section_method_atom_kind.method_atom_kind_explicit_electrons = atom_desc["valence"]
if "pseudopotential" in atom_desc:
section_method_atom_kind.method_atom_kind_pseudopotential_name = atom_desc["pseudopotential"]
root_section.section_method[-1].x_vasp_atom_kind_refs = root_section.section_method[-1].section_method_atom_kind
labels2 = [kind_labels[i - 1] for i in atom_types]
else:
backend.pwarn(
self.logger.warn(
"unexpected array named %s in atominfo" % name)
else:
backend.pwarn("unexpected tag %s in atominfo" % el.tag)
self.logger.warn("unexpected tag %s in atominfo" % el.tag)
self.labels = np.asarray(labels2) if labels2 else np.asarray(labels)
def incarOutTag(self, el):
backend = self.parser.backend
metaEnv = self.parser.backend.metaInfoEnv()
if (el.tag != "i"):
backend.pwarn("unexpected tag %s %s %r in incar" %
(el.tag, el.attrib, el.text))
def _metainfo_type(self, meta):
dtype = meta.type
if dtype == str:
return 'C'
elif dtype == bool:
return 'b'
elif dtype == int or type(dtype) == np.dtype:
return 'i'
elif dtype == float:
return 'f'
else:
name = el.attrib.get("name", None)
valType = el.attrib.get("type")
meta = metaEnv['x_vasp_incarOut_' + name]
return
def _incar_out_tag(self, el):
if (el.tag != "i"):
self.logger.warn("unexpected tag %s %s %r in incar" % (el.tag, el.attrib, el.text))
else:
root_section = self.parser.root_section
name = el.attrib.get("name", None)
val_type = el.attrib.get("type")
try:
meta = self.parser.metainfo_env.resolve_definition('x_vasp_incarOut_' + name, Quantity)
except Exception:
return
if not meta:
# Unknown_Incars_Begin: storage into a dictionary
if not valType:
# On vasp's xml files, valType *could* be absent if incar value is float
valType = 'float'
if not val_type:
# On vasp's xml files, val_type *could* be absent if incar value is float
val_type = 'float'
# map vasp's datatype to nomad's datatype [b, f, i, C, D, R]
nomad_dtypeStr = vasp_to_metainfo_type_mapping[valType][0]
nomad_dtype_str = vasp_to_metainfo_type_mapping[val_type][0]
converter = metaTypeTransformers.get(nomad_dtypeStr)
text_value = el.text.strip() # text representation of incar value
converter = meta_type_transformers.get(nomad_dtype_str)
text_value = el.text.strip() # text representation of incar value
try:
pyvalue = converter(text_value) # python data type
pyvalue = converter(text_value) # python data type
except Exception:
pyvalue = text_value
......@@ -718,42 +702,42 @@ class VasprunContext(object):
self.unknown_incars[name] = pyvalue
# Unknown_Incars_end
else:
if not valType:
valType = 'float'
if not val_type:
val_type = 'float'
vasp_metainfo_type = vasp_to_metainfo_type_mapping.get(valType)[0]
metainfo_type = meta.get('dtypeStr')
vasp_metainfo_type = vasp_to_metainfo_type_mapping.get(val_type)[0]
metainfo_type = self._metainfo_type(meta)
if not vasp_metainfo_type:
backend.pwarn("Unknown value type %s encountered in INCAR out: %s %s %r" % (
valType, el.tag, el.attrib, el.text))
self.logger.warn("Unknown value type %s encountered in INCAR out: %s %s %r" % (
val_type, el.tag, el.attrib, el.text))
elif metainfo_type != vasp_metainfo_type:
if (metainfo_type == 'C' and vasp_metainfo_type == 'b'):
if (metainfo_type == 'C' and vasp_metainfo_type == 'b'):
pass
elif (metainfo_type == 'i' and vasp_metainfo_type == 'f'):
elif (metainfo_type == 'i' and vasp_metainfo_type == 'f'):
pass
else:
backend.pwarn("Data type mismatch: %s. Vasp_type: %s, metainfo_type: %s " %
(name, vasp_metainfo_type, metainfo_type))
self.logger.warn(
"Data type mismatch: %s. Vasp_type: %s, metainfo_type: %s " % (
name, vasp_metainfo_type, metainfo_type))
try:
shape = meta.get("shape", None)
converter = metaTypeTransformers.get(metainfo_type)
shape = meta.get("shape")
converter = meta_type_transformers.get(metainfo_type)
if not converter:
backend.pwarn(
"could not find converter for dtypeStr %s when handling meta info %s" %
(metainfo_type, meta ))
self.logger.warn(
"could not find converter for %s when handling meta info %s" %
(metainfo_type, meta))
elif shape:
vals = re.split("\s+", el.text.strip())
backend.addValue(
meta["name"], [converter(x) for x in vals])
vals = re.split(r"\s+", el.text.strip())
setattr(root_section.section_method[-1], meta["name"], [converter(x) for x in vals])
else:
# If-block to handle incars without value
if el.text == None:
if not el.text:
el.text = ''
backend.addValue(meta["name"], converter(el.text))
setattr(root_section.section_method[-1], meta["name"], converter(el.text))
except:
backend.pwarn("Exception trying to handle incarOut %s: %s" % (
except Exception:
self.logger.warn("Exception trying to handle incarOut %s: %s" % (
name, traceback.format_exc()))
if name == 'ENMAX' or name == 'PREC':
......@@ -765,7 +749,7 @@ class VasprunContext(object):
else:
self.prec = 1.0
if name == 'GGA':
fMap = {
f_map = {
'91': ['GGA_X_PW91', 'GGA_C_PW91'],
'PE': ['GGA_X_PBE', 'GGA_C_PBE'],
'RP': ['GGA_X_RPBE', 'GGA_C_PBE'],
......@@ -773,80 +757,63 @@ class VasprunContext(object):
'MK': ['GGA_X_OPTB86_VDW'],
'--': ['GGA_X_PBE', 'GGA_C_PBE'] # should check potcar
}
functs = fMap.get(el.text.strip(), None)
functs = f_map.get(el.text.strip(), None)
if not functs:
backend.pwarn("Unknown XC functional %s" %
el.text.strip())
self.logger.warn("Unknown XC functional %s" % el.text.strip())
else:
for f in functs:
backend.openNonOverlappingSection(
"section_XC_functionals")
backend.addValue("XC_functional_name", f)
backend.closeNonOverlappingSection(
"section_XC_functionals")
section_XC_functionals = root_section.section_method[-1].m_create(msection_XC_functionals)
section_XC_functionals.XC_functional_name = f
elif name == "ISPIN":
self.ispin = int(el.text.strip())
def separatorScan(self, element, backend, depth=0):
def _separator_scan(self, element, depth=0):
for separators in element:
if separators.tag == "separator":
separatorName = separators.attrib.get("name")
for el in separators:
if el.tag == "i":
self.incarOutTag(el)
self._incar_out_tag(el)
elif el.tag == "separator":
self.separatorScan(el, backend, depth + 1)
self._separator_scan(el, depth + 1)
else:
# backend.pwarn("unexpected tag %s %s in parameters separator %s at depth %d" % (
# el.tag, el.attrib, separatorName, depth))
pass
elif separators.tag == "i":
self.incarOutTag(separators)
self._incar_out_tag(separators)
else:
# backend.pwarn("unexpected tag %s %s in parameters at depth %d" % (
# separators.tag, separators.attrib, depth))
pass
def onEnd_parameters(self, parser, event, element, pathStr):
self.separatorScan(element, parser.backend)
backend = parser.backend
def on_end_parameters(self, element, path_str):
self._separator_scan(element)
root_section = self.parser.root_section
try:
self.prec
try:
self.enmax
self.waveCut = backend.openNonOverlappingSection(
"section_basis_set_cell_dependent")
backend.addValue("basis_set_planewave_cutoff",
eV2J(self.enmax*self.prec))
backend.closeNonOverlappingSection(
"section_basis_set_cell_dependent")
backend.openNonOverlappingSection("section_method_basis_set")
backend.addValue(
"mapping_section_method_basis_set_cell_associated", self.waveCut)
backend.closeNonOverlappingSection("section_method_basis_set")
self.waveCut = root_section.m_create(msection_basis_set_cell_dependent)
self.waveCut.basis_set_planewave_cutoff = eV2J(self.enmax * self.prec)
section_method_basis_set = root_section.section_method[-1].m_create(msection_method_basis_set)
section_method_basis_set.mapping_section_method_basis_set_cell_associated = self.waveCut
except AttributeError:
import traceback
traceback.print_exc()
backend.pwarn(
self.logger.warn(
"Missing ENMAX for calculating plane wave basis cut off ")
except AttributeError:
backend.pwarn(
self.logger.pwarn(
"Missing PREC for calculating plane wave basis cut off ")
def onEnd_dos(self, parser, event, element, pathStr):
def on_end_dos(self, element, path_str):
"density of states"
backend = parser.backend
backend.openNonOverlappingSection("section_dos")
root_section = self.parser.root_section
section_dos = root_section.section_single_configuration_calculation[-1].m_create(msection_dos)
for el in element:
if el.tag == "i":
if el.attrib.get("name") == "efermi":
self.eFermi = eV2J(float(el.text.strip()))
backend.addArrayValues(
"energy_reference_fermi", np.array([self.eFermi] * self.ispin))
self.e_fermi = eV2J(float(el.text.strip()))
section_dos.energy_reference_fermi = np.array([self.e_fermi] * self.ispin)
else:
backend.pwarn("unexpected tag %s %s in dos" %
(el.tag, el.attrib))
self.logger.warn("unexpected tag %s %s in dos" % (el.tag, el.attrib))
elif el.tag == "total":
for el1 in el:
if el1.tag == "array":
......@@ -855,20 +822,20 @@ class VasprunContext(object):
pass
elif el2.tag == "set":
dosL = []
for spinComponent in el2:
if spinComponent.tag == "set":
for spin_component in el2:
if spin_component.tag == "set":
dosL.append(
getVector(spinComponent, field="r"))
get_vector(spin_component, field="r"))
else:
backend.pwarn("unexpected tag %s %s in dos total array set" % (
spinComponent.tag, spinComponent.attrib))
dosA = np.asarray(dosL)
if len(dosA.shape) != 3:
self.logger.warn("unexpected tag %s %s in dos total array set" % (
spin_component.tag, spin_component.attrib))
dos_a = np.asarray(dosL)
if len(dos_a.shape) != 3:
raise Exception("unexpected shape %s (%s) for total dos (ragged arrays?)" % (
dosA.shape), dosA.dtype)
dosE = eV2JV(dosA[0, :, 0])
dosI = dosA[:, :, 2]
dosV = dosA[:, :, 1]
dos_a.shape), dos_a.dtype)
dos_e = eV2JV(dos_a[0, :, 0])
dos_i = dos_a[:, :, 2]
dos_v = dos_a[:, :, 1]
# Convert the DOS values to SI. VASP uses the
# following units in the output:
......@@ -878,18 +845,17 @@ class VasprunContext(object):
# the integrated dos value is the number of electrons until that energy level
# and thus not directly energy dependent anymore
joule_in_ev = convert_unit(1, "eV", "J")
dosV = dosV / joule_in_ev
dos_v = dos_v / joule_in_ev
backend.addArrayValues("dos_energies", dosE)
section_dos.dos_energies = dos_e
cell_volume = np.abs(np.linalg.det(self.cell))
backend.addArrayValues("dos_values", dosV * cell_volume)
backend.addArrayValues(
"dos_integrated_values", dosI)
section_dos.dos_values = dos_v * cell_volume
section_dos.dos_integrated_values = dos_i
else:
backend.pwarn("unexpected tag %s %s in dos total array" % (
self.logger.warn("unexpected tag %s %s in dos total array" % (
el2.tag, el2.attrib))
else:
backend.pwarn("unexpected tag %s %s in dos total" % (
self.logger.warn("unexpected tag %s %s in dos total" % (
el2.tag, el2.attrib))
elif el.tag == "partial":
for el1 in el:
......@@ -924,42 +890,38 @@ class VasprunContext(object):
if atom.tag == "set":
atomL = []
dosL.append(atomL)
for spinComponent in atom:
if spinComponent.tag == "set":
for spin_component in atom:
if spin_component.tag == "set":
atomL.append(
getVector(spinComponent, field="r"))
get_vector(spin_component, field="r"))
else:
backend.pwarn("unexpected tag %s %s in dos partial array set set" % (
spinComponent.tag, spinComponent.attrib))
self.logger.warn("unexpected tag %s %s in dos partial array set set" % (
spin_component.tag, spin_component.attrib))
else:
backend.pwarn("unexpected tag %s %s in dos partial array set" % (
spinComponent.tag, spinComponent.attrib))
self.logger.warn("unexpected tag %s %s in dos partial array set" % (
spin_component.tag, spin_component.attrib))
dosLM = np.asarray(dosL)
assert len(
dosLM.shape) == 4, "invalid shape dimension in projected dos (ragged arrays?)"
backend.addArrayValues(
"dos_values_lm", dosLM[:, :, :, 1:])
section_dos.dos_values_lm = dosLM[:, :, :, 1:]
else:
backend.pwarn("unexpected tag %s %s in dos total array" % (
self.logger.warn("unexpected tag %s %s in dos total array" % (
el2.tag, el2.attrib))
backend.addArrayValues("dos_lm", np.asarray(lm))
backend.addValue("dos_m_kind", "polynomial")
section_dos