diff --git a/autoplex/auto/flows.py b/autoplex/auto/flows.py index 2a1d0ad3b..653622b22 100644 --- a/autoplex/auto/flows.py +++ b/autoplex/auto/flows.py @@ -11,7 +11,6 @@ from emmet.core.math import Matrix3D from pymatgen.core.structure import Structure -from atomate2.vasp.flows.phonons import PhononMaker as DFTPhononMaker from jobflow import Flow, Maker from autoplex.auto.jobs import ( @@ -22,7 +21,7 @@ ) from autoplex.benchmark.flows import PhononBenchmarkMaker from autoplex.benchmark.jobs import write_benchmark_metrics -from autoplex.data.flows import TightDFTStaticMaker +from autoplex.data.flows import DFTPhononMaker, TightDFTStaticMaker from autoplex.fitting.flows import MLIPFitMaker __all__ = [ diff --git a/autoplex/data/flows.py b/autoplex/data/flows.py index cb4fb1326..30f3d0971 100644 --- a/autoplex/data/flows.py +++ b/autoplex/data/flows.py @@ -14,8 +14,10 @@ PhononDisplacementMaker, run_phonon_displacements, ) -from atomate2.vasp.jobs.core import StaticMaker -from atomate2.vasp.sets.core import StaticSetGenerator +from atomate2.vasp.flows.core import DoubleRelaxMaker +from atomate2.vasp.flows.phonons import PhononMaker +from atomate2.vasp.jobs.core import StaticMaker, TightRelaxMaker +from atomate2.vasp.sets.core import StaticSetGenerator, TightRelaxSetGenerator from jobflow import Flow, Maker from phonopy.structure.cells import get_supercell from pymatgen.core import Molecule, Site @@ -24,6 +26,7 @@ from autoplex.data.jobs import generate_randomized_structures __all__ = [ + "DFTPhononMaker", "IsoAtomMaker", "IsoAtomStaticMaker", "RandomStructuresDataGenerator", @@ -83,6 +86,117 @@ class TightDFTStaticMaker(PhononDisplacementMaker): ) +@dataclass +class DFTPhononMaker(PhononMaker): + """ + Adapted PhononMaker to calculate harmonic phonons with VASP and Phonopy. + + The input set used is same as PhononMaker from atomate2. + Only difference is Spin polarization is switched off and Gaussian smearing is used + + Parameters + ---------- + name : str = "phonon" + Name of the flows produced by this maker. + sym_reduce : bool = True + Whether to reduce the number of deformations using symmetry. + symprec : float = 1e-4 + Symmetry precision to use in the + reduction of symmetry to find the primitive/conventional cell + (use_primitive_standard_structure, use_conventional_standard_structure) + and to handle all symmetry-related tasks in phonopy + displacement: float = 0.01 + displacement distance for phonons + min_length: float = 20.0 + min length of the supercell that will be built + prefer_90_degrees: bool = True + if set to True, supercell algorithm will first try to find a supercell + with 3 90 degree angles + get_supercell_size_kwargs: dict = {} + kwargs that will be passed to get_supercell_size to determine supercell size + use_symmetrized_structure: str or None = None + allowed strings: "primitive", "conventional", None + + - "primitive" will enforce to start the phonon computation + from the primitive standard structure + according to Setyawan, W., & Curtarolo, S. (2010). + High-throughput electronic band structure calculations: + Challenges and tools. Computational Materials Science, + 49(2), 299-312. doi:10.1016/j.commatsci.2010.05.010. + This makes it possible to use certain k-path definitions + with this workflow. Otherwise, we must rely on seekpath + - "conventional" will enforce to start the phonon computation + from the conventional standard structure + according to Setyawan, W., & Curtarolo, S. (2010). + High-throughput electronic band structure calculations: + Challenges and tools. Computational Materials Science, + 49(2), 299-312. doi:10.1016/j.commatsci.2010.05.010. + We will however use seekpath and primitive structures + as determined by from phonopy to compute the phonon band structure + bulk_relax_maker : .BaseVaspMaker or None + A maker to perform a tight relaxation on the bulk. + Set to ``None`` to skip the + bulk relaxation + static_energy_maker : .BaseVaspMaker or None + A maker to perform the computation of the DFT energy on the bulk. + Set to ``None`` to skip the + static energy computation + born_maker: .BaseVaspMaker or None + Maker to compute the BORN charges. + phonon_displacement_maker : .BaseVaspMaker or None + Maker used to compute the forces for a supercell. + generate_frequencies_eigenvectors_kwargs : dict + Keyword arguments passed to :obj:`generate_frequencies_eigenvectors`. + create_thermal_displacements: bool + Arg that determines if thermal_displacement_matrices are computed + kpath_scheme: str = "seekpath" + scheme to generate kpoints. Please be aware that + you can only use seekpath with any kind of cell + Otherwise, please use the standard primitive structure + Available schemes are: + "seekpath", "hinuma", "setyawan_curtarolo", "latimer_munro". + "seekpath" and "hinuma" are the same definition but + seekpath can be used with any kind of unit cell as + it relies on phonopy to handle the relationship + to the primitive cell and not pymatgen + code: str = "vasp" + determines the DFT code. currently only vasp is implemented. + This keyword might enable the implementation of other codes + in the future + store_force_constants: bool + if True, force constants will be stored + """ + + name: str = "phonon" + sym_reduce: bool = True + symprec: float = 1e-4 + displacement: float = 0.01 + min_length: float | None = 20.0 + prefer_90_degrees: bool = True + get_supercell_size_kwargs: dict = field(default_factory=dict) + use_symmetrized_structure: str | None = None + bulk_relax_maker: BaseVaspMaker | None = field( + default_factory=lambda: DoubleRelaxMaker.from_relax_maker( + TightRelaxMaker( + input_set_generator=TightRelaxSetGenerator( + user_incar_settings={"ISPIN": 1, "LAECHG": False, "ISMEAR": 0} + ) + ) + ), + ) + static_energy_maker: BaseVaspMaker | None = field( + default_factory=lambda: StaticMaker( + input_set_generator=StaticSetGenerator( + auto_ispin=False, + user_incar_settings={"ISPIN": 1, "LAECHG": False, "ISMEAR": 0}, + ) + ) + ) + phonon_displacement_maker: BaseVaspMaker = field( + default_factory=TightDFTStaticMaker + ) + + @dataclass class IsoAtomStaticMaker(StaticMaker): """ diff --git a/tests/auto/test_auto_flows.py b/tests/auto/test_auto_flows.py index 7fb20cd26..7425b98ed 100644 --- a/tests/auto/test_auto_flows.py +++ b/tests/auto/test_auto_flows.py @@ -85,8 +85,8 @@ def test_complete_dft_vs_ml_benchmark_workflow( } fake_run_vasp_kwargs = { - "tight relax 1": {"incar_settings": ["NSW"]}, - "tight relax 2": {"incar_settings": ["NSW"]}, + "tight relax 1": {"incar_settings": ["NSW", "ISMEAR"]}, + "tight relax 2": {"incar_settings": ["NSW", "ISMEAR"]}, "phonon static 1/2": {"incar_settings": ["NSW", "ISMEAR"]}, "phonon static 2/2": {"incar_settings": ["NSW", "ISMEAR"]}, "phonon static 1/3": { @@ -356,10 +356,10 @@ def test_phonon_dft_ml_data_generation_flow( } fake_run_vasp_kwargs = { - "tight relax 1": {"incar_settings": ["NSW"]}, - "tight relax 2": {"incar_settings": ["NSW"]}, + "tight relax 1": {"incar_settings": ["NSW", "ISMEAR"]}, + "tight relax 2": {"incar_settings": ["NSW", "ISMEAR"]}, "phonon static 1/2": {"incar_settings": ["NSW", "ISMEAR"]}, - "phonon static 2/2": {"incar_settings": ["NSW"]}, + "phonon static 2/2": {"incar_settings": ["NSW", "ISMEAR"]}, "phonon static 1/3": { "incar_settings": ["NSW", "ISMEAR"], "check_inputs": ["incar", "kpoints", "potcar"],