Skip to content

Commit 4390eeb

Browse files
authored
Merge pull request #155 from matk86/leps
refactor LepsFW
2 parents be8e5aa + d1c8140 commit 4390eeb

File tree

2 files changed

+111
-22
lines changed

2 files changed

+111
-22
lines changed

atomate/vasp/fireworks/core.py

Lines changed: 107 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
sequences of VASP calculations.
88
"""
99

10+
from monty.dev import deprecated
11+
1012
from fireworks import Firework
1113

1214
from pymatgen import Structure
@@ -176,6 +178,7 @@ def __init__(self, structure, name="nscf", mode="uniform", vasp_cmd="vasp",
176178
structure.composition.reduced_formula, name, mode), **kwargs)
177179

178180

181+
@deprecated(None, " This firework will be removed soon. Use DFPTFW and/or RamanFW fireworks.")
179182
class LepsFW(Firework):
180183
def __init__(self, structure, name="static dielectric", vasp_cmd="vasp", copy_vasp_outputs=True,
181184
db_file=None, parents=None, phonon=False, mode=None, displacement=None,
@@ -184,7 +187,7 @@ def __init__(self, structure, name="static dielectric", vasp_cmd="vasp", copy_va
184187
Standard static calculation Firework for dielectric constants using DFPT.
185188
186189
Args:
187-
structure (Structure): Input structure. If copy_vasp_outputs, used only to set the
190+
structure (Structure): Input structure. If copy_vasp_outputs, used only to set the
188191
name of the FW.
189192
name (str): Name for the Firework.
190193
vasp_cmd (str): Command to run vasp.
@@ -217,30 +220,13 @@ def __init__(self, structure, name="static dielectric", vasp_cmd="vasp", copy_va
217220

218221
if phonon:
219222
if mode is None and displacement is None:
220-
# TODO: @matk86 - I really don't understand the point of setting phonon=True w/o
221-
# the mode or displacement. It seems to simply be running a regular static run and
222-
# doing nothing else than changing the name of the Firework and perhaps passing
223-
# normal modes data (but it's unclear how that data is generated. Why would anyone
224-
# want to do this? -computron
225223
name = "{} {}".format("phonon", name)
226-
227-
# TODO: @matk86 - not sure why this line is here. I understand you are trying to
228-
# keep the code short but the logic is very confusing. The RunVaspCustodian is
229-
# common to all 3 situations (phonon=F, phonon=T/mode=F, phonon=T/mode=T) yet is
230-
# duplicated in each place. Instead, for better clarity construct the Firework
231-
# sequentially (write inputs, run vasp, parse output data, pass output data) and
232-
# add if/else for phonons where it is needed. Any name overrides can go near the
233-
# top of the Firework. -computron
234224
t.append(RunVaspCustodian(vasp_cmd=vasp_cmd))
235225
t.append(pass_vasp_result({"structure": "a>>final_structure",
236226
"eigenvals": "a>>normalmode_eigenvals",
237227
"eigenvecs": "a>>normalmode_eigenvecs"}, parse_eigen=True,
238228
mod_spec_key="normalmodes"))
239229
else:
240-
# TODO: @matk86 - Why is this second calculation being tacked on to the first one?
241-
# It looks like it will overwrite INCAR/CHGCAR/etc of the first calculation and
242-
# thus completely remove access to the original output files. Shouldn't this be a
243-
# new Firework rather than a second calculation in the same Firework? -computron
244230
name = "raman_{}_{} {}".format(str(mode), str(displacement), name)
245231
key = "{}_{}".format(mode, displacement).replace('-', 'm').replace('.', 'd')
246232
pass_fw = pass_vasp_result(pass_dict={"mode": mode, "displacement": displacement,
@@ -259,6 +245,109 @@ def __init__(self, structure, name="static dielectric", vasp_cmd="vasp", copy_va
259245
structure.composition.reduced_formula, name), **kwargs)
260246

261247

248+
class DFPTFW(Firework):
249+
def __init__(self, structure, name="static dielectric", vasp_cmd="vasp", copy_vasp_outputs=True,
250+
db_file=None, parents=None, user_incar_settings=None, pass_nm_results=False, **kwargs):
251+
252+
"""
253+
Static DFPT calculation Firework
254+
255+
Args:
256+
structure (Structure): Input structure. If copy_vasp_outputs, used only to set the
257+
name of the FW.
258+
name (str): Name for the Firework.
259+
vasp_cmd (str): Command to run vasp.
260+
copy_vasp_outputs (bool): Whether to copy outputs from previous
261+
run. Defaults to True.
262+
db_file (str): Path to file specifying db credentials.
263+
parents (Firework): Parents of this particular Firework.
264+
FW or list of FWS.
265+
user_incar_settings (dict): Parameters in INCAR to override
266+
pass_nm_results (bool): if true the normal mode eigen vals and vecs are passed so that
267+
next firework can use it.
268+
\*\*kwargs: Other kwargs that are passed to Firework.__init__.
269+
"""
270+
271+
name = "{} {}".format("phonon", name)
272+
273+
user_incar_settings = user_incar_settings or {}
274+
t = []
275+
276+
if copy_vasp_outputs:
277+
t.append(CopyVaspOutputs(calc_loc=True, contcar_to_poscar=True))
278+
t.append(WriteVaspStaticFromPrev(lepsilon=True, other_params={'user_incar_settings': user_incar_settings}))
279+
else:
280+
vasp_input_set = MPStaticSet(structure, lepsilon=True, user_incar_settings=user_incar_settings)
281+
t.append(WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set))
282+
283+
t.append(RunVaspCustodian(vasp_cmd=vasp_cmd))
284+
285+
if pass_nm_results:
286+
t.append(pass_vasp_result({"structure": "a>>final_structure",
287+
"eigenvals": "a>>normalmode_eigenvals",
288+
"eigenvecs": "a>>normalmode_eigenvecs"},
289+
parse_eigen=True,
290+
mod_spec_key="normalmodes"))
291+
292+
t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name}))
293+
294+
spec = kwargs.pop("spec", {})
295+
spec.update({"_files_out": {"POSCAR": "CONTCAR", "OUTCAR": "OUTCAR*", 'vasprunxml': "vasprun.xml*"}})
296+
297+
super(DFPTFW, self).__init__(t, parents=parents, name="{}-{}".format(
298+
structure.composition.reduced_formula, name), spec=spec, **kwargs)
299+
300+
301+
class RamanFW(Firework):
302+
def __init__(self, structure, mode, displacement, name="raman", vasp_cmd="vasp", db_file=None,
303+
parents=None, user_incar_settings=None, **kwargs):
304+
"""
305+
Static calculation Firework that computes the DFPT dielectric constant for
306+
structure displaced along the given normal mode direction.
307+
308+
Args:
309+
structure (Structure): Input structure. If copy_vasp_outputs, used only to set the
310+
name of the FW.
311+
mode (int): normal mode index.
312+
displacement (float): displacement along the normal mode in Angstroms.
313+
name (str): Name for the Firework.
314+
vasp_cmd (str): Command to run vasp.
315+
db_file (str): Path to file specifying db credentials.
316+
parents (Firework): Parents of this particular Firework.
317+
FW or list of FWS.
318+
user_incar_settings (dict): Parameters in INCAR to override
319+
\*\*kwargs: Other kwargs that are passed to Firework.__init__.
320+
"""
321+
322+
name = "{}_{}_{} static dielectric".format(name, str(mode), str(displacement))
323+
user_incar_settings = user_incar_settings or {}
324+
325+
spec = kwargs.pop("spec", {})
326+
spec.update({"_files_in": {"POSCAR": "POSCAR", "OUTCAR": "OUTCAR", "vasprunxml": "vasprun.xml"}})
327+
328+
t = []
329+
330+
t.append(WriteVaspStaticFromPrev(lepsilon=True, other_params={'user_incar_settings': user_incar_settings}))
331+
332+
t.append(WriteNormalmodeDisplacedPoscar(mode=mode, displacement=displacement))
333+
334+
t.append(RunVaspCustodian(vasp_cmd=vasp_cmd))
335+
336+
key = "{}_{}".format(mode, displacement).replace('-', 'm').replace('.', 'd')
337+
t.append(pass_vasp_result(pass_dict={"mode": mode,
338+
"displacement": displacement,
339+
"epsilon": "a>>epsilon_static"},
340+
mod_spec_key="raman_epsilon->{}".format(key),
341+
parse_eigen=True))
342+
343+
t.append(PassCalcLocs(name=name))
344+
345+
t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name}))
346+
347+
super(RamanFW, self).__init__(t, parents=parents, name="{}-{}".format(
348+
structure.composition.reduced_formula, name), spec=spec, **kwargs)
349+
350+
262351
class SOCFW(Firework):
263352
def __init__(self, structure, magmom, name="spin-orbit coupling", saxis=(0, 0, 1),
264353
vasp_cmd="vasp_ncl", copy_vasp_outputs=True, db_file=None, parents=None, **kwargs):

atomate/vasp/workflows/base/raman.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pymatgen.io.vasp.sets import MPRelaxSet
1212

1313
from atomate.utils.utils import get_logger
14-
from atomate.vasp.fireworks.core import OptimizeFW, LepsFW
14+
from atomate.vasp.fireworks.core import OptimizeFW, DFPTFW, RamanFW
1515
from atomate.vasp.firetasks.parse_outputs import RamanTensorToDb
1616

1717
__author__ = 'Kiran Mathew'
@@ -56,15 +56,15 @@ def get_wf_raman_spectra(structure, modes=None, step_size=0.005, vasp_cmd="vasp"
5656
fws.append(fw_opt)
5757

5858
# Static run: compute the normal modes and pass
59-
fw_leps = LepsFW(structure=structure, vasp_cmd=vasp_cmd, db_file=db_file, parents=fw_opt, phonon=True)
59+
fw_leps = DFPTFW(structure=structure, vasp_cmd=vasp_cmd, db_file=db_file, parents=fw_opt, pass_nm_results=True)
60+
6061
fws.append(fw_leps)
6162

6263
# Static runs to compute epsilon for each mode and displacement along that mode.
6364
fws_nm_disp = []
6465
for mode in modes:
6566
for disp in displacements:
66-
fws_nm_disp.append(LepsFW(structure, parents=fw_leps, vasp_cmd=vasp_cmd, db_file=db_file,
67-
phonon=True, mode=mode, displacement=disp))
67+
fws_nm_disp.append(RamanFW(structure, mode, disp, parents=fw_leps, vasp_cmd=vasp_cmd, db_file=db_file))
6868
fws.extend(fws_nm_disp)
6969

7070
# Compute the Raman susceptibility tensor

0 commit comments

Comments
 (0)