Skip to content

Commit

Permalink
Fix generating phonon-supercell files in velph
Browse files Browse the repository at this point in the history
  • Loading branch information
atztogo committed Aug 29, 2024
1 parent 7f8523f commit 6a82b55
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 81 deletions.
56 changes: 33 additions & 23 deletions src/phelel/velph/cli/init/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,6 @@ def _get_toml_lines(
primitive,
sym_dataset,
supercell_dimension,
velph_dict,
cell_choices["nac"],
cell_choices["relax"],
)
Expand Down Expand Up @@ -718,7 +717,6 @@ def _get_kpoints_dict(
primitive: PhonopyAtoms,
sym_dataset: SpglibDataset,
supercell_dimension: np.ndarray,
velph_dict: dict,
cell_for_nac: CellChoice,
cell_for_relax: CellChoice,
) -> tuple[dict, dict, dict, dict]:
Expand Down Expand Up @@ -926,50 +924,61 @@ def _get_vasp_lines(

lines = []

for calc_type in ("supercell", "phono3py"):
if calc_type in vasp_dict:
_add_incar_lines(lines, vasp_dict, incar_commons, calc_type)
lines.append(f"[vasp.{calc_type}.kpoints]")
_add_kpoints_lines(lines, supercell_kpoints)
_add_calc_type_scheduler_lines(lines, vasp_dict, calc_type)
lines.append("")
for calc_type in ("supercell", "phono3py", "phono3py.phonon"):
keys = calc_type.split(".")
_vasp_dict = vasp_dict
for key in keys:
if key in _vasp_dict:
_vasp_dict = _vasp_dict[key]
else:
continue

_add_incar_lines(lines, _vasp_dict, incar_commons, calc_type)
lines.append(f"[vasp.{calc_type}.kpoints]")
_add_kpoints_lines(lines, supercell_kpoints)
_add_calc_type_scheduler_lines(lines, _vasp_dict, calc_type)
lines.append("")

for calc_type in ("selfenergy", "transport"):
if calc_type in vasp_dict:
# primitive cell
_add_incar_lines(lines, vasp_dict, incar_commons, calc_type)
_vasp_dict = vasp_dict[calc_type]
_add_incar_lines(lines, _vasp_dict, incar_commons, calc_type)
lines.append(f"[vasp.{calc_type}.kpoints]")
_add_kpoints_lines(lines, selfenergy_kpoints)
lines.append(f"[vasp.{calc_type}.kpoints_dense]")
_add_kpoints_lines(lines, selfenergy_kpoints_dense)
_add_calc_type_scheduler_lines(lines, vasp_dict, calc_type)
_add_calc_type_scheduler_lines(lines, _vasp_dict, calc_type)
lines.append("")

if "relax" in vasp_dict:
lines.append("[vasp.relax]")
assert cell_for_relax in CellChoice
assert cell_for_relax is not CellChoice.UNSPECIFIED
_vasp_dict = vasp_dict["relax"]
lines.append(f'cell = "{cell_for_relax.value}"')
_add_incar_lines(lines, vasp_dict, incar_commons, "relax")
_add_incar_lines(lines, _vasp_dict, incar_commons, "relax")
lines.append("[vasp.relax.kpoints]")
_add_kpoints_lines(lines, relax_kpoints)
_add_calc_type_scheduler_lines(lines, vasp_dict, "relax")
_add_calc_type_scheduler_lines(lines, _vasp_dict, "relax")
lines.append("")

if "nac" in vasp_dict:
lines.append("[vasp.nac]")
assert cell_for_nac in CellChoice
assert cell_for_nac is not CellChoice.UNSPECIFIED
_vasp_dict = vasp_dict["nac"]
lines.append(f'cell = "{cell_for_nac.value}"')
_add_incar_lines(lines, vasp_dict, incar_commons, "nac")
_add_incar_lines(lines, _vasp_dict, incar_commons, "nac")
lines.append("[vasp.nac.kpoints]")
_add_kpoints_lines(lines, nac_kpoints)
_add_calc_type_scheduler_lines(lines, vasp_dict, "nac")
_add_calc_type_scheduler_lines(lines, _vasp_dict, "nac")
lines.append("")

if "el_bands" in vasp_dict:
# primitive cell
_add_incar_lines(lines, vasp_dict, incar_commons, "el_bands")
_vasp_dict = vasp_dict["el_bands"]
_add_incar_lines(lines, _vasp_dict, incar_commons, "el_bands")
lines.append("[vasp.el_bands.kpoints]")
_add_kpoints_lines(lines, el_bands_kpoints)
if el_bands_kpoints_opt:
Expand All @@ -978,18 +987,19 @@ def _get_vasp_lines(
if el_bands_kpoints_dense:
lines.append("[vasp.el_bands.kpoints_dense]")
_add_kpoints_lines(lines, el_bands_kpoints_dense)
_add_calc_type_scheduler_lines(lines, vasp_dict, "el_bands")
_add_calc_type_scheduler_lines(lines, _vasp_dict, "el_bands")
lines.append("")

if "ph_bands" in vasp_dict:
# primitive cell
_add_incar_lines(lines, vasp_dict, incar_commons, "ph_bands")
_vasp_dict = vasp_dict["ph_bands"]
_add_incar_lines(lines, _vasp_dict, incar_commons, "ph_bands")
lines.append("[vasp.ph_bands.kpoints]")
_add_kpoints_lines(lines, ph_bands_kpoints)
if ph_bands_qpoints:
lines.append("[vasp.ph_bands.qpoints]")
_add_kpoints_lines_bands(lines, ph_bands_qpoints)
_add_calc_type_scheduler_lines(lines, vasp_dict, "ph_bands")
_add_calc_type_scheduler_lines(lines, _vasp_dict, "ph_bands")
lines.append("")

return lines
Expand Down Expand Up @@ -1091,11 +1101,11 @@ def _get_phelel_lines(


def _add_incar_lines(lines: list, vasp_dict: dict, incar_commons: dict, calc_type: str):
if "incar" in vasp_dict[calc_type]:
if "incar" in vasp_dict:
lines.append(f"[vasp.{calc_type}.incar]")
lines.append(
tomli_w.dumps(
_merge_incar_commons(vasp_dict[calc_type]["incar"], incar_commons)
_merge_incar_commons(vasp_dict["incar"], incar_commons)
).strip()
)

Expand Down Expand Up @@ -1125,9 +1135,9 @@ def _add_kpoints_lines(lines: list, kpt_dict: dict) -> None:


def _add_calc_type_scheduler_lines(lines: list, vasp_dict: dict, calc_type: str):
if "scheduler" in vasp_dict[calc_type]:
if "scheduler" in vasp_dict:
lines.append(f"[vasp.{calc_type}.scheduler]")
lines.append(tomli_w.dumps(vasp_dict[calc_type]["scheduler"]))
lines.append(tomli_w.dumps(vasp_dict["scheduler"]))


def _get_cell_toml_lines(
Expand Down
28 changes: 11 additions & 17 deletions src/phelel/velph/cli/phono3py/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ def _generate_phono3py_supercells(
is_plusminus: Union[str, bool] = "auto",
is_diagonal: bool = True,
number_of_snapshots: Optional[int] = None,
log_level: int = 0,
):
"""Generate phelel supercells."""
if distance is None:
Expand All @@ -112,24 +111,19 @@ def _generate_phono3py_supercells(
is_diagonal=is_diagonal,
number_of_snapshots=number_of_snapshots,
)
if log_level:
print("Displacement distance: %s" % _distance)
print(
"Number of displacements: %d" % len(phono3py.supercells_with_displacements)
)
click.echo(f"Displacement distance: {_distance}")
click.echo(
f"Number of displacements: {len(phono3py.supercells_with_displacements)}"
)

if phono3py.phonon_supercell_matrix is not None:
# For estimating number of displacements for harmonic phonon
phono3py.generate_fc2_displacements(
distance=distance, is_plusminus=False, is_diagonal=False
)
n_disps = len(phono3py.phonon_supercells_with_displacements)
phono3py.generate_fc2_displacements(
distance=distance, is_plusminus=is_plusminus, is_diagonal=is_diagonal
distance=distance, number_of_snapshots=n_disps, is_plusminus=True
)
n_snapshots = len(phono3py.phonon_supercells_with_displacements)
if number_of_snapshots is not None:
phono3py.generate_fc2_displacements(
distance=distance, number_of_snapshots=n_snapshots
)

if log_level:
print(
"Number of displacements for phonon: %d"
% len(phono3py.phonon_supercells_with_displacements)
)
click.echo(f"Number of displacements for phonon: {n_snapshots}")
61 changes: 29 additions & 32 deletions src/phelel/velph/cli/supercell/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,14 @@ def write_supercells(
directory = pathlib.Path(disp_dir_name)
directory.mkdir(parents=True, exist_ok=True)

# POSCAR
write_crystal_structure(directory / "POSCAR", cell)

# INCAR
write_incar(toml_dict["vasp"][dir_name]["incar"], directory, cell=cell)

# KPOINTS
write_kpoints_mesh_mode(
toml_dict["vasp"][dir_name]["incar"],
_write_vasp_files(
directory,
f"vasp.{dir_name}.kpoints",
cell,
toml_dict["vasp"][dir_name]["incar"],
dir_name,
kpoints_dict,
)

# POTCAR
potcar_path = pathlib.Path("POTCAR")
if potcar_path.exists():
shutil.copy2(potcar_path, directory / potcar_path)

# Scheduler launch script
if "scheduler" in toml_dict:
scheduler_dict = get_scheduler_dict(toml_dict, dir_name)
Expand Down Expand Up @@ -123,30 +112,38 @@ def write_phonon_supercells(
directory = pathlib.Path(disp_dir_name)
directory.mkdir(parents=True, exist_ok=True)

# POSCAR
write_crystal_structure(directory / "POSCAR", cell)

# INCAR
write_incar(
toml_dict["vasp"][dir_name]["phonon"]["incar"], directory, cell=cell
)

# KPOINTS
write_kpoints_mesh_mode(
toml_dict["vasp"][dir_name]["phonon"]["incar"],
_write_vasp_files(
directory,
f"vasp.{dir_name}.phonon.kpoints",
cell,
toml_dict["vasp"][dir_name]["phonon"]["incar"],
f"{dir_name}.phonon",
kpoints_dict,
)

# POTCAR
potcar_path = pathlib.Path("POTCAR")
if potcar_path.exists():
shutil.copy2(potcar_path, directory / potcar_path)

# Scheduler launch script
if "scheduler" in toml_dict:
scheduler_dict = get_scheduler_dict(toml_dict, f"{dir_name}.phonon")
write_launch_script(scheduler_dict, directory, job_id=id_number)

click.echo(f'VASP input files were generated in "{disp_dir_name}".')


def _write_vasp_files(directory, cell, toml_incar_dict, dir_name, kpoints_dict):
# POSCAR
write_crystal_structure(directory / "POSCAR", cell)

# INCAR
write_incar(toml_incar_dict, directory, cell=cell)

# KPOINTS
write_kpoints_mesh_mode(
toml_incar_dict,
directory,
f"vasp.{dir_name}.kpoints",
kpoints_dict,
)

# POTCAR
potcar_path = pathlib.Path("POTCAR")
if potcar_path.exists():
shutil.copy2(potcar_path, directory / potcar_path)
26 changes: 18 additions & 8 deletions src/phelel/velph/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,30 @@ def write_launch_script(
toml_scheduler_dict: dict, directory: pathlib.Path, job_id: Optional[str] = None
) -> None:
"""Write scheduler launch script."""
if toml_scheduler_dict["scheduler_name"] in ("sge", "slurm", "custom"):
if toml_scheduler_dict["scheduler_name"] == "sge":
sched_string = get_sge_scheduler_script(toml_scheduler_dict, job_id=job_id)
elif toml_scheduler_dict["scheduler_name"] == "slurm":
sched_string = get_slurm_scheduler_script(
toml_scheduler_dict, job_id=job_id
sched_string = None
if toml_scheduler_dict["scheduler_name"] == "sge":
sched_string = get_sge_scheduler_script(toml_scheduler_dict, job_id=job_id)
elif toml_scheduler_dict["scheduler_name"] == "slurm":
sched_string = get_slurm_scheduler_script(toml_scheduler_dict, job_id=job_id)
elif toml_scheduler_dict["scheduler_name"] == "custom":
if "custom_template" in toml_scheduler_dict:
raise RuntimeError(
'Key "custom_template" is obsoleted. Use "scheduler_template".'
)
elif toml_scheduler_dict["scheduler_name"] == "custom":

if "scheduler_template" not in toml_scheduler_dict:
click.echo(
'"scheduler_template" has to be specified in scheduler setting.',
err=True,
)
else:
sched_string = get_custom_schedular_script(
toml_scheduler_dict["custom_template"],
toml_scheduler_dict["scheduler_template"],
toml_scheduler_dict,
job_id=job_id,
)

if sched_string:
with open(directory / "_job.sh", "w") as w:
w.write(sched_string)

Expand Down
10 changes: 9 additions & 1 deletion src/phelel/velph/utils/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def get_sge_scheduler_script(
) -> str:
"""Return scheduler script of SGE.
This is called when scheduler_name = "sge".
Supported parameters
--------------------
Necessary tags:
Expand Down Expand Up @@ -62,6 +64,8 @@ def get_slurm_scheduler_script(
) -> str:
"""Return scheduler script of SLURM.
This is called when scheduler_name = "slurm".
Supported parameters
--------------------
Necessary tags:
Expand Down Expand Up @@ -96,7 +100,11 @@ def get_slurm_scheduler_script(
def get_custom_schedular_script(
template: str, toml_scheduler_dict: dict, job_id: Optional[Union[str, int]]
) -> str:
"""Return scheduler script with given template."""
"""Return scheduler script with given template.
This is called when scheduler_name = "custom".
"""
sched_dict = copy.deepcopy(toml_scheduler_dict)
if job_id is not None:
sched_dict["job_name"] += f"-{job_id}"
Expand Down

0 comments on commit 6a82b55

Please sign in to comment.