From 012a24918ea0a840d65c76fd9cb6322036f60779 Mon Sep 17 00:00:00 2001 From: Atsushi Togo Date: Fri, 7 Jun 2024 11:45:42 +0900 Subject: [PATCH] Set version v3.1.0 --- doc/changelog.md | 4 ++ doc/conf.py | 2 +- phono3py/api_phono3py.py | 43 ++++++++++---------- phono3py/cui/create_force_constants.py | 21 +++++++--- phono3py/cui/load.py | 54 +++++++++++++++----------- phono3py/cui/phono3py_script.py | 41 +++++++++++-------- phono3py/interface/phono3py_yaml.py | 2 +- phono3py/version.py | 2 +- requirements.txt | 2 +- setup.py | 2 +- 10 files changed, 102 insertions(+), 71 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index df2f26b7..d7fc680f 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,10 @@ # Change Log +## Jun-7-2024: Version 3.1.0 + +- Change to write forces in phono3py-yaml as default. + ## Jun-7-2024: Version 3.0.4 - Bug fix when handling different supercell size of fc2 than that of fc3. diff --git a/doc/conf.py b/doc/conf.py index 983941ac..17a295e4 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -60,7 +60,7 @@ copyright = "2015, Atsushi Togo" # The short X.Y version. version = "3.0" # The full version, including alpha/beta/rc tags. -release = "3.0.4" +release = "3.1.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/phono3py/api_phono3py.py b/phono3py/api_phono3py.py index 34b6be28..c2197b0e 100644 --- a/phono3py/api_phono3py.py +++ b/phono3py/api_phono3py.py @@ -44,6 +44,7 @@ from phonopy.harmonic.displacement import ( directions_to_displacement_dataset, get_least_displacements, ) +from phonopy.harmonic.dynamical_matrix import DynamicalMatrix from phonopy.harmonic.force_constants import get_fc2 as get_phonopy_fc2 from phonopy.harmonic.force_constants import ( set_permutation_symmetry, @@ -179,7 +180,7 @@ class Phono3py: Supercell matrix used for fc2. In phono3py, supercell matrix for fc3 and fc2 can be different to support longer range interaction of fc2 than that of fc3. Unless setting this, supercell_matrix is used. - This is only valide when unitcell or unitcell_filename is given. + This is only valid when unitcell or unitcell_filename is given. Default is None. cutoff_frequency : float, optional Phonon frequency below this value is ignored when the cutoff is @@ -297,7 +298,7 @@ class Phono3py: self._set_band_indices() @property - def version(self): + def version(self) -> str: """Return phono3py release version number. str @@ -317,7 +318,7 @@ class Phono3py: return self._calculator @property - def fc3(self): + def fc3(self) -> Optional[np.ndarray]: """Setter and getter of third order force constants (fc3). ndarray @@ -334,7 +335,7 @@ class Phono3py: self._fc3 = fc3 @property - def fc2(self): + def fc2(self) -> Optional[np.ndarray]: """Setter and getter of second order force constants (fc2). ndarray @@ -351,12 +352,12 @@ class Phono3py: self._fc2 = fc2 @property - def force_constants(self): + def force_constants(self) -> Optional[np.ndarray]: """Return fc2. This is same as the getter attribute `fc2`.""" return self.fc2 @property - def sigmas(self): + def sigmas(self) -> list: """Setter and getter of smearing widths. list @@ -386,7 +387,7 @@ class Phono3py: self._sigmas.append(None) @property - def sigma_cutoff(self): + def sigma_cutoff(self) -> Optional[float]: """Setter and getter of Smearing cutoff width. This is given as a multiple of the standard deviation. @@ -403,7 +404,7 @@ class Phono3py: self._sigma_cutoff = sigma_cutoff @property - def nac_params(self): + def nac_params(self) -> Optional[dict]: """Setter and getter of parameters for non-analytical term correction. dict @@ -427,7 +428,7 @@ class Phono3py: self._init_dynamical_matrix() @property - def dynamical_matrix(self): + def dynamical_matrix(self) -> Optional[DynamicalMatrix]: """Return DynamicalMatrix instance. This is not dynamical matrices but the instance of DynamicalMatrix @@ -522,7 +523,7 @@ class Phono3py: return self._phonon_supercell_symmetry @property - def supercell_matrix(self): + def supercell_matrix(self) -> np.ndarray: """Return transformation matrix to supercell cell from unit cell. ndarray @@ -533,7 +534,7 @@ class Phono3py: return self._supercell_matrix @property - def phonon_supercell_matrix(self): + def phonon_supercell_matrix(self) -> Optional[np.ndarray]: """Return transformation matrix to phonon supercell from unit cell. ndarray @@ -544,7 +545,7 @@ class Phono3py: return self._phonon_supercell_matrix @property - def primitive_matrix(self): + def primitive_matrix(self) -> np.ndarray: """Return transformation matrix to primitive cell from unit cell. ndarray @@ -555,7 +556,7 @@ class Phono3py: return self._primitive_matrix @property - def unit_conversion_factor(self): + def unit_conversion_factor(self) -> float: """Return phonon frequency unit conversion factor. float @@ -567,7 +568,7 @@ class Phono3py: return self._frequency_factor_to_THz @property - def dataset(self): + def dataset(self) -> Optional[dict]: """Setter and getter of displacement-force dataset. dict @@ -629,7 +630,7 @@ class Phono3py: self._phonon_supercells_with_displacements = None @property - def phonon_dataset(self): + def phonon_dataset(self) -> Optional[dict]: """Setter and getter of displacement-force dataset for fc2. dict @@ -674,10 +675,10 @@ class Phono3py: self._phonon_supercells_with_displacements = None @property - def band_indices(self): + def band_indices(self) -> list[np.ndarray]: """Setter and getter of band indices. - array_like + list[np.ndarray] List of band indices specified to select specific bands to computer ph-ph interaction related properties. @@ -693,11 +694,11 @@ class Phono3py: num_band = len(self._primitive) * 3 self._band_indices = [np.arange(num_band, dtype="int_")] else: - self._band_indices = band_indices + self._band_indices = [np.array(bi, dtype="int_") for bi in band_indices] self._band_indices_flatten = np.hstack(self._band_indices).astype("int_") @property - def masses(self): + def masses(self) -> np.ndarray: """Setter and getter of atomic masses of primitive cell.""" return self._primitive.masses @@ -719,7 +720,7 @@ class Phono3py: self._phonon_supercell.masses = s_masses @property - def supercells_with_displacements(self): + def supercells_with_displacements(self) -> list[PhonopyAtoms]: """Return supercells with displacements. list of PhonopyAtoms @@ -2038,7 +2039,7 @@ class Phono3py: the settings expected to be updated from the following default settings are needed to be set in the dictionary. The possible parameters and their default settings are: - {'force_sets': False, + {'force_sets': True, 'displacements': True, 'force_constants': False, 'born_effective_charge': True, diff --git a/phono3py/cui/create_force_constants.py b/phono3py/cui/create_force_constants.py index 6165d405..d3bae975 100644 --- a/phono3py/cui/create_force_constants.py +++ b/phono3py/cui/create_force_constants.py @@ -34,8 +34,11 @@ # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +from __future__ import annotations + import copy import os +import pathlib import sys from typing import Optional @@ -247,7 +250,7 @@ def parse_forces( # None is returned unless type-2. # can emit FileNotFoundError. if dataset is None or dataset is not None and not forces_in_dataset(dataset): - _dataset = _get_type2_dataset( + _dataset = read_type2_dataset( natom, filename=force_filename, log_level=log_level ) # Do not overwrite dataset when _dataset is None. @@ -311,13 +314,18 @@ def parse_forces( return dataset -def forces_in_dataset(dataset): +def forces_in_dataset(dataset: dict) -> bool: """Return whether forces in dataset or not.""" return "forces" in dataset or ( "first_atoms" in dataset and "forces" in dataset["first_atoms"][0] ) +def displacements_in_dataset(dataset: dict) -> bool: + """Return whether displacements in dataset or not.""" + return "displacements" in dataset or "first_atoms" in dataset + + def get_fc_calculator_params(settings): """Return fc_calculator and fc_calculator_params from settings.""" fc_calculator = None @@ -338,7 +346,7 @@ def get_fc_calculator_params(settings): return fc_calculator, fc_calculator_options -def _read_phono3py_fc3(phono3py, symmetrize_fc3r, input_filename, log_level): +def _read_phono3py_fc3(phono3py: Phono3py, symmetrize_fc3r, input_filename, log_level): if input_filename is None: filename = "fc3.hdf5" else: @@ -357,7 +365,7 @@ def _read_phono3py_fc3(phono3py, symmetrize_fc3r, input_filename, log_level): if log_level: print_error() sys.exit(1) - num_atom = phono3py.supercell.get_number_of_atoms() + num_atom = len(phono3py.supercell) if fc3.shape[1] != num_atom: print("Matrix shape of fc3 doesn't agree with supercell size.") if log_level: @@ -407,8 +415,9 @@ def _read_phono3py_fc2(phono3py, symmetrize_fc2, input_filename, log_level): phono3py.fc2 = phonon_fc2 -def _get_type2_dataset(natom, filename="FORCES_FC3", log_level=0): - if not os.path.isfile(filename): +def read_type2_dataset(natom, filename="FORCES_FC3", log_level=0) -> Optional[dict]: + """Read type-2 FORCES_FC3.""" + if not pathlib.Path(filename).exists(): return None with open(filename, "r") as f: diff --git a/phono3py/cui/load.py b/phono3py/cui/load.py index d57a8ac9..6bde5592 100644 --- a/phono3py/cui/load.py +++ b/phono3py/cui/load.py @@ -48,7 +48,12 @@ from phonopy.structure.atoms import PhonopyAtoms from phonopy.structure.cells import determinant from phono3py import Phono3py -from phono3py.cui.create_force_constants import forces_in_dataset, parse_forces +from phono3py.cui.create_force_constants import ( + displacements_in_dataset, + forces_in_dataset, + parse_forces, + read_type2_dataset, +) from phono3py.file_IO import read_fc2_from_hdf5, read_fc3_from_hdf5 from phono3py.interface.phono3py_yaml import Phono3pyYaml from phono3py.phonon3.fc3 import show_drift_fc3 @@ -494,28 +499,31 @@ def _set_dataset_or_fc3( read_fc3 = True if log_level: print('fc3 was read from "fc3.hdf5".') - elif pathlib.Path("FORCES_FC3").exists(): - _set_dataset_for_fc3( - ph3py, - ph3py_yaml, - "FORCES_FC3", - phono3py_yaml_filename, - cutoff_pair_distance, - log_level, - ) - elif ( - ph3py_yaml is not None - and ph3py_yaml.dataset is not None - and forces_in_dataset(ph3py_yaml.dataset) - ): - _set_dataset_for_fc3( - ph3py, - ph3py_yaml, - None, - phono3py_yaml_filename, - cutoff_pair_distance, - log_level, - ) + elif dataset := read_type2_dataset( + len(ph3py.supercell), "FORCES_FC3", log_level=log_level + ): # := Assignment Expressions (Python>=3.8) + ph3py.dataset = dataset + elif ph3py_yaml is not None and ph3py_yaml.dataset is not None: + if pathlib.Path("FORCES_FC3").exists() and displacements_in_dataset( + ph3py_yaml.dataset + ): + _set_dataset_for_fc3( + ph3py, + ph3py_yaml, + "FORCES_FC3", + phono3py_yaml_filename, + cutoff_pair_distance, + log_level, + ) + if forces_in_dataset(ph3py_yaml.dataset): + _set_dataset_for_fc3( + ph3py, + ph3py_yaml, + None, + phono3py_yaml_filename, + cutoff_pair_distance, + log_level, + ) return read_fc3 diff --git a/phono3py/cui/phono3py_script.py b/phono3py/cui/phono3py_script.py index 0850d0b2..3fc35cc1 100644 --- a/phono3py/cui/phono3py_script.py +++ b/phono3py/cui/phono3py_script.py @@ -541,14 +541,7 @@ def store_force_constants( log_level=log_level, ) except ForceCalculatorRequiredError: - if log_level: - print("") - print( - "Built-in force constants calculator doesn't support the " - "dispalcements-forces dataset. " - "An external force calculator, e.g., ALM (--alm), has to be used " - "to compute force constants." - ) + _show_fc_calculator_not_found(log_level) if log_level: if phono3py.fc3 is None: @@ -592,15 +585,31 @@ def store_force_constants( if log_level: print('fc2 was written into "fc2.hdf5".') else: - create_phono3py_force_constants( - phono3py, - settings, - ph3py_yaml=ph3py_yaml, - phono3py_yaml_filename=phono3py_yaml_filename, - input_filename=input_filename, - output_filename=output_filename, - log_level=log_level, + try: + create_phono3py_force_constants( + phono3py, + settings, + ph3py_yaml=ph3py_yaml, + phono3py_yaml_filename=phono3py_yaml_filename, + input_filename=input_filename, + output_filename=output_filename, + log_level=log_level, + ) + except ForceCalculatorRequiredError: + _show_fc_calculator_not_found(log_level) + + +def _show_fc_calculator_not_found(log_level): + if log_level: + print("") + print( + "Built-in force constants calculator doesn't support the " + "dispalcements-forces dataset. " + "An external force calculator, e.g., ALM (--alm), has to be used " + "to compute force constants." ) + print_error() + sys.exit(1) def run_gruneisen_then_exit(phono3py, settings, output_filename, log_level): diff --git a/phono3py/interface/phono3py_yaml.py b/phono3py/interface/phono3py_yaml.py index faf1aabb..9369e282 100644 --- a/phono3py/interface/phono3py_yaml.py +++ b/phono3py/interface/phono3py_yaml.py @@ -265,7 +265,7 @@ class Phono3pyYamlDumper(PhonopyYamlDumperBase): """Phono3pyYaml dumper.""" _default_dumper_settings = { - "force_sets": False, + "force_sets": True, "displacements": True, "force_constants": False, "born_effective_charge": True, diff --git a/phono3py/version.py b/phono3py/version.py index a334d571..663dd683 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.0.4" +__version__ = "3.1.0" diff --git a/requirements.txt b/requirements.txt index a8ad2963..b7fdc84d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ numpy >= 1.17.0 PyYAML >= 5.3 matplotlib >= 2.2.2 h5py >= 3.0 -phonopy >=2.23,<2.24 +phonopy >=2.24,<2.25 diff --git a/setup.py b/setup.py index 26c05a49..04f071d8 100644 --- a/setup.py +++ b/setup.py @@ -326,7 +326,7 @@ def main(build_dir): "matplotlib>=2.2.2", "h5py>=3.0", "spglib>=2.0", - "phonopy>=2.23,<2.24", + "phonopy>=2.24,<2.25", ], provides=["phono3py"], scripts=scripts_phono3py,