|
15 | 15 | from jobflow import Flow, Maker
|
16 | 16 | from pymatgen.io.vasp.sets import LobsterSet
|
17 | 17 |
|
| 18 | +from atomate2.common.jobs.utils import remove_workflow_files |
| 19 | +from atomate2.common.utils import _recursive_get_dir_names |
18 | 20 | from atomate2.lobster.jobs import LobsterMaker
|
19 | 21 | from atomate2.vasp.flows.core import DoubleRelaxMaker
|
20 | 22 | from atomate2.vasp.flows.lobster import VaspLobsterMaker
|
21 | 23 | from atomate2.vasp.jobs.mp import (
|
| 24 | + MP24PreRelaxMaker, |
| 25 | + MP24RelaxMaker, |
| 26 | + MP24StaticMaker, |
22 | 27 | MPGGARelaxMaker,
|
23 | 28 | MPGGAStaticMaker,
|
24 | 29 | MPMetaGGARelaxMaker,
|
|
29 | 34 | logger = logging.getLogger(__name__)
|
30 | 35 |
|
31 | 36 | if TYPE_CHECKING:
|
| 37 | + from collections.abc import Sequence |
32 | 38 | from pathlib import Path
|
33 | 39 |
|
34 | 40 | from pymatgen.core.structure import Structure
|
@@ -194,6 +200,95 @@ def make(self, structure: Structure, prev_dir: str | Path | None = None) -> Flow
|
194 | 200 | return Flow(jobs=jobs, output=output, name=self.name)
|
195 | 201 |
|
196 | 202 |
|
| 203 | +@dataclass |
| 204 | +class MP24DoubleRelaxMaker(DoubleRelaxMaker): |
| 205 | + """MP24 PBEsol + r2SCAN double relaxation workflow. |
| 206 | +
|
| 207 | + Parameters |
| 208 | + ---------- |
| 209 | + name : str |
| 210 | + Name of the flows produced by this maker. |
| 211 | + relax_maker1 : .BaseVaspMaker |
| 212 | + Maker to generate the first relaxation. |
| 213 | + relax_maker2 : .BaseVaspMaker |
| 214 | + Maker to generate the second relaxation. |
| 215 | + """ |
| 216 | + |
| 217 | + name: str = "MP24 double relax" |
| 218 | + relax_maker1: Maker | None = field(default_factory=MP24PreRelaxMaker) |
| 219 | + relax_maker2: Maker = field( |
| 220 | + default_factory=lambda: MP24RelaxMaker( |
| 221 | + copy_vasp_kwargs={"additional_vasp_files": ("WAVECAR", "CHGCAR")} |
| 222 | + ) |
| 223 | + ) |
| 224 | + |
| 225 | + |
| 226 | +@dataclass |
| 227 | +class MP24DoubleRelaxStaticMaker(Maker): |
| 228 | + """MP24 workflow to relax a structure with r2SCAN. |
| 229 | +
|
| 230 | + Optionally, files can be automatically cleaned following completion |
| 231 | + of the workflow. By default, WAVECAR files are removed. |
| 232 | +
|
| 233 | + Parameters |
| 234 | + ---------- |
| 235 | + name : str |
| 236 | + Name of the flows produced by this maker. |
| 237 | + relax_maker : .BaseVaspMaker |
| 238 | + Maker to generate the relaxation. |
| 239 | + static_maker : .BaseVaspMaker |
| 240 | + Maker to generate the static calculation before the relaxation. |
| 241 | + clean_files : Sequence of str or None |
| 242 | + If a list of strings, names of files to remove following the workflow. |
| 243 | + By default, this removes the WAVECAR files (gzipped or not). |
| 244 | + """ |
| 245 | + |
| 246 | + name: str = "MP24 r2SCAN workflow" |
| 247 | + relax_maker: Maker = field(default_factory=MP24DoubleRelaxMaker) |
| 248 | + static_maker: Maker = field( |
| 249 | + default_factory=lambda: MP24StaticMaker( |
| 250 | + copy_vasp_kwargs={"additional_vasp_files": ("WAVECAR", "CHGCAR")} |
| 251 | + ) |
| 252 | + ) |
| 253 | + clean_files: Sequence[str] | None = ("WAVECAR",) |
| 254 | + |
| 255 | + def make(self, structure: Structure, prev_dir: str | Path | None = None) -> Flow: |
| 256 | + """Relax a structure with r2SCAN. |
| 257 | +
|
| 258 | + Parameters |
| 259 | + ---------- |
| 260 | + structure : .Structure |
| 261 | + A pymatgen structure object. |
| 262 | + prev_dir : str or Path or None |
| 263 | + A previous VASP calculation directory to copy output files from. |
| 264 | +
|
| 265 | + Returns |
| 266 | + ------- |
| 267 | + Flow |
| 268 | + A flow containing the MP relaxation workflow. |
| 269 | + """ |
| 270 | + relax_flow = self.relax_maker.make(structure=structure, prev_dir=prev_dir) |
| 271 | + |
| 272 | + static_job = self.static_maker.make( |
| 273 | + structure=relax_flow.output.structure, prev_dir=relax_flow.output.dir_name |
| 274 | + ) |
| 275 | + |
| 276 | + jobs = [relax_flow, static_job] |
| 277 | + |
| 278 | + self.clean_files = self.clean_files or [] |
| 279 | + if len(self.clean_files) > 0: |
| 280 | + directories: list[str] = [] |
| 281 | + _recursive_get_dir_names(jobs, directories) |
| 282 | + cleanup = remove_workflow_files( |
| 283 | + directories=directories, |
| 284 | + file_names=self.clean_files, |
| 285 | + allow_zpath=True, |
| 286 | + ) |
| 287 | + jobs += [cleanup] |
| 288 | + |
| 289 | + return Flow(jobs=jobs, output=static_job.output, name=self.name) |
| 290 | + |
| 291 | + |
197 | 292 | # update potcars to 54, use correct W potcar
|
198 | 293 | # use staticmaker for compatibility
|
199 | 294 | @dataclass
|
|
0 commit comments