|
6 | 6 | import numpy as np
|
7 | 7 | import pytest
|
8 | 8 | from emmet.core.tasks import TaskDoc
|
| 9 | +from emmet.core.thermo import ThermoType |
9 | 10 | from emmet.core.vasp.calc_types import CalcType
|
10 | 11 | from pymatgen.analysis.phase_diagram import PhaseDiagram
|
11 | 12 | from pymatgen.analysis.pourbaix_diagram import IonEntry, PourbaixDiagram, PourbaixEntry
|
|
18 | 19 | BandStructureSymmLine,
|
19 | 20 | )
|
20 | 21 | from pymatgen.electronic_structure.dos import CompleteDos
|
21 |
| -from pymatgen.entries.compatibility import MaterialsProjectAqueousCompatibility |
| 22 | +from pymatgen.entries.compatibility import ( |
| 23 | + MaterialsProjectAqueousCompatibility, |
| 24 | + MaterialsProject2020Compatibility, |
| 25 | +) |
| 26 | +from pymatgen.entries.mixing_scheme import MaterialsProjectDFTMixingScheme |
22 | 27 | from pymatgen.entries.computed_entries import ComputedEntry, GibbsComputedStructureEntry
|
23 | 28 | from pymatgen.io.cif import CifParser
|
24 | 29 | from pymatgen.io.vasp import Chgcar
|
@@ -429,3 +434,78 @@ def test_get_cohesive_energy(self):
|
429 | 434 | assert all(
|
430 | 435 | v == pytest.approx(e_coh["noserial"][k]) for k, v in e_coh["serial"].items()
|
431 | 436 | )
|
| 437 | + |
| 438 | + @pytest.mark.parametrize( |
| 439 | + "chemsys, thermo_type", |
| 440 | + [ |
| 441 | + [("Fe", "P"), "GGA_GGA+U"], |
| 442 | + [("Li", "S"), ThermoType.GGA_GGA_U_R2SCAN], |
| 443 | + [("Ni", "Se"), ThermoType.R2SCAN], |
| 444 | + [("Ni", "Kr"), "R2SCAN"], |
| 445 | + ], |
| 446 | + ) |
| 447 | + def test_get_stability(self, chemsys, thermo_type): |
| 448 | + """ |
| 449 | + This test is adapted from the pymatgen one - the scope is broadened |
| 450 | + to include more diverse chemical environments and thermo types which |
| 451 | + reflect the scope of the current MP database. |
| 452 | + """ |
| 453 | + with MPRester() as mpr: |
| 454 | + entries = mpr.get_entries_in_chemsys( |
| 455 | + chemsys, additional_criteria={"thermo_types": [thermo_type]} |
| 456 | + ) |
| 457 | + |
| 458 | + no_compound_entries = all( |
| 459 | + len(entry.composition.elements) == 1 for entry in entries |
| 460 | + ) |
| 461 | + |
| 462 | + modified_entries = [ |
| 463 | + ComputedEntry( |
| 464 | + entry.composition, |
| 465 | + entry.uncorrected_energy + 0.01, |
| 466 | + parameters=entry.parameters, |
| 467 | + entry_id=f"mod_{entry.entry_id}", |
| 468 | + ) |
| 469 | + for entry in entries |
| 470 | + if entry.composition.reduced_formula in ["Fe2P", "".join(chemsys)] |
| 471 | + ] |
| 472 | + |
| 473 | + if len(modified_entries) == 0: |
| 474 | + # create fake entry to get PD retrieval to fail |
| 475 | + modified_entries = [ |
| 476 | + ComputedEntry( |
| 477 | + "".join(chemsys), |
| 478 | + np.average([entry.energy for entry in entries]), |
| 479 | + entry_id=f"hypothetical", |
| 480 | + ) |
| 481 | + ] |
| 482 | + |
| 483 | + if no_compound_entries: |
| 484 | + with pytest.warns(UserWarning, match="No phase diagram data available"): |
| 485 | + mpr.get_stability(modified_entries, thermo_type=thermo_type) |
| 486 | + return |
| 487 | + |
| 488 | + else: |
| 489 | + rester_ehulls = mpr.get_stability( |
| 490 | + modified_entries, thermo_type=thermo_type |
| 491 | + ) |
| 492 | + |
| 493 | + all_entries = entries + modified_entries |
| 494 | + |
| 495 | + compat = None |
| 496 | + if thermo_type == "GGA_GGA+U": |
| 497 | + compat = MaterialsProject2020Compatibility() |
| 498 | + elif thermo_type == "GGA_GGA+U_R2SCAN": |
| 499 | + compat = MaterialsProjectDFTMixingScheme(run_type_2="r2SCAN") |
| 500 | + |
| 501 | + if compat: |
| 502 | + all_entries = compat.process_entries(all_entries) |
| 503 | + |
| 504 | + pd = PhaseDiagram(all_entries) |
| 505 | + for entry in all_entries: |
| 506 | + if str(entry.entry_id).startswith("mod"): |
| 507 | + for dct in rester_ehulls: |
| 508 | + if dct["entry_id"] == entry.entry_id: |
| 509 | + data = dct |
| 510 | + break |
| 511 | + assert pd.get_e_above_hull(entry) == pytest.approx(data["e_above_hull"]) |
0 commit comments