Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix generating phonon-supercell files in velph #18

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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