From 2afef356dba2766862e805d7d5b96403337e7f01 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Mon, 13 Jan 2025 10:13:33 +0900 Subject: [PATCH 01/17] Minor fix of show_general_settings --- phono3py/cui/show_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phono3py/cui/show_log.py b/phono3py/cui/show_log.py index c03f90b6..03539979 100644 --- a/phono3py/cui/show_log.py +++ b/phono3py/cui/show_log.py @@ -65,7 +65,7 @@ def show_general_settings( print("-" * 29 + " General settings " + "-" * 29) if run_mode: - print("Run mode: {run_mode}") + print(f"Run mode: {run_mode}") if output_filename: print(f"Output filename is modified by {output_filename}.") if input_filename: From 5146070780f7e4ad7a53b87db7ce6d6d729821cd Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Mon, 13 Jan 2025 16:19:45 +0900 Subject: [PATCH 02/17] Update pypolymlp example --- example/NaCl-pypolymlp/README.md | 9 +++++++++ example/NaCl-pypolymlp/make_phono3py_params.py | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 example/NaCl-pypolymlp/README.md create mode 100644 example/NaCl-pypolymlp/make_phono3py_params.py diff --git a/example/NaCl-pypolymlp/README.md b/example/NaCl-pypolymlp/README.md new file mode 100644 index 00000000..438d9c82 --- /dev/null +++ b/example/NaCl-pypolymlp/README.md @@ -0,0 +1,9 @@ +# Example to create force constants using MLPs by pypolymlp + +This is an example to follow the documentation +https://phonopy.github.io/phono3py/pypolymlp.html. +`phono3py_params.yaml` can be also generated by + +```bash +% python make_phono3py_params.py ../NaCl-rd/phono3py_params_NaCl.yaml.xz +``` diff --git a/example/NaCl-pypolymlp/make_phono3py_params.py b/example/NaCl-pypolymlp/make_phono3py_params.py new file mode 100644 index 00000000..2aeec2cf --- /dev/null +++ b/example/NaCl-pypolymlp/make_phono3py_params.py @@ -0,0 +1,13 @@ +import sys + +import phono3py + +ph3 = phono3py.load(sys.argv[1], produce_fc=False, log_level=1) +ph3_new = phono3py.Phono3py( + ph3.unitcell, + supercell_matrix=ph3.supercell_matrix, + primitive_matrix=ph3.primitive_matrix, +) +ph3_new.dataset = ph3.dataset +ph3_new.nac_params = ph3.nac_params +ph3_new.save("phono3py_params.yaml") From 705ade84f806a82a5cef6dce33c4f6229618a009 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 00:34:39 +0000 Subject: [PATCH 03/17] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.8.6 → v0.9.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.6...v0.9.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9f8058ea..9fa2d2b3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: exclude: ^example/AlN-LDA/ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.6 + rev: v0.9.1 hooks: - id: ruff args: [ "--fix", "--show-fixes" ] From 33522bda1a7c29e8c19a5c874e481504f17ad53b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 00:34:47 +0000 Subject: [PATCH 04/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- phono3py/conductivity/base.py | 9 ++++----- phono3py/conductivity/direct_solution.py | 2 +- phono3py/cui/kaccum_script.py | 4 ++-- phono3py/file_IO.py | 2 +- phono3py/phonon/grid.py | 2 +- phono3py/phonon3/imag_self_energy.py | 2 +- phono3py/phonon3/interaction.py | 8 ++++---- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/phono3py/conductivity/base.py b/phono3py/conductivity/base.py index 4e750b16..4e5d04af 100644 --- a/phono3py/conductivity/base.py +++ b/phono3py/conductivity/base.py @@ -128,7 +128,7 @@ def kappa(self): def get_kappa(self): """Return kappa.""" warnings.warn( - "Use attribute, Conductivity.kappa " "instead of Conductivity.get_kappa().", + "Use attribute, Conductivity.kappa instead of Conductivity.get_kappa().", DeprecationWarning, stacklevel=2, ) @@ -550,7 +550,7 @@ def gamma(self, gamma): def get_gamma(self): """Return gamma.""" warnings.warn( - "Use attribute, Conductivity.gamma " "instead of Conductivity.get_gamma().", + "Use attribute, Conductivity.gamma instead of Conductivity.get_gamma().", DeprecationWarning, stacklevel=2, ) @@ -559,7 +559,7 @@ def get_gamma(self): def set_gamma(self, gamma): """Set gamma.""" warnings.warn( - "Use attribute, Conductivity.gamma " "instead of Conductivity.set_gamma().", + "Use attribute, Conductivity.gamma instead of Conductivity.set_gamma().", DeprecationWarning, stacklevel=2, ) @@ -603,8 +603,7 @@ def sigmas(self): def get_sigmas(self): """Return sigmas.""" warnings.warn( - "Use attribute, Conductivity.sigmas " - "instead of Conductivity.get_sigmas().", + "Use attribute, Conductivity.sigmas instead of Conductivity.get_sigmas().", DeprecationWarning, stacklevel=2, ) diff --git a/phono3py/conductivity/direct_solution.py b/phono3py/conductivity/direct_solution.py index 8bca4a8b..21f5e790 100644 --- a/phono3py/conductivity/direct_solution.py +++ b/phono3py/conductivity/direct_solution.py @@ -730,7 +730,7 @@ def _average_collision_matrix_by_degeneracy(self): # Average matrix elements belonging to degenerate bands if self._log_level: sys.stdout.write( - "- Averaging collision matrix elements " "by phonon degeneracy " + "- Averaging collision matrix elements by phonon degeneracy " ) sys.stdout.flush() diff --git a/phono3py/cui/kaccum_script.py b/phono3py/cui/kaccum_script.py index b32d327f..c08ac3c7 100644 --- a/phono3py/cui/kaccum_script.py +++ b/phono3py/cui/kaccum_script.py @@ -230,7 +230,7 @@ def _get_parser(): parser.add_argument( "--trace", action="store_true", - help=("Output the traces of the tensors " "rather than the unique elements"), + help=("Output the traces of the tensors rather than the unique elements"), ) parser.add_argument( "--smearing", @@ -329,7 +329,7 @@ def main(): conditions = frequencies > 0 if np.logical_not(conditions).sum() > 3: sys.stderr.write( - "# Imaginary frequencies are found. " "They are set to be zero.\n" + "# Imaginary frequencies are found. They are set to be zero.\n" ) frequencies = np.where(conditions, frequencies, 0) diff --git a/phono3py/file_IO.py b/phono3py/file_IO.py index e8f6fb5e..40aa472c 100644 --- a/phono3py/file_IO.py +++ b/phono3py/file_IO.py @@ -1333,7 +1333,7 @@ def read_pp_from_hdf5( # check_consistency==True in write_pp_to_hdf5 required. if check_consistency and g_zero is not None: if verbose: - print("Checking consistency of ph-ph interanction " "strength.") + print("Checking consistency of ph-ph interanction strength.") assert (g_zero == f["g_zero"][:]).all() assert np.allclose(pp, f["pp"][:]) else: diff --git a/phono3py/phonon/grid.py b/phono3py/phonon/grid.py index 972f481d..31c596fc 100644 --- a/phono3py/phonon/grid.py +++ b/phono3py/phonon/grid.py @@ -741,7 +741,7 @@ def _get_mock_symmetry_dataset(self, transformation_matrix) -> dict: tmat_inv = np.linalg.inv(transformation_matrix) tmat_inv_int = np.rint(tmat_inv).astype(int) if (tmat_inv - tmat_inv_int > 1e-8).all(): - msg = "Inverse of transformation matrix has to be an " "integer matrix." + msg = "Inverse of transformation matrix has to be an integer matrix." raise RuntimeError(msg) if determinant(tmat_inv_int) < 0: msg = "Determinant of transformation matrix has to be positive." diff --git a/phono3py/phonon3/imag_self_energy.py b/phono3py/phonon3/imag_self_energy.py index 6c06a86b..ba9c4018 100644 --- a/phono3py/phonon3/imag_self_energy.py +++ b/phono3py/phonon3/imag_self_energy.py @@ -732,7 +732,7 @@ def get_imag_self_energy( "--------------------" ) print("Grid point: %d" % gp) - print("Number of ir-triplets: " "%d / %d" % (len(weights), weights.sum())) + print("Number of ir-triplets: %d / %d" % (len(weights), weights.sum())) ise.run_interaction() frequencies = interaction.get_phonons()[0][gp] diff --git a/phono3py/phonon3/interaction.py b/phono3py/phonon3/interaction.py index c4555bb5..f58c61e4 100644 --- a/phono3py/phonon3/interaction.py +++ b/phono3py/phonon3/interaction.py @@ -261,7 +261,7 @@ def fc3(self) -> np.ndarray: def get_fc3(self): """Return fc3.""" warnings.warn( - "Use attribute, Interaction.fc3 " "instead of Interaction.get_fc3().", + "Use attribute, Interaction.fc3 instead of Interaction.get_fc3().", DeprecationWarning, stacklevel=2, ) @@ -693,12 +693,12 @@ def set_phonon_data(self, frequencies, eigenvectors, bz_grid_addresses): """Set phonons on grid.""" if bz_grid_addresses.shape != self._bz_grid.addresses.shape: raise RuntimeError( - "Input grid address size is inconsistent. " "Setting phonons faild." + "Input grid address size is inconsistent. Setting phonons faild." ) if (self._bz_grid.addresses - bz_grid_addresses).all(): raise RuntimeError( - "Input grid addresses are inconsistent. " "Setting phonons faild." + "Input grid addresses are inconsistent. Setting phonons faild." ) else: self._phonon_done[:] = 1 @@ -797,7 +797,7 @@ def run_phonon_solver_with_eigvec_rotation(self): bz_grid_points_solved = self._get_phonons_at_minus_q() if bz_grid_points_solved: - print("DEBUG: BZ-grid points additionally solved " "than ir-grid-points.") + print("DEBUG: BZ-grid points additionally solved than ir-grid-points.") qpoints = np.dot( self._bz_grid.addresses[bz_grid_points_solved] / self._bz_grid.D_diag.astype("double"), From 2f91fea9cf98312e874e49b6be56958bd53bc465 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 16:15:37 +0900 Subject: [PATCH 05/17] Refactor CUI for using pypolymlp --- phono3py/cui/create_force_constants.py | 62 ++--- phono3py/cui/load.py | 191 +++++++--------- phono3py/cui/phono3py_script.py | 303 +++++++++++++------------ 3 files changed, 280 insertions(+), 276 deletions(-) diff --git a/phono3py/cui/create_force_constants.py b/phono3py/cui/create_force_constants.py index 489e2d61..780122ee 100644 --- a/phono3py/cui/create_force_constants.py +++ b/phono3py/cui/create_force_constants.py @@ -514,6 +514,7 @@ def run_pypolymlp_to_compute_forces( displacement_distance: Optional[float] = None, number_of_snapshots: Optional[int] = None, random_seed: Optional[int] = None, + prepare_dataset: bool = False, mlp_filename: str = "phono3py.pmlp", log_level: int = 0, ): @@ -546,43 +547,44 @@ def run_pypolymlp_to_compute_forces( if log_level: print("-" * 30 + " pypolymlp end " + "-" * 31, flush=True) - if displacement_distance is None: - _displacement_distance = 0.001 - else: - _displacement_distance = displacement_distance + if prepare_dataset: + if displacement_distance is None: + _displacement_distance = 0.001 + else: + _displacement_distance = displacement_distance - if log_level: - if number_of_snapshots: - print("Generate random displacements") + if log_level: + if number_of_snapshots: + print("Generate random displacements") + print( + " Twice of number of snapshots will be generated " + "for plus-minus displacements." + ) + else: + print("Generate displacements") print( - " Twice of number of snapshots will be generated " - "for plus-minus displacements." - ) - else: - print("Generate displacements") - print( - f" Displacement distance: {_displacement_distance:.5f}".rstrip("0").rstrip( - "." + f" Displacement distance: {_displacement_distance:.5f}".rstrip( + "0" + ).rstrip(".") ) + ph3py.generate_displacements( + distance=_displacement_distance, + is_plusminus=True, + number_of_snapshots=number_of_snapshots, + random_seed=random_seed, ) - ph3py.generate_displacements( - distance=_displacement_distance, - is_plusminus=True, - number_of_snapshots=number_of_snapshots, - random_seed=random_seed, - ) - if log_level: - print( - f"Evaluate forces in {ph3py.displacements.shape[0]} supercells " - "by pypolymlp", - flush=True, - ) + if log_level: + print( + f"Evaluate forces in {ph3py.displacements.shape[0]} supercells " + "by pypolymlp", + flush=True, + ) - if ph3py.supercells_with_displacements is None: - raise RuntimeError("Displacements are not set. Run generate_displacements.") + if ph3py.supercells_with_displacements is None: + raise RuntimeError("Displacements are not set. Run generate_displacements.") - ph3py.evaluate_mlp() + ph3py.evaluate_mlp() def run_pypolymlp_to_compute_phonon_forces( diff --git a/phono3py/cui/load.py b/phono3py/cui/load.py index e4dda9d0..b3fb96c8 100644 --- a/phono3py/cui/load.py +++ b/phono3py/cui/load.py @@ -340,29 +340,34 @@ def load( log_level=log_level, ) - read_fc = set_dataset_and_force_constants( + load_fc2_and_fc3( + ph3py, fc3_filename=fc3_filename, fc2_filename=fc2_filename, log_level=log_level + ) + load_dataset_and_phonon_dataset( ph3py, ph3py_yaml, - fc3_filename=fc3_filename, - fc2_filename=fc2_filename, forces_fc3_filename=forces_fc3_filename, forces_fc2_filename=forces_fc2_filename, phono3py_yaml_filename=phono3py_yaml, calculator=_calculator, - use_pypolymlp=use_pypolymlp, log_level=log_level, ) + if use_pypolymlp and ph3py.fc3 is None and forces_in_dataset(ph3py.dataset): + ph3py.mlp_dataset = ph3py.dataset + ph3py.dataset = None if produce_fc: + if ph3py.fc3 is None and use_pypolymlp: + run_pypolymlp_to_compute_forces( + ph3py, mlp_params=mlp_params, log_level=log_level + ) + compute_force_constants_from_datasets( ph3py, - read_fc, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options, symmetrize_fc=symmetrize_fc, is_compact_fc=is_compact_fc, - use_pypolymlp=use_pypolymlp, - mlp_params=mlp_params, log_level=log_level, ) @@ -376,76 +381,62 @@ def load( return ph3py -def set_dataset_and_force_constants( +def load_fc2_and_fc3( ph3py: Phono3py, - ph3py_yaml: Optional[Phono3pyYaml] = None, fc3_filename: Optional[os.PathLike] = None, fc2_filename: Optional[os.PathLike] = None, + log_level: int = 0, +): + """Set force constants.""" + if fc3_filename is not None or pathlib.Path("fc3.hdf5").exists(): + fc3 = _load_fc3(ph3py, fc3_filename=fc3_filename, log_level=log_level) + ph3py.fc3 = fc3 + + if fc2_filename is not None or pathlib.Path("fc2.hdf5").exists(): + fc2 = _load_fc2(ph3py, fc2_filename=fc2_filename, log_level=log_level) + ph3py.fc2 = fc2 + + +def load_dataset_and_phonon_dataset( + ph3py: Phono3py, + ph3py_yaml: Optional[Phono3pyYaml] = None, forces_fc3_filename: Optional[Union[os.PathLike, Sequence]] = None, forces_fc2_filename: Optional[Union[os.PathLike, Sequence]] = None, phono3py_yaml_filename: Optional[os.PathLike] = None, cutoff_pair_distance: Optional[float] = None, calculator: Optional[str] = None, - use_pypolymlp: bool = False, log_level: int = 0, -) -> dict: - """Set displacements, forces, and create force constants. - - Most of properties are stored in ph3py. - - Returns - ------- - dict - This contains flags indicating whether fc2 and fc3 were read from - file(s) or not. This information can be different from ph3py.fc3 is - (not) None and ph3py.fc2 is (not) None. Items are as follows: - fc3 : bool - fc2 : bool - - """ - read_fc = {"fc2": False, "fc3": False} - read_fc["fc3"], dataset = _get_dataset_or_fc3( +): + """Set displacements, forces, and create force constants.""" + dataset = _select_and_load_dataset( ph3py, ph3py_yaml=ph3py_yaml, - fc3_filename=fc3_filename, forces_fc3_filename=forces_fc3_filename, phono3py_yaml_filename=phono3py_yaml_filename, cutoff_pair_distance=cutoff_pair_distance, calculator=calculator, log_level=log_level, ) - if not read_fc["fc3"]: - if use_pypolymlp: - if forces_in_dataset(dataset): - ph3py.mlp_dataset = dataset - else: - ph3py.dataset = dataset - read_fc["fc2"], phonon_dataset = _get_dataset_phonon_dataset_or_fc2( + if dataset is not None: + ph3py.dataset = dataset + + phonon_dataset = _select_and_load_phonon_dataset( ph3py, ph3py_yaml=ph3py_yaml, - fc2_filename=fc2_filename, forces_fc2_filename=forces_fc2_filename, calculator=calculator, log_level=log_level, ) - if not read_fc["fc2"]: + if phonon_dataset is not None: ph3py.phonon_dataset = phonon_dataset - return read_fc - def compute_force_constants_from_datasets( ph3py: Phono3py, - read_fc: dict, fc_calculator: Optional[str] = None, fc_calculator_options: Optional[Union[dict, str]] = None, symmetrize_fc: bool = True, is_compact_fc: bool = True, - use_pypolymlp: bool = False, - mlp_params: Optional[Union[dict, str]] = None, - displacement_distance: Optional[float] = None, - number_of_snapshots: Optional[int] = None, - random_seed: Optional[int] = None, log_level: int = 0, ): """Compute force constants from datasets. @@ -462,30 +453,19 @@ def compute_force_constants_from_datasets( """ fc3_calculator = extract_fc2_fc3_calculators(fc_calculator, 3) fc2_calculator = extract_fc2_fc3_calculators(fc_calculator, 2) - if not read_fc["fc3"]: - if use_pypolymlp: - run_pypolymlp_to_compute_forces( - ph3py, - mlp_params=mlp_params, - displacement_distance=displacement_distance, - number_of_snapshots=number_of_snapshots, - random_seed=random_seed, - log_level=log_level, - ) - if forces_in_dataset(ph3py.dataset): - ph3py.produce_fc3( - symmetrize_fc3r=symmetrize_fc, - is_compact_fc=is_compact_fc, - fc_calculator=fc3_calculator, - fc_calculator_options=extract_fc2_fc3_calculators( - fc_calculator_options, 3 - ), - ) + exist_fc2 = ph3py.fc2 is not None + if ph3py.fc3 is None and forces_in_dataset(ph3py.dataset): + ph3py.produce_fc3( + symmetrize_fc3r=symmetrize_fc, + is_compact_fc=is_compact_fc, + fc_calculator=fc3_calculator, + fc_calculator_options=extract_fc2_fc3_calculators(fc_calculator_options, 3), + ) - if log_level and symmetrize_fc and fc_calculator is None: - print("fc3 was symmetrized.") + if log_level and symmetrize_fc and fc_calculator is None: + print("fc3 was symmetrized.") - if not read_fc["fc2"]: + if not exist_fc2: if ( ph3py.phonon_supercell_matrix is None and forces_in_dataset(ph3py.dataset) ) or ( @@ -504,32 +484,34 @@ def compute_force_constants_from_datasets( print("fc2 was symmetrized.") -def _get_dataset_or_fc3( +def _load_fc3( ph3py: Phono3py, - ph3py_yaml: Optional[Phono3pyYaml] = None, fc3_filename: Optional[os.PathLike] = None, + log_level: int = 0, +) -> np.ndarray: + p2s_map = ph3py.primitive.p2s_map + if fc3_filename is None: + _fc3_filename = "fc3.hdf5" + else: + _fc3_filename = fc3_filename + fc3 = read_fc3_from_hdf5(filename=_fc3_filename, p2s_map=p2s_map) + _check_fc3_shape(ph3py, fc3, filename=_fc3_filename) + if log_level: + print(f'fc3 was read from "{_fc3_filename}".') + return fc3 + + +def _select_and_load_dataset( + ph3py: Phono3py, + ph3py_yaml: Optional[Phono3pyYaml] = None, forces_fc3_filename: Optional[Union[os.PathLike, Sequence]] = None, phono3py_yaml_filename: Optional[os.PathLike] = None, cutoff_pair_distance: Optional[float] = None, calculator: Optional[str] = None, log_level: int = 0, -) -> tuple[bool, dict]: - p2s_map = ph3py.primitive.p2s_map - read_fc3 = False +) -> Optional[dict]: dataset = None - - if fc3_filename is not None or pathlib.Path("fc3.hdf5").exists(): - if fc3_filename is None: - _fc3_filename = "fc3.hdf5" - else: - _fc3_filename = fc3_filename - fc3 = read_fc3_from_hdf5(filename=_fc3_filename, p2s_map=p2s_map) - _check_fc3_shape(ph3py, fc3, filename=_fc3_filename) - ph3py.fc3 = fc3 - read_fc3 = True - if log_level: - print(f'fc3 was read from "{_fc3_filename}".') - elif ( + if ( ph3py_yaml is not None and ph3py_yaml.dataset is not None and forces_in_dataset(ph3py_yaml.dataset) @@ -570,32 +552,33 @@ def _get_dataset_or_fc3( log_level, ) - return read_fc3, dataset + return dataset + +def _load_fc2( + ph3py: Phono3py, fc2_filename: Optional[os.PathLike] = None, log_level: int = 0 +) -> np.ndarray: + phonon_p2s_map = ph3py.phonon_primitive.p2s_map + if fc2_filename is None: + _fc2_filename = "fc2.hdf5" + else: + _fc2_filename = fc2_filename + fc2 = read_fc2_from_hdf5(filename=_fc2_filename, p2s_map=phonon_p2s_map) + _check_fc2_shape(ph3py, fc2, filename=_fc2_filename) + if log_level: + print(f'fc2 was read from "{_fc2_filename}".') + return fc2 -def _get_dataset_phonon_dataset_or_fc2( + +def _select_and_load_phonon_dataset( ph3py: Phono3py, ph3py_yaml: Optional[Phono3pyYaml] = None, - fc2_filename: Optional[os.PathLike] = None, forces_fc2_filename: Optional[Union[os.PathLike, Sequence]] = None, calculator: Optional[str] = None, log_level: int = 0, -) -> tuple[bool, dict, dict]: - phonon_p2s_map = ph3py.phonon_primitive.p2s_map - read_fc2 = False +) -> Optional[dict]: phonon_dataset = None - if fc2_filename is not None or pathlib.Path("fc2.hdf5").exists(): - if fc2_filename is None: - _fc2_filename = "fc2.hdf5" - else: - _fc2_filename = fc2_filename - fc2 = read_fc2_from_hdf5(filename=_fc2_filename, p2s_map=phonon_p2s_map) - _check_fc2_shape(ph3py, fc2, filename=_fc2_filename) - ph3py.fc2 = fc2 - read_fc2 = True - if log_level: - print(f'fc2 was read from "{_fc2_filename}".') - elif ( + if ( ph3py_yaml is not None and ph3py_yaml.phonon_dataset is not None and forces_in_dataset(ph3py_yaml.phonon_dataset) @@ -635,7 +618,7 @@ def _get_dataset_phonon_dataset_or_fc2( log_level, ) - return read_fc2, phonon_dataset + return phonon_dataset def _get_dataset_for_fc3( diff --git a/phono3py/cui/phono3py_script.py b/phono3py/cui/phono3py_script.py index 5299f87f..7640a23c 100644 --- a/phono3py/cui/phono3py_script.py +++ b/phono3py/cui/phono3py_script.py @@ -67,6 +67,7 @@ from phono3py.cui.create_force_constants import ( create_phono3py_force_constants, get_fc_calculator_params, + run_pypolymlp_to_compute_forces, ) from phono3py.cui.create_force_sets import ( create_FORCE_SETS_from_FORCES_FCx, @@ -76,7 +77,8 @@ from phono3py.cui.create_supercells import create_phono3py_supercells from phono3py.cui.load import ( compute_force_constants_from_datasets, - set_dataset_and_force_constants, + load_dataset_and_phonon_dataset, + load_fc2_and_fc3, ) from phono3py.cui.phono3py_argparse import get_parser from phono3py.cui.settings import Phono3pyConfParser, Phono3pySettings @@ -548,8 +550,8 @@ def create_supercells_with_displacements( """Create supercells and write displacements.""" if ( settings.create_displacements - or settings.random_displacements - or settings.random_displacements_fc2 + or settings.random_displacements is not None + or settings.random_displacements_fc2 is not None ): phono3py = create_phono3py_supercells( cell_info, @@ -588,115 +590,78 @@ def create_supercells_with_displacements( ) -def store_force_constants( - phono3py: Phono3py, - settings, - ph3py_yaml: Phono3pyYaml, - phono3py_yaml_filename, - calculator, - input_filename, - output_filename, - load_phono3py_yaml, - log_level, -): +def _store_force_constants(ph3py: Phono3py, settings: Phono3pySettings, log_level: int): """Calculate, read, and write force constants.""" - if load_phono3py_yaml: - if log_level: - print("-" * 29 + " Force constants " + "-" * 30) + if log_level: + print("-" * 29 + " Force constants " + "-" * 30) - read_fc = set_dataset_and_force_constants( - phono3py, - ph3py_yaml=ph3py_yaml, - phono3py_yaml_filename=phono3py_yaml_filename, - cutoff_pair_distance=settings.cutoff_pair_distance, - use_pypolymlp=settings.use_pypolymlp, - calculator=calculator, + read_fc3 = ph3py.fc3 is not None + read_fc2 = ph3py.fc2 is not None + + load_fc2_and_fc3(ph3py, log_level=log_level) + + (fc_calculator, fc_calculator_options) = get_fc_calculator_params( + settings, log_level=(not read_fc3) * 1 + ) + try: + compute_force_constants_from_datasets( + ph3py, + fc_calculator=fc_calculator, + fc_calculator_options=fc_calculator_options, + symmetrize_fc=settings.fc_symmetry, + is_compact_fc=settings.is_compact_fc, log_level=log_level, ) - (fc_calculator, fc_calculator_options) = get_fc_calculator_params( - settings, log_level=(not read_fc["fc3"]) * 1 - ) - try: - compute_force_constants_from_datasets( - phono3py, - read_fc, - fc_calculator=fc_calculator, - fc_calculator_options=fc_calculator_options, - symmetrize_fc=settings.fc_symmetry, - is_compact_fc=settings.is_compact_fc, - use_pypolymlp=settings.use_pypolymlp, - mlp_params=settings.mlp_params, - displacement_distance=settings.displacement_distance, - number_of_snapshots=settings.random_displacements, - random_seed=settings.random_seed, - log_level=log_level, - ) - except ForceCalculatorRequiredError: - _show_fc_calculator_not_found(log_level) + except ForceCalculatorRequiredError: + _show_fc_calculator_not_found(log_level) - if log_level: - if phono3py.fc3 is None: - print("fc3 could not be obtained.") - if not forces_in_dataset(phono3py.dataset): + if log_level: + if ph3py.fc3 is None: + print("fc3 could not be obtained.") + if not forces_in_dataset(ph3py.dataset): + print("Forces were not found.") + else: + show_drift_fc3(ph3py.fc3, primitive=ph3py.primitive) + if ph3py.fc2 is None: + print("fc2 could not be obtained.") + if ph3py.phonon_supercell_matrix is None: + if not forces_in_dataset(ph3py.dataset): print("Forces were not found.") else: - show_drift_fc3(phono3py.fc3, primitive=phono3py.primitive) - if phono3py.fc2 is None: - print("fc2 could not be obtained.") - if phono3py.phonon_supercell_matrix is None: - if not forces_in_dataset(phono3py.dataset): - print("Forces were not found.") - else: - if not forces_in_dataset(phono3py.phonon_dataset): - print("Forces for dim-fc2 were not found.") - else: - show_drift_force_constants( - phono3py.fc2, primitive=phono3py.phonon_primitive, name="fc2" - ) + if not forces_in_dataset(ph3py.phonon_dataset): + print("Forces for dim-fc2 were not found.") + else: + show_drift_force_constants( + ph3py.fc2, primitive=ph3py.phonon_primitive, name="fc2" + ) - if phono3py.fc3 is None or phono3py.fc2 is None: - print_error() - sys.exit(1) + if ph3py.fc3 is None or ph3py.fc2 is None: + print_error() + sys.exit(1) - cutoff_distance = settings.cutoff_fc3_distance - if cutoff_distance is not None and cutoff_distance > 0: - if log_level: - print( - "Cutting-off fc3 by zero (cut-off distance: %f)" % cutoff_distance - ) - phono3py.cutoff_fc3_by_zero(cutoff_distance) + cutoff_distance = settings.cutoff_fc3_distance + if cutoff_distance is not None and cutoff_distance > 0: + if log_level: + print("Cutting-off fc3 by zero (cut-off distance: %f)" % cutoff_distance) + ph3py.cutoff_fc3_by_zero(cutoff_distance) - if not read_fc["fc3"]: - write_fc3_to_hdf5( - phono3py.fc3, - p2s_map=phono3py.primitive.p2s_map, - compression=settings.hdf5_compression, - ) - if log_level: - print('fc3 was written into "fc3.hdf5".') - if not read_fc["fc2"]: - write_fc2_to_hdf5( - phono3py.fc2, - p2s_map=phono3py.primitive.p2s_map, - physical_unit="eV/angstrom^2", - compression=settings.hdf5_compression, - ) - if log_level: - print('fc2 was written into "fc2.hdf5".') - else: - try: - create_phono3py_force_constants( - phono3py, - settings, - ph3py_yaml=ph3py_yaml, - phono3py_yaml_filename=phono3py_yaml_filename, - calculator=calculator, - input_filename=input_filename, - output_filename=output_filename, - log_level=log_level, - ) - except ForceCalculatorRequiredError: - _show_fc_calculator_not_found(log_level) + if not read_fc3: + write_fc3_to_hdf5( + ph3py.fc3, + p2s_map=ph3py.primitive.p2s_map, + compression=settings.hdf5_compression, + ) + if log_level: + print('fc3 was written into "fc3.hdf5".') + if not read_fc2: + write_fc2_to_hdf5( + ph3py.fc2, + p2s_map=ph3py.primitive.p2s_map, + physical_unit="eV/angstrom^2", + compression=settings.hdf5_compression, + ) + if log_level: + print('fc2 was written into "fc2.hdf5".') def _show_fc_calculator_not_found(log_level): @@ -1032,7 +997,7 @@ def main(**argparse_control): # 'frequency_factor_to_THz', 'num_frequency_points', # 'frequency_step', 'frequency_scale_factor', # 'cutoff_frequency') - phono3py, updated_settings = init_phono3py( + ph3py, updated_settings = init_phono3py( settings, cell_info, interface_mode, symprec, log_level ) @@ -1043,23 +1008,23 @@ def main(**argparse_control): show_general_settings( settings, run_mode, - phono3py, + ph3py, unitcell_filename, input_filename, output_filename, interface_mode, ) - if phono3py.supercell.magnetic_moments is None: - print("Spacegroup: %s" % phono3py.symmetry.get_international_table()) + if ph3py.supercell.magnetic_moments is None: + print("Spacegroup: %s" % ph3py.symmetry.get_international_table()) else: print( "Number of symmetry operations in supercell: %d" - % len(phono3py.symmetry.symmetry_operations["rotations"]) + % len(ph3py.symmetry.symmetry_operations["rotations"]) ) if log_level > 1: - show_phono3py_cells(phono3py) + show_phono3py_cells(ph3py) elif log_level: print( "Use -v option to watch primitive cell, unit cell, " @@ -1104,10 +1069,10 @@ def main(**argparse_control): # Write ir-grid points and grid addresses and then exit # ######################################################### if run_mode == "write_grid_info": - phono3py.mesh_numbers = settings.mesh_numbers + ph3py.mesh_numbers = settings.mesh_numbers write_grid_points( - phono3py.primitive, - phono3py.grid, + ph3py.primitive, + ph3py.grid, band_indices=settings.band_indices, sigmas=updated_settings["sigmas"], temperatures=updated_settings["temperatures"], @@ -1124,11 +1089,11 @@ def main(**argparse_control): # Show reduced number of triplets at grid points and then exit # ################################################################ if run_mode == "show_triplets_info": - phono3py.mesh_numbers = settings.mesh_numbers - grid_points = settings_to_grid_points(settings, phono3py.grid) + ph3py.mesh_numbers = settings.mesh_numbers + grid_points = settings_to_grid_points(settings, ph3py.grid) show_num_triplets( - phono3py.primitive, - phono3py.grid, + ph3py.primitive, + ph3py.grid, band_indices=settings.band_indices, grid_points=grid_points, is_kappa_star=settings.is_kappa_star, @@ -1143,7 +1108,7 @@ def main(**argparse_control): ################################## if settings.is_nac: store_nac_params( - phono3py, + ph3py, settings, cell_info["phonopy_yaml"], unitcell_filename, @@ -1152,39 +1117,93 @@ def main(**argparse_control): load_phonopy_yaml=load_phono3py_yaml, ) + ############ + # Datasets # + ############ + if load_phono3py_yaml: + assert ph3py.dataset is None + assert ph3py.phonon_dataset is None + load_dataset_and_phonon_dataset( + ph3py, + ph3py_yaml=cell_info["phonopy_yaml"], + phono3py_yaml_filename=unitcell_filename, + cutoff_pair_distance=settings.cutoff_pair_distance, + calculator=interface_mode, + log_level=log_level, + ) + + ################### + # polynomial MLPs # + ################### + if load_phono3py_yaml and settings.use_pypolymlp: + assert ph3py.mlp_dataset is None + if ph3py.dataset is not None: + ph3py.mlp_dataset = ph3py.dataset + ph3py.dataset = None + prepare_dataset = ( + settings.create_displacements or settings.random_displacements is not None + ) + run_pypolymlp_to_compute_forces( + ph3py, + mlp_params=settings.mlp_params, + displacement_distance=settings.displacement_distance, + number_of_snapshots=settings.random_displacements, + random_seed=settings.random_seed, + prepare_dataset=prepare_dataset, + log_level=log_level, + ) + + # pypolymlp dataset is stored in "phono3py.pmlp" and stop here. + if not prepare_dataset: + if log_level: + print( + "Generate displacements (--rd or -d) for proceeding to phonon " + "calculations." + ) + finalize_phono3py( + ph3py, confs_dict, log_level, filename=output_yaml_filename + ) + ################### # Force constants # ################### - store_force_constants( - phono3py, - settings, - cell_info["phonopy_yaml"], - unitcell_filename, - interface_mode, - input_filename, - output_filename, - load_phono3py_yaml, - log_level, - ) + if load_phono3py_yaml: + assert ph3py.fc2 is None + assert ph3py.fc3 is None + _store_force_constants(ph3py, settings, log_level) + else: + try: + create_phono3py_force_constants( + ph3py, + settings, + ph3py_yaml=cell_info["phonopy_yaml"], + phono3py_yaml_filename=unitcell_filename, + calculator=interface_mode, + input_filename=input_filename, + output_filename=output_filename, + log_level=log_level, + ) + except ForceCalculatorRequiredError: + _show_fc_calculator_not_found(log_level) ############################################ # Phonon Gruneisen parameter and then exit # ############################################ if settings.is_gruneisen: - run_gruneisen_then_exit(phono3py, settings, output_filename, log_level) + run_gruneisen_then_exit(ph3py, settings, output_filename, log_level) ################# # Show settings # ################# if log_level and run_mode is not None: - show_phono3py_settings(phono3py, settings, updated_settings, log_level) + show_phono3py_settings(ph3py, settings, updated_settings, log_level) ########################### # Joint DOS and then exit # ########################### if run_mode == "jdos": run_jdos_then_exit( - phono3py, settings, updated_settings, output_filename, log_level + ph3py, settings, updated_settings, output_filename, log_level ) ################################################ @@ -1193,7 +1212,7 @@ def main(**argparse_control): if settings.is_isotope and settings.mass_variances is None: from phonopy.structure.atoms import isotope_data - symbols = phono3py.phonon_primitive.symbols + symbols = ph3py.phonon_primitive.symbols in_database = True for s in set(symbols): if s not in isotope_data: @@ -1210,14 +1229,14 @@ def main(**argparse_control): # Phonon-isotope lifetime and then exit # ######################################### if run_mode == "isotope": - run_isotope_then_exit(phono3py, settings, updated_settings, log_level) + run_isotope_then_exit(ph3py, settings, updated_settings, log_level) ######################################## # Initialize phonon-phonon interaction # ######################################## if run_mode is not None: init_phph_interaction( - phono3py, + ph3py, settings, updated_settings, input_filename, @@ -1229,8 +1248,8 @@ def main(**argparse_control): # Run imaginary part of self energy of bubble diagram # ####################################################### if run_mode == "imag_self_energy": - phono3py.run_imag_self_energy( - settings_to_grid_points(settings, phono3py.grid), + ph3py.run_imag_self_energy( + settings_to_grid_points(settings, ph3py.grid), updated_settings["temperature_points"], frequency_step=updated_settings["frequency_step"], num_frequency_points=updated_settings["num_frequency_points"], @@ -1245,8 +1264,8 @@ def main(**argparse_control): # Run frequency shift calculation of bubble diagram # ##################################################### elif run_mode == "real_self_energy": - phono3py.run_real_self_energy( - settings_to_grid_points(settings, phono3py.grid), + ph3py.run_real_self_energy( + settings_to_grid_points(settings, ph3py.grid), updated_settings["temperature_points"], frequency_step=updated_settings["frequency_step"], num_frequency_points=updated_settings["num_frequency_points"], @@ -1259,8 +1278,8 @@ def main(**argparse_control): # Run spectral function calculation of bubble diagram # ####################################################### elif run_mode == "spectral_function": - phono3py.run_spectral_function( - settings_to_grid_points(settings, phono3py.grid), + ph3py.run_spectral_function( + settings_to_grid_points(settings, ph3py.grid), updated_settings["temperature_points"], frequency_step=updated_settings["frequency_step"], num_frequency_points=updated_settings["num_frequency_points"], @@ -1274,8 +1293,8 @@ def main(**argparse_control): # Run lattice thermal conductivity # #################################### elif run_mode == "conductivity-RTA" or run_mode == "conductivity-LBTE": - grid_points = settings_to_grid_points(settings, phono3py.grid) - phono3py.run_thermal_conductivity( + grid_points = settings_to_grid_points(settings, ph3py.grid) + ph3py.run_thermal_conductivity( is_LBTE=settings.is_lbte, temperatures=updated_settings["temperatures"], is_isotope=settings.is_isotope, @@ -1314,4 +1333,4 @@ def main(**argparse_control): + "-" * 11 ) - finalize_phono3py(phono3py, confs_dict, log_level, filename=output_yaml_filename) + finalize_phono3py(ph3py, confs_dict, log_level, filename=output_yaml_filename) From 9587735e29878cc4e4ef769aea1536dbc9a0f615 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 16:21:40 +0900 Subject: [PATCH 06/17] Made possible to specify -d option for phono3py-load --- phono3py/cui/phono3py_argparse.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phono3py/cui/phono3py_argparse.py b/phono3py/cui/phono3py_argparse.py index cd61b766..597f3074 100644 --- a/phono3py/cui/phono3py_argparse.py +++ b/phono3py/cui/phono3py_argparse.py @@ -236,15 +236,15 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False): "force constants" ), ) + parser.add_argument( + "-d", + "--disp", + dest="is_displacement", + action="store_true", + default=False, + help="As first stage, get least displacements", + ) if not load_phono3py_yaml: - parser.add_argument( - "-d", - "--disp", - dest="is_displacement", - action="store_true", - default=False, - help="As first stage, get least displacements", - ) parser.add_argument( "--dim", nargs="+", From bd9cfd81c70ec7494acc8e183ad49b4debb820f1 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 16:42:42 +0900 Subject: [PATCH 07/17] Minor fix of run_mode --- doc/pypolymlp.md | 24 ++++++++++++------------ phono3py/cui/phono3py_script.py | 4 +++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/doc/pypolymlp.md b/doc/pypolymlp.md index 59fba9ca..f7c52183 100644 --- a/doc/pypolymlp.md +++ b/doc/pypolymlp.md @@ -162,16 +162,16 @@ crystal symmetry. Having `phono3py_params.yaml`, phono3py is executed with `--pypolymlp` option, ``` -% phono3py-load --pypolymlp phono3py_params.yaml +% phono3py-load phono3py_params.yaml --pypolymlp -d _ _____ _ __ | |__ ___ _ __ ___|___ / _ __ _ _ | '_ \| '_ \ / _ \| '_ \ / _ \ |_ \| '_ \| | | | | |_) | | | | (_) | | | | (_) |__) | |_) | |_| | | .__/|_| |_|\___/|_| |_|\___/____/| .__/ \__, | |_| |_| |___/ - 3.5.0 + 3.11.2 --------------------------[time 2024-09-19 15:20:27]------------------------- +-------------------------[time 2025-01-15 16:25:17]------------------------- Compiled with OpenMP support (max 10 threads). Running in phono3py.load mode. Python version 3.12.6 @@ -187,7 +187,6 @@ Primitive matrix: Spacegroup: Fm-3m (225) Use -v option to watch primitive cell, unit cell, and supercell structures. NAC parameters were read from "phono3py_params.yaml". ------------------------------ Force constants ------------------------------ Displacement dataset for fc3 was read from "phono3py_params.yaml". ----------------------------- pypolymlp start ------------------------------ Pypolymlp is a generator of polynomial machine learning potentials. @@ -204,16 +203,17 @@ Clear training X.T @ X Calculate X.T @ X for test data Clear test X.T @ X Regression: model selection ... -- alpha = 1.000e-03 : rmse (train, test) = 9.39542e+14 9.39543e+14 -- alpha = 1.000e-02 : rmse (train, test) = 9.39542e+14 9.39543e+14 -- alpha = 1.000e-01 : rmse (train, test) = 0.03738 0.04961 -- alpha = 1.000e+00 : rmse (train, test) = 0.03900 0.04742 -- alpha = 1.000e+01 : rmse (train, test) = 0.04058 0.04584 +- alpha = 1.000e-03 : rmse (train, test) = 1.12211e+15 1.12211e+15 +- alpha = 1.000e-02 : rmse (train, test) = 1.12211e+15 1.12211e+15 +- alpha = 1.000e-01 : rmse (train, test) = 0.00002 0.00002 +- alpha = 1.000e+00 : rmse (train, test) = 0.00002 0.00002 +- alpha = 1.000e+01 : rmse (train, test) = 0.00002 0.00002 MLPs were written into "phono3py.pmlp" ------------------------------ pypolymlp end ------------------------------- Generate displacements Displacement distance: 0.001 Evaluate forces in 292 supercells by pypolymlp +----------------------------- Force constants ------------------------------ Computing fc3[ 1, x, x ] using numpy.linalg.pinv. Displacements (in Angstrom): [ 0.0010 0.0000 0.0000] @@ -225,14 +225,14 @@ Displacements (in Angstrom): Expanding fc3. fc3 was symmetrized. fc2 was symmetrized. -Max drift of fc3: -0.000000 (zzz) -0.000000 (zzz) -0.000000 (zzz) -Max drift of fc2: -0.000000 (zz) -0.000000 (zz) +Max drift of fc3: 0.000000 (xxx) 0.000000 (xxx) 0.000000 (xxx) +Max drift of fc2: 0.000000 (yy) 0.000000 (yy) fc3 was written into "fc3.hdf5". fc2 was written into "fc2.hdf5". ----------- None of ph-ph interaction calculation was performed. ----------- Dataset generated using MLPs was written in "phono3py_mlp_eval_dataset.yaml". Summary of calculation was written in "phono3py.yaml". --------------------------[time 2024-09-19 15:21:41]------------------------- +-------------------------[time 2025-01-15 16:26:37]------------------------- _ ___ _ __ __| | / _ \ '_ \ / _` | diff --git a/phono3py/cui/phono3py_script.py b/phono3py/cui/phono3py_script.py index 7640a23c..3ce2cb85 100644 --- a/phono3py/cui/phono3py_script.py +++ b/phono3py/cui/phono3py_script.py @@ -206,7 +206,9 @@ def get_run_mode(settings): run_mode = "conductivity-RTA" elif settings.is_lbte: run_mode = "conductivity-LBTE" - elif settings.create_displacements: + elif ( + settings.create_displacements or settings.random_displacements is not None + ) and not settings.use_pypolymlp: run_mode = "displacements" elif settings.write_phonon: run_mode = "phonon" From a66f59ac47492a16bf91d6ed47d3bedc1eee0fae Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 17:00:53 +0900 Subject: [PATCH 08/17] Symfc is used to handle random displacements unless specified in CUI. --- doc/pypolymlp.md | 32 ++++++++++++++++---------------- phono3py/cui/phono3py_script.py | 13 ++++++++++++- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/doc/pypolymlp.md b/doc/pypolymlp.md index f7c52183..86e61f7c 100644 --- a/doc/pypolymlp.md +++ b/doc/pypolymlp.md @@ -269,9 +269,9 @@ Having `phono3py_params.yaml`, phono3py is executed with `--pypolymlp` option, | |_) | | | | (_) | | | | (_) |__) | |_) | |_| | | .__/|_| |_|\___/|_| |_|\___/____/| .__/ \__, | |_| |_| |___/ - 3.5.0 + 3.11.2 --------------------------[time 2024-09-19 15:33:23]------------------------- +-------------------------[time 2025-01-15 16:43:57]------------------------- Compiled with OpenMP support (max 10 threads). Running in phono3py.load mode. Python version 3.12.6 @@ -287,7 +287,6 @@ Primitive matrix: Spacegroup: Fm-3m (225) Use -v option to watch primitive cell, unit cell, and supercell structures. NAC parameters were read from "phono3py_params.yaml". ------------------------------ Force constants ------------------------------ Displacement dataset for fc3 was read from "phono3py_params.yaml". ----------------------------- pypolymlp start ------------------------------ Pypolymlp is a generator of polynomial machine learning potentials. @@ -304,39 +303,40 @@ Clear training X.T @ X Calculate X.T @ X for test data Clear test X.T @ X Regression: model selection ... -- alpha = 1.000e-03 : rmse (train, test) = 9.39542e+14 9.39543e+14 -- alpha = 1.000e-02 : rmse (train, test) = 9.39542e+14 9.39543e+14 -- alpha = 1.000e-01 : rmse (train, test) = 0.03738 0.04961 -- alpha = 1.000e+00 : rmse (train, test) = 0.03900 0.04742 -- alpha = 1.000e+01 : rmse (train, test) = 0.04058 0.04584 +- alpha = 1.000e-03 : rmse (train, test) = 1.12211e+15 1.12211e+15 +- alpha = 1.000e-02 : rmse (train, test) = 1.12211e+15 1.12211e+15 +- alpha = 1.000e-01 : rmse (train, test) = 0.00002 0.00002 +- alpha = 1.000e+00 : rmse (train, test) = 0.00002 0.00002 +- alpha = 1.000e+01 : rmse (train, test) = 0.00002 0.00002 MLPs were written into "phono3py.pmlp" ------------------------------ pypolymlp end ------------------------------- Generate random displacements Twice of number of snapshots will be generated for plus-minus displacements. Displacement distance: 0.001 Evaluate forces in 400 supercells by pypolymlp +----------------------------- Force constants ------------------------------ -------------------------------- Symfc start ------------------------------- -Symfc is a non-trivial force constants calculator. Please cite the paper: -A. Seko and A. Togo, arXiv:2403.03588. +Symfc is a force constants calculator. See the following paper: +A. Seko and A. Togo, Phys. Rev. B, 110, 214302 (2024). Symfc is developed at https://github.com/symfc/symfc. Computing [2, 3] order force constants. Increase log-level to watch detailed symfc log. --------------------------------- Symfc end -------------------------------- -------------------------------- Symfc start ------------------------------- -Symfc is a non-trivial force constants calculator. Please cite the paper: -A. Seko and A. Togo, arXiv:2403.03588. +Symfc is a force constants calculator. See the following paper: +A. Seko and A. Togo, Phys. Rev. B, 110, 214302 (2024). Symfc is developed at https://github.com/symfc/symfc. Computing [2] order force constants. Increase log-level to watch detailed symfc log. --------------------------------- Symfc end -------------------------------- -Max drift of fc3: -0.000000 (xyx) 0.000000 (zyy) -0.000000 (xyx) -Max drift of fc2: 0.000000 (xx) 0.000000 (xx) +Max drift of fc3: -0.000000 (zxz) -0.000000 (xzz) -0.000000 (xzz) +Max drift of fc2: -0.000000 (yy) -0.000000 (yy) fc3 was written into "fc3.hdf5". fc2 was written into "fc2.hdf5". ----------- None of ph-ph interaction calculation was performed. ----------- Dataset generated using MLPs was written in "phono3py_mlp_eval_dataset.yaml". Summary of calculation was written in "phono3py.yaml". --------------------------[time 2024-09-19 15:34:41]------------------------- +-------------------------[time 2025-01-15 16:45:15]------------------------- _ ___ _ __ __| | / _ \ '_ \ / _` | @@ -377,7 +377,7 @@ constants by loading the MLPs from `phono3py.pmlp` as follows: | |_) | | | | (_) | | | | (_) |__) | |_) | |_| | | .__/|_| |_|\___/|_| |_|\___/____/| .__/ \__, | |_| |_| |___/ - 3.11.1-dev14+g5f281b65 + 3.11.2 -------------------------[time 2025-01-12 10:08:31]------------------------- Compiled with OpenMP support (max 10 threads). diff --git a/phono3py/cui/phono3py_script.py b/phono3py/cui/phono3py_script.py index 3ce2cb85..f1188d28 100644 --- a/phono3py/cui/phono3py_script.py +++ b/phono3py/cui/phono3py_script.py @@ -615,7 +615,18 @@ def _store_force_constants(ph3py: Phono3py, settings: Phono3pySettings, log_leve log_level=log_level, ) except ForceCalculatorRequiredError: - _show_fc_calculator_not_found(log_level) + if log_level: + print("Symfc will be used to handle general (or random) displacements.") + + compute_force_constants_from_datasets( + ph3py, + fc_calculator="symfc", + fc_calculator_options=fc_calculator_options, + symmetrize_fc=settings.fc_symmetry, + is_compact_fc=settings.is_compact_fc, + log_level=log_level, + ) + # _show_fc_calculator_not_found(log_level) if log_level: if ph3py.fc3 is None: From bbd238090a3b698238a8b47d150c4cc2bc0e48e4 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 18:10:29 +0900 Subject: [PATCH 09/17] Update a test due to the change of default behaviour --- test/cui/test_phono3py_load_script.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/cui/test_phono3py_load_script.py b/test/cui/test_phono3py_load_script.py index c3b751b1..3e7523a6 100644 --- a/test/cui/test_phono3py_load_script.py +++ b/test/cui/test_phono3py_load_script.py @@ -67,9 +67,13 @@ def test_phono3py_load(): file_path.unlink() -@pytest.mark.parametrize("fc_calculator,exit_code", [(None, 1), ("symfc", 0)]) +@pytest.mark.parametrize("fc_calculator,exit_code", [(None, 0), ("symfc", 0)]) def test_phono3py_load_with_typeII_dataset(fc_calculator, exit_code): - """Test phono3py-load script with typeII dataset.""" + """Test phono3py-load script with typeII dataset. + + When None, fallback to symfc. + + """ pytest.importorskip("symfc") argparse_control = _get_phono3py_load_args( cwd / ".." / "phono3py_params-Si111-rd.yaml.xz", fc_calculator=fc_calculator From c64aefd726a16449f235ce4a67a4c774864f29d1 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 19:36:24 +0900 Subject: [PATCH 10/17] Update pypolymlp interface documentation --- doc/pypolymlp.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/doc/pypolymlp.md b/doc/pypolymlp.md index 86e61f7c..39a4af60 100644 --- a/doc/pypolymlp.md +++ b/doc/pypolymlp.md @@ -257,12 +257,13 @@ corresponding forces are stored in the `phono3py_mlp_eval_dataset` file. After developing MLPs, random displacements are generated by specifying {ref}`--rd ` option. To compute force constants with random displacements, an external force constants calculator is necessary. -For this, symfc is used which is invoked by `--symfc` option. +By default, symfc is used unless another force constants solver is explicitly +specified. Having `phono3py_params.yaml`, phono3py is executed with `--pypolymlp` option, ``` -% phono3py-load --pypolymlp --rd 200 --symfc phono3py_params.yaml +% phono3py-load --pypolymlp --rd 200 phono3py_params.yaml _ _____ _ __ | |__ ___ _ __ ___|___ / _ __ _ _ | '_ \| '_ \ / _ \| '_ \ / _ \ |_ \| '_ \| | | | @@ -271,10 +272,10 @@ Having `phono3py_params.yaml`, phono3py is executed with `--pypolymlp` option, |_| |_| |___/ 3.11.2 --------------------------[time 2025-01-15 16:43:57]------------------------- +-------------------------[time 2025-01-15 19:30:47]------------------------- Compiled with OpenMP support (max 10 threads). Running in phono3py.load mode. -Python version 3.12.6 +Python version 3.12.3 Spglib version 2.5.0 ----------------------------- General settings ----------------------------- HDF5 data compression filter: gzip @@ -315,6 +316,7 @@ Generate random displacements Displacement distance: 0.001 Evaluate forces in 400 supercells by pypolymlp ----------------------------- Force constants ------------------------------ +Symfc will be used to handle general (or random) displacements. -------------------------------- Symfc start ------------------------------- Symfc is a force constants calculator. See the following paper: A. Seko and A. Togo, Phys. Rev. B, 110, 214302 (2024). @@ -336,7 +338,7 @@ fc2 was written into "fc2.hdf5". ----------- None of ph-ph interaction calculation was performed. ----------- Dataset generated using MLPs was written in "phono3py_mlp_eval_dataset.yaml". Summary of calculation was written in "phono3py.yaml". --------------------------[time 2025-01-15 16:45:15]------------------------- +-------------------------[time 2025-01-15 19:32:04]------------------------- _ ___ _ __ __| | / _ \ '_ \ / _` | @@ -360,9 +362,8 @@ resulting forces are computed accordingly. The displacement distance is set by the `--amplitude` option, whose default value is 0.001 Angstrom. When the `--rd` option is used, it specifies the number of supercells with random directional displacements. Note that to achieve accurate force constants, the actual number -of generated supercells is twice the specified number. Additionally, when using -`--rd`, the `--symfc` option must be used together. If `--rd` is omitted, -systematic displacements are introduced, and thus `--symfc` is not required. +of generated supercells is twice the specified number. If `--rd` is omitted, +systematic displacements are introduced. Once the file `phono3py.pmlp` is obtained, force constants can be calculated using MLPs from `phono3py.pmlp`. After removing the `fc3.hdf5` and `fc2.hdf5` @@ -370,7 +371,7 @@ files, `phono3py-load` will detect `phono3py.pmlp` and then compute the force constants by loading the MLPs from `phono3py.pmlp` as follows: ``` -% phono3py-load --pypolymlp --rd 100 --symfc --amplitude 0.01 phono3py.yaml +% phono3py-load --pypolymlp --rd 100 --amplitude 0.01 phono3py.yaml _ _____ _ __ | |__ ___ _ __ ___|___ / _ __ _ _ | '_ \| '_ \ / _ \| '_ \ / _ \ |_ \| '_ \| | | | @@ -379,7 +380,7 @@ constants by loading the MLPs from `phono3py.pmlp` as follows: |_| |_| |___/ 3.11.2 --------------------------[time 2025-01-12 10:08:31]------------------------- +-------------------------[time 2025-01-15 19:28:22]------------------------- Compiled with OpenMP support (max 10 threads). Running in phono3py.load mode. Python version 3.12.3 @@ -395,7 +396,6 @@ Primitive matrix: Spacegroup: Fm-3m (225) Use -v option to watch primitive cell, unit cell, and supercell structures. NAC parameters were read from "phono3py.yaml". ------------------------------ Force constants ------------------------------ ----------------------------- pypolymlp start ------------------------------ Pypolymlp is a generator of polynomial machine learning potentials. Please cite the paper: A. Seko, J. Appl. Phys. 133, 011101 (2023). @@ -406,6 +406,8 @@ Generate random displacements Twice of number of snapshots will be generated for plus-minus displacements. Displacement distance: 0.01 Evaluate forces in 200 supercells by pypolymlp +----------------------------- Force constants ------------------------------ +Symfc will be used to handle general (or random) displacements. -------------------------------- Symfc start ------------------------------- Symfc is a force constants calculator. See the following paper: A. Seko and A. Togo, Phys. Rev. B, 110, 214302 (2024). @@ -427,7 +429,7 @@ fc2 was written into "fc2.hdf5". ----------- None of ph-ph interaction calculation was performed. ----------- Dataset generated using MLPs was written in "phono3py_mlp_eval_dataset.yaml". Summary of calculation was written in "phono3py.yaml". --------------------------[time 2025-01-12 10:08:40]------------------------- +-------------------------[time 2025-01-15 19:28:30]------------------------- _ ___ _ __ __| | / _ \ '_ \ / _` | From 90c600c61b0753e21ade519cf9d4ed1759b2c27d Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Wed, 15 Jan 2025 21:46:22 +0900 Subject: [PATCH 11/17] Fix kaccum_script --- phono3py/cui/kaccum_script.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/phono3py/cui/kaccum_script.py b/phono3py/cui/kaccum_script.py index c08ac3c7..3cb5e076 100644 --- a/phono3py/cui/kaccum_script.py +++ b/phono3py/cui/kaccum_script.py @@ -85,7 +85,7 @@ def _get_ir_grid_info(bz_grid: BZGrid, weights, qpoints=None, ir_grid_points=Non """ (ir_grid_points_ref, weights_ref, ir_grid_map) = get_ir_grid_points(bz_grid) - + ir_grid_points_ref = bz_grid.grg2bzg[ir_grid_points_ref] _assert_grid_in_hdf5( weights, qpoints, ir_grid_points, weights_ref, ir_grid_points_ref, bz_grid ) @@ -116,7 +116,8 @@ def _assert_grid_in_hdf5( D_diag = bz_grid.D_diag.astype("double") qpoints_for_check = np.dot(addresses / D_diag, bz_grid.Q.T) diff_q = qpoints - qpoints_for_check - np.testing.assert_almost_equal(diff_q, np.rint(diff_q)) + diff_q -= np.rint(diff_q) + np.testing.assert_allclose(diff_q, 0, atol=1e-5) def _get_calculator(args): @@ -299,7 +300,10 @@ def main(): if "weight" in f_kappa: frequencies = f_kappa["frequency"][:] ir_weights = f_kappa["weight"][:] - ir_grid_points_BZ = None + if "grid_point" in f_kappa: + ir_grid_points_BZ = f_kappa["grid_point"][:] + else: + ir_grid_points_BZ = None qpoints = f_kappa["qpoint"][:] elif "ir_grid_weights" in f_kappa and not args.no_gridsym: ir_weights = f_kappa["ir_grid_weights"][:] @@ -321,11 +325,9 @@ def main(): ir_grid_map = None else: ir_grid_points, ir_grid_map = _get_ir_grid_info( - bz_grid, - ir_weights, - qpoints=qpoints, - ir_grid_points=bz_grid.bzg2grg[ir_grid_points_BZ], + bz_grid, ir_weights, qpoints=qpoints, ir_grid_points=ir_grid_points_BZ ) + ir_grid_points = bz_grid.bzg2grg[ir_grid_points] conditions = frequencies > 0 if np.logical_not(conditions).sum() > 3: sys.stderr.write( From befc1fdba008afa9f41af3a8af8b206c3a5a73fc Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Thu, 16 Jan 2025 12:45:56 +0900 Subject: [PATCH 12/17] Refactoring of kaccum_script.py --- phono3py/cui/kaccum_script.py | 372 +++++++++++++++++++--------------- phono3py/phonon/grid.py | 10 +- 2 files changed, 221 insertions(+), 161 deletions(-) diff --git a/phono3py/cui/kaccum_script.py b/phono3py/cui/kaccum_script.py index 3cb5e076..b42c18d6 100644 --- a/phono3py/cui/kaccum_script.py +++ b/phono3py/cui/kaccum_script.py @@ -2,11 +2,12 @@ import argparse import sys +from typing import Optional import h5py import numpy as np from phonopy.cui.collect_cell_info import collect_cell_info -from phonopy.interface.calculator import read_crystal_structure +from phonopy.structure.atoms import PhonopyAtoms from phonopy.structure.symmetry import Symmetry from phono3py.interface.phono3py_yaml import Phono3pyYaml @@ -61,7 +62,12 @@ def _set_T_target(temperatures, mode_prop, T_target, mean_freepath=None): return temperatures, mode_prop -def _get_ir_grid_info(bz_grid: BZGrid, weights, qpoints=None, ir_grid_points=None): +def _get_ir_grid_info( + bz_grid: BZGrid, + weights: np.ndarray, + qpoints: Optional[np.ndarray] = None, + ir_grid_points: Optional[np.ndarray] = None, +) -> tuple[np.ndarray, np.ndarray]: """Return ir-grid point information. Parameters @@ -80,7 +86,7 @@ def _get_ir_grid_info(bz_grid: BZGrid, weights, qpoints=None, ir_grid_points=Non ir_grid_points : ndarray Ir-grid point indices in BZ-grid. shape=(ir_grid_points, ), dtype='long' - ir_grid_map : ndarray, optional, default=None + ir_grid_map : ndarray Mapping table to ir-grid point indices in GR-grid. """ @@ -120,37 +126,6 @@ def _assert_grid_in_hdf5( np.testing.assert_allclose(diff_q, 0, atol=1e-5) -def _get_calculator(args): - """Return calculator name.""" - interface_mode = None - # if args.qe_mode: - # interface_mode = "qe" - # elif args.crystal_mode: - # interface_mode = "crystal" - # elif args.abinit_mode: - # interface_mode = "abinit" - # elif args.turbomole_mode: - # interface_mode = "turbomole" - return interface_mode - - -def _read_files(args): - """Read crystal structure and kappa.hdf5 files.""" - interface_mode = _get_calculator(args) - if len(args.filenames) > 1: - cell, _ = read_crystal_structure( - args.filenames[0], interface_mode=interface_mode - ) - f = h5py.File(args.filenames[1], "r") - else: - cell, _ = read_crystal_structure( - args.cell_filename, interface_mode=interface_mode - ) - f = h5py.File(args.filenames[0], "r") - - return cell, f - - def _get_mode_property(args, f_kappa): """Read property data from hdf5 file object.""" if args.pqj: @@ -249,55 +224,58 @@ def _get_parser(): return args -def main(): - """Calculate kappa spectrum. - - Usage - ----- - If `phono3py_disp.yaml` or `phono3py.yaml` exists in current directory, - ``` - % phono3py-kaccum kappa-m111111.hdf5 - ``` - - Plot by gnuplot - --------------- - ``` - % gnuplot - ... - gnuplot> p "kaccum.dat" i 30 u 1:2 w l, "kaccum.dat" i 30 u 1:8 w l - ``` - - """ - args = _get_parser() +def _read_files(args: argparse.Namespace) -> tuple[h5py.File, PhonopyAtoms]: primitive = None - if len(args.filenames) > 1: - raise RuntimeError( - 'Use of "phono3py-kaccum CRYSTAL_STRUCTURE_FILE" is not supported.' - ) - else: - cell_info = collect_cell_info( - supercell_matrix=np.eye(3, dtype=int), - phonopy_yaml_cls=Phono3pyYaml, - ) - cell_filename = cell_info["optional_structure_info"][0] - print(f'# Crystal structure was read from "{cell_filename}".') - cell = cell_info["unitcell"] - phpy_yaml = cell_info.get("phonopy_yaml", None) - if phpy_yaml is not None: - primitive = cell_info["phonopy_yaml"].primitive - if primitive is None: - primitive = cell - f_kappa = h5py.File(args.filenames[0], "r") - + cell_info = collect_cell_info( + supercell_matrix=np.eye(3, dtype=int), + phonopy_yaml_cls=Phono3pyYaml, + ) + cell_filename = cell_info["optional_structure_info"][0] + print(f'# Crystal structure was read from "{cell_filename}".') + cell = cell_info["unitcell"] + phpy_yaml = cell_info.get("phonopy_yaml", None) + if phpy_yaml is not None: + primitive = cell_info["phonopy_yaml"].primitive + if primitive is None: + primitive = cell + f_kappa = h5py.File(args.filenames[0], "r") + return f_kappa, primitive + + +def _collect_data( + f_kappa: h5py.File, primitive: PhonopyAtoms, args: argparse.Namespace +) -> tuple[ + Optional[np.ndarray], + Optional[np.ndarray], + np.ndarray, + BZGrid, + np.ndarray, + np.ndarray, +]: + # bz_grid if "grid_matrix" in f_kappa: mesh = np.array(f_kappa["grid_matrix"][:], dtype="long") else: mesh = np.array(f_kappa["mesh"][:], dtype="long") + primitive_symmetry = Symmetry(primitive) + bz_grid = BZGrid( + mesh, + lattice=primitive.cell, + symmetry_dataset=primitive_symmetry.dataset, + store_dense_gp_map=True, + ) + + # temperatures if "temperature" in f_kappa: temperatures = f_kappa["temperature"][:] else: temperatures = np.zeros(1, dtype="double") + + # frequencies, ir_weights if "weight" in f_kappa: + # This is to read "kappa-xxx.hdf5". + # ir_grid_points_BZ in BZ-grid index will be transformed to GR-grid index. + print("# Read frequency, weight, qpoint, and optionally grid_point.") frequencies = f_kappa["frequency"][:] ir_weights = f_kappa["weight"][:] if "grid_point" in f_kappa: @@ -306,20 +284,18 @@ def main(): ir_grid_points_BZ = None qpoints = f_kappa["qpoint"][:] elif "ir_grid_weights" in f_kappa and not args.no_gridsym: + # This is to read "phonon-xxx.hdf5". + print("# Read ir_grid_weights.") ir_weights = f_kappa["ir_grid_weights"][:] ir_grid_points_BZ = f_kappa["ir_grid_points"][:] qpoints = None frequencies = np.array(f_kappa["frequency"][ir_grid_points_BZ], dtype="double") else: + print("# Read frequency.") frequencies = f_kappa["frequency"][:] ir_weights = np.ones(len(frequencies), dtype="long") - primitive_symmetry = Symmetry(primitive) - bz_grid = BZGrid( - mesh, - lattice=primitive.cell, - symmetry_dataset=primitive_symmetry.dataset, - store_dense_gp_map=True, - ) + + # ir_grid_points (GR-grid), ir_grid_map (GR-grid) if args.no_gridsym or (ir_weights == 1).all(): ir_grid_points = None ir_grid_map = None @@ -328,6 +304,7 @@ def main(): bz_grid, ir_weights, qpoints=qpoints, ir_grid_points=ir_grid_points_BZ ) ir_grid_points = bz_grid.bzg2grg[ir_grid_points] + conditions = frequencies > 0 if np.logical_not(conditions).sum() > 3: sys.stderr.write( @@ -335,6 +312,143 @@ def main(): ) frequencies = np.where(conditions, frequencies, 0) + return ir_grid_points, ir_grid_map, ir_weights, bz_grid, frequencies, temperatures + + +def _run_scalar( + args: argparse.Namespace, + f_kappa: h5py.File, + temperatures: np.ndarray, + frequencies: np.ndarray, + ir_weights: np.ndarray, + ir_grid_map: Optional[np.ndarray], + ir_grid_points: Optional[np.ndarray], + bz_grid: BZGrid, +): + mode_prop = _get_mode_property(args, f_kappa) + + if args.temperature is not None and not ( + args.gv_norm or args.pqj or args.gruneisen or args.dos + ): + temperatures, mode_prop = _set_T_target( + temperatures, mode_prop, args.temperature + ) + if args.smearing: + mode_prop_dos = GammaDOSsmearing( + mode_prop, + frequencies, + ir_weights, + num_sampling_points=args.num_sampling_points, + ) + sampling_points, gdos = mode_prop_dos.get_gdos() + sampling_points = np.tile(sampling_points, (len(gdos), 1)) + _show_scalar(gdos[:, :, :], temperatures, sampling_points, args) + else: + for i, w in enumerate(ir_weights): + mode_prop[:, i, :] *= w + kdos, sampling_points = run_prop_dos( + frequencies, + mode_prop[:, :, :, None], + ir_grid_map, + ir_grid_points, + args.num_sampling_points, + bz_grid, + ) + _show_scalar(kdos[:, :, :, 0], temperatures, sampling_points, args) + + +def _run_tensor( + args: argparse.Namespace, + f_kappa: h5py.File, + temperatures: np.ndarray, + frequencies: np.ndarray, + ir_grid_map: Optional[np.ndarray], + ir_grid_points: Optional[np.ndarray], + bz_grid: BZGrid, + primitive: PhonopyAtoms, +): + if args.gv: + gv_sum2 = f_kappa["gv_by_gv"][:] + # gv x gv is divied by primitive cell volume. + unit_conversion = primitive.volume + mode_prop = gv_sum2.reshape((1,) + gv_sum2.shape) / unit_conversion + else: + if "mode_kappa" in f_kappa: + mode_prop = f_kappa["mode_kappa"][:] + else: + print('No "mode_kappa" in mode_prop.') + sys.exit(1) + + if args.mfp: + if "mean_free_path" in f_kappa: + mfp = f_kappa["mean_free_path"][:] + mean_freepath = np.sqrt((mfp**2).sum(axis=3)) + else: + mean_freepath = get_mfp(f_kappa["gamma"][:], f_kappa["group_velocity"][:]) + if args.temperature is not None: + (temperatures, mode_prop, mean_freepath) = _set_T_target( + temperatures, + mode_prop, + args.temperature, + mean_freepath=mean_freepath, + ) + + kdos, sampling_points = run_mfp_dos( + mean_freepath, + mode_prop, + ir_grid_map, + ir_grid_points, + args.num_sampling_points, + bz_grid, + ) + _show_tensor(kdos, temperatures, sampling_points, args) + else: + if args.temperature is not None and not args.gv: + temperatures, mode_prop = _set_T_target( + temperatures, mode_prop, args.temperature + ) + kdos, sampling_points = run_prop_dos( + frequencies, + mode_prop, + ir_grid_map, + ir_grid_points, + args.num_sampling_points, + bz_grid, + ) + _show_tensor(kdos, temperatures, sampling_points, args) + + +def main(): + """Calculate kappa spectrum. + + Usage + ----- + If `phono3py_disp.yaml` or `phono3py.yaml` exists in current directory, + ``` + % phono3py-kaccum kappa-m111111.hdf5 + ``` + + Plot by gnuplot + --------------- + ``` + % gnuplot + ... + gnuplot> p "kaccum.dat" i 30 u 1:2 w l, "kaccum.dat" i 30 u 1:8 w l + ``` + + """ + args = _get_parser() + if len(args.filenames) > 1: + raise RuntimeError( + 'Use of "phono3py-kaccum CRYSTAL_STRUCTURE_FILE" is not supported.' + ) + + f_kappa, primitive = _read_files(args) + + ir_grid_points, ir_grid_map, ir_weights, bz_grid, frequencies, temperatures = ( + _collect_data(f_kappa, primitive, args) + ) + # Run for scaler if ( args.gamma @@ -345,82 +459,24 @@ def main(): or args.gv_norm or args.dos ): - mode_prop = _get_mode_property(args, f_kappa) - - if args.temperature is not None and not ( - args.gv_norm or args.pqj or args.gruneisen or args.dos - ): - temperatures, mode_prop = _set_T_target( - temperatures, mode_prop, args.temperature - ) - if args.smearing: - mode_prop_dos = GammaDOSsmearing( - mode_prop, - frequencies, - ir_weights, - num_sampling_points=args.num_sampling_points, - ) - sampling_points, gdos = mode_prop_dos.get_gdos() - sampling_points = np.tile(sampling_points, (len(gdos), 1)) - _show_scalar(gdos[:, :, :], temperatures, sampling_points, args) - else: - for i, w in enumerate(ir_weights): - mode_prop[:, i, :] *= w - kdos, sampling_points = run_prop_dos( - frequencies, - mode_prop[:, :, :, None], - ir_grid_map, - ir_grid_points, - args.num_sampling_points, - bz_grid, - ) - _show_scalar(kdos[:, :, :, 0], temperatures, sampling_points, args) - + _run_scalar( + args, + f_kappa, + temperatures, + frequencies, + ir_weights, + ir_grid_map, + ir_grid_points, + bz_grid, + ) else: # Run for tensor - if args.gv: - gv_sum2 = f_kappa["gv_by_gv"][:] - # gv x gv is divied by primitive cell volume. - unit_conversion = primitive.volume - mode_prop = gv_sum2.reshape((1,) + gv_sum2.shape) / unit_conversion - else: - mode_prop = f_kappa["mode_kappa"][:] - - if args.mfp: - if "mean_free_path" in f_kappa: - mfp = f_kappa["mean_free_path"][:] - mean_freepath = np.sqrt((mfp**2).sum(axis=3)) - else: - mean_freepath = get_mfp( - f_kappa["gamma"][:], f_kappa["group_velocity"][:] - ) - if args.temperature is not None: - (temperatures, mode_prop, mean_freepath) = _set_T_target( - temperatures, - mode_prop, - args.temperature, - mean_freepath=mean_freepath, - ) - - kdos, sampling_points = run_mfp_dos( - mean_freepath, - mode_prop, - ir_grid_map, - ir_grid_points, - args.num_sampling_points, - bz_grid, - ) - _show_tensor(kdos, temperatures, sampling_points, args) - else: - if args.temperature is not None and not args.gv: - temperatures, mode_prop = _set_T_target( - temperatures, mode_prop, args.temperature - ) - kdos, sampling_points = run_prop_dos( - frequencies, - mode_prop, - ir_grid_map, - ir_grid_points, - args.num_sampling_points, - bz_grid, - ) - _show_tensor(kdos, temperatures, sampling_points, args) + _run_tensor( + args, + f_kappa, + temperatures, + frequencies, + ir_grid_map, + ir_grid_points, + bz_grid, + primitive, + ) diff --git a/phono3py/phonon/grid.py b/phono3py/phonon/grid.py index 31c596fc..7dacbc2f 100644 --- a/phono3py/phonon/grid.py +++ b/phono3py/phonon/grid.py @@ -908,7 +908,7 @@ def get_grid_point_from_address(address, D_diag): return gps -def get_ir_grid_points(bz_grid: BZGrid): +def get_ir_grid_points(bz_grid: BZGrid) -> tuple[np.ndarray, np.ndarray, np.ndarray]: """Return ir-grid-points in generalized regular grid. bz_grid : BZGrid @@ -925,7 +925,7 @@ def get_ir_grid_points(bz_grid: BZGrid): shape=(num_ir_grid_points, ), dtype='long' ir_grid_map : ndarray Index mapping table to irreducible grid points from all grid points - such as, [0, 0, 2, 3, 3, ...]. + such as, [0, 0, 2, 3, 3, ...] in GR-grid. shape=(prod(D_diag), ), dtype='long' """ @@ -1174,7 +1174,11 @@ def _relocate_BZ_grid_address( return bz_grid_addresses, bz_map, bzg2grg -def _get_ir_grid_map(D_diag, grg_rotations, PS=None): +def _get_ir_grid_map( + D_diag: Union[np.ndarray, Sequence], + grg_rotations: Union[np.ndarray, Sequence], + PS: Optional[Union[np.ndarray, Sequence]] = None, +) -> np.ndarray: """Return mapping to irreducible grid points in GR-grid. Parameters From 2d9b233c743a409d18f86b906b07c4cefd31e8b5 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Sat, 18 Jan 2025 12:10:40 +0900 Subject: [PATCH 13/17] Add github workflow to build wheels --- .github/workflows/wheels.yml | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 .github/workflows/wheels.yml diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml new file mode 100644 index 00000000..1fa837a4 --- /dev/null +++ b/.github/workflows/wheels.yml @@ -0,0 +1,84 @@ +name: wheel-build-and-deploy + +on: + push: + branches: + - make-wheel + - make-wheel-test + +jobs: + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest,] + # os: [ubuntu-latest, windows-latest, macos-13, macos-latest] + + + steps: + - uses: actions/checkout@v4 + + # Used to host cibuildwheel + - uses: actions/setup-python@v5 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==2.22.0 + + - name: Build wheels + run: | + git tag v`grep __version__ phono3py/version.py|awk -F'"' '{print($2)}'` + python -m cibuildwheel --output-dir wheelhouse + env: + CIBW_SKIP: "cp39-* pp* *_i686 *musllinux*" + CIBW_BUILD_VERBOSITY: 1 + + # to supply options, put them in 'env', like: + # env: + # CIBW_SOME_OPTION: value + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + + upload_pypi_test: + name: Upload to PyPI (test) + strategy: + matrix: + os: [ubuntu-latest,] + needs: [build_wheels,] + runs-on: ${{ matrix.os }} + if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/make-wheel-test') + steps: + - uses: actions/download-artifact@v4 + with: + pattern: cibw-wheels-* + path: dist + merge-multiple: true + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + skip-existing: true + + upload_pypi: + name: Upload to PyPI + strategy: + matrix: + os: [ubuntu-latest,] + needs: [build_wheels,] + runs-on: ${{ matrix.os }} + if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/make-wheel') + steps: + - uses: actions/download-artifact@v4 + with: + pattern: cibw-wheels-* + path: dist + merge-multiple: true + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + skip-existing: true From 4489781af1c6737caf90931ef7a8b0065e806085 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Sat, 18 Jan 2025 12:28:21 +0900 Subject: [PATCH 14/17] Update github workflow to build wheels --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e46d3fa..329eda8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,17 +136,17 @@ if(BUILD_RECGRID_LIB OR BUILD_PHPHCALC_LIB OR BUILD_NANOBIND_MODULE) # Source code - set(SOURCES_PHPHCALC + set(SOURCES_RECGRID ${PROJECT_SOURCE_DIR}/c/bzgrid.c ${PROJECT_SOURCE_DIR}/c/grgrid.c ${PROJECT_SOURCE_DIR}/c/lagrid.c ${PROJECT_SOURCE_DIR}/c/snf3x3.c ${PROJECT_SOURCE_DIR}/c/recgrid.c) if(BUILD_SHARED_LIBS) # Shared library - add_library(recgrid_lib SHARED ${SOURCES_PHPHCALC}) + add_library(recgrid_lib SHARED ${SOURCES_RECGRID}) else() # Static link library - add_library(recgrid_lib STATIC ${SOURCES_PHPHCALC}) + add_library(recgrid_lib STATIC ${SOURCES_RECGRID}) endif() if(NOT BUILD_NANOBIND_MODULE) From ba101f1b528b5cb5fc5d2c69bb7289e0cac42c8c Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Sat, 18 Jan 2025 12:37:35 +0900 Subject: [PATCH 15/17] Update github workflow to build wheels --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 329eda8c..d8a0269f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ option(PHONO3PY_WITH_TESTS "build unit tests" OFF) option(BUILD_SHARED_LIBS "Option to build shared library" OFF) option(BUILD_WITHOUT_LAPACKE "Option to build without LAPACKE" ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + if(PHONO3PY_WITH_Fortran) enable_language(Fortran) set(BUILD_GRIDSYS_LIB ON) From 845e5e5418e94c0cde08c463fd8966037ed4e50e Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Sat, 18 Jan 2025 12:42:07 +0900 Subject: [PATCH 16/17] Update github workflow to build wheels --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8a0269f..f6d65466 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,6 @@ option(PHONO3PY_WITH_TESTS "build unit tests" OFF) option(BUILD_SHARED_LIBS "Option to build shared library" OFF) option(BUILD_WITHOUT_LAPACKE "Option to build without LAPACKE" ON) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - if(PHONO3PY_WITH_Fortran) enable_language(Fortran) set(BUILD_GRIDSYS_LIB ON) @@ -33,6 +31,7 @@ else() endif() if(BUILD_NANOBIND_MODULE) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) project(${SKBUILD_PROJECT_NAME}) set(DEV_MODULE Development.Module) find_package( From ee213e9395d6067a41c504edc1c31f440d5bf812 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Sat, 18 Jan 2025 19:20:36 +0900 Subject: [PATCH 17/17] Set version 3.11.2 --- doc/changelog.md | 4 ++++ doc/conf.py | 2 +- phono3py/version.py | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index ce470e95..0b558db1 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,10 @@ # Change Log +## Jan-18-2024: Version 3.11.2 + +- Maintenance release. + ## Jan-12-2024: Version 3.11.1 - `-i`, `-o`, `--io` options have been deprecated. diff --git a/doc/conf.py b/doc/conf.py index 2f6a6cfb..3d463b0d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -60,7 +60,7 @@ # The short X.Y version. version = "3.11" # The full version, including alpha/beta/rc tags. -release = "3.11.1" +release = "3.11.2" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/phono3py/version.py b/phono3py/version.py index 55ed6e8e..60fb166e 100644 --- a/phono3py/version.py +++ b/phono3py/version.py @@ -34,4 +34,4 @@ # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -__version__ = "3.11.1" +__version__ = "3.11.2"