def defect_energies(): return DefectEnergies( atom_io={"O": -1}, charges=[0, 1, 2], defect_energies=[DefectEnergy(1.0, {"corr": 2.0}, is_shallow=False), DefectEnergy(2.0, {"corr": 2.0}, is_shallow=False), DefectEnergy(3.0, {"corr": 2.0}, is_shallow=True)])
def test_defect_energy_summary_str(): defect_energies = DefectEnergies( atom_io={"O": -1}, charges=[1, 2, 0], defect_energies=[ DefectEnergy(2.0001, {"corr": 2.0001}, is_shallow=False), DefectEnergy(3.0001, {"corr": 2.0001}, is_shallow=True), DefectEnergy(1.0001, {"corr": 2.0001}, is_shallow=False), ]) defect_energy_summary = DefectEnergySummary( title="MgAl2O4", defect_energies={"Va_O1": defect_energies}, rel_chem_pots={"A": {"O": -1.000000001}, "B": {"O": -2.000000001}}, cbm=2.000000001, supercell_vbm=-1.000000001, supercell_cbm=3.000000001) actual = defect_energy_summary.__str__() expected = """title: MgAl₂O₄ rel_chem_pots: -A O: -1.00 -B O: -2.00 vbm: 0.00, cbm: 2.00, supercell vbm: -1.00, supercell_cbm: 3.00 name atom_io charge energy correction is_shallow ------ --------- -------- -------- ------------ ------------ Va_O1 O: -1 0 1.000 2.000 False 1 2.000 2.000 False 2 3.000 2.000 True""" assert actual == expected
def test_generate_defect_energies(): defect_energies = [ SingleDefectEnergy("Va_O1", 0, -1, 1), SingleDefectEnergy("Va_Mg1", 0, -2, 2), SingleDefectEnergy("Va_O1", 1, 7, 3), SingleDefectEnergy("Va_Mg1", -1, -14, 4), SingleDefectEnergy("Va_O1", 2, 15, 5), SingleDefectEnergy("Va_Mg1", -2, -14, 6) ] actual = make_defect_energies(defect_energies) expected = [ DefectEnergy("Va_Mg1", [0, -1, -2], [-2, -14, -14], [2, 4, 6]), DefectEnergy("Va_O1", [0, 1, 2], [-1, 7, 15], [1, 3, 5]) ] assert actual == expected
def test_make_defect_energy_info(mocker): defect_entry = mocker.Mock(DefectEntry, autospec=True) defect_entry.name = "Va_Mg1" defect_entry.charge = -1 calc_results = mocker.Mock(CalcResults, autospec=True) calc_results.structure = IStructure(Lattice.cubic(1.0), ["O"], [[0.0]*3]) calc_results.energy = 10.0 calc_results.electronic_conv = False correction = mocker.Mock(Correction, autospec=True) correction.correction_dict = {"a": 10.0} p_calc_results = mocker.Mock(CalcResults, autospec=True) p_calc_results.structure = IStructure(Lattice.cubic(1.0), ["Mg", "O"], [[0.0]*3]*2) p_calc_results.energy = 1.0 standard_energies = StandardEnergies({"Mg": 10.0, "O": 20.0}) unitcell = mocker.Mock() unitcell.vbm = 100.0 actual = make_defect_energy_info(defect_entry, calc_results, correction, p_calc_results, standard_energies, unitcell) energy = DefectEnergy(formation_energy=10.0 - 1.0 + 10 - 100.0, energy_corrections={"a": 10.0}, is_shallow=None) expected = DefectEnergyInfo(name="Va_Mg1", charge=-1, atom_io={"Mg": -1}, defect_energy=energy) assert actual == expected
def make_defect_energy_info( defect_entry: DefectEntry, calc_results: CalcResults, correction: Correction, perfect_calc_results: CalcResults, standard_energies: StandardEnergies, unitcell: Unitcell, band_edge_states: BandEdgeStates = None) -> DefectEnergyInfo: atom_io = num_atom_differences(calc_results.structure, perfect_calc_results.structure) formation_energy = calc_results.energy - perfect_calc_results.energy formation_energy += defect_entry.charge * unitcell.vbm for k, v in atom_io.items(): formation_energy -= standard_energies[k] * v is_shallow = band_edge_states.is_shallow if band_edge_states else None energy = DefectEnergy(formation_energy=formation_energy, energy_corrections=correction.correction_dict, is_shallow=is_shallow) return DefectEnergyInfo(defect_entry.name, defect_entry.charge, atom_io=atom_io, defect_energy=energy)
def defect_energy_plotters(): va_o = DefectEnergy(name="Va_O1", charges=[0, 1, 2], energies=[5, 2, -5], corrections=[1, 1, 1]) va_mg = DefectEnergy(name="Va_Mg1", charges=[-2, -1, 0], energies=[5, 2, 0], corrections=[-1, -1, -1]) mg_i = DefectEnergy(name="Mg_i1", charges=[1], energies=[4], corrections=[1]) d = dict(title=latexify("MgAl2O4"), defect_energies=[va_o, va_mg, mg_i], vbm=1.5, cbm=5.5, supercell_vbm=1.0, supercell_cbm=6.0) return DefectEnergyMplPlotter(**d), DefectEnergyPlotlyPlotter(**d)
def test_slide_energy(): energies = [ DefectEnergy("Va_Mg1", [0], [0], [0]), DefectEnergy("Va_O1", [1], [0], [0]), DefectEnergy("Va_O2", [2], [0], [0]), DefectEnergy("Mg_i1", [0], [0], [0]) ] actual = slide_energy(energies, 1.0) expected = [ DefectEnergy("Va_Mg1", [0], [0], [0]), DefectEnergy("Va_O1", [1], [1.0], [0]), DefectEnergy("Va_O2", [2], [2.0], [0]), DefectEnergy("Mg_i1", [0], [0], [0]) ] assert actual == expected """
def test_make_defect_energy_summary(mocker): energy1 = DefectEnergy(0.0, {"PC correction": 2.0}, False) energy2 = DefectEnergy(1.0, {"PC correction": 3.0}, True) defect_infos = [ DefectEnergyInfo("Va_Mg1", 0, {"Mg": -1}, energy1), DefectEnergyInfo("Va_Mg1", 1, {"Mg": -1}, energy2) ] target_vertices = TargetVertices(target="MgO", vertices={"A": TargetVertex({"Mg": 5.0})}) unitcell = mocker.Mock() unitcell.vbm = 1.0 unitcell.cbm = 11.0 perf_be_state = mocker.Mock() perf_be_state.vbm_info.energy = 0.0 perf_be_state.cbm_info.energy = 12.0 actual = make_defect_energy_summary(defect_infos, target_vertices, unitcell, perf_be_state) defect_energies = { "Va_Mg1": DefectEnergies(atom_io={"Mg": -1}, charges=[0, 1], defect_energies=[energy1, energy2]) } expected = DefectEnergySummary(title=unitcell.system, defect_energies=defect_energies, rel_chem_pots={"A": { "Mg": 5.0 }}, cbm=10.0, supercell_vbm=-1.0, supercell_cbm=11.0) assert actual == expected
def defect_energy_info2(): energy = DefectEnergy(formation_energy=0.0, energy_corrections={"no correction": 0.0}) return DefectEnergyInfo(name="hole polaron", charge=1, atom_io={}, defect_energy=energy)
def defect_energy(): return DefectEnergy(formation_energy=1.0, energy_corrections={"1st order": 1.0, "alignment": 2.0}, is_shallow=False)
def test_generate_defect_energies(): energies = [ DefectEnergy("Va_Mg1", [0], [0], [0]), DefectEnergy("Va_O1", [0], [0], [0]), DefectEnergy("Va_O2", [0], [0], [0]), DefectEnergy("Mg_i1", [0], [0], [0]), DefectEnergy("O_i1", [0], [0], [0]) ] actual = sanitize_defect_energies_for_plot(energies) expected = [ DefectEnergy("$V_{{\\rm Mg}}$", [0], [0], [0]), DefectEnergy("$V_{{\\rm O}1}$", [0], [0], [0]), DefectEnergy("$V_{{\\rm O}2}$", [0], [0], [0]), DefectEnergy("${\\rm Mg}_{i}$", [0], [0], [0]), DefectEnergy("${\\rm O}_{i}$", [0], [0], [0]) ] assert actual == expected energies = [ DefectEnergy("Mg_i1", [0], [0], [0]), DefectEnergy("Mg_i2", [0], [0], [0]), ] actual = sanitize_defect_energies_for_plot(energies) expected = [ DefectEnergy("${\\rm Mg}_{i1}$", [0], [0], [0]), DefectEnergy("${\\rm Mg}_{i2}$", [0], [0], [0]) ] assert actual == expected energies = [ DefectEnergy("Mg_i1", [0], [0], [0]), DefectEnergy("Mg_i2", [0], [0], [0]), ] actual = sanitize_defect_energies_for_plot(energies, for_plotly=True) expected = [ DefectEnergy("Mg<sub>i1</sub>", [0], [0], [0]), DefectEnergy("Mg<sub>i2</sub>", [0], [0], [0]) ] assert actual == expected
def defect_energy(): return DefectEnergy(name="Va_O1", charges=[0, 1, 2], energies=[4, 2, -4], corrections=[2, 1, 0])
ChemPotDiagMaker if __name__ == "__main__": app = JupyterDash(suppress_callback_exceptions=True, assets_folder=SETTINGS.ASSETS_PATH) # relative_energies = RelativeEnergies({"MgCaO2": -100.0}) relative_energies = RelativeEnergies({"MgCaBaO2": -100.0}) # cpd = ChemPotDiagMaker(relative_energies, # elements=["Mg", "Ca", "O"], # target="MgCaO2").chem_pot_diag cpd = ChemPotDiagMaker(relative_energies, elements=["Mg", "Ca", "Ba", "O"], target="MgCaBaO2").chem_pot_diag energy = DefectEnergy(0.0, {"corr": 1.0}, is_shallow=False) defect_energy_summary = DefectEnergySummary( title="test", defect_energies={ "Va_O1": DefectEnergies(atom_io={"O": -1}, charges=[0], defect_energies=[energy]) }, rel_chem_pots=cpd.to_target_vertices.chem_pots, cbm=2.0, supercell_vbm=-0.2, supercell_cbm=2.2) cpd_e_component = CpdEnergyComponent(cpd, defect_energy_summary)