def cpd(): return ChemPotDiag([ CompositionEnergy(Composition('O8'), -39.58364375, "mp-1"), CompositionEnergy(Composition('Mg3'), -4.79068775, "mp-2"), CompositionEnergy(Composition('Mg1O1'), -11.96742144, "mp-3") ], target=Composition("MgO"))
def cpd_plot_info_2d(): energies = [ CompositionEnergy(Composition("H"), 0.0, ""), CompositionEnergy(Composition("O"), 1.0, ""), CompositionEnergy(Composition("H4O2"), -4.0, "") ] cpd = ChemPotDiag(energies, target=Composition("H2O")) return CpdPlotInfo(cpd, min_range=-10)
def comp_energies(): return CompositionEnergies({ Composition('O8'): CompositionEnergy(-39.58364375, "mp-1"), Composition('Mg3'): CompositionEnergy(-4.79068775, "mp-2"), Composition('Mg1O1'): CompositionEnergy(-11.96742144, "mp-3") })
def comp_energies_corr(): return CompositionEnergies({ Composition('O8'): CompositionEnergy(-39.58364375 + diff["O"] * 8, "mp-1"), Composition('Mg3'): CompositionEnergy(-4.79068775 + diff["Mg"] * 3, "mp-2"), Composition('Mg1O1'): CompositionEnergy(-11.96742144 + diff["Mg"] + diff["O"], "mp-3") })
def cpd_corr(): return ChemPotDiag([ CompositionEnergy(Composition('O8'), -39.58364375 + diff["O"] * 8, "mp-1"), CompositionEnergy(Composition('Mg3'), -4.79068775 + diff["Mg"] * 3, "mp-2"), CompositionEnergy(Composition('Mg1O1'), -11.96742144 + diff["Mg"] + diff["O"], "mp-3") ], target=Composition("MgO"))
def cpd2(): energies_here = [ CompositionEnergy(Composition("H"), 0.0, "a"), CompositionEnergy(Composition("H4O2"), -4.0, "c"), CompositionEnergy(Composition("O"), 1.0, "b"), CompositionEnergy(Composition("Cl2"), 3.0, "e"), ] return ChemPotDiag(energies_here, target=Composition("H2O"), vertex_elements=[Element.H, Element.O])
def test_remove_higher_energy_comp(): comp_es = CompositionEnergies( {Composition('Mg1'): CompositionEnergy(-1.9, "mp-2"), Composition('Mg2'): CompositionEnergy(-4.0, "mp-3"), Composition('O2'): CompositionEnergy(-4.0, "mp-4")}) actual = remove_higher_energy_comp(comp_es) expected = CompositionEnergies( {Composition('Mg2'): CompositionEnergy(-4.0, "mp-3"), Composition('O2'): CompositionEnergy(-4.0, "mp-4"),}) assert actual == expected
def test_remove_higher_energy_comp(): comp_es = [ CompositionEnergy(Composition('O2'), -2.1, "mp-1"), CompositionEnergy(Composition('O4'), -4.0, "mp-2"), CompositionEnergy(Composition('Mg1'), -10, "mp-3") ] actual = remove_higher_energy_comp(comp_es) expected = [ CompositionEnergy(Composition('O2'), -2.1, "mp-1"), CompositionEnergy(Composition('Mg1'), -10, "mp-3") ] assert actual == expected
def make_chem_pot_diag_from_mp(target: Union[Composition, str], additional_elements: List[str] = None, vertex_elements: List[str] = None, atom_energy_yaml: Optional[str] = None): """Obtain the energies from Materials Project.""" properties = ["task_id", "full_formula", "final_energy"] target = target if isinstance(target, Composition) else Composition(target) elements = target.chemical_system.split("-") vertex_elements = vertex_elements or elements vertex_elements = [Element(e) for e in vertex_elements] if additional_elements: elements.extend(additional_elements) query = MpQuery(elements, properties=properties) comp_es = [] if atom_energy_yaml: if ".yaml" in atom_energy_yaml: energies = loadfn(atom_energy_yaml) else: logger.info(f"Atom energy set for {atom_energy_yaml} is used.") energies = AtomEnergyType.from_string(atom_energy_yaml).energies diff = {e: energies[e] - mp_energies[e] for e in elements} else: diff = None for m in query.materials: energy = m["final_energy"] if diff: for k, v in Composition(m["full_formula"]).as_dict().items(): energy += diff[k] * v comp_es.append( CompositionEnergy(Composition(m["full_formula"]), energy, m["task_id"])) comp_es = remove_higher_energy_comp(comp_es) return ChemPotDiag(comp_es, target, vertex_elements)
def make_composition_energies_from_mp( elements: List[str], atom_energy_yaml: Optional[str] = None, ) -> CompositionEnergies: """Obtain the energies from Materials Project. When the atom_energy_yaml is provided, the total energies are aligned via atom energies. """ properties = ["task_id", "full_formula", "final_energy"] query = MpQuery(elements, properties=properties) comp_es = {} if atom_energy_yaml: energies = loadfn(atom_energy_yaml) diff = {e: energies[e] - mp_energies[e] for e in elements} else: diff = {e: 0.0 for e in elements} for m in query.materials: key = Composition(m["full_formula"]) energy = m["final_energy"] for k, v in key.as_dict().items(): energy += diff[k] * v comp_es[key] = CompositionEnergy(energy, m["task_id"]) print(comp_es) comp_es = remove_higher_energy_comp(comp_es) print(comp_es) return CompositionEnergies(comp_es)
def make_composition_energies(args): if args.yaml_file: composition_energies = CompositionEnergies.from_yaml(args.yaml_file) else: composition_energies = CompositionEnergies() for d in args.dirs: vasprun = Vasprun(d / defaults.vasprun) composition = vasprun.final_structure.composition energy = float(vasprun.final_energy) # original type is FloatWithUnit composition_energies[composition] = CompositionEnergy(energy, "local") composition_energies.to_yaml_file()
def make_composition_energies(args): if args.yaml_file: composition_energies = CompositionEnergies.from_yaml(args.yaml_file) else: composition_energies = CompositionEnergies() for d in args.dirs: outcar = Outcar(d / defaults.outcar) composition = Structure.from_file(d / defaults.contcar).composition energy = float(outcar.final_energy) # original type is FloatWithUnit composition_energies[composition] = CompositionEnergy(energy, "local") composition_energies.to_yaml_file()
def test_host_ele_abs_energies_per_atom_2(): energies_with_cl = deepcopy(energies) energies_with_cl.append(CompositionEnergy(Composition("Cl"), 10.0, "z")) cpd = ChemPotDiag(energies_with_cl, target=Composition("H2O"), vertex_elements=[Element.H, Element.O, Element.Cl]) assert cpd.vertex_elements_abs_energies_per_atom == { Composition("H2"): 0.0, Composition("O2"): 1.0, Composition("H2O"): -2 / 3, Composition("ClO"): 1.5, Composition("ClO2"): 1.0, Composition("Cl2"): 10.0 }
def test_composition_energies_from_mp(mocker, tmpdir): tmpdir.chdir() args = Namespace(elements=["H"], atom_energy_yaml="a.yaml") mock = mocker.patch( "pydefect.cli.main_util_functions.make_composition_energies_from_mp") mock.return_value = CompositionEnergies( {Composition("H"): CompositionEnergy(1.0, "mp-1")}) composition_energies_from_mp(args) mock.assert_called_once_with(elements=["H"], atom_energy_yaml="a.yaml") actual = Path("composition_energies.yaml").read_text() expected = """H1: energy: 1.0 source: mp-1 """ assert actual == expected
def test_make_standard_and_relative_energies(mocker, tmpdir): tmpdir.chdir() args = Namespace(composition_energies_yaml="a.yaml") mock = mocker.patch("pydefect.cli.main_functions.CompositionEnergies") mock.from_yaml.return_value = CompositionEnergies({ Composition("H"): CompositionEnergy(-1.0), Composition("He"): CompositionEnergy(-2.0), Composition("HHe"): CompositionEnergy(-5.0) }) make_standard_and_relative_energies(args) mock.from_yaml.assert_called_once_with("a.yaml") actual = Path("standard_energies.yaml").read_text() expected = """H: -1.0 He: -2.0 """ assert actual == expected actual = Path("relative_energies.yaml").read_text() expected = """HHe: -1.0 """ assert actual == expected
def cpd_3d_info(): energies = [ CompositionEnergy(Composition("H"), 0.0, ""), CompositionEnergy(Composition("O"), 1.0, ""), CompositionEnergy(Composition("H4O2"), -4.0, ""), CompositionEnergy(Composition("MgH2O"), -10.0, ""), CompositionEnergy(Composition("Mg"), 0.0, ""), CompositionEnergy(Composition("MgO"), -3.0, "") ] cpd = ChemPotDiag(energies, target=Composition("MgH2O")) return CpdPlotInfo(cpd)
def test_replace_comp_energy(): cpd = ChemPotDiag([ CompositionEnergy(Composition("H"), 0.0, "a"), CompositionEnergy(Composition("O"), 1.0, "b"), CompositionEnergy(Composition("F"), 1.0, "c") ], target={"H": 1}) replace_comp_energy(cpd, [ CompositionEnergy(Composition("H"), -1.0, "x"), CompositionEnergy(Composition("O"), 0.0, "y") ]) expected = ChemPotDiag([ CompositionEnergy(Composition("H"), -1.0, "x"), CompositionEnergy(Composition("O"), 0.0, "y"), CompositionEnergy(Composition("F"), 1.0, "c") ], target={"H": 1}) assert cpd == expected
def make_chem_pot_diag(args) -> None: if args.elements: cpd = make_chem_pot_diag_from_mp(additional_elements=args.elements, target=args.target, atom_energy_yaml=args.atom_energy_yaml) else: comp_es = [] for d in args.dirs: vasprun = Vasprun(d / defaults.vasprun) composition = vasprun.final_structure.composition energy = float(vasprun.final_energy) # type is FloatWithUnit comp_es.append(CompositionEnergy(composition, energy, "local")) if args.update: cpd = ChemPotDiag.from_yaml(args.yaml) replace_comp_energy(cpd, comp_es) else: cpd = ChemPotDiag(comp_es, args.target) cpd.to_yaml(args.yaml)
def composition_energies(): return CompositionEnergies({ Composition("H"): CompositionEnergy(0.0, "a"), Composition("H4O2"): CompositionEnergy(-4.0, "c"), Composition("O"): CompositionEnergy(1.0, "b"), Composition("Cl"): CompositionEnergy(12.0, "f"), Composition("O2Cl"): CompositionEnergy(3.0, "e"), Composition("O2Cl2"): CompositionEnergy(6.0, "d") })
def make_composition_energies_from_mp(elements: List[str], atom_energy_yaml: Optional[str] = None, ) -> CompositionEnergies: """Obtain the energies from Materials Project. When the atom_energy_yaml is provided, the total energies are aligned via atom energies. """ entries: List[ComputedEntry] = MpEntries(elements).materials comp_es = {} if atom_energy_yaml: energies = loadfn(atom_energy_yaml) diff = {e: energies[e] - mp_energies[e] for e in elements} else: diff = {e: 0.0 for e in elements} for e in entries: key = e.composition energy = e.energy for k, v in key.as_dict().items(): energy += diff[k] * v comp_es[key] = CompositionEnergy(energy, e.entry_id) comp_es = remove_higher_energy_comp(comp_es) return CompositionEnergies(comp_es)
# -*- coding: utf-8 -*- # Copyright (c) 2020. Distributed under the terms of the MIT License. from copy import deepcopy from pathlib import Path import numpy as np import pandas as pd import pytest from pydefect.chem_pot_diag.chem_pot_diag import ChemPotDiag, CpdPlotInfo, \ NoElementEnergyError, CompositionEnergy, replace_comp_energy # When same keys are inserted, only the latter one is accepted. from pydefect.tests.helpers.assertion import assert_msonable from pymatgen import Composition, Element energies = [ CompositionEnergy(Composition("H"), 0.0, "a"), CompositionEnergy(Composition("H4O2"), -4.0, "c"), CompositionEnergy(Composition("O"), 1.0, "b"), CompositionEnergy(Composition("O2Cl"), 3.0, "e"), CompositionEnergy(Composition("O2Cl2"), 6.0, "d"), ] @pytest.fixture def cpd(): return ChemPotDiag(energies, target=Composition("H2O"), vertex_elements=[Element.H, Element.O]) def test_print(cpd):
def test_impurity_rel_energy(cpd_h2o): expected = CompositionEnergy(Composition("Cl2O2"), 6.0, 'd'), -7.0 assert cpd_h2o.impurity_rel_energy(Element.Cl, "A") == expected
def test_cpd_plot_info_lacking_element_data(): new_energies = deepcopy(energies) new_energies.append(CompositionEnergy(Composition("MgO"), -3.0, "f")) with pytest.raises(NoElementEnergyError): ChemPotDiag(new_energies, target={"Mg": 1, "O": 1}).offset_to_abs
def test_impurity_abs_energy(cpd): expected = CompositionEnergy(Composition("Cl2O2"), 6.0, 'd'), 5.0 assert cpd.impurity_abs_energy(Element.Cl, "A") == expected
from pydefect.analyzer.dash_components.cpd_energy_dash import CpdEnergyComponent from pydefect.chem_pot_diag.chem_pot_diag import ChemPotDiag, CpdPlotInfo, CompositionEnergy from pydefect.corrections.manual_correction import ManualCorrection from pydefect.input_maker.defect_entry import DefectEntry from pymatgen import Composition, Structure, Lattice, Element import dash_html_components as html import crystal_toolkit.components as ctc from dash.dependencies import Input, Output, State import json app = JupyterDash(suppress_callback_exceptions=True, assets_folder=SETTINGS.ASSETS_PATH) from vise.analyzer.band_edge_properties import BandEdge comp_energies = [ CompositionEnergy(Composition("Mg"), 0.0, "a"), CompositionEnergy(Composition("Ca"), 0.0, "a"), CompositionEnergy(Composition("Sr"), 0.0, "a"), CompositionEnergy(Composition("O"), 0.0, "a"), CompositionEnergy(Composition("H"), 0.0, "a"), # CompositionEnergy(Composition("MgCaO3"), -100.0, "a"), CompositionEnergy(Composition("MgCaSrO3"), -100.0, "a"), ] #cpd = ChemPotDiag(comp_energies, target=Composition("MgCaO3")) cpd = ChemPotDiag(comp_energies, target=Composition("MgCaSrO3")) cpd_plot_info = CpdPlotInfo(cpd) # In[2]:
def test_composition_energies_from_dict(): actual = CompositionEnergies.from_dict({"Mg": -1.0}) expected = CompositionEnergies( {Composition("Mg"): CompositionEnergy(-1.0)}) assert actual == expected actual = actual.std_rel_energies
def test_impurity_abs_energy2(cpd2): expected = CompositionEnergy(Composition("Cl2"), 3.0, 'e'), 1.5 assert cpd2.impurity_abs_energy(Element.Cl, "A") == expected
def test_composition_roundtrip(cpd): comp_e = CompositionEnergy(Composition("H"), 0.0, "a") rounded_comp_e = comp_e.__class__.from_dict(comp_e.as_dict()) assert comp_e == rounded_comp_e