|
8 | 8 | from ase import Atoms |
9 | 9 | from numpy import ndarray |
10 | 10 | import phonopy |
11 | | -from phonopy.file_IO import write_force_constants_to_hdf5 |
| 11 | +from phonopy.file_IO import parse_QPOINTS, write_force_constants_to_hdf5 |
12 | 12 | from phonopy.phonon.band_structure import ( |
13 | 13 | get_band_qpoints_and_path_connections, |
14 | 14 | get_band_qpoints_by_seekpath, |
@@ -342,11 +342,13 @@ def __init__( |
342 | 342 | self.phonopy_file = self._build_filename("phonopy.yml") |
343 | 343 | self.force_consts_file = self._build_filename("force_constants.hdf5") |
344 | 344 |
|
345 | | - filename = "bands" + (".hdf5" if hdf5 else ".yml") |
| 345 | + suffix = ".hdf5" if hdf5 else ".yml" |
| 346 | + filename = "bands" + suffix |
346 | 347 | if not self.qpoint_file: |
347 | 348 | filename = f"auto_{filename}" |
348 | 349 | self.bands_file = self._build_filename(filename) |
349 | 350 | self.bands_plot_file = self._build_filename("bands.svg") |
| 351 | + self.qpoints_file = self._build_filename("qpoints" + suffix) |
350 | 352 | self.dos_file = self._build_filename("dos.dat") |
351 | 353 | self.dos_plot_file = self._build_filename("dos.svg") |
352 | 354 | self.bands_dos_plot_file = self._build_filename("bs-dos.svg") |
@@ -438,6 +440,11 @@ def output_files(self) -> None: |
438 | 440 | if self.write_results and "bands" in self.calcs |
439 | 441 | else None |
440 | 442 | ), |
| 443 | + "qpoints": ( |
| 444 | + self.qpoints_file |
| 445 | + if self.write_results and "qpoints" in self.calcs |
| 446 | + else None |
| 447 | + ), |
441 | 448 | "bands_plot": self.bands_plot_file if self.plot_to_file else None, |
442 | 449 | "dos": ( |
443 | 450 | self.dos_file if self.write_results and "dos" in self.calcs else None |
@@ -712,6 +719,86 @@ def write_bands( |
712 | 719 | build_file_dir(self.bands_plot_file) |
713 | 720 | bplt.savefig(self.bands_plot_file) |
714 | 721 |
|
| 722 | + def calc_qpoints(self, write_qpoints: bool | None = None, **kwargs) -> None: |
| 723 | + """ |
| 724 | + Calculate phonons at qpoints supplied by file QPOINTS, analoguous to phonopy. |
| 725 | +
|
| 726 | + Parameters |
| 727 | + ---------- |
| 728 | + write_qpoints |
| 729 | + Whether to write out results to file. Default is self.write_results. |
| 730 | + **kwargs |
| 731 | + Additional keyword arguments to pass to `write_bands`. |
| 732 | + """ |
| 733 | + if write_qpoints is None: |
| 734 | + write_qpoints = self.write_results |
| 735 | + |
| 736 | + # Calculate phonons if not already in results |
| 737 | + if "phonon" not in self.results: |
| 738 | + # Use general (self.write_results) setting for writing force constants |
| 739 | + self.calc_force_constants(write_force_consts=self.write_results) |
| 740 | + |
| 741 | + if write_qpoints: |
| 742 | + self.write_qpoints(**kwargs) |
| 743 | + |
| 744 | + def write_qpoints( |
| 745 | + self, |
| 746 | + *, |
| 747 | + hdf5: bool | None = None, |
| 748 | + qpoints_file: PathLike | None = None, |
| 749 | + ) -> None: |
| 750 | + """ |
| 751 | + Write results of qpoints mode calculations. |
| 752 | +
|
| 753 | + Parameters |
| 754 | + ---------- |
| 755 | + hdf5 |
| 756 | + Whether to save the bands in an hdf5 file. Default is |
| 757 | + self.hdf5. |
| 758 | + qpoints_file |
| 759 | + Name of yaml file to save band structure. Default is inferred from |
| 760 | + `file_prefix`. |
| 761 | + """ |
| 762 | + if "phonon" not in self.results: |
| 763 | + raise ValueError( |
| 764 | + "Force constants have not been calculated yet. " |
| 765 | + "Please run `calc_force_constants` first" |
| 766 | + ) |
| 767 | + |
| 768 | + if hdf5 is None: |
| 769 | + hdf5 = self.hdf5 |
| 770 | + |
| 771 | + if qpoints_file: |
| 772 | + self.qpoints_file = qpoints_file |
| 773 | + |
| 774 | + # maybe use self.qpoint_file or allow custom input filename |
| 775 | + # also allow passing a list of points programmatically |
| 776 | + q_points = parse_QPOINTS() |
| 777 | + |
| 778 | + fonons = self.results["phonon"] |
| 779 | + |
| 780 | + fonons.run_qpoints( |
| 781 | + q_points, |
| 782 | + with_eigenvectors=self.write_full, |
| 783 | + with_group_velocities=self.write_full, |
| 784 | + with_dynamical_matrices=self.write_full, |
| 785 | + # nac_q_direction = self.nac_q_direction, |
| 786 | + ) |
| 787 | + |
| 788 | + build_file_dir(self.qpoints_file) |
| 789 | + if hdf5: |
| 790 | + # not in phonopy yet |
| 791 | + # fonons.write_hdf5_qpoints_phonon(filename=self.qpoints_file) |
| 792 | + |
| 793 | + # until the above is implemented in phonopy |
| 794 | + fonons._qpoints.write_hdf5(filename=self.qpoints_file) |
| 795 | + else: |
| 796 | + # not in phonopy yet |
| 797 | + # fonons.write_yaml_qpoints_phonon(filename=self.qpoints_file) |
| 798 | + |
| 799 | + # until the above is implemented in phonopy |
| 800 | + fonons._qpoints.write_yaml(filename=self.qpoints_file) |
| 801 | + |
715 | 802 | def calc_thermal_props( |
716 | 803 | self, |
717 | 804 | mesh: tuple[int, int, int] | None = None, |
@@ -1014,12 +1101,16 @@ def run(self) -> None: |
1014 | 1101 | if "bands" in self.calcs: |
1015 | 1102 | self.calc_bands() |
1016 | 1103 |
|
| 1104 | + if "qpoints" in self.calcs: |
| 1105 | + self.calc_qpoints() |
| 1106 | + |
1017 | 1107 | # Calculate thermal properties if specified |
1018 | 1108 | if "thermal" in self.calcs: |
1019 | 1109 | self.calc_thermal_props() |
1020 | 1110 |
|
1021 | 1111 | # Calculate DOS and PDOS if specified |
1022 | 1112 | if "dos" in self.calcs: |
1023 | 1113 | self.calc_dos(plot_bands="bands" in self.calcs) |
| 1114 | + |
1024 | 1115 | if "pdos" in self.calcs: |
1025 | 1116 | self.calc_pdos() |
0 commit comments