From 527c46b595024d9fe5f9da95b32b25c26b6bcb02 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 08:45:04 -0700 Subject: [PATCH 01/26] add manual deprecation into validation --- emmet-core/emmet/core/vasp/validation.py | 39 ++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/emmet-core/emmet/core/vasp/validation.py b/emmet-core/emmet/core/vasp/validation.py index 9de9997a73..f4961dc6fd 100644 --- a/emmet-core/emmet/core/vasp/validation.py +++ b/emmet-core/emmet/core/vasp/validation.py @@ -13,6 +13,7 @@ class DeprecationMessage(DocEnum): MANUAL = "M", "manual deprecation" + DEPRECATED_TAGS = "M001", "Deprecated tag" KPTS = "C001", "Too few KPoints" KSPACING = "C002", "KSpacing not high enough" ENCUT = "C002", "ENCUT too low" @@ -56,6 +57,7 @@ def from_task_doc( input_sets: Dict[str, PyObject] = SETTINGS.VASP_DEFAULT_INPUT_SETS, LDAU_fields: List[str] = SETTINGS.VASP_CHECKED_LDAU_FIELDS, max_allowed_scf_gradient: float = SETTINGS.VASP_MAX_SCF_GRADIENT, + deprecated_tags: Optional[List[str]] = None, ) -> "ValidationDoc": """ Determines if a calculation is valid based on expected input parameters from a pymatgen inputset @@ -73,12 +75,18 @@ def from_task_doc( structure = task_doc.output.structure calc_type = task_doc.calc_type inputs = task_doc.orig_inputs + bandgap = task_doc.output.bandgap reasons = [] data = {} if str(calc_type) in input_sets: - valid_input_set = input_sets[str(calc_type)](structure) + + # Ensure inputsets that need the bandgap get it + try: + valid_input_set = input_sets[str(calc_type)](structure, bandgap=bandgap) + except TypeError: + valid_input_set = input_sets[str(calc_type)](structure) # Checking K-Points # Calculations that use KSPACING will not have a .kpoints attr @@ -137,18 +145,25 @@ def from_task_doc( ): reasons.append(DeprecationMessage.LDAU) - # Check the max upwards SCF step - skip = inputs.get("incar", {}).get("NLEMDL") - energies = [ - d["e_fr_energy"] - for d in task_doc.calcs_reversed[0]["output"]["ionic_steps"][-1][ - "electronic_steps" - ] + # Check the max upwards SCF step + skip = inputs.get("incar", {}).get("NLEMDL") + energies = [ + d["e_fr_energy"] + for d in task_doc.calcs_reversed[0]["output"]["ionic_steps"][-1][ + "electronic_steps" ] - max_gradient = np.max(np.gradient(energies)[skip:]) - data["max_gradient"] = max_gradient - if max_gradient > max_allowed_scf_gradient: - reasons.append(DeprecationMessage.MAX_SCF) + ] + max_gradient = np.max(np.gradient(energies)[skip:]) + data["max_gradient"] = max_gradient + if max_gradient > max_allowed_scf_gradient: + reasons.append(DeprecationMessage.MAX_SCF) + + # Check for Manual deprecations + if deprecated_tags is not None: + bad_tags = list(set(task_doc.tags).intersection(deprecated_tags)) + if len(bad_tags) > 0: + reasons.append(DeprecationMessage.DEPRECATED_TAGS) + data["bad_tags"] = bad_tags doc = ValidationDoc( task_id=task_doc.task_id, From 6a5daf49ea7e239a1bb7ac47581ee535ead1a1a1 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 08:53:29 -0700 Subject: [PATCH 02/26] switch default deprecated tags to setting --- emmet-core/emmet/core/settings.py | 4 ++++ emmet-core/emmet/core/vasp/validation.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/emmet-core/emmet/core/settings.py b/emmet-core/emmet/core/settings.py index 23fd23b494..60cfbeba60 100644 --- a/emmet-core/emmet/core/settings.py +++ b/emmet-core/emmet/core/settings.py @@ -79,6 +79,10 @@ class EmmetSettings(BaseSettings): description="Maximum upward gradient in the last SCF for any VASP calculation", ) + VASP_DEPRECATED_TAGS: List[str] = Field( + [], description="List of tags to manually deprecate in task validation" + ) + class Config: env_prefix = "emmet_" extra = "ignore" diff --git a/emmet-core/emmet/core/vasp/validation.py b/emmet-core/emmet/core/vasp/validation.py index f4961dc6fd..d019e66a04 100644 --- a/emmet-core/emmet/core/vasp/validation.py +++ b/emmet-core/emmet/core/vasp/validation.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union import numpy as np from pydantic import BaseModel, Field, PyObject @@ -57,7 +57,7 @@ def from_task_doc( input_sets: Dict[str, PyObject] = SETTINGS.VASP_DEFAULT_INPUT_SETS, LDAU_fields: List[str] = SETTINGS.VASP_CHECKED_LDAU_FIELDS, max_allowed_scf_gradient: float = SETTINGS.VASP_MAX_SCF_GRADIENT, - deprecated_tags: Optional[List[str]] = None, + deprecated_tags: List[str] = SETTINGS.VASP_DEPRECATED_TAGS, ) -> "ValidationDoc": """ Determines if a calculation is valid based on expected input parameters from a pymatgen inputset From fc8a94ca6fc7b90ad1276005f57d0f6279061428 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 09:05:54 -0700 Subject: [PATCH 03/26] move use_statics to settings --- emmet-core/emmet/core/settings.py | 5 +++++ emmet-core/emmet/core/vasp/material.py | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/emmet-core/emmet/core/settings.py b/emmet-core/emmet/core/settings.py index 60cfbeba60..4a57b36967 100644 --- a/emmet-core/emmet/core/settings.py +++ b/emmet-core/emmet/core/settings.py @@ -83,6 +83,11 @@ class EmmetSettings(BaseSettings): [], description="List of tags to manually deprecate in task validation" ) + VASP_USE_STATICS: bool = Field( + True, + description="Use static calculations for structure and energy along with structure optimizations", + ) + class Config: env_prefix = "emmet_" extra = "ignore" diff --git a/emmet-core/emmet/core/vasp/material.py b/emmet-core/emmet/core/vasp/material.py index 43cd95f92c..862c628e84 100644 --- a/emmet-core/emmet/core/vasp/material.py +++ b/emmet-core/emmet/core/vasp/material.py @@ -44,8 +44,8 @@ class MaterialsDoc(CoreMaterialsDoc, StructureMetadata): def from_tasks( cls, task_group: List[TaskDocument], - quality_scores=SETTINGS.VASP_QUALITY_SCORES, - use_statics: bool = False, + quality_scores: Dict[str, int] = SETTINGS.VASP_QUALITY_SCORES, + use_statics: bool = SETTINGS.VASP_USE_STATICS, ) -> "MaterialsDoc": """ Converts a group of tasks into one material From f929bf9df1be6514dc8c05df3da32a43d1c63cf3 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 09:06:57 -0700 Subject: [PATCH 04/26] clean up imports --- emmet-core/emmet/core/settings.py | 6 +++--- emmet-core/emmet/core/vasp/material.py | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/emmet-core/emmet/core/settings.py b/emmet-core/emmet/core/settings.py index 4a57b36967..4f096f0f84 100644 --- a/emmet-core/emmet/core/settings.py +++ b/emmet-core/emmet/core/settings.py @@ -1,13 +1,13 @@ """ Settings for defaults in the core definitions of Materials Project Documents """ -import importlib import json -from typing import Dict, List, Optional, Type, TypeVar, Union +from pathlib import Path +from typing import Dict, List, Type, TypeVar, Union import requests from pydantic import BaseSettings, Field, root_validator, validator -from pydantic.types import Path, PyObject +from pydantic.types import PyObject DEFAULT_CONFIG_FILE_PATH = str(Path.home().joinpath(".emmet.json")) diff --git a/emmet-core/emmet/core/vasp/material.py b/emmet-core/emmet/core/vasp/material.py index 862c628e84..bca02a369c 100644 --- a/emmet-core/emmet/core/vasp/material.py +++ b/emmet-core/emmet/core/vasp/material.py @@ -1,12 +1,9 @@ """ Core definition of a Materials Document """ -from datetime import datetime -from functools import partial -from typing import ClassVar, List, Mapping, Optional, Sequence, Tuple, TypeVar, Union +from typing import Dict, List, Mapping, Sequence -from pydantic import BaseModel, Field, create_model +from pydantic import Field from pymatgen.analysis.structure_analyzer import SpacegroupAnalyzer -from pymatgen.analysis.structure_matcher import ElementComparator, StructureMatcher -from pymatgen.core import Structure +from pymatgen.analysis.structure_matcher import StructureMatcher from pymatgen.entries.computed_entries import ComputedStructureEntry from emmet.core import SETTINGS From a590c4e8a7dd21f04451d252ddb579d1de390d40 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 09:56:47 -0700 Subject: [PATCH 05/26] add warnings for kspacing and ismear --- emmet-core/emmet/core/vasp/validation.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/emmet-core/emmet/core/vasp/validation.py b/emmet-core/emmet/core/vasp/validation.py index d019e66a04..ab3d46d795 100644 --- a/emmet-core/emmet/core/vasp/validation.py +++ b/emmet-core/emmet/core/vasp/validation.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Optional, Union +from typing import Dict, List, Union import numpy as np from pydantic import BaseModel, Field, PyObject @@ -79,6 +79,7 @@ def from_task_doc( reasons = [] data = {} + warnings = [] if str(calc_type) in input_sets: @@ -110,6 +111,15 @@ def from_task_doc( # larger KSPACING means fewer k-points if data["kspacing_delta"] > kspacing_tolerance: reasons.append(DeprecationMessage.KSPACING) + elif data["kspacing_delta"] < kspacing_tolerance: + warnings.append( + f"KSPACING is lower than input set: {data['kspacing_delta']}" + " lower than {kspacing_tolerance} ", + ) + + # warn, but don't invalidate if wrong ISMEAR + if inputs.get("incar", {}).get("ISMEAR") > 0 and bandgap > 0: + warnings.append("Inappropriate smearing settings") # Checking ENCUT encut = inputs.get("incar", {}).get("ENCUT") @@ -172,6 +182,7 @@ def from_task_doc( valid=len(reasons) == 0, reasons=reasons, data=data, + warnings=warnings, ) return doc From cfc7176d3e45725a3818eef2c02e1395d090b270 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 10:36:17 -0700 Subject: [PATCH 06/26] update test since default for use_statics is now True --- tests/emmet-core/vasp/test_materials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/emmet-core/vasp/test_materials.py b/tests/emmet-core/vasp/test_materials.py index 73f9992076..33222945bf 100644 --- a/tests/emmet-core/vasp/test_materials.py +++ b/tests/emmet-core/vasp/test_materials.py @@ -29,7 +29,7 @@ def test_make_mat(test_tasks): ] with pytest.raises(Exception): - MaterialsDoc.from_tasks(bad_task_group) + MaterialsDoc.from_tasks(bad_task_group, use_statics=False) def test_schema(): From 0210fc207d862fc8639c3bbda8ed541b0c928220 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 12:16:02 -0700 Subject: [PATCH 07/26] speed up PD construction --- emmet-core/emmet/core/thermo.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/emmet-core/emmet/core/thermo.py b/emmet-core/emmet/core/thermo.py index 056d14911e..c547ca0023 100644 --- a/emmet-core/emmet/core/thermo.py +++ b/emmet-core/emmet/core/thermo.py @@ -1,17 +1,13 @@ """ Core definition of a Thermo Document """ -from datetime import datetime -from enum import Enum +from collections import defaultdict from typing import ClassVar, Dict, List, Union from pydantic import BaseModel, Field -from pymatgen.analysis.phase_diagram import PhaseDiagram, PhaseDiagramError -from pymatgen.core import Composition -from pymatgen.core.periodic_table import Element +from pymatgen.analysis.phase_diagram import PhaseDiagram from pymatgen.entries.computed_entries import ComputedEntry, ComputedStructureEntry from emmet.core.material_property import PropertyDoc from emmet.core.mpid import MPID -from emmet.core.structure import StructureMetadata class DecompositionProduct(BaseModel): @@ -94,7 +90,17 @@ class ThermoDoc(PropertyDoc): @classmethod def from_entries(cls, entries: List[Union[ComputedEntry, ComputedStructureEntry]]): - pd = PhaseDiagram(entries) + entries_by_comp = defaultdict(list) + for e in entries: + entries_by_comp[e.composition.reduced_formula].append(e) + + # Only use lowest entry per composition to speed up QHull in Phase Diagram + reduced_entries = [ + sorted(comp_entries, key=lambda e: e.energy_per_atom)[0] + for comp_entries in entries_by_comp.values() + ] + + pd = PhaseDiagram(reduced_entries) docs = [] From 85850771bfbe5a3b7d60cb4a0d082b6c2acb1da3 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 14:15:34 -0700 Subject: [PATCH 08/26] remove deprecation from core since its in builders --- emmet-core/emmet/core/settings.py | 4 ---- emmet-core/emmet/core/vasp/validation.py | 9 --------- 2 files changed, 13 deletions(-) diff --git a/emmet-core/emmet/core/settings.py b/emmet-core/emmet/core/settings.py index 4f096f0f84..68a1497394 100644 --- a/emmet-core/emmet/core/settings.py +++ b/emmet-core/emmet/core/settings.py @@ -79,10 +79,6 @@ class EmmetSettings(BaseSettings): description="Maximum upward gradient in the last SCF for any VASP calculation", ) - VASP_DEPRECATED_TAGS: List[str] = Field( - [], description="List of tags to manually deprecate in task validation" - ) - VASP_USE_STATICS: bool = Field( True, description="Use static calculations for structure and energy along with structure optimizations", diff --git a/emmet-core/emmet/core/vasp/validation.py b/emmet-core/emmet/core/vasp/validation.py index ab3d46d795..9beb59d9bd 100644 --- a/emmet-core/emmet/core/vasp/validation.py +++ b/emmet-core/emmet/core/vasp/validation.py @@ -13,7 +13,6 @@ class DeprecationMessage(DocEnum): MANUAL = "M", "manual deprecation" - DEPRECATED_TAGS = "M001", "Deprecated tag" KPTS = "C001", "Too few KPoints" KSPACING = "C002", "KSpacing not high enough" ENCUT = "C002", "ENCUT too low" @@ -57,7 +56,6 @@ def from_task_doc( input_sets: Dict[str, PyObject] = SETTINGS.VASP_DEFAULT_INPUT_SETS, LDAU_fields: List[str] = SETTINGS.VASP_CHECKED_LDAU_FIELDS, max_allowed_scf_gradient: float = SETTINGS.VASP_MAX_SCF_GRADIENT, - deprecated_tags: List[str] = SETTINGS.VASP_DEPRECATED_TAGS, ) -> "ValidationDoc": """ Determines if a calculation is valid based on expected input parameters from a pymatgen inputset @@ -168,13 +166,6 @@ def from_task_doc( if max_gradient > max_allowed_scf_gradient: reasons.append(DeprecationMessage.MAX_SCF) - # Check for Manual deprecations - if deprecated_tags is not None: - bad_tags = list(set(task_doc.tags).intersection(deprecated_tags)) - if len(bad_tags) > 0: - reasons.append(DeprecationMessage.DEPRECATED_TAGS) - data["bad_tags"] = bad_tags - doc = ValidationDoc( task_id=task_doc.task_id, calc_type=calc_type, From 870dad427c2ebbf0c35323477ff1cfc7e827a880 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:01:41 -0700 Subject: [PATCH 09/26] Add oxidation states to thermo builder --- emmet-builders/emmet/builders/vasp/thermo.py | 26 ++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index 191a9955d6..b7f5df8def 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -25,6 +25,7 @@ def __init__( self, materials: Store, thermo: Store, + oxidation_states: Optional[Store] = None, query: Optional[Dict] = None, compatibility=None, **kwargs, @@ -48,11 +49,17 @@ def __init__( self.compatibility = ( compatibility if compatibility - else MaterialsProjectCompatibility("Advanced") + else MaterialsProject2020Compatibility("Advanced") ) + self.oxidation_states = oxidation_states self._completed_tasks = set() self._entries_cache = defaultdict(list) - super().__init__(sources=[materials], targets=[thermo], **kwargs) + + sources = [materials] + if oxidation_states is not None: + sources.append(oxidation_states) + + super().__init__(sources=sources, targets=[thermo], **kwargs) def ensure_indexes(self): """ @@ -212,6 +219,18 @@ def get_entries(self, chemsys: str) -> List[Dict]: ) ) + # Get Oxidation state data for each material + oxi_states_data = {} + if self.oxidation_states: + material_ids = [t["material_id"] for t in materials_docs] + oxi_states_data = { + d["material_id"]: d["bond_valence"]["average_oxidation_states"] + for d in self.oxidation_states.query( + properties=["material_id", "bond_valence.average_oxidation_states"], + criteria={"material_id": {"$in": material_ids}, "successful": True}, + ) + } + self.logger.debug( f"Got {len(materials_docs)} entries from DB for {len(query_chemsys)} sub-chemsys for {chemsys}" ) @@ -219,6 +238,9 @@ def get_entries(self, chemsys: str) -> List[Dict]: # Convert the entries into ComputedEntries and store for doc in materials_docs: for r_type, entry_dict in doc.get("entries", {}).items(): + entry_dict["data"]["oxidation_states"] = oxi_states_data.get( + entry_dict["entry_id"], {} + ) entry_dict["data"]["run_type"] = r_type elsyms = sorted(set([el for el in entry_dict["composition"]])) self._entries_cache["-".join(elsyms)].append(entry_dict) From 08db4464c5f0445710466b1c1eae7e6c51847321 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:02:05 -0700 Subject: [PATCH 10/26] add prechunk to thermo and materials --- .../emmet/builders/vasp/materials.py | 30 +++++++++++++++++++ emmet-builders/emmet/builders/vasp/thermo.py | 15 ++++++++++ 2 files changed, 45 insertions(+) diff --git a/emmet-builders/emmet/builders/vasp/materials.py b/emmet-builders/emmet/builders/vasp/materials.py index fe6f10608b..9608ae1935 100644 --- a/emmet-builders/emmet/builders/vasp/materials.py +++ b/emmet-builders/emmet/builders/vasp/materials.py @@ -91,6 +91,36 @@ def ensure_indexes(self): self.task_validation.ensure_index("task_id") self.task_validation.ensure_index("valid") + def prechunk(self, number_splits: int) -> Iterable[Dict]: + """Prechunk the materials builder for distributed computation""" + temp_query = dict(self.query) + temp_query["state"] = "successful" + if len(self.settings.BUILD_TAGS) > 0 and len(self.settings.EXCLUDED_TAGS) > 0: + temp_query["$and"] = [ + {"tags": {"$in": self.settings.BUILD_TAGS}}, + {"tags": {"$nin": self.settings.EXCLUDED_TAGS}}, + ] + elif len(self.settings.BUILD_TAGS) > 0: + temp_query["tags"] = {"$in": self.settings.BUILD_TAGS} + + self.logger.info("Finding tasks to process") + all_tasks = { + doc[self.tasks.key] + for doc in self.tasks.query(temp_query, [self.tasks.key]) + } + processed_tasks = { + t_id + for d in self.materials.query({}, ["task_ids"]) + for t_id in d.get("task_ids", []) + } + to_process_tasks = all_tasks - processed_tasks + to_process_forms = self.tasks.distinct( + "formula_pretty", {self.tasks.key: {"$in": list(to_process_tasks)}} + ) + + for formula_chunk in grouper(to_process_forms, number_splits): + yield {"formula_pretty": {"$in": list(formula_chunk)}} + def get_items(self) -> Iterator[List[Dict]]: """ Gets all items to process into materials documents. diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index b7f5df8def..e1f23f4538 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -74,6 +74,21 @@ def ensure_indexes(self): self.thermo.ensure_index("material_id") self.thermo.ensure_index("last_updated") + def prechunk(self, number_splits: int) -> Iterable[Dict]: + updated_chemsys = self.get_updated_chemsys() + new_chemsys = self.get_new_chemsys() + + affected_chemsys = self.get_affected_chemsys(updated_chemsys | new_chemsys) + + # Remove overlapping chemical systems + to_process_chemsys = set() + for chemsys in updated_chemsys | new_chemsys | affected_chemsys: + if chemsys not in to_process_chemsys: + to_process_chemsys |= chemsys_permutations(chemsys) + + for chemsys_chunk in grouper(to_process_chemsys, number_splits): + yield {"chemsys": {"$in": list(chemsys_chunk)}} + def get_items(self) -> Iterator[List[Dict]]: """ Gets whole chemical systems of entries to process From d0fc4351efe4ef6f886490b694c60e809626f645 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:02:23 -0700 Subject: [PATCH 11/26] jsanitize in process to not bog down main process --- emmet-builders/emmet/builders/vasp/materials.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/materials.py b/emmet-builders/emmet/builders/vasp/materials.py index 9608ae1935..a186553491 100644 --- a/emmet-builders/emmet/builders/vasp/materials.py +++ b/emmet-builders/emmet/builders/vasp/materials.py @@ -243,7 +243,7 @@ def process_item(self, tasks: List[Dict]) -> List[Dict]: ) self.logger.debug(f"Produced {len(materials)} materials for {formula}") - return [mat.dict() for mat in materials] + return jsanitize([mat.dict() for mat in materials], allow_bson=True) def update_targets(self, items: List[List[Dict]]): """ @@ -265,7 +265,7 @@ def update_targets(self, items: List[List[Dict]]): self.logger.info(f"Updating {len(items)} materials") self.materials.remove_docs({self.materials.key: {"$in": material_ids}}) self.materials.update( - docs=jsanitize(items, allow_bson=True), + docs=items, key=["material_id"], ) else: From e74f55fe432c5b59831ed80724cae2b0d3d03ab9 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:02:44 -0700 Subject: [PATCH 12/26] remove vestige of sandbox --- emmet-builders/emmet/builders/vasp/materials.py | 1 - 1 file changed, 1 deletion(-) diff --git a/emmet-builders/emmet/builders/vasp/materials.py b/emmet-builders/emmet/builders/vasp/materials.py index a186553491..00ef9e563d 100644 --- a/emmet-builders/emmet/builders/vasp/materials.py +++ b/emmet-builders/emmet/builders/vasp/materials.py @@ -84,7 +84,6 @@ def ensure_indexes(self): # Search index for materials self.materials.ensure_index("material_id") self.materials.ensure_index("last_updated") - self.materials.ensure_index("sandboxes") self.materials.ensure_index("task_ids") if self.task_validation: From aad5eeb5b67653d7f80e64317de6836048e17780 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:03:06 -0700 Subject: [PATCH 13/26] clean up --- .../emmet/builders/vasp/materials.py | 20 +++-------- .../emmet/builders/vasp/task_validator.py | 4 +-- emmet-builders/emmet/builders/vasp/thermo.py | 33 +++++++------------ 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/materials.py b/emmet-builders/emmet/builders/vasp/materials.py index 00ef9e563d..c9f76560ff 100644 --- a/emmet-builders/emmet/builders/vasp/materials.py +++ b/emmet-builders/emmet/builders/vasp/materials.py @@ -1,21 +1,13 @@ from datetime import datetime from itertools import chain -from operator import itemgetter -from typing import Dict, Iterator, List, Optional +from typing import Dict, Iterable, Iterator, List, Optional from maggma.builders import Builder from maggma.stores import Store -from pymatgen.core import Structure -from pymatgen.analysis.structure_analyzer import oxide_type -from pymatgen.analysis.structure_matcher import ElementComparator, StructureMatcher +from maggma.utils import grouper -from emmet.builders.utils import maximal_spanning_non_intersecting_subsets - -# from emmet.core import SETTINGS -from emmet.builders import SETTINGS from emmet.builders.settings import EmmetBuildSettings from emmet.core.utils import group_structures, jsanitize -from emmet.core.vasp.calc_types import TaskType from emmet.core.vasp.material import MaterialsDoc from emmet.core.vasp.task import TaskDocument @@ -33,11 +25,8 @@ class MaterialsBuilder(Builder): 1.) Find all documents with the same formula 2.) Select only task documents for the task_types we can select properties from 3.) Aggregate task documents based on strucutre similarity - 4.) Convert task docs to property docs with metadata for selection and aggregation - 5.) Select the best property doc for each property - 6.) Build material document from best property docs - 7.) Post-process material document - 8.) Validate material document + 4.) Create a MaterialDoc from the group of task documents + 5.) Validate material document """ @@ -56,6 +45,7 @@ def __init__( materials: Store of materials documents to generate task_validation: Store for storing task validation results query: dictionary to limit tasks to be analyzed + settings: EmmetSettings to use in the build process """ self.tasks = tasks diff --git a/emmet-builders/emmet/builders/vasp/task_validator.py b/emmet-builders/emmet/builders/vasp/task_validator.py index 82843f23b4..1f8d368d8f 100644 --- a/emmet-builders/emmet/builders/vasp/task_validator.py +++ b/emmet-builders/emmet/builders/vasp/task_validator.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Union, Optional +from typing import Dict, List, Optional, Union import numpy as np from maggma.builders import MapBuilder @@ -6,10 +6,10 @@ from pymatgen.core import Structure from emmet.builders import SETTINGS +from emmet.builders.settings import EmmetBuildSettings from emmet.core.vasp.calc_types import run_type, task_type from emmet.core.vasp.task import TaskDocument from emmet.core.vasp.validation import DeprecationMessage, ValidationDoc -from emmet.builders.settings import EmmetBuildSettings class TaskValidator(MapBuilder): diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index e1f23f4538..cba5a262c7 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -1,23 +1,17 @@ from collections import defaultdict -from datetime import datetime from itertools import chain -from typing import Dict, Iterator, List, Optional, Set, Tuple +from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple from maggma.core import Builder, Store +from maggma.utils import grouper from monty.json import MontyDecoder -from pymatgen.core import Structure from pymatgen.analysis.phase_diagram import PhaseDiagramError -from pymatgen.analysis.structure_analyzer import oxide_type -from pymatgen.entries.compatibility import MaterialsProjectCompatibility +from pymatgen.entries.compatibility import MaterialsProject2020Compatibility from pymatgen.entries.computed_entries import ComputedEntry, ComputedStructureEntry -from emmet.core.utils import jsanitize -from emmet.builders.utils import ( - chemsys_permutations, - maximal_spanning_non_intersecting_subsets, -) +from emmet.builders.utils import chemsys_permutations from emmet.core.thermo import ThermoDoc -from emmet.core.vasp.calc_types import run_type +from emmet.core.utils import jsanitize class Thermo(Builder): @@ -121,13 +115,12 @@ def get_items(self) -> Iterator[List[Dict]]: entries = self.get_entries(chemsys) yield entries - def process_item(self, item: Tuple[List[str], List[ComputedEntry]]): + def process_item(self, item: List[Dict]): - entries = item - if len(entries) == 0: + if len(item) == 0: return [] - entries = [ComputedStructureEntry.from_dict(entry) for entry in entries] + entries = [ComputedStructureEntry.from_dict(entry) for entry in item] # determine chemsys elements = sorted( set([el.symbol for e in entries for el in e.composition.elements]) @@ -229,9 +222,7 @@ def get_entries(self, chemsys: str) -> List[Dict]: new_q["chemsys"] = {"$in": list(query_chemsys)} new_q["deprecated"] = False materials_docs = list( - self.materials.query( - criteria=new_q, properties=[self.materials.key, "entries"] - ) + self.materials.query(criteria=new_q, properties=["material_id", "entries"]) ) # Get Oxidation state data for each material @@ -268,7 +259,7 @@ def get_entries(self, chemsys: str) -> List[Dict]: def get_updated_chemsys( self, ) -> Set: - """ Gets updated chemical system as defined by the updating of an existing material """ + """Gets updated chemical system as defined by the updating of an existing material""" updated_mats = self.thermo.newer_in(self.materials, criteria=self.query) updated_chemsys = set( @@ -281,7 +272,7 @@ def get_updated_chemsys( return updated_chemsys def get_new_chemsys(self) -> Set: - """ Gets newer chemical system as defined by introduction of a new material """ + """Gets newer chemical system as defined by introduction of a new material""" # All materials that are not present in the thermo collection thermo_mat_ids = self.thermo.distinct(self.thermo.key) @@ -294,7 +285,7 @@ def get_new_chemsys(self) -> Set: return new_mat_chemsys def get_affected_chemsys(self, chemical_systems: Set) -> Set: - """ Gets chemical systems affected by changes in the supplied chemical systems """ + """Gets chemical systems affected by changes in the supplied chemical systems""" # First get all chemsys with any of the elements we've marked affected_chemsys = set() affected_els = list({el for c in chemical_systems for el in c.split("-")}) From 0791b3be65a6742997e591b9b32b3effae4d3683 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:12:20 -0700 Subject: [PATCH 14/26] reraise exception if failure --- emmet-core/emmet/core/oxidation_states.py | 1 + 1 file changed, 1 insertion(+) diff --git a/emmet-core/emmet/core/oxidation_states.py b/emmet-core/emmet/core/oxidation_states.py index 41ecfc1a50..46f120f96c 100644 --- a/emmet-core/emmet/core/oxidation_states.py +++ b/emmet-core/emmet/core/oxidation_states.py @@ -85,3 +85,4 @@ def from_structure(cls, structure: Structure): except Exception as e: logging.error("Oxidation state guess failed with: {}".format(e)) + raise e From 801f920776ac2895eb2b0d2c38d0269f69ce693a Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:12:28 -0700 Subject: [PATCH 15/26] add oxidation state builder --- .../builders/materials/oxidation_states.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 emmet-builders/emmet/builders/materials/oxidation_states.py diff --git a/emmet-builders/emmet/builders/materials/oxidation_states.py b/emmet-builders/emmet/builders/materials/oxidation_states.py new file mode 100644 index 0000000000..46a726e326 --- /dev/null +++ b/emmet-builders/emmet/builders/materials/oxidation_states.py @@ -0,0 +1,55 @@ +from typing import Dict, List, Optional + +from maggma.builders.map_builder import MapBuilder +from maggma.core import Store +from pymatgen.core import Structure + +from pymatgen.core import __version__ as pymatgen_version + + +from emmet.core.oxidation_states import OxidationStateDoc + + +class OxidationStates(MapBuilder): + def __init__( + self, + materials: Store, + oxidation_states: Store, + **kwargs, + ): + """ + Creates Oxidation State documents from materials + + Args: + materials: Store of materials docs + oxidation_states: Store to update with oxidation state document + query : query on materials to limit search + """ + self.materials = materials + self.oxidation_states = oxidation_states + self.kwargs = kwargs + + # Enforce that we key on material_id + self.materials.key = "material_id" + self.oxidation_states.key = "material_id" + super().__init__( + source=materials, + target=oxidation_states, + projection=["structure"], + **kwargs, + ) + + def unary_function(self, item): + + structure = Structure.from_dict(item["structure"]) + oxi_doc = OxidationStateDoc.from_structure(structure) + doc = oxi_doc.dict() + + doc.update( + { + "pymatgen_version": pymatgen_version, + "successful": True, + } + ) + + return doc From 9e47131f30c1e3d750ebacc062b8d619e60ced75 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:32:43 -0700 Subject: [PATCH 16/26] compatability will select run_type --- emmet-builders/emmet/builders/vasp/thermo.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index cba5a262c7..51ecfb3964 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -134,13 +134,7 @@ def process_item(self, item: List[Dict]): for entry in entries: material_entries[entry.entry_id][entry.data["run_type"]] = entry - # TODO: How to make this general and controllable via SETTINGS? - for material_id in material_entries: - if "GGA+U" in material_entries[material_id]: - pd_entries.append(material_entries[material_id]["GGA+U"]) - elif "GGA" in material_entries[material_id]: - pd_entries.append(material_entries[material_id]["GGA"]) - pd_entries = self.compatibility.process_entries(pd_entries) + pd_entries = self.compatibility.process_entries(entries) self.logger.debug(f"{len(pd_entries)} remain in {chemsys} after filtering") try: From 00e4cce2233325033931fd2d62c2f19c1d273805 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:33:01 -0700 Subject: [PATCH 17/26] clean up --- emmet-builders/emmet/builders/vasp/thermo.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index 51ecfb3964..8b87da3835 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -158,7 +158,7 @@ def process_item(self, item: List[Dict]): ) return [] - return [d.dict() for d in docs] + return jsanitize([d.dict() for d in docs], allow_bson=True) def update_targets(self, items): """ @@ -169,9 +169,9 @@ def update_targets(self, items): # flatten out lists items = list(filter(None, chain.from_iterable(items))) # Check if already updated this run - items = [i for i in items if i[self.thermo.key] not in self._completed_tasks] + items = [i for i in items if i["material_id"] not in self._completed_tasks] - self._completed_tasks |= {i[self.thermo.key] for i in items} + self._completed_tasks |= {i["material_id"] for i in items} for item in items: if isinstance(item["last_updated"], dict): @@ -181,7 +181,7 @@ def update_targets(self, items): if len(items) > 0: self.logger.info(f"Updating {len(items)} thermo documents") - self.thermo.update(docs=jsanitize(items), key=[self.thermo.key]) + self.thermo.update(docs=items, key=["material_id"]) else: self.logger.info("No items to update") From d7cab8aab595325df9778be1934d87c93e760732 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 15:46:24 -0700 Subject: [PATCH 18/26] update builder names --- emmet-builders/emmet/builders/materials/oxidation_states.py | 3 +-- emmet-builders/emmet/builders/vasp/thermo.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/emmet-builders/emmet/builders/materials/oxidation_states.py b/emmet-builders/emmet/builders/materials/oxidation_states.py index 46a726e326..b250fdec3a 100644 --- a/emmet-builders/emmet/builders/materials/oxidation_states.py +++ b/emmet-builders/emmet/builders/materials/oxidation_states.py @@ -10,7 +10,7 @@ from emmet.core.oxidation_states import OxidationStateDoc -class OxidationStates(MapBuilder): +class OxidationStatesBuilder(MapBuilder): def __init__( self, materials: Store, @@ -40,7 +40,6 @@ def __init__( ) def unary_function(self, item): - structure = Structure.from_dict(item["structure"]) oxi_doc = OxidationStateDoc.from_structure(structure) doc = oxi_doc.dict() diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index 8b87da3835..c237ff2b2f 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -14,7 +14,7 @@ from emmet.core.utils import jsanitize -class Thermo(Builder): +class ThermoBuilder(Builder): def __init__( self, materials: Store, From b119add3d8e6772951d6557265e08cc5eed1dec6 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 16:06:54 -0700 Subject: [PATCH 19/26] fix misc bugs --- emmet-builders/emmet/builders/vasp/task_validator.py | 4 ++-- emmet-core/emmet/core/vasp/validation.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/task_validator.py b/emmet-builders/emmet/builders/vasp/task_validator.py index 1f8d368d8f..66226ac0e1 100644 --- a/emmet-builders/emmet/builders/vasp/task_validator.py +++ b/emmet-builders/emmet/builders/vasp/task_validator.py @@ -40,8 +40,8 @@ def __init__( projection=[ "orig_inputs", "output.structure", - "input.parameters", - "calcs_reversed.output.ionic_steps.e_fr_energy", + "output.bandgap" "input.parameters", + "calcs_reversed.output.ionic_steps.electronic_steps.e_fr_energy", "tags", ], query=query, diff --git a/emmet-core/emmet/core/vasp/validation.py b/emmet-core/emmet/core/vasp/validation.py index 9beb59d9bd..9846c3624b 100644 --- a/emmet-core/emmet/core/vasp/validation.py +++ b/emmet-core/emmet/core/vasp/validation.py @@ -116,7 +116,7 @@ def from_task_doc( ) # warn, but don't invalidate if wrong ISMEAR - if inputs.get("incar", {}).get("ISMEAR") > 0 and bandgap > 0: + if inputs.get("incar", {}).get("ISMEAR", 1) > 0 and bandgap > 0: warnings.append("Inappropriate smearing settings") # Checking ENCUT From 30ce56a842f8a83bcec34b0446d22fbab230ed54 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Thu, 27 May 2021 16:07:07 -0700 Subject: [PATCH 20/26] formatting bug --- emmet-builders/emmet/builders/vasp/task_validator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emmet-builders/emmet/builders/vasp/task_validator.py b/emmet-builders/emmet/builders/vasp/task_validator.py index 66226ac0e1..08610f2993 100644 --- a/emmet-builders/emmet/builders/vasp/task_validator.py +++ b/emmet-builders/emmet/builders/vasp/task_validator.py @@ -40,7 +40,8 @@ def __init__( projection=[ "orig_inputs", "output.structure", - "output.bandgap" "input.parameters", + "output.bandgap", + "input.parameters", "calcs_reversed.output.ionic_steps.electronic_steps.e_fr_energy", "tags", ], From ddf6fa1fde4bbb1508468bc8e204f535cbf30d47 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Fri, 28 May 2021 13:47:04 -0700 Subject: [PATCH 21/26] mark when ismear differs --- emmet-core/emmet/core/vasp/validation.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/emmet-core/emmet/core/vasp/validation.py b/emmet-core/emmet/core/vasp/validation.py index 9846c3624b..6dcfdc35bd 100644 --- a/emmet-core/emmet/core/vasp/validation.py +++ b/emmet-core/emmet/core/vasp/validation.py @@ -116,8 +116,13 @@ def from_task_doc( ) # warn, but don't invalidate if wrong ISMEAR - if inputs.get("incar", {}).get("ISMEAR", 1) > 0 and bandgap > 0: - warnings.append("Inappropriate smearing settings") + valid_ismear = valid_input_set.incar.get("ISMEAR", 1) + curr_ismear = inputs.get("incar", {}).get("ISMEAR", 1) + if curr_ismear != valid_ismear: + warnings.append( + f"Inappropriate smearing settings. Set to {curr_ismear}," + " but should be {valid_ismear}" + ) # Checking ENCUT encut = inputs.get("incar", {}).get("ENCUT") From 8bc1999d3b947b8716d19af46e626be9ce3fafab Mon Sep 17 00:00:00 2001 From: Shyam D Date: Fri, 28 May 2021 13:48:08 -0700 Subject: [PATCH 22/26] add unrecognized task_type --- .../emmet/core/vasp/calc_types/enums.py | 60 +++++++++++++++++++ .../emmet/core/vasp/calc_types/generate.py | 15 +---- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/emmet-core/emmet/core/vasp/calc_types/enums.py b/emmet-core/emmet/core/vasp/calc_types/enums.py index 35bb01b22d..5c0241e80f 100644 --- a/emmet-core/emmet/core/vasp/calc_types/enums.py +++ b/emmet-core/emmet/core/vasp/calc_types/enums.py @@ -99,6 +99,7 @@ class CalcType(ValueEnum): AM05_Static = "AM05 Static" AM05_Structure_Optimization = "AM05 Structure Optimization" AM05_Deformation = "AM05 Deformation" + AM05_Unrecognized = "AM05 Unrecognized" GGA_NSCF_Line = "GGA NSCF Line" GGA_NSCF_Uniform = "GGA NSCF Uniform" GGA_Dielectric = "GGA Dielectric" @@ -109,6 +110,7 @@ class CalcType(ValueEnum): GGA_Static = "GGA Static" GGA_Structure_Optimization = "GGA Structure Optimization" GGA_Deformation = "GGA Deformation" + GGA_Unrecognized = "GGA Unrecognized" PBE_NSCF_Line = "PBE NSCF Line" PBE_NSCF_Uniform = "PBE NSCF Uniform" PBE_Dielectric = "PBE Dielectric" @@ -119,6 +121,7 @@ class CalcType(ValueEnum): PBE_Static = "PBE Static" PBE_Structure_Optimization = "PBE Structure Optimization" PBE_Deformation = "PBE Deformation" + PBE_Unrecognized = "PBE Unrecognized" PBESol_NSCF_Line = "PBESol NSCF Line" PBESol_NSCF_Uniform = "PBESol NSCF Uniform" PBESol_Dielectric = "PBESol Dielectric" @@ -129,6 +132,7 @@ class CalcType(ValueEnum): PBESol_Static = "PBESol Static" PBESol_Structure_Optimization = "PBESol Structure Optimization" PBESol_Deformation = "PBESol Deformation" + PBESol_Unrecognized = "PBESol Unrecognized" RevPBE_PADE_NSCF_Line = "RevPBE+PADE NSCF Line" RevPBE_PADE_NSCF_Uniform = "RevPBE+PADE NSCF Uniform" RevPBE_PADE_Dielectric = "RevPBE+PADE Dielectric" @@ -139,6 +143,7 @@ class CalcType(ValueEnum): RevPBE_PADE_Static = "RevPBE+PADE Static" RevPBE_PADE_Structure_Optimization = "RevPBE+PADE Structure Optimization" RevPBE_PADE_Deformation = "RevPBE+PADE Deformation" + RevPBE_PADE_Unrecognized = "RevPBE+PADE Unrecognized" optB86b_NSCF_Line = "optB86b NSCF Line" optB86b_NSCF_Uniform = "optB86b NSCF Uniform" optB86b_Dielectric = "optB86b Dielectric" @@ -149,6 +154,7 @@ class CalcType(ValueEnum): optB86b_Static = "optB86b Static" optB86b_Structure_Optimization = "optB86b Structure Optimization" optB86b_Deformation = "optB86b Deformation" + optB86b_Unrecognized = "optB86b Unrecognized" optB88_NSCF_Line = "optB88 NSCF Line" optB88_NSCF_Uniform = "optB88 NSCF Uniform" optB88_Dielectric = "optB88 Dielectric" @@ -159,6 +165,7 @@ class CalcType(ValueEnum): optB88_Static = "optB88 Static" optB88_Structure_Optimization = "optB88 Structure Optimization" optB88_Deformation = "optB88 Deformation" + optB88_Unrecognized = "optB88 Unrecognized" optPBE_NSCF_Line = "optPBE NSCF Line" optPBE_NSCF_Uniform = "optPBE NSCF Uniform" optPBE_Dielectric = "optPBE Dielectric" @@ -169,6 +176,7 @@ class CalcType(ValueEnum): optPBE_Static = "optPBE Static" optPBE_Structure_Optimization = "optPBE Structure Optimization" optPBE_Deformation = "optPBE Deformation" + optPBE_Unrecognized = "optPBE Unrecognized" revPBE_NSCF_Line = "revPBE NSCF Line" revPBE_NSCF_Uniform = "revPBE NSCF Uniform" revPBE_Dielectric = "revPBE Dielectric" @@ -179,6 +187,7 @@ class CalcType(ValueEnum): revPBE_Static = "revPBE Static" revPBE_Structure_Optimization = "revPBE Structure Optimization" revPBE_Deformation = "revPBE Deformation" + revPBE_Unrecognized = "revPBE Unrecognized" B3LYP_NSCF_Line = "B3LYP NSCF Line" B3LYP_NSCF_Uniform = "B3LYP NSCF Uniform" B3LYP_Dielectric = "B3LYP Dielectric" @@ -189,6 +198,7 @@ class CalcType(ValueEnum): B3LYP_Static = "B3LYP Static" B3LYP_Structure_Optimization = "B3LYP Structure Optimization" B3LYP_Deformation = "B3LYP Deformation" + B3LYP_Unrecognized = "B3LYP Unrecognized" HF_NSCF_Line = "HF NSCF Line" HF_NSCF_Uniform = "HF NSCF Uniform" HF_Dielectric = "HF Dielectric" @@ -199,6 +209,7 @@ class CalcType(ValueEnum): HF_Static = "HF Static" HF_Structure_Optimization = "HF Structure Optimization" HF_Deformation = "HF Deformation" + HF_Unrecognized = "HF Unrecognized" HSE03_NSCF_Line = "HSE03 NSCF Line" HSE03_NSCF_Uniform = "HSE03 NSCF Uniform" HSE03_Dielectric = "HSE03 Dielectric" @@ -209,6 +220,7 @@ class CalcType(ValueEnum): HSE03_Static = "HSE03 Static" HSE03_Structure_Optimization = "HSE03 Structure Optimization" HSE03_Deformation = "HSE03 Deformation" + HSE03_Unrecognized = "HSE03 Unrecognized" HSE06_NSCF_Line = "HSE06 NSCF Line" HSE06_NSCF_Uniform = "HSE06 NSCF Uniform" HSE06_Dielectric = "HSE06 Dielectric" @@ -219,6 +231,7 @@ class CalcType(ValueEnum): HSE06_Static = "HSE06 Static" HSE06_Structure_Optimization = "HSE06 Structure Optimization" HSE06_Deformation = "HSE06 Deformation" + HSE06_Unrecognized = "HSE06 Unrecognized" PB0_NSCF_Line = "PB0 NSCF Line" PB0_NSCF_Uniform = "PB0 NSCF Uniform" PB0_Dielectric = "PB0 Dielectric" @@ -229,6 +242,7 @@ class CalcType(ValueEnum): PB0_Static = "PB0 Static" PB0_Structure_Optimization = "PB0 Structure Optimization" PB0_Deformation = "PB0 Deformation" + PB0_Unrecognized = "PB0 Unrecognized" M06L_NSCF_Line = "M06L NSCF Line" M06L_NSCF_Uniform = "M06L NSCF Uniform" M06L_Dielectric = "M06L Dielectric" @@ -239,6 +253,7 @@ class CalcType(ValueEnum): M06L_Static = "M06L Static" M06L_Structure_Optimization = "M06L Structure Optimization" M06L_Deformation = "M06L Deformation" + M06L_Unrecognized = "M06L Unrecognized" MBJL_NSCF_Line = "MBJL NSCF Line" MBJL_NSCF_Uniform = "MBJL NSCF Uniform" MBJL_Dielectric = "MBJL Dielectric" @@ -249,6 +264,7 @@ class CalcType(ValueEnum): MBJL_Static = "MBJL Static" MBJL_Structure_Optimization = "MBJL Structure Optimization" MBJL_Deformation = "MBJL Deformation" + MBJL_Unrecognized = "MBJL Unrecognized" MS0_NSCF_Line = "MS0 NSCF Line" MS0_NSCF_Uniform = "MS0 NSCF Uniform" MS0_Dielectric = "MS0 Dielectric" @@ -259,6 +275,7 @@ class CalcType(ValueEnum): MS0_Static = "MS0 Static" MS0_Structure_Optimization = "MS0 Structure Optimization" MS0_Deformation = "MS0 Deformation" + MS0_Unrecognized = "MS0 Unrecognized" MS1_NSCF_Line = "MS1 NSCF Line" MS1_NSCF_Uniform = "MS1 NSCF Uniform" MS1_Dielectric = "MS1 Dielectric" @@ -269,6 +286,7 @@ class CalcType(ValueEnum): MS1_Static = "MS1 Static" MS1_Structure_Optimization = "MS1 Structure Optimization" MS1_Deformation = "MS1 Deformation" + MS1_Unrecognized = "MS1 Unrecognized" MS2_NSCF_Line = "MS2 NSCF Line" MS2_NSCF_Uniform = "MS2 NSCF Uniform" MS2_Dielectric = "MS2 Dielectric" @@ -279,6 +297,7 @@ class CalcType(ValueEnum): MS2_Static = "MS2 Static" MS2_Structure_Optimization = "MS2 Structure Optimization" MS2_Deformation = "MS2 Deformation" + MS2_Unrecognized = "MS2 Unrecognized" RTPSS_NSCF_Line = "RTPSS NSCF Line" RTPSS_NSCF_Uniform = "RTPSS NSCF Uniform" RTPSS_Dielectric = "RTPSS Dielectric" @@ -289,6 +308,7 @@ class CalcType(ValueEnum): RTPSS_Static = "RTPSS Static" RTPSS_Structure_Optimization = "RTPSS Structure Optimization" RTPSS_Deformation = "RTPSS Deformation" + RTPSS_Unrecognized = "RTPSS Unrecognized" SCAN_NSCF_Line = "SCAN NSCF Line" SCAN_NSCF_Uniform = "SCAN NSCF Uniform" SCAN_Dielectric = "SCAN Dielectric" @@ -299,6 +319,7 @@ class CalcType(ValueEnum): SCAN_Static = "SCAN Static" SCAN_Structure_Optimization = "SCAN Structure Optimization" SCAN_Deformation = "SCAN Deformation" + SCAN_Unrecognized = "SCAN Unrecognized" TPSS_NSCF_Line = "TPSS NSCF Line" TPSS_NSCF_Uniform = "TPSS NSCF Uniform" TPSS_Dielectric = "TPSS Dielectric" @@ -309,6 +330,7 @@ class CalcType(ValueEnum): TPSS_Static = "TPSS Static" TPSS_Structure_Optimization = "TPSS Structure Optimization" TPSS_Deformation = "TPSS Deformation" + TPSS_Unrecognized = "TPSS Unrecognized" SCAN_rVV10_NSCF_Line = "SCAN-rVV10 NSCF Line" SCAN_rVV10_NSCF_Uniform = "SCAN-rVV10 NSCF Uniform" SCAN_rVV10_Dielectric = "SCAN-rVV10 Dielectric" @@ -319,6 +341,7 @@ class CalcType(ValueEnum): SCAN_rVV10_Static = "SCAN-rVV10 Static" SCAN_rVV10_Structure_Optimization = "SCAN-rVV10 Structure Optimization" SCAN_rVV10_Deformation = "SCAN-rVV10 Deformation" + SCAN_rVV10_Unrecognized = "SCAN-rVV10 Unrecognized" optB86b_vdW_NSCF_Line = "optB86b-vdW NSCF Line" optB86b_vdW_NSCF_Uniform = "optB86b-vdW NSCF Uniform" optB86b_vdW_Dielectric = "optB86b-vdW Dielectric" @@ -329,6 +352,7 @@ class CalcType(ValueEnum): optB86b_vdW_Static = "optB86b-vdW Static" optB86b_vdW_Structure_Optimization = "optB86b-vdW Structure Optimization" optB86b_vdW_Deformation = "optB86b-vdW Deformation" + optB86b_vdW_Unrecognized = "optB86b-vdW Unrecognized" optB88_vdW_NSCF_Line = "optB88-vdW NSCF Line" optB88_vdW_NSCF_Uniform = "optB88-vdW NSCF Uniform" optB88_vdW_Dielectric = "optB88-vdW Dielectric" @@ -339,6 +363,7 @@ class CalcType(ValueEnum): optB88_vdW_Static = "optB88-vdW Static" optB88_vdW_Structure_Optimization = "optB88-vdW Structure Optimization" optB88_vdW_Deformation = "optB88-vdW Deformation" + optB88_vdW_Unrecognized = "optB88-vdW Unrecognized" optPBE_vdW_NSCF_Line = "optPBE-vdW NSCF Line" optPBE_vdW_NSCF_Uniform = "optPBE-vdW NSCF Uniform" optPBE_vdW_Dielectric = "optPBE-vdW Dielectric" @@ -349,6 +374,7 @@ class CalcType(ValueEnum): optPBE_vdW_Static = "optPBE-vdW Static" optPBE_vdW_Structure_Optimization = "optPBE-vdW Structure Optimization" optPBE_vdW_Deformation = "optPBE-vdW Deformation" + optPBE_vdW_Unrecognized = "optPBE-vdW Unrecognized" rev_vdW_DF2_NSCF_Line = "rev-vdW-DF2 NSCF Line" rev_vdW_DF2_NSCF_Uniform = "rev-vdW-DF2 NSCF Uniform" rev_vdW_DF2_Dielectric = "rev-vdW-DF2 Dielectric" @@ -359,6 +385,7 @@ class CalcType(ValueEnum): rev_vdW_DF2_Static = "rev-vdW-DF2 Static" rev_vdW_DF2_Structure_Optimization = "rev-vdW-DF2 Structure Optimization" rev_vdW_DF2_Deformation = "rev-vdW-DF2 Deformation" + rev_vdW_DF2_Unrecognized = "rev-vdW-DF2 Unrecognized" revPBE_vdW_NSCF_Line = "revPBE-vdW NSCF Line" revPBE_vdW_NSCF_Uniform = "revPBE-vdW NSCF Uniform" revPBE_vdW_Dielectric = "revPBE-vdW Dielectric" @@ -369,6 +396,7 @@ class CalcType(ValueEnum): revPBE_vdW_Static = "revPBE-vdW Static" revPBE_vdW_Structure_Optimization = "revPBE-vdW Structure Optimization" revPBE_vdW_Deformation = "revPBE-vdW Deformation" + revPBE_vdW_Unrecognized = "revPBE-vdW Unrecognized" vdW_DF2_NSCF_Line = "vdW-DF2 NSCF Line" vdW_DF2_NSCF_Uniform = "vdW-DF2 NSCF Uniform" vdW_DF2_Dielectric = "vdW-DF2 Dielectric" @@ -379,6 +407,7 @@ class CalcType(ValueEnum): vdW_DF2_Static = "vdW-DF2 Static" vdW_DF2_Structure_Optimization = "vdW-DF2 Structure Optimization" vdW_DF2_Deformation = "vdW-DF2 Deformation" + vdW_DF2_Unrecognized = "vdW-DF2 Unrecognized" AM05_U_NSCF_Line = "AM05+U NSCF Line" AM05_U_NSCF_Uniform = "AM05+U NSCF Uniform" AM05_U_Dielectric = "AM05+U Dielectric" @@ -389,6 +418,7 @@ class CalcType(ValueEnum): AM05_U_Static = "AM05+U Static" AM05_U_Structure_Optimization = "AM05+U Structure Optimization" AM05_U_Deformation = "AM05+U Deformation" + AM05_U_Unrecognized = "AM05+U Unrecognized" GGA_U_NSCF_Line = "GGA+U NSCF Line" GGA_U_NSCF_Uniform = "GGA+U NSCF Uniform" GGA_U_Dielectric = "GGA+U Dielectric" @@ -399,6 +429,7 @@ class CalcType(ValueEnum): GGA_U_Static = "GGA+U Static" GGA_U_Structure_Optimization = "GGA+U Structure Optimization" GGA_U_Deformation = "GGA+U Deformation" + GGA_U_Unrecognized = "GGA+U Unrecognized" PBE_U_NSCF_Line = "PBE+U NSCF Line" PBE_U_NSCF_Uniform = "PBE+U NSCF Uniform" PBE_U_Dielectric = "PBE+U Dielectric" @@ -409,6 +440,7 @@ class CalcType(ValueEnum): PBE_U_Static = "PBE+U Static" PBE_U_Structure_Optimization = "PBE+U Structure Optimization" PBE_U_Deformation = "PBE+U Deformation" + PBE_U_Unrecognized = "PBE+U Unrecognized" PBESol_U_NSCF_Line = "PBESol+U NSCF Line" PBESol_U_NSCF_Uniform = "PBESol+U NSCF Uniform" PBESol_U_Dielectric = "PBESol+U Dielectric" @@ -419,6 +451,7 @@ class CalcType(ValueEnum): PBESol_U_Static = "PBESol+U Static" PBESol_U_Structure_Optimization = "PBESol+U Structure Optimization" PBESol_U_Deformation = "PBESol+U Deformation" + PBESol_U_Unrecognized = "PBESol+U Unrecognized" RevPBE_PADE_U_NSCF_Line = "RevPBE+PADE+U NSCF Line" RevPBE_PADE_U_NSCF_Uniform = "RevPBE+PADE+U NSCF Uniform" RevPBE_PADE_U_Dielectric = "RevPBE+PADE+U Dielectric" @@ -431,6 +464,7 @@ class CalcType(ValueEnum): RevPBE_PADE_U_Static = "RevPBE+PADE+U Static" RevPBE_PADE_U_Structure_Optimization = "RevPBE+PADE+U Structure Optimization" RevPBE_PADE_U_Deformation = "RevPBE+PADE+U Deformation" + RevPBE_PADE_U_Unrecognized = "RevPBE+PADE+U Unrecognized" optB86b_U_NSCF_Line = "optB86b+U NSCF Line" optB86b_U_NSCF_Uniform = "optB86b+U NSCF Uniform" optB86b_U_Dielectric = "optB86b+U Dielectric" @@ -441,6 +475,7 @@ class CalcType(ValueEnum): optB86b_U_Static = "optB86b+U Static" optB86b_U_Structure_Optimization = "optB86b+U Structure Optimization" optB86b_U_Deformation = "optB86b+U Deformation" + optB86b_U_Unrecognized = "optB86b+U Unrecognized" optB88_U_NSCF_Line = "optB88+U NSCF Line" optB88_U_NSCF_Uniform = "optB88+U NSCF Uniform" optB88_U_Dielectric = "optB88+U Dielectric" @@ -451,6 +486,7 @@ class CalcType(ValueEnum): optB88_U_Static = "optB88+U Static" optB88_U_Structure_Optimization = "optB88+U Structure Optimization" optB88_U_Deformation = "optB88+U Deformation" + optB88_U_Unrecognized = "optB88+U Unrecognized" optPBE_U_NSCF_Line = "optPBE+U NSCF Line" optPBE_U_NSCF_Uniform = "optPBE+U NSCF Uniform" optPBE_U_Dielectric = "optPBE+U Dielectric" @@ -461,6 +497,7 @@ class CalcType(ValueEnum): optPBE_U_Static = "optPBE+U Static" optPBE_U_Structure_Optimization = "optPBE+U Structure Optimization" optPBE_U_Deformation = "optPBE+U Deformation" + optPBE_U_Unrecognized = "optPBE+U Unrecognized" revPBE_U_NSCF_Line = "revPBE+U NSCF Line" revPBE_U_NSCF_Uniform = "revPBE+U NSCF Uniform" revPBE_U_Dielectric = "revPBE+U Dielectric" @@ -471,6 +508,7 @@ class CalcType(ValueEnum): revPBE_U_Static = "revPBE+U Static" revPBE_U_Structure_Optimization = "revPBE+U Structure Optimization" revPBE_U_Deformation = "revPBE+U Deformation" + revPBE_U_Unrecognized = "revPBE+U Unrecognized" B3LYP_U_NSCF_Line = "B3LYP+U NSCF Line" B3LYP_U_NSCF_Uniform = "B3LYP+U NSCF Uniform" B3LYP_U_Dielectric = "B3LYP+U Dielectric" @@ -481,6 +519,7 @@ class CalcType(ValueEnum): B3LYP_U_Static = "B3LYP+U Static" B3LYP_U_Structure_Optimization = "B3LYP+U Structure Optimization" B3LYP_U_Deformation = "B3LYP+U Deformation" + B3LYP_U_Unrecognized = "B3LYP+U Unrecognized" HF_U_NSCF_Line = "HF+U NSCF Line" HF_U_NSCF_Uniform = "HF+U NSCF Uniform" HF_U_Dielectric = "HF+U Dielectric" @@ -491,6 +530,7 @@ class CalcType(ValueEnum): HF_U_Static = "HF+U Static" HF_U_Structure_Optimization = "HF+U Structure Optimization" HF_U_Deformation = "HF+U Deformation" + HF_U_Unrecognized = "HF+U Unrecognized" HSE03_U_NSCF_Line = "HSE03+U NSCF Line" HSE03_U_NSCF_Uniform = "HSE03+U NSCF Uniform" HSE03_U_Dielectric = "HSE03+U Dielectric" @@ -501,6 +541,7 @@ class CalcType(ValueEnum): HSE03_U_Static = "HSE03+U Static" HSE03_U_Structure_Optimization = "HSE03+U Structure Optimization" HSE03_U_Deformation = "HSE03+U Deformation" + HSE03_U_Unrecognized = "HSE03+U Unrecognized" HSE06_U_NSCF_Line = "HSE06+U NSCF Line" HSE06_U_NSCF_Uniform = "HSE06+U NSCF Uniform" HSE06_U_Dielectric = "HSE06+U Dielectric" @@ -511,6 +552,7 @@ class CalcType(ValueEnum): HSE06_U_Static = "HSE06+U Static" HSE06_U_Structure_Optimization = "HSE06+U Structure Optimization" HSE06_U_Deformation = "HSE06+U Deformation" + HSE06_U_Unrecognized = "HSE06+U Unrecognized" PB0_U_NSCF_Line = "PB0+U NSCF Line" PB0_U_NSCF_Uniform = "PB0+U NSCF Uniform" PB0_U_Dielectric = "PB0+U Dielectric" @@ -521,6 +563,7 @@ class CalcType(ValueEnum): PB0_U_Static = "PB0+U Static" PB0_U_Structure_Optimization = "PB0+U Structure Optimization" PB0_U_Deformation = "PB0+U Deformation" + PB0_U_Unrecognized = "PB0+U Unrecognized" M06L_U_NSCF_Line = "M06L+U NSCF Line" M06L_U_NSCF_Uniform = "M06L+U NSCF Uniform" M06L_U_Dielectric = "M06L+U Dielectric" @@ -531,6 +574,7 @@ class CalcType(ValueEnum): M06L_U_Static = "M06L+U Static" M06L_U_Structure_Optimization = "M06L+U Structure Optimization" M06L_U_Deformation = "M06L+U Deformation" + M06L_U_Unrecognized = "M06L+U Unrecognized" MBJL_U_NSCF_Line = "MBJL+U NSCF Line" MBJL_U_NSCF_Uniform = "MBJL+U NSCF Uniform" MBJL_U_Dielectric = "MBJL+U Dielectric" @@ -541,6 +585,7 @@ class CalcType(ValueEnum): MBJL_U_Static = "MBJL+U Static" MBJL_U_Structure_Optimization = "MBJL+U Structure Optimization" MBJL_U_Deformation = "MBJL+U Deformation" + MBJL_U_Unrecognized = "MBJL+U Unrecognized" MS0_U_NSCF_Line = "MS0+U NSCF Line" MS0_U_NSCF_Uniform = "MS0+U NSCF Uniform" MS0_U_Dielectric = "MS0+U Dielectric" @@ -551,6 +596,7 @@ class CalcType(ValueEnum): MS0_U_Static = "MS0+U Static" MS0_U_Structure_Optimization = "MS0+U Structure Optimization" MS0_U_Deformation = "MS0+U Deformation" + MS0_U_Unrecognized = "MS0+U Unrecognized" MS1_U_NSCF_Line = "MS1+U NSCF Line" MS1_U_NSCF_Uniform = "MS1+U NSCF Uniform" MS1_U_Dielectric = "MS1+U Dielectric" @@ -561,6 +607,7 @@ class CalcType(ValueEnum): MS1_U_Static = "MS1+U Static" MS1_U_Structure_Optimization = "MS1+U Structure Optimization" MS1_U_Deformation = "MS1+U Deformation" + MS1_U_Unrecognized = "MS1+U Unrecognized" MS2_U_NSCF_Line = "MS2+U NSCF Line" MS2_U_NSCF_Uniform = "MS2+U NSCF Uniform" MS2_U_Dielectric = "MS2+U Dielectric" @@ -571,6 +618,7 @@ class CalcType(ValueEnum): MS2_U_Static = "MS2+U Static" MS2_U_Structure_Optimization = "MS2+U Structure Optimization" MS2_U_Deformation = "MS2+U Deformation" + MS2_U_Unrecognized = "MS2+U Unrecognized" RTPSS_U_NSCF_Line = "RTPSS+U NSCF Line" RTPSS_U_NSCF_Uniform = "RTPSS+U NSCF Uniform" RTPSS_U_Dielectric = "RTPSS+U Dielectric" @@ -581,6 +629,7 @@ class CalcType(ValueEnum): RTPSS_U_Static = "RTPSS+U Static" RTPSS_U_Structure_Optimization = "RTPSS+U Structure Optimization" RTPSS_U_Deformation = "RTPSS+U Deformation" + RTPSS_U_Unrecognized = "RTPSS+U Unrecognized" SCAN_U_NSCF_Line = "SCAN+U NSCF Line" SCAN_U_NSCF_Uniform = "SCAN+U NSCF Uniform" SCAN_U_Dielectric = "SCAN+U Dielectric" @@ -591,6 +640,7 @@ class CalcType(ValueEnum): SCAN_U_Static = "SCAN+U Static" SCAN_U_Structure_Optimization = "SCAN+U Structure Optimization" SCAN_U_Deformation = "SCAN+U Deformation" + SCAN_U_Unrecognized = "SCAN+U Unrecognized" TPSS_U_NSCF_Line = "TPSS+U NSCF Line" TPSS_U_NSCF_Uniform = "TPSS+U NSCF Uniform" TPSS_U_Dielectric = "TPSS+U Dielectric" @@ -601,6 +651,7 @@ class CalcType(ValueEnum): TPSS_U_Static = "TPSS+U Static" TPSS_U_Structure_Optimization = "TPSS+U Structure Optimization" TPSS_U_Deformation = "TPSS+U Deformation" + TPSS_U_Unrecognized = "TPSS+U Unrecognized" SCAN_rVV10_U_NSCF_Line = "SCAN-rVV10+U NSCF Line" SCAN_rVV10_U_NSCF_Uniform = "SCAN-rVV10+U NSCF Uniform" SCAN_rVV10_U_Dielectric = "SCAN-rVV10+U Dielectric" @@ -613,6 +664,7 @@ class CalcType(ValueEnum): SCAN_rVV10_U_Static = "SCAN-rVV10+U Static" SCAN_rVV10_U_Structure_Optimization = "SCAN-rVV10+U Structure Optimization" SCAN_rVV10_U_Deformation = "SCAN-rVV10+U Deformation" + SCAN_rVV10_U_Unrecognized = "SCAN-rVV10+U Unrecognized" optB86b_vdW_U_NSCF_Line = "optB86b-vdW+U NSCF Line" optB86b_vdW_U_NSCF_Uniform = "optB86b-vdW+U NSCF Uniform" optB86b_vdW_U_Dielectric = "optB86b-vdW+U Dielectric" @@ -625,6 +677,7 @@ class CalcType(ValueEnum): optB86b_vdW_U_Static = "optB86b-vdW+U Static" optB86b_vdW_U_Structure_Optimization = "optB86b-vdW+U Structure Optimization" optB86b_vdW_U_Deformation = "optB86b-vdW+U Deformation" + optB86b_vdW_U_Unrecognized = "optB86b-vdW+U Unrecognized" optB88_vdW_U_NSCF_Line = "optB88-vdW+U NSCF Line" optB88_vdW_U_NSCF_Uniform = "optB88-vdW+U NSCF Uniform" optB88_vdW_U_Dielectric = "optB88-vdW+U Dielectric" @@ -637,6 +690,7 @@ class CalcType(ValueEnum): optB88_vdW_U_Static = "optB88-vdW+U Static" optB88_vdW_U_Structure_Optimization = "optB88-vdW+U Structure Optimization" optB88_vdW_U_Deformation = "optB88-vdW+U Deformation" + optB88_vdW_U_Unrecognized = "optB88-vdW+U Unrecognized" optPBE_vdW_U_NSCF_Line = "optPBE-vdW+U NSCF Line" optPBE_vdW_U_NSCF_Uniform = "optPBE-vdW+U NSCF Uniform" optPBE_vdW_U_Dielectric = "optPBE-vdW+U Dielectric" @@ -649,6 +703,7 @@ class CalcType(ValueEnum): optPBE_vdW_U_Static = "optPBE-vdW+U Static" optPBE_vdW_U_Structure_Optimization = "optPBE-vdW+U Structure Optimization" optPBE_vdW_U_Deformation = "optPBE-vdW+U Deformation" + optPBE_vdW_U_Unrecognized = "optPBE-vdW+U Unrecognized" rev_vdW_DF2_U_NSCF_Line = "rev-vdW-DF2+U NSCF Line" rev_vdW_DF2_U_NSCF_Uniform = "rev-vdW-DF2+U NSCF Uniform" rev_vdW_DF2_U_Dielectric = "rev-vdW-DF2+U Dielectric" @@ -661,6 +716,7 @@ class CalcType(ValueEnum): rev_vdW_DF2_U_Static = "rev-vdW-DF2+U Static" rev_vdW_DF2_U_Structure_Optimization = "rev-vdW-DF2+U Structure Optimization" rev_vdW_DF2_U_Deformation = "rev-vdW-DF2+U Deformation" + rev_vdW_DF2_U_Unrecognized = "rev-vdW-DF2+U Unrecognized" revPBE_vdW_U_NSCF_Line = "revPBE-vdW+U NSCF Line" revPBE_vdW_U_NSCF_Uniform = "revPBE-vdW+U NSCF Uniform" revPBE_vdW_U_Dielectric = "revPBE-vdW+U Dielectric" @@ -673,6 +729,7 @@ class CalcType(ValueEnum): revPBE_vdW_U_Static = "revPBE-vdW+U Static" revPBE_vdW_U_Structure_Optimization = "revPBE-vdW+U Structure Optimization" revPBE_vdW_U_Deformation = "revPBE-vdW+U Deformation" + revPBE_vdW_U_Unrecognized = "revPBE-vdW+U Unrecognized" vdW_DF2_U_NSCF_Line = "vdW-DF2+U NSCF Line" vdW_DF2_U_NSCF_Uniform = "vdW-DF2+U NSCF Uniform" vdW_DF2_U_Dielectric = "vdW-DF2+U Dielectric" @@ -683,6 +740,7 @@ class CalcType(ValueEnum): vdW_DF2_U_Static = "vdW-DF2+U Static" vdW_DF2_U_Structure_Optimization = "vdW-DF2+U Structure Optimization" vdW_DF2_U_Deformation = "vdW-DF2+U Deformation" + vdW_DF2_U_Unrecognized = "vdW-DF2+U Unrecognized" LDA_NSCF_Line = "LDA NSCF Line" LDA_NSCF_Uniform = "LDA NSCF Uniform" LDA_Dielectric = "LDA Dielectric" @@ -693,6 +751,7 @@ class CalcType(ValueEnum): LDA_Static = "LDA Static" LDA_Structure_Optimization = "LDA Structure Optimization" LDA_Deformation = "LDA Deformation" + LDA_Unrecognized = "LDA Unrecognized" LDA_U_NSCF_Line = "LDA+U NSCF Line" LDA_U_NSCF_Uniform = "LDA+U NSCF Uniform" LDA_U_Dielectric = "LDA+U Dielectric" @@ -703,3 +762,4 @@ class CalcType(ValueEnum): LDA_U_Static = "LDA+U Static" LDA_U_Structure_Optimization = "LDA+U Structure Optimization" LDA_U_Deformation = "LDA+U Deformation" + LDA_U_Unrecognized = "LDA+U Unrecognized" diff --git a/emmet-core/emmet/core/vasp/calc_types/generate.py b/emmet-core/emmet/core/vasp/calc_types/generate.py index 825df77d62..16d0f1f3bd 100644 --- a/emmet-core/emmet/core/vasp/calc_types/generate.py +++ b/emmet-core/emmet/core/vasp/calc_types/generate.py @@ -1,20 +1,8 @@ """ Module to define various calculation types as Enums for VASP """ -import datetime -from itertools import groupby, product +from itertools import product from pathlib import Path -from typing import Dict, Iterator, List -import bson -import numpy as np -from monty.json import MSONable from monty.serialization import loadfn -from pydantic import BaseModel -from pymatgen.analysis.structure_matcher import ElementComparator, StructureMatcher -from pymatgen.core.structure import Structure -from typing_extensions import Literal - -from emmet.core import SETTINGS -from emmet.core.utils import ValueEnum _RUN_TYPE_DATA = loadfn(str(Path(__file__).parent.joinpath("run_types.yaml").resolve())) _TASK_TYPES = [ @@ -28,6 +16,7 @@ "Static", "Structure Optimization", "Deformation", + "Unrecognized", ] _RUN_TYPES = ( From 03d3512cc6b2f512faa25a1a1a245ef87eee7bf9 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Fri, 28 May 2021 14:01:43 -0700 Subject: [PATCH 23/26] fix minor conversion bugs --- emmet-builders/emmet/builders/vasp/thermo.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index c237ff2b2f..a64616a934 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -224,9 +224,9 @@ def get_entries(self, chemsys: str) -> List[Dict]: if self.oxidation_states: material_ids = [t["material_id"] for t in materials_docs] oxi_states_data = { - d["material_id"]: d["bond_valence"]["average_oxidation_states"] + d["material_id"]: d.get("average_oxidation_states", {}) for d in self.oxidation_states.query( - properties=["material_id", "bond_valence.average_oxidation_states"], + properties=["material_id", "average_oxidation_states"], criteria={"material_id": {"$in": material_ids}, "successful": True}, ) } @@ -258,7 +258,7 @@ def get_updated_chemsys( updated_mats = self.thermo.newer_in(self.materials, criteria=self.query) updated_chemsys = set( self.materials.distinct( - "chemsys", {self.materials.key: {"$in": list(updated_mats)}} + "chemsys", {"material_id": {"$in": list(updated_mats)}} ) ) self.logger.debug(f"Found {len(updated_chemsys)} updated chemical systems") @@ -269,8 +269,8 @@ def get_new_chemsys(self) -> Set: """Gets newer chemical system as defined by introduction of a new material""" # All materials that are not present in the thermo collection - thermo_mat_ids = self.thermo.distinct(self.thermo.key) - mat_ids = self.materials.distinct(self.materials.key, self.query) + thermo_mat_ids = self.thermo.distinct("material_id") + mat_ids = self.materials.distinct("material_id", self.query) dif_task_ids = list(set(mat_ids) - set(thermo_mat_ids)) q = {"material_id": {"$in": dif_task_ids}} new_mat_chemsys = set(self.materials.distinct("chemsys", q)) From 2994cb4cb74ec7b381bae21d415dc3808c63e0eb Mon Sep 17 00:00:00 2001 From: Shyam D Date: Fri, 28 May 2021 14:14:25 -0700 Subject: [PATCH 24/26] fix counting of chemsys to process --- emmet-builders/emmet/builders/vasp/thermo.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index a64616a934..1b971e64c2 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -62,6 +62,7 @@ def ensure_indexes(self): # Search index for materials self.materials.ensure_index("material_id") + self.materials.ensure_index("chemsys") self.materials.ensure_index("last_updated") # Search index for thermo @@ -99,10 +100,12 @@ def get_items(self) -> Iterator[List[Dict]]: affected_chemsys = self.get_affected_chemsys(updated_chemsys | new_chemsys) # Remove overlapping chemical systems - to_process_chemsys = set() + processed = set() + to_process_chemsys = [] for chemsys in updated_chemsys | new_chemsys | affected_chemsys: - if chemsys not in to_process_chemsys: - to_process_chemsys |= chemsys_permutations(chemsys) + if chemsys not in processed: + processed |= chemsys_permutations(chemsys) + to_process_chemsys.append(chemsys) self.logger.info( f"Found {len(to_process_chemsys)} chemical systems with new/updated materials to process" From fabbe34dc3796bc3a7c257fd2d449d25bcec4162 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Fri, 28 May 2021 14:16:51 -0700 Subject: [PATCH 25/26] catch warnings from compatability --- emmet-builders/emmet/builders/vasp/thermo.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/emmet-builders/emmet/builders/vasp/thermo.py b/emmet-builders/emmet/builders/vasp/thermo.py index 1b971e64c2..591f8aaac6 100644 --- a/emmet-builders/emmet/builders/vasp/thermo.py +++ b/emmet-builders/emmet/builders/vasp/thermo.py @@ -1,3 +1,4 @@ +import warnings from collections import defaultdict from itertools import chain from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple @@ -137,7 +138,11 @@ def process_item(self, item: List[Dict]): for entry in entries: material_entries[entry.entry_id][entry.data["run_type"]] = entry - pd_entries = self.compatibility.process_entries(entries) + with warnings.catch_warnings(): + warnings.filterwarnings( + "ignore", message="Failed to guess oxidation states.*" + ) + pd_entries = self.compatibility.process_entries(entries) self.logger.debug(f"{len(pd_entries)} remain in {chemsys} after filtering") try: From cb293cd108201555c0595638a94b336d7c9925e9 Mon Sep 17 00:00:00 2001 From: Shyam D Date: Fri, 28 May 2021 15:43:30 -0700 Subject: [PATCH 26/26] fix bad structures into oxidation doc test --- tests/emmet-core/test_oxidation_states.py | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/tests/emmet-core/test_oxidation_states.py b/tests/emmet-core/test_oxidation_states.py index df19ae60bf..7c73fbac71 100644 --- a/tests/emmet-core/test_oxidation_states.py +++ b/tests/emmet-core/test_oxidation_states.py @@ -1,3 +1,4 @@ +import pydantic import pytest from pymatgen.core import Structure from pymatgen.util.testing import PymatgenTest @@ -5,7 +6,7 @@ from emmet.core.oxidation_states import OxidationStateDoc test_structures = { - name: struc + name: struc.get_reduced_structure() for name, struc in PymatgenTest.TEST_STRUCTURES.items() if name in [ @@ -20,14 +21,6 @@ "NaFePO4", "Pb2TiZrO6", "SrTiO3", - ] -} - -fail_structures = { - name: struc - for name, struc in PymatgenTest.TEST_STRUCTURES.items() - if name - in [ "TiO2", "BaNiO3", "VO2", @@ -38,16 +31,6 @@ @pytest.mark.parametrize("structure", test_structures.values()) def test_oxidation_state(structure: Structure): """Very simple test to make sure this actually works""" - + print(f"Should work : {structure.composition}") doc = OxidationStateDoc.from_structure(structure) - print(structure.composition) assert doc is not None - - -@pytest.mark.parametrize("structure", fail_structures.values()) -def test_oxidation_state_failures(structure: Structure): - """Very simple test to make sure this actually fails""" - - doc = OxidationStateDoc.from_structure(structure) - print(structure.composition) - assert doc is None