def test_chem_pot_diag_yaml(cpd, tmpdir): print(tmpdir) tmpdir.chdir() cpd.to_yaml() expected = """H1: energy: 0.0 source: a H4O2: energy: -4.0 source: c O1: energy: 1.0 source: b O2Cl1: energy: 3.0 source: e O2Cl2: energy: 6.0 source: d target: H2O1 vertex_elements: - H - O """ assert Path("cpd.yaml").read_text() == expected actual = ChemPotDiag.from_yaml("cpd.yaml") assert actual == cpd
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_3d(): polygons = { "H": [[0.0, 0.0, -3.3], [0.0, 0.0, -3.0], [0.0, -3.0, 0.0], [0.0, -3.3, 0.0], [0.0, -3.3, -3.3]], "O": [[0.0, 0.0, -3.3], [0.0, 0.0, -3.0], [-3.0, 0.0, 0.0], [-3.3, 0.0, 0.0], [-3.3, 0.0, -3.3]], "N": [[-3.3, 0.0, 0.0], [-3.0, 0.0, 0.0], [0.0, -3.0, 0.0], [0.0, -3.3, 0.0], [-3.3, -3.3, 0.0]], "HON": [[0.0, 0.0, -3.0], [0.0, -3.0, 0.0], [-3.0, 0.0, 0.0]] } return ChemPotDiag(vertex_elements=["H", "O", "N"], polygons=polygons, target="HON", target_vertices_dict={ "A": TargetVertex({ "H": 0.0, "O": 0.0, "N": -3.0 }, ["H", "O"], None), "B": TargetVertex({ "H": 0.0, "O": -3.0, "N": 0.0 }, ["H", "N"], None), "C": TargetVertex({ "H": -3.0, "O": 0.0, "N": 0.0 }, ["O", "N"], None) })
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 test(tmpdir): tmpdir.chdir() tmpdir.join("cpd.yaml").write("""F8: energy: -6.69753983 source: local Mg2F4: energy: -31.54326603 source: local Mg3: energy: -4.50835875 source: local Na1F1: energy: -8.67062716 source: local Na20: energy: -25.85889772 source: local Na4Mg4F12: energy: -98.24594267 source: local target: MgF2 vertex_elements: - Na - Mg - F """) cpd = ChemPotDiag.from_yaml("cpd.yaml") expected = [[0, 0, -6.5404898], [-1.83646145e-01, 0, -6.35684365e+00], [-3.62484384e-01, 0, -6.29723090e+00], [-6.5404898, -12.7136873, 0], [-6.65971529, -12.59446181, 0]] actual = cpd.vertex_coords np.testing.assert_array_almost_equal(expected, actual)
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 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 make_layouts(structure: Structure, dos_plot_data, band_plot_data, perfect_dirname, defect_dirnames, supercell_info, chem_pot_diag): cpd_plot_info = CpdPlotInfo(ChemPotDiag.from_yaml(chem_pot_diag)) perfect: CalcResults = loadfn(perfect_dirname / "calc_results.json") defects, defect_entries, corrections, single_defect_layouts = [], [], [], [] for d in defect_dirnames: #TODO: check convergence defects.append(loadfn(d / "calc_results.json")) defect_entry = loadfn(d / "defect_entry.json") defect_entries.append(defect_entry) corrections.append(loadfn(d / "correction.json")) defect_entry: DefectEntry = loadfn(d / "defect_entry.json") efnv_correction = loadfn(d / "correction.json") eigval = loadfn(d / "band_edge_eigenvalues.json") pot = SitePotentialPlotlyPlotter(title=defect_entry.full_name, efnv_correction=efnv_correction) eig = EigenvaluePlotlyPlotter(title=defect_entry.full_name, band_edge_eigenvalues=eigval, supercell_vbm=perfect.vbm, supercell_cbm=perfect.cbm) scene_dicts = loadfn(d / "parchgs" / "scene_dicts.json") if isinstance(scene_dicts, dict): scene_dicts = SceneDicts.from_dict(scene_dicts) single_defect_layouts.append( SingleDefectComponent(pot, eig, scene_dicts, defect_entry.full_name, id=f"{defect_entry.full_name}").layout()) if cpd_plot_info.cpd.dim in [2, 3]: cpd_energy_comp = CpdEnergy2D3DComponent(cpd_plot_info, perfect, defects, defect_entries, corrections) else: cpd_energy_comp = CpdEnergyOtherComponent(cpd_plot_info, perfect, defects, defect_entries, corrections) structure_component = StructureComponent(structure) comp = structure.composition.reduced_formula band_dos_component = BandDosComponent( dos_plot_data, band_plot_data, id=f"band_dos_{comp}", ) supercell_component = SupercellComponent(supercell_info) symmetrizer = StructureSymmetrizer(structure) return create_ctk(structure_component, symmetry_layout(structure), mpid_and_link(symmetrizer), site_layout(symmetrizer), band_dos_component, supercell_component.layout, cpd_energy_comp.layout, single_defect_layouts)
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 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 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 test_plot_chem_pot_diag(tmpdir): tmpdir.chdir() chem_pot_diag = ChemPotDiag(vertex_elements=["Mg", "O"], polygons={ "Mg": [[0.0, -3.0], [0.0, -1.0]], "O": [[-3.0, 0.0], [-1.0, 0.0]], "MgO": [[-1.0, 0.0], [0.0, -1.0]] }) args = Namespace(chem_pot_diag=chem_pot_diag) plot_chem_pot_diag(args)
def test_cpd_maker_chem_pot_diag(cpd_maker): actual = cpd_maker.chem_pot_diag min_val = -9.0 * 1.1 expected = ChemPotDiag(vertex_elements=["Mg", "O"], polygons={ 'Mg': [[0.0, min_val], [0.0, -4.5]], 'MgO2': [[0.0, -4.5], [-9.0, 0.0]], 'O': [[min_val, 0.0], [-9.0, 0.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 plot_chem_pot_diag(args) -> None: cpd = ChemPotDiag.from_yaml(args.yaml) if cpd.dim == 2: plotter = ChemPotDiagMpl2DMplPlotter(CpdPlotInfo(cpd)) elif cpd.dim == 3: plotter = ChemPotDiagMpl3DMplPlotter(CpdPlotInfo(cpd)) else: raise CpdNotSupportedError("Number of elements must be 2 or 3. " f"Now {cpd.vertex_elements}.") print(cpd) plt = plotter.draw_diagram() plt.savefig(fname="cpd.pdf") plt.show()
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 plot_chem_pot_diag(args) -> None: cpd = ChemPotDiag.from_yaml(args.yaml) if cpd.dim == 1: logger.warning("Single element is not supported for the plot.") return print(cpd) if cpd.dim == 2: plotter = ChemPotDiagMpl2DMplPlotter(CpdPlotInfo(cpd)) elif cpd.dim == 3: plotter = ChemPotDiagMpl3DMplPlotter(CpdPlotInfo(cpd)) else: logger.info("Number of elements must be 2 or 3. " f"Now, elements are {cpd.vertex_elements}.") return plt = plotter.draw_diagram() plt.savefig(fname="cpd.pdf") plt.show()
def make_defect_formation_energy(args): title = latexify( args.perfect_calc_results.structure.composition.reduced_formula) chem_pot_diag = ChemPotDiag.from_yaml(args.chem_pot_diag) abs_chem_pot = chem_pot_diag.abs_chem_pot_dict(args.label) single_energies = [] for d in args.dirs: if args.skip_shallow and loadfn( d / "band_edge_states.json").is_shallow: continue single_energies.append( make_single_defect_energy(args.perfect_calc_results, loadfn(d / "calc_results.json"), loadfn(d / "defect_entry.json"), abs_chem_pot, loadfn(d / "correction.json"))) defect_energies = make_defect_energies(single_energies) if args.print: print(" charge E_f correction ") for e in defect_energies: print(e) print("") print("-- cross points -- ") for e in defect_energies: print(e.name) print(e.cross_points(args.unitcell.vbm, args.unitcell.cbm)) print("") return plotter = DefectEnergyMplPlotter( title=title, defect_energies=defect_energies, vbm=args.unitcell.vbm, cbm=args.unitcell.cbm, supercell_vbm=args.perfect_calc_results.vbm, supercell_cbm=args.perfect_calc_results.cbm, y_range=args.y_range) plotter.construct_plot() plotter.plt.savefig(f"energy_{args.label}.pdf")
def cpd(): min_val = -9.0 * 1.1 return ChemPotDiag(vertex_elements=["Mg", "O"], polygons={ 'Mg': [[0.0, min_val], [0.0, -4.5]], 'MgO2': [[0.0, -4.5], [-9.0, 0.0]], 'O': [[min_val, 0.0], [-9.0, 0.0]] }, target="MgO2", target_vertices={ "A": TargetVertex({ "Mg": 0.0, "O": -4.5, "Al": -1.0 }, ["Mg"], ["MgAlO2"]), "B": TargetVertex({ "Mg": -9.0, "O": 0.0, "Al": -1.0 }, ["O"], ["MgAlO2"]) })
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]: print(cpd.target.elements) print(cpd.dim) print(cpd.target_vertices) print(cpd.all_compounds) print(cpd.impurity_abs_energy(Element.H, label="A")) # In[3]:
# -*- coding: utf-8 -*- # Copyright (c) 2020 Kumagai group. import argparse import sys from pydefect.chem_pot_diag.chem_pot_diag import ChemPotDiag, CpdPlotInfo from pydefect.chem_pot_diag.cpd_plotter import ChemPotDiag3DPlotlyPlotter def parse_args(args): parser = argparse.ArgumentParser(description="") parser.add_argument("-c", "--chem_pot_diag", type=str) parser.add_argument("--port", type=int) return parser.parse_args(args) if __name__ == "__main__": args = parse_args(sys.argv[1:]) cpd = ChemPotDiag.from_yaml(args.chem_pot_diag) print(cpd.target_vertices) print(cpd.vertex_coords) cpd_plot_info = CpdPlotInfo(cpd) print(cpd_plot_info.comp_vertices) plotter = ChemPotDiag3DPlotlyPlotter(cpd_plot_info) fig = plotter.figure fig.show() # ctc.register_crystal_toolkit(app=app, layout=layout, cache=None) # app.run_server(debug=True, port=args.port)
def cpd_plot_info(): cpd = ChemPotDiag(energies, target=Composition("H2O")) return CpdPlotInfo(cpd, min_range=-10)
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 make_defect_formation_energy(args): formula = args.perfect_calc_results.structure.composition.reduced_formula chem_pot_diag = ChemPotDiag.from_yaml(args.cpd_yaml) pcr = args.perfect_calc_results defects, defect_entries, corrections, edge_states = [], [], [], [] for d in args.dirs: if args.skip_shallow: edge_states = BandEdgeStates.from_yaml(d / "band_edge_states.yaml") if edge_states.is_shallow: continue defects.append(loadfn(d / "calc_results.json")) defect_entries.append(loadfn(d / "defect_entry.json")) corrections.append(loadfn(d / "correction.json")) if args.web_gui: from crystal_toolkit.settings import SETTINGS import dash_html_components as html from crystal_toolkit.helpers.layouts import Column import crystal_toolkit.components as ctc import dash edge_states = [] for d in args.dirs: edge_states.append( BandEdgeStates.from_yaml(d / "band_edge_states.yaml")) app = dash.Dash(__name__, suppress_callback_exceptions=True, assets_folder=SETTINGS.ASSETS_PATH, external_stylesheets=[ 'https://codepen.io/chriddyp/pen/bWLwgP.css' ]) cpd_plot_info = CpdPlotInfo(chem_pot_diag) cpd_e_component = CpdEnergyComponent(cpd_plot_info, pcr, defects, defect_entries, corrections, args.unitcell.vbm, args.unitcell.cbm, edge_states) my_layout = html.Div([Column(cpd_e_component.layout)]) ctc.register_crystal_toolkit(app=app, layout=my_layout, cache=None) app.run_server(port=args.port) return abs_chem_pot = chem_pot_diag.abs_chem_pot_dict(args.label) title = " ".join([latexify(formula), "point", args.label]) defect_energies = make_energies(pcr, defects, defect_entries, corrections, abs_chem_pot) if args.print: defect_energies = slide_energy(defect_energies, args.unitcell.vbm) print(" charge E_f correction ") for e in defect_energies: print(e) print("") print("-- cross points -- ") for e in defect_energies: print(e.name) print( e.cross_points(ef_min=args.unitcell.vbm, ef_max=args.unitcell.cbm, base_ef=args.unitcell.vbm)) print("") return plotter = DefectEnergyMplPlotter(title=title, defect_energies=defect_energies, vbm=args.unitcell.vbm, cbm=args.unitcell.cbm, supercell_vbm=pcr.vbm, supercell_cbm=pcr.cbm, y_range=args.y_range, supercell_edge=args.supercell_edge, label_line=args.label_line, add_charges=args.add_charges) plotter.construct_plot() plotter.plt.savefig(f"energy_{args.label}.pdf")
def cpd(): return ChemPotDiag(energies, target=Composition("H2O"), vertex_elements=[Element.H, Element.O])