Merge branch 'rc'

This commit is contained in:
Atsushi Togo 2024-06-29 21:49:25 +09:00
commit 6ae8b6641b
49 changed files with 1193 additions and 621 deletions

View File

@ -10,31 +10,12 @@ repos:
exclude: ^conda/
- id: check-added-large-files
- repo: https://github.com/pycqa/flake8
rev: 7.1.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.10
hooks:
- id: flake8
args:
- "--max-line-length=88"
- "--ignore=E203,W503"
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
args:
- --line-length=88
- repo: https://github.com/pycqa/pydocstyle
rev: 6.3.0
hooks:
- id: pydocstyle
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
- id: ruff
args: [ "--fix", "--show-fixes" ]
- id: ruff-format
- repo: https://github.com/Takishima/cmake-pre-commit-hooks
rev: v1.9.6

View File

@ -6,14 +6,20 @@
# phono3py
A simulation package of phonon-phonon interaction related properties. Phono3py
user documentation is found at http://phonopy.github.io/phono3py/.
A simulation package of phonon-phonon interaction related properties mainly
written in python. Phono3py user documentation is found at
http://phonopy.github.io/phono3py/.
## Mailing list for questions
Usual phono3py questions should be sent to phonopy mailing list
(https://sourceforge.net/p/phonopy/mailman/).
## Dependency
See `requirements.txt`. Optionally `symfc` and `scipy` are required
for using additional features.
## Development
The development of phono3py is managed on the `develop` branch of github
@ -21,26 +27,19 @@ phono3py repository.
- Github issues is the place to discuss about phono3py issues.
- Github pull request is the place to request merging source code.
- Python 3.7 is the minimum requirement.
- Formatting is written in `pyproject.toml`.
- Not strictly, but VSCode's `settings.json` may be written like
- Formatting rules are found in `pyproject.toml`.
- Not strictly, but VSCode's `settings.json` may be written like below
```json
"python.linting.flake8Enabled": true,
"python.linting.flake8Args": ["--max-line-length=88", "--ignore=E203,W503"],
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.mypyEnabled": true,
"python.linting.pycodestyleEnabled": false,
"python.linting.pydocstyleEnabled": true,
"python.formatting.provider": "black",
"python.formatting.blackArgs": ["--line-length=88"],
"python.sortImports.args": ["--profile", "black"],
"ruff.lint.args": [
"--config=${workspaceFolder}/pyproject.toml",
],
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
}
"source.organizeImports": "explicit"
}
},
```
- Use of pre-commit (https://pre-commit.com/) is encouraged.
@ -57,7 +56,8 @@ stored in `doc` directory. Please see how to write the documentation at
## How to run tests
You need pytest. At home directory of phono3py after setup,
Tests are written using pytest. To run tests, pytest has to be installed. The
tests can be run by
```bash
% pytest

View File

@ -2,6 +2,11 @@
# Change Log
## Jun-29-2024: Version 3.2.0
- `--rd` and `--rd-fc2` options for generating random directional displacements.
- Experimental implementation for using pypolymlp.
## Jun-19-2024: Version 3.1.2
- Treatment of numpy 2.0.

View File

@ -181,7 +181,7 @@ created from `FORCES_FC2` and `phono3py_disp.yaml` instead of `FORCES_FC3` and
### `--dim` (`DIM`)
Supercell dimension is specified. See the detail at
http://phonopy.github.io/phonopy/setting-tags.html#dim. When a proper
<http://phonopy.github.io/phonopy/setting-tags.html#dim>. When a proper
`phono3py_disp.yaml` exists in the current directory, this is unnecessary to be
specified.
@ -233,7 +233,7 @@ that created in the usual phono3py run without `--dim-fc2` option.
Transformation matrix from a non-primitive cell to the primitive cell. See
phonopy `PRIMITIVE_AXES` tag (`--pa` option) at
http://phonopy.github.io/phonopy/setting-tags.html#primitive-axis. When a proper
<http://phonopy.github.io/phonopy/setting-tags.html#primitive-axis>. When a proper
`phono3py_disp.yaml` exists in the current directory, this is unnecessary to be
specified.
@ -261,10 +261,17 @@ e.g., `--pa="F"` if the input unit cell has F-centring.
(amplitude_option)=
### `--rd` (`RANDOM_DISPLACEMENTS`), `--rd-fc2` (`RANDOM_DISPLACEMENTS_FC2`) and `--random-seed` (`RANDOM_SEED`)
Random directional displacements are generated for fc3 and fc2 supercells by
`--rd` and `--rd-fc2`, respectively. `--amplitude` and `--random-seed` options
may be used together. These are used in the equivalent way to [`--rd` of
phonopy](https://phonopy.github.io/phonopy/setting-tags.html#random-displacements).
### `--amplitude` (`DISPLACEMENT_DISTANCE`)
Atomic displacement distance is specified. This value may be increased for the
weak interaction systems and descreased when the force calculator is numerically
weak interaction systems and decreased when the force calculator is numerically
very accurate.
The default value depends on calculator. See
@ -279,7 +286,7 @@ The default value depends on calculator. See
When creating force constants from `FORCES_FC3` and/or `FORCES_FC2`, force
constants that use smaller data size are created. The shape of the data array is
`(num_patom, num_satom)` for fc2 and `(num_patom, num_satom, num_satom)` for
fc3, where `num_patom` and `num_satom` are the numbers of atoms in primtive cell
fc3, where `num_patom` and `num_satom` are the numbers of atoms in primitive cell
and supercell. In the full size force constants case, `num_patom` is replaced by
`num_satom`. Therefore if the supercell dimension is large, this reduction of
data size becomes large. If the input crystal structure has centring
@ -298,7 +305,7 @@ imperfect symmetrization scheme that phono3py employs.
### `--sym-fc` (`FC_SYMMETRY = .TRUE.`)
Second- and third-order force constants are symmetrized. The index exchange of
real space force constantsand translational invariance symmetry are applied in a
real space force constants and translational invariance symmetry are applied in a
simple way. This symmetrization just removes drift force constants evenly from
all elements and then applies averaging index-exchange equivalent elements.
Therefore the different symmetries are not simultaneously enforced. For better
@ -336,7 +343,7 @@ or computed with less numerical accuracy. More details are found at
This invokes ALM as the force constants calculator for fc2 and fc3. See the
detail at
[phonopy documentaton](https://phonopy.github.io/phonopy/setting-tags.html#alm).
[phonopy documentation](https://phonopy.github.io/phonopy/setting-tags.html#alm).
This option is useful for fitting random displacement dataset or MD data to
force constants. Phono3py doesn't provide command-line interface to generate
random displacements. Instead simply
@ -359,7 +366,7 @@ as written
### `--gp` (`GRID_POINTS`)
Grid points are specified by their unique indices, e.g., for selecting the
q-points where imaginary parts of self energees are calculated. For thermal
q-points where imaginary parts of self energies are calculated. For thermal
conductivity calculation, this can be used to distribute its calculation over
q-points (see {ref}`workload_distribution`).
@ -382,7 +389,7 @@ This is used to specify grid points like `--gp` option but in their addresses
represented by integer numbers. For example with `--mesh="16 16 16"`, a q-point
of (0.5, 0.5, 0.5) is given by `--ga="8 8 8"`. The values have to be integers.
If you want to specify the point on a path,
`--ga="0 0 0 1 1 1 2 2 2 3 3 3 ..."`, where each three values are recogninzed as
`--ga="0 0 0 1 1 1 2 2 2 3 3 3 ..."`, where each three values are recognized as
a grid point. The grid points given by `--ga` option are translated to grid
point indices as given by `--gp` option, and the values given by `--ga` option
will not be shown in log files.
@ -394,7 +401,7 @@ will not be shown in log files.
Band indices are specified. The calculated values at indices separated by space
are averaged, and those separated by comma are separately calculated. The output
file name will be, e.g., `gammas-mxxx-gxx(-sx)-bx.dat` where `bxbx...` shows the
band indices where the values are calcualted and summed and averaged over those
band indices where the values are calculated and summed and averaged over those
bands.
```bash
@ -489,7 +496,7 @@ $$
\delta(\omega-\omega_{\lambda'}-\omega_{\lambda''}) \right.
+ (n_{\lambda'}-n_{\lambda''})
\left[\delta(\omega+\omega_{\lambda'}-\omega_{\lambda''})
- \left. \delta(\omega-\omega_{\lambda'}+\omega_{\lambda''})
+ \left. \delta(\omega-\omega_{\lambda'}+\omega_{\lambda''})
\right]\right\}.
$$
@ -524,16 +531,17 @@ equivalent to that of `--br`. More detail is documented at
### `--wigner`
Run calculation of lattice thermal conductivity tensor computing the coherences (wave-like) contribution
to the thermal conductivity, obtained solving the Wigner transport equation equation.
This option can be combined with `--lbte` or `--br`; in the former case the populations
conductivity (particle-like, equivalent to the conductivity obtained solving the LBTE) is computed exactly,
in the latter case the populations conductivity is
computed in the relaxation-time approximation (RTA).
The coherences contribution to the conductivity is always computed exactly.
The coherences conductivity is usually non-negligible compared to the particle-like conductivity in materials
with ultralow or glass-like conductivity.
More details can be found at {ref}`wigner_solution`.
Run calculation of lattice thermal conductivity tensor computing the coherences
(wave-like) contribution to the thermal conductivity, obtained solving the
Wigner transport equation equation. This option can be combined with `--lbte` or
`--br`; in the former case the populations conductivity (particle-like,
equivalent to the conductivity obtained solving the LBTE) is computed exactly,
in the latter case the populations conductivity is computed in the
relaxation-time approximation (RTA). The coherences contribution to the
conductivity is always computed exactly. The coherences conductivity is usually
non-negligible compared to the particle-like conductivity in materials with
ultralow or glass-like conductivity. More details can be found at
{ref}`wigner_solution`.
## Scattering
@ -718,7 +726,7 @@ $$
\bigl|\Phi_{-\lambda\lambda_1\lambda_2}\bigl|^2
(n_{\lambda_1}-n_{\lambda_2})
\left[\delta(\omega+\omega_{\lambda_1}-\omega_{\lambda_2})
- \delta(\omega-\omega_{\lambda_1}+\omega_{\lambda_2})
+ \delta(\omega-\omega_{\lambda_1}+\omega_{\lambda_2})
\right]
\end{align*}
$$
@ -732,7 +740,7 @@ $$
\bigl|\Phi_{-\lambda\lambda_1\lambda_2}\bigl|^2
(n_{\lambda_1}+ n_{\lambda_2}+1)
\left[ \delta(\omega-\omega_{\lambda_1}-\omega_{\lambda_2})
- \delta(\omega + \omega_{\lambda_1} + \omega_{\lambda_2}) \right]
+ \delta(\omega + \omega_{\lambda_1} + \omega_{\lambda_2}) \right]
\end{align*},
$$
@ -758,7 +766,7 @@ Specific temperatures are specified by `--ts`.
Temperatures at equal interval are specified by `--tmax`, `--tmin`, `--tstep`.
See phonopy's document for the same tags at
http://phonopy.github.io/phonopy/setting-tags.html#tprop-tmin-tmax-tstep.
<http://phonopy.github.io/phonopy/setting-tags.html#tprop-tmin-tmax-tstep>.
```bash
% phono3py --fc3 --fc2 --dim="2 2 2" -v --mesh="11 11 11" -c POSCAR-unitcell --br --tmin=100 --tmax=1000 --tstep=50
@ -779,7 +787,7 @@ file.
This is used with `--nac` to specify reciprocal-space direction at
$\mathbf{q}\rightarrow \mathbf{0}$. See the detail at
http://phonopy.github.io/phonopy/setting-tags.html#q-direction.
<http://phonopy.github.io/phonopy/setting-tags.html#q-direction>.
(self_energy_options)=
@ -800,11 +808,11 @@ $$
\bigl|\Phi_{-\lambda\lambda_1\lambda_2}\bigl|^2 &
\left\{(n_{\lambda_1}+ n_{\lambda_2}+1)
\left[ \delta(\omega-\omega_{\lambda_1}-\omega_{\lambda_2})
- \delta(\omega+\omega_{\lambda_1}+\omega_{\lambda_2}) \right] \right.
+ \delta(\omega+\omega_{\lambda_1}+\omega_{\lambda_2}) \right] \right.
\\
& + (n_{\lambda_1}-n_{\lambda_2})
\left[\delta(\omega+\omega_{\lambda_1}-\omega_{\lambda_2})
- \left. \delta(\omega-\omega_{\lambda_1}+\omega_{\lambda_2})
+ \left. \delta(\omega-\omega_{\lambda_1}+\omega_{\lambda_2})
\right]\right\},
\end{align*}
$$
@ -819,14 +827,14 @@ $$
\left\{
\left[ \frac{(n_{\lambda_1}+ n_{\lambda_2}+1)}{
(\omega-\omega_{\lambda_1}-\omega_{\lambda_2})_\mathrm{p}}
- \frac{(n_{\lambda_1}+ n_{\lambda_2}+1)}{
+ \frac{(n_{\lambda_1}+ n_{\lambda_2}+1)}{
(\omega+\omega_{\lambda_1}+\omega_{\lambda_2})_\mathrm{p}}
\right]
\right. \\
& + \left[
\frac{(n_{\lambda_1}-n_{\lambda_2})}{(\omega +
\omega_{\lambda_1} - \omega_{\lambda_2})_\mathrm{p}}
- \left. \frac{(n_{\lambda_1}-n_{\lambda_2})}{(\omega -
+ \left. \frac{(n_{\lambda_1}-n_{\lambda_2})}{(\omega -
\omega_{\lambda_1} + \omega_{\lambda_2})_\mathrm{p}}
\right]\right\},
\end{align*}
@ -1186,7 +1194,7 @@ different CPU architectures. {ref}`--pa <pa_option>` and
### `--write-pp` (`WRITE_PP = .TRUE.`) and `--read-pp` (`READ_PP = .TRUE.`)
Phonon-phonon (ph-ph) intraction strengths are written to and read from
Phonon-phonon (ph-ph) interaction strengths are written to and read from
`pp-mxxx-gx.hdf5`. This works only in the calculation of lattice thermal
conductivity, i.e., usable only with `--br` or `--lbte`. The stored data are
different with and without specifying `--full-pp` option. In the former case,
@ -1212,7 +1220,7 @@ Most of phono3py HDF5 output file is compressed by default with the `gzip`
compression filter. To avoid compression, `--hdf5-compression=None` has to be
set. Other filters (`lzf` or integer values of 0 to 9) may be used, see h5py
documentation
(http://docs.h5py.org/en/stable/high/dataset.html#filter-pipeline).
(<http://docs.h5py.org/en/stable/high/dataset.html#filter-pipeline>).
(output_filename_option)=
@ -1226,12 +1234,12 @@ Using this option, output file names are slightly modified. For example, with
This rule is applied to
- `fc3.hdf5`
- `fc2.hdf5`
- `kappa-xxx.hdf5`
- `phonon-xxx.hdf5`
- `pp-xxx.hdf5`
- `gamma_detail-xxx.hdf5` (write only)
+ `fc3.hdf5`
+ `fc2.hdf5`
+ `kappa-xxx.hdf5`
+ `phonon-xxx.hdf5`
+ `pp-xxx.hdf5`
+ `gamma_detail-xxx.hdf5` (write only)
(input_filename_option)=
@ -1245,11 +1253,11 @@ specifying `-i iso --fc3`, a file name `fc3.iso.hdf5` is read instead of
This rule is applied to
- `fc3.hdf5`
- `fc2.hdf5`
- `kappa-xxx.hdf5`
- `phonon-xxx.hdf5`
- `pp-xxx.hdf5`
+ `fc3.hdf5`
+ `fc2.hdf5`
+ `kappa-xxx.hdf5`
+ `phonon-xxx.hdf5`
+ `pp-xxx.hdf5`
### `--io` (command option only)

View File

@ -58,9 +58,9 @@ copyright = "2015, Atsushi Togo"
# built documents.
#
# The short X.Y version.
version = "3.1"
version = "3.2"
# The full version, including alpha/beta/rc tags.
release = "3.1.2"
release = "3.2.0"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -40,12 +40,12 @@ from phonopy.structure.symmetry import Symmetry
from phonopy.units import VaspToTHz
from phono3py.file_IO import write_joint_dos
from phono3py.phonon.grid import BZGrid
from phono3py.phonon3.imag_self_energy import (
get_freq_points_batches,
get_frequency_points,
)
from phono3py.phonon3.joint_dos import JointDos
from phono3py.phonon.grid import BZGrid
class Phono3pyJointDos:

View File

@ -44,6 +44,7 @@ from phonopy.exception import ForceCalculatorRequiredError
from phonopy.harmonic.displacement import (
directions_to_displacement_dataset,
get_least_displacements,
get_random_displacements_dataset,
)
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix
from phonopy.harmonic.force_constants import get_fc2 as get_phonopy_fc2
@ -54,6 +55,13 @@ from phonopy.harmonic.force_constants import (
symmetrize_force_constants,
)
from phonopy.interface.fc_calculator import get_fc2
from phonopy.interface.pypolymlp import (
PypolymlpData,
PypolymlpParams,
develop_polymlp,
evalulate_polymlp,
parse_mlp_params,
)
from phonopy.structure.atoms import PhonopyAtoms
from phonopy.structure.cells import (
Primitive,
@ -72,19 +80,20 @@ from phono3py.conductivity.direct_solution import get_thermal_conductivity_LBTE
from phono3py.conductivity.rta import get_thermal_conductivity_RTA
from phono3py.interface.fc_calculator import get_fc3
from phono3py.interface.phono3py_yaml import Phono3pyYaml
from phono3py.phonon.grid import BZGrid
from phono3py.phonon3.dataset import get_displacements_and_forces_fc3
from phono3py.phonon3.displacement_fc3 import (
direction_to_displacement,
get_third_order_displacements,
)
from phono3py.phonon3.fc3 import cutoff_fc3_by_zero
from phono3py.phonon3.fc3 import get_fc3 as get_phono3py_fc3
from phono3py.phonon3.fc3 import (
cutoff_fc3_by_zero,
set_permutation_symmetry_compact_fc3,
set_permutation_symmetry_fc3,
set_translational_invariance_compact_fc3,
set_translational_invariance_fc3,
)
from phono3py.phonon3.fc3 import get_fc3 as get_phono3py_fc3
from phono3py.phonon3.imag_self_energy import (
get_imag_self_energy,
write_imag_self_energy,
@ -95,7 +104,6 @@ from phono3py.phonon3.real_self_energy import (
write_real_self_energy,
)
from phono3py.phonon3.spectral_function import run_spectral_function
from phono3py.phonon.grid import BZGrid
from phono3py.version import __version__
@ -288,10 +296,16 @@ class Phono3py:
self._frequency_points = None
self._temperatures = None
# Other variables
# Force constants
self._fc2 = None
self._fc3 = None
# MLP
self._mlp = None
self._mlp_dataset = None
self._phonon_mlp = None
self._phonon_mlp_dataset = None
# Setup interaction
self._interaction = None
self._band_indices = None
@ -675,6 +689,38 @@ class Phono3py:
self._phonon_supercells_with_displacements = None
@property
def mlp_dataset(self) -> Optional[dict]:
"""Return displacement-force dataset.
The supercell matrix is equal to that of usual displacement-force
dataset. Only type 2 format is supported. "displacements",
"forces", and "supercell_energies" should be contained.
"""
return self._mlp_dataset
@mlp_dataset.setter
def mlp_dataset(self, mlp_dataset: dict):
self._check_mlp_dataset(mlp_dataset)
self._mlp_dataset = mlp_dataset
@property
def phonon_mlp_dataset(self) -> Optional[dict]:
"""Return phonon displacement-force dataset.
The phonon supercell matrix is equal to that of usual displacement-force
dataset. Only type 2 format is supported. "displacements", "forces", and
"supercell_energies" should be contained.
"""
return self._phonon_mlp_dataset
@phonon_mlp_dataset.setter
def phonon_mlp_dataset(self, mlp_dataset: dict):
self._check_mlp_dataset(mlp_dataset)
self._phonon_mlp_dataset = mlp_dataset
@property
def band_indices(self) -> list[np.ndarray]:
"""Setter and getter of band indices.
@ -805,7 +851,7 @@ class Phono3py:
for disp1 in dataset["first_atoms"]:
num_scells += len(disp1["second_atoms"])
displacements = np.zeros(
(num_scells, self._supercell.get_number_of_atoms(), 3),
(num_scells, len(self._supercell), 3),
dtype="double",
order="C",
)
@ -909,18 +955,18 @@ class Phono3py:
shape=(supercells, natom, 3), dtype='double', order='C'
"""
if self._phonon_supercell_matrix is None:
raise RuntimeError("phonon_supercell_matrix is not set.")
dataset = self._phonon_dataset
if "first_atoms" in dataset:
num_scells = len(dataset["first_atoms"])
if self._phonon_dataset is None:
raise RuntimeError("phonon_dataset is not set.")
if "first_atoms" in self._phonon_dataset:
num_scells = len(self._phonon_dataset["first_atoms"])
natom = len(self._phonon_supercell)
displacements = np.zeros((num_scells, natom, 3), dtype="double", order="C")
for i, disp1 in enumerate(dataset["first_atoms"]):
for i, disp1 in enumerate(self._phonon_dataset["first_atoms"]):
displacements[i, disp1["number"]] = disp1["displacement"]
elif "forces" in dataset or "displacements" in dataset:
displacements = dataset["displacements"]
elif (
"forces" in self._phonon_dataset or "displacements" in self._phonon_dataset
):
displacements = self._phonon_dataset["displacements"]
else:
raise RuntimeError("displacement dataset has wrong format.")
@ -1004,6 +1050,16 @@ class Phono3py:
"""
return self._bz_grid
@property
def mlp(self):
"""Return MLP instance."""
return self._mlp
@property
def phonon_mlp(self):
"""Return MLP instance for fc2."""
return self._phonon_mlp
def init_phph_interaction(
self,
nac_q_direction=None,
@ -1166,65 +1222,105 @@ class Phono3py:
cutoff_pair_distance=None,
is_plusminus="auto",
is_diagonal=True,
number_of_snapshots: Optional[int] = None,
random_seed: Optional[int] = None,
is_random_distance: bool = False,
min_distance: Optional[float] = None,
):
"""Generate displacement dataset in supercell for fc3.
This systematically generates single and pair atomic displacements
in supercells to calculate fc3 considering crystal symmetry.
When this method is called, existing cache of supercells with
displacements for fc3 are removed.
Systematic displacements
------------------------
For fc3, two atoms are displaced for each configuration
considering crystal symmetry. The first displacement is chosen
in the perfect supercell, and the second displacement in the
displaced supercell. The first displacements are taken along
the basis vectors of the supercell. This is because the
symmetry is expected to be less broken by the introduced first
displacement, and as the result, the number of second
displacements may become smaller than the case that the first
atom is displaced not along the basis vectors.
Unless number_of_snapshots is specified, this method systematically
generates single and pair atomic displacements in supercells to
calculate fc3 considering crystal symmetry.
For fc3, two atoms are displaced for each configuration considering
crystal symmetry. The first displacement is chosen in the perfect
supercell, and the second displacement in the displaced supercell. The
first displacements are taken along the basis vectors of the supercell.
This is because the symmetry is expected to be less broken by the
introduced first displacement, and as the result, the number of second
displacements may become smaller than the case that the first atom is
displaced not along the basis vectors.
Random displacements
--------------------
Unless number_of_snapshots is specified, displacements are generated
randomly. There are several options how the random displacements are
generated.
Note
----
When phonon_supercell_matrix is not given, fc2 is also
computed from the same set of the displacements for fc3 and
respective supercell forces. When phonon_supercell_matrix is
set, the displacements in phonon_supercell are generated unless
those already exist.
When phonon_supercell_matrix is not given, fc2 is also computed from the
same set of the displacements for fc3 and respective supercell forces.
When phonon_supercell_matrix is set, the displacements in
phonon_supercell are generated unless those already exist. If a specific
set of displacements for fc2 is expected, generate_fc2_displacements
should be called.
Parameters
----------
distance : float, optional
Constant displacement Euclidean distance. Default is 0.03.
cutoff_pair_distance : float, optional
This is used as a cutoff Euclidean distance to determine if
each pair of displacements is considered to calculate fc3 or not.
Default is None, which means cutoff is not used.
This is used as a cutoff Euclidean distance to determine if each
pair of displacements is considered to calculate fc3 or not. Default
is None, which means cutoff is not used.
is_plusminus : True, False, or 'auto', optional
With True, atomis are displaced in both positive and negative
directions. With False, only one direction. With 'auto',
mostly equivalent to is_plusminus=True, but only one direction
is chosen when the displacements in both directions are
symmetrically equivalent. Default is 'auto'.
directions. With False, only one direction. With 'auto', mostly
equivalent to is_plusminus=True, but only one direction is chosen
when the displacements in both directions are symmetrically
equivalent. Default is 'auto'.
is_diagonal : Bool, optional
With False, the second displacements are made along the basis
vectors of the supercell. With True, direction not along the basis
vectors can be chosen when the number of the displacements
may be reduced.
vectors can be chosen when the number of the displacements may be
reduced.
number_of_snapshots : int or None, optional
Number of snapshots of supercells with random displacements. Random
displacements are generated displacing all atoms in random
directions with a fixed displacement distance specified by
'distance' parameter, i.e., all atoms in supercell are displaced
with the same displacement distance in direct space. Default is
None.
random_seed : int or None, optional
Random seed for random displacements generation. Default is None.
is_random_distance : bool, optional
Random direction displacements are generated also with random
amplitudes. The maximum value is defined by `distance` and minimum
value is given by `min_distance`. Default is False.
min_distance : float or None, optional
In random direction displacements generation with random distance
(`is_random_distance=True`), the minimum distance is given by this
value.
"""
direction_dataset = get_third_order_displacements(
self._supercell,
self._symmetry,
is_plusminus=is_plusminus,
is_diagonal=is_diagonal,
)
self._dataset = direction_to_displacement(
direction_dataset,
distance,
self._supercell,
cutoff_distance=cutoff_pair_distance,
)
if number_of_snapshots is not None and number_of_snapshots > 0:
self._dataset = self._generate_random_displacements(
number_of_snapshots,
len(self._supercell),
distance=distance,
is_plusminus=is_plusminus is True,
random_seed=random_seed,
is_random_distance=is_random_distance,
min_distance=min_distance,
)
else:
direction_dataset = get_third_order_displacements(
self._supercell,
self._symmetry,
is_plusminus=is_plusminus,
is_diagonal=is_diagonal,
)
self._dataset = direction_to_displacement(
direction_dataset,
distance,
self._supercell,
cutoff_distance=cutoff_pair_distance,
)
self._supercells_with_displacements = None
if self._phonon_supercell_matrix is not None and self._phonon_dataset is None:
@ -1233,7 +1329,14 @@ class Phono3py:
)
def generate_fc2_displacements(
self, distance=0.03, is_plusminus="auto", is_diagonal=False
self,
distance: float = 0.03,
is_plusminus: str = "auto",
is_diagonal: bool = False,
number_of_snapshots: Optional[int] = None,
random_seed: Optional[int] = None,
is_random_distance: bool = False,
min_distance: Optional[float] = None,
):
"""Generate displacement dataset in phonon supercell for fc2.
@ -1263,77 +1366,91 @@ class Phono3py:
vectors of the supercell. With True, direction not along the basis
vectors can be chosen when the number of the displacements
may be reduced. Default is False.
number_of_snapshots : int or None, optional
Number of snapshots of supercells with random displacements. Random
displacements are generated displacing all atoms in random
directions with a fixed displacement distance specified by
'distance' parameter, i.e., all atoms in supercell are displaced
with the same displacement distance in direct space. Default is
None.
random_seed : int or None, optional
Random seed for random displacements generation. Default is None.
is_random_distance : bool, optional
Random direction displacements are generated also with random
amplitudes. The maximum value is defined by `distance` and minimum
value is given by `min_distance`. Default is False.
min_distance : float or None, optional
In random direction displacements generation with random distance
(`is_random_distance=True`), the minimum distance is given by this
value.
"""
if self._phonon_supercell_matrix is None:
msg = (
"phonon_supercell_matrix is not set. "
"This method is used to generate displacements to "
"calculate phonon_fc2."
if number_of_snapshots is not None and number_of_snapshots > 0:
self._phonon_dataset = self._generate_random_displacements(
number_of_snapshots,
len(self._phonon_supercell),
distance=distance,
is_plusminus=is_plusminus is True,
random_seed=random_seed,
is_random_distance=is_random_distance,
min_distance=min_distance,
)
else:
phonon_displacement_directions = get_least_displacements(
self._phonon_supercell_symmetry,
is_plusminus=is_plusminus,
is_diagonal=is_diagonal,
)
self._phonon_dataset = directions_to_displacement_dataset(
phonon_displacement_directions, distance, self._phonon_supercell
)
raise RuntimeError(msg)
phonon_displacement_directions = get_least_displacements(
self._phonon_supercell_symmetry,
is_plusminus=is_plusminus,
is_diagonal=is_diagonal,
)
self._phonon_dataset = directions_to_displacement_dataset(
phonon_displacement_directions, distance, self._phonon_supercell
)
self._phonon_supercells_with_displacements = None
def produce_fc3(
self,
symmetrize_fc3r=False,
is_compact_fc=False,
fc_calculator=None,
fc_calculator_options=None,
symmetrize_fc3r: bool = False,
is_compact_fc: bool = False,
fc_calculator: Optional[str] = None,
fc_calculator_options: Optional[Union[str, dict]] = None,
):
"""Calculate fc3 from displacements and forces.
Parameters
----------
symmetrize_fc3r : bool
Only for type 1 displacement_dataset, translational and
permutation symmetries are applied after creating fc3. This
symmetrization is not very sophisticated and can break space
group symmetry, but often useful. If better symmetrization is
expected, it is recommended to use external force constants
calculator such as ALM. Default is False.
is_compact_fc : bool
symmetrize_fc3r : bool, optional
Only for type 1 displacement_dataset, translational and permutation
symmetries are applied after creating fc3. This symmetrization is
not very sophisticated and can break space group symmetry, but often
useful. If better symmetrization is expected, it is recommended to
use external force constants calculator such as ALM. Default is
False.
is_compact_fc : bool, optional
fc3 shape is
False: (supercell, supercell, supecell, 3, 3, 3)
True: (primitive, supercell, supecell, 3, 3, 3)
False: (supercell, supercell, supecell, 3, 3, 3) True:
(primitive, supercell, supecell, 3, 3, 3)
where 'supercell' and 'primitive' indicate number of atoms in these
cells. Default is False.
fc_calculator : str or None
fc_calculator : str, optional
Force constants calculator given by str.
fc_calculator_options : dict
fc_calculator_options : dict or str, optional
Options for external force constants calculator.
"""
disp_dataset = self._dataset
fc3_calculator, fc3_calculator_options = self._extract_fc2_fc3_calculators(
fc_calculator, fc_calculator_options, 3
)
if fc3_calculator is not None:
disps, forces = get_displacements_and_forces_fc3(disp_dataset)
if fc_calculator is not None:
disps, forces = get_displacements_and_forces_fc3(self._dataset)
fc2, fc3 = get_fc3(
self._supercell,
self._primitive,
disps,
forces,
fc_calculator=fc3_calculator,
fc_calculator_options=fc3_calculator_options,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
is_compact_fc=is_compact_fc,
symmetry=self._symmetry,
log_level=self._log_level,
)
else:
if "displacements" in disp_dataset:
if "displacements" in self._dataset:
msg = (
"fc_calculator has to be set to produce force "
"constans from this dataset."
@ -1342,7 +1459,7 @@ class Phono3py:
fc2, fc3 = get_phono3py_fc3(
self._supercell,
self._primitive,
disp_dataset,
self._dataset,
self._symmetry,
is_compact_fc=is_compact_fc,
verbose=self._log_level,
@ -1412,19 +1529,15 @@ class Phono3py:
else:
p2s_map = None
fc2_calculator, fc2_calculator_options = self._extract_fc2_fc3_calculators(
fc_calculator, fc_calculator_options, 2
)
if fc2_calculator is not None:
if fc_calculator is not None:
disps, forces = get_displacements_and_forces(disp_dataset)
self._fc2 = get_fc2(
self._phonon_supercell,
self._phonon_primitive,
disps,
forces,
fc_calculator=fc2_calculator,
fc_calculator_options=fc2_calculator_options,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
atom_list=p2s_map,
symmetry=self._phonon_supercell_symmetry,
symprec=self._symprec,
@ -2055,6 +2168,136 @@ class Phono3py:
with open(filename, "w") as w:
w.write(str(ph3py_yaml))
def develop_mlp(self, params: Optional[Union[PypolymlpParams, dict, str]] = None):
"""Develop MLP of pypolymlp.
Parameters
----------
params : PypolymlpParams or dict, optional
Parameters for developing MLP. Default is None. When dict is given,
PypolymlpParams instance is created from the dict.
"""
if self._mlp_dataset is None:
raise RuntimeError("MLP dataset is not set.")
if params is not None:
_params = parse_mlp_params(params)
else:
_params = params
disps = self._mlp_dataset["displacements"]
forces = self._mlp_dataset["forces"]
energies = self._mlp_dataset["supercell_energies"]
n = int(len(disps) * 0.9)
train_data = PypolymlpData(
displacements=disps[:n], forces=forces[:n], supercell_energies=energies[:n]
)
test_data = PypolymlpData(
displacements=disps[n:], forces=forces[n:], supercell_energies=energies[n:]
)
self._mlp = develop_polymlp(
self._supercell,
train_data,
test_data,
params=_params,
verbose=self._log_level - 1 > 0,
)
def evaluate_mlp(self):
"""Evaluate the machine learning potential of pypolymlp.
This method calculates the supercell energies and forces from the MLP
for the displacements in self._dataset of type 2. The results are stored
in self._dataset.
The displacements may be generated by the produce_force_constants method
with number_of_snapshots > 0. With MLP, a small distance parameter, such
as 0.001, can be numerically stable for the computation of force
constants.
"""
if self._mlp is None:
raise RuntimeError("MLP is not developed yet.")
if self.supercells_with_displacements is None:
raise RuntimeError("Displacements are not set. Run generate_displacements.")
energies, forces, _ = evalulate_polymlp(
self._mlp, self.supercells_with_displacements
)
self.supercell_energies = energies
self.forces = forces
def develop_phonon_mlp(
self, params: Optional[Union[PypolymlpParams, dict, str]] = None
):
"""Develop MLP of pypolymlp for fc2.
Parameters
----------
params : PypolymlpParams or dict, optional
Parameters for developing MLP. Default is None. When dict is given,
PypolymlpParams instance is created from the dict.
"""
if self._phonon_mlp_dataset is None:
raise RuntimeError("MLP dataset is not set.")
if params is not None:
_params = parse_mlp_params(params)
else:
_params = params
disps = self._phonon_mlp_dataset["displacements"]
forces = self._phonon_mlp_dataset["forces"]
energies = self._phonon_mlp_dataset["supercell_energies"]
n = int(len(disps) * 0.9)
train_data = PypolymlpData(
displacements=disps[:n], forces=forces[:n], supercell_energies=energies[:n]
)
test_data = PypolymlpData(
displacements=disps[n:], forces=forces[n:], supercell_energies=energies[n:]
)
self._phonon_mlp = develop_polymlp(
self._phonon_supercell,
train_data,
test_data,
params=_params,
verbose=self._log_level - 1 > 0,
)
def evaluate_phonon_mlp(self):
"""Evaluate the machine learning potential of pypolymlp.
This method calculates the supercell energies and forces from the MLP
for the displacements in self._dataset of type 2. The results are stored
in self._dataset.
The displacements may be generated by the produce_force_constants method
with number_of_snapshots > 0. With MLP, a small distance parameter, such
as 0.001, can be numerically stable for the computation of force
constants.
"""
if self._mlp is None and self._phonon_mlp is None:
raise RuntimeError("MLP is not developed yet.")
if self.phonon_supercells_with_displacements is None:
raise RuntimeError(
"Displacements are not set. Run generate_fc2_displacements."
)
if self._phonon_mlp is None:
mlp = self._mlp
else:
mlp = self._phonon_mlp
energies, forces, _ = evalulate_polymlp(
mlp, self.phonon_supercells_with_displacements
)
self.phonon_supercell_energies = energies
self.phonon_forces = forces
###################
# private methods #
###################
@ -2135,32 +2378,44 @@ class Phono3py:
raise RuntimeError
def _build_phonon_supercells_with_displacements(
self, supercell: PhonopyAtoms, displacement_dataset
self, supercell: PhonopyAtoms, dataset
):
supercells = []
positions = supercell.positions
magmoms = supercell.magnetic_moments
masses = supercell.masses
numbers = supercell.numbers
lattice = supercell.cell
for disp1 in displacement_dataset["first_atoms"]:
disp_cart1 = disp1["displacement"]
positions = supercell.positions
positions[disp1["number"]] += disp_cart1
supercells.append(
PhonopyAtoms(
numbers=numbers,
masses=masses,
magnetic_moments=magmoms,
positions=positions,
cell=lattice,
if "displacements" in dataset:
for disp in dataset["displacements"]:
supercells.append(
PhonopyAtoms(
numbers=numbers,
masses=masses,
magnetic_moments=magmoms,
positions=positions + disp,
cell=lattice,
)
)
else:
for disp1 in dataset["first_atoms"]:
disp_cart1 = disp1["displacement"]
positions = supercell.positions
positions[disp1["number"]] += disp_cart1
supercells.append(
PhonopyAtoms(
numbers=numbers,
masses=masses,
magnetic_moments=magmoms,
positions=positions,
cell=lattice,
)
)
)
return supercells
def _build_supercells_with_displacements(self):
supercells = []
magmoms = self._supercell.magnetic_moments
masses = self._supercell.masses
numbers = self._supercell.numbers
@ -2170,28 +2425,29 @@ class Phono3py:
self._supercell, self._dataset
)
for disp1 in self._dataset["first_atoms"]:
disp_cart1 = disp1["displacement"]
for disp2 in disp1["second_atoms"]:
if "included" in disp2:
included = disp2["included"]
else:
included = True
if included:
positions = self._supercell.positions
positions[disp1["number"]] += disp_cart1
positions[disp2["number"]] += disp2["displacement"]
supercells.append(
PhonopyAtoms(
numbers=numbers,
masses=masses,
magnetic_moments=magmoms,
positions=positions,
cell=lattice,
if "first_atoms" in self._dataset:
for disp1 in self._dataset["first_atoms"]:
disp_cart1 = disp1["displacement"]
for disp2 in disp1["second_atoms"]:
if "included" in disp2:
included = disp2["included"]
else:
included = True
if included:
positions = self._supercell.positions
positions[disp1["number"]] += disp_cart1
positions[disp2["number"]] += disp2["displacement"]
supercells.append(
PhonopyAtoms(
numbers=numbers,
masses=masses,
magnetic_moments=magmoms,
positions=positions,
cell=lattice,
)
)
)
else:
supercells.append(None)
else:
supercells.append(None)
self._supercells_with_displacements = supercells
@ -2257,41 +2513,6 @@ class Phono3py:
print(" But this frequency is forced to be zero.")
print("=" * 61)
def _extract_fc2_fc3_calculators(self, fc_calculator, fc_calculator_options, order):
"""Extract fc_calculator and fc_calculator_options for fc2 and fc3.
fc_calculator : str
FC calculator. "|" separates fc2 and fc3. First and last
parts separated correspond to fc2 and fc3 calculators, respectively.
fc_calculator_options : str
FC calculator options. "|" separates fc2 and fc3. First and last
parts separated correspond to fc2 and fc3 options, respectively.
order : int = 2 or 3
2 and 3 indicate fc2 and fc3, respectively.
"""
if fc_calculator is not None:
if "|" in fc_calculator:
_fc_calculator = fc_calculator.split("|")[order - 2]
if _fc_calculator == "":
_fc_calculator = None
else:
_fc_calculator = fc_calculator
else:
_fc_calculator = None
if fc_calculator_options is not None:
if "|" in fc_calculator_options:
_fc_calculator_options = fc_calculator_options.split("|")[order - 2]
if _fc_calculator_options == "":
_fc_calculator_options = None
else:
_fc_calculator_options = fc_calculator_options
else:
_fc_calculator_options = None
return _fc_calculator, _fc_calculator_options
def _get_forces_energies(
self, target: Literal["forces", "supercell_energies"]
) -> Optional[np.ndarray]:
@ -2404,3 +2625,47 @@ class Phono3py:
self._phonon_dataset[target] = _values
else:
raise RuntimeError("Set of FC2 displacements is not available.")
def _generate_random_displacements(
self,
number_of_snapshots: int,
number_of_atoms: int,
distance: float = 0.03,
is_plusminus: bool = False,
random_seed: Optional[int] = None,
is_random_distance: bool = False,
min_distance: Optional[float] = None,
):
if random_seed is not None and random_seed >= 0 and random_seed < 2**32:
_random_seed = random_seed
dataset = {"random_seed": _random_seed}
else:
_random_seed = None
dataset = {}
d = get_random_displacements_dataset(
number_of_snapshots,
number_of_atoms,
distance,
random_seed=_random_seed,
is_plusminus=is_plusminus,
is_random_distance=is_random_distance,
min_distance=min_distance,
)
dataset["displacements"] = d
return dataset
def _check_mlp_dataset(self, mlp_dataset: dict):
if not isinstance(mlp_dataset, dict):
raise TypeError("mlp_dataset has to be a dictionary.")
if "displacements" not in mlp_dataset:
raise RuntimeError("Displacements have to be given.")
if "forces" not in mlp_dataset:
raise RuntimeError("Forces have to be given.")
if "supercell_energy" in mlp_dataset:
raise RuntimeError("Supercell energies have to be given.")
if len(mlp_dataset["displacements"]) != len(mlp_dataset["forces"]):
raise RuntimeError("Length of displacements and forces are different.")
if len(mlp_dataset["displacements"]) != len(mlp_dataset["supercell_energies"]):
raise RuntimeError(
"Length of displacements and supercell_energies are different."
)

View File

@ -45,10 +45,10 @@ from phonopy.phonon.thermal_properties import mode_cv
from phonopy.units import EV, Angstrom, Kb, THz, THzToEv
from phono3py.other.isotope import Isotope
from phono3py.phonon.grid import get_grid_points_by_rotations, get_ir_grid_points
from phono3py.phonon3.collision_matrix import CollisionMatrix
from phono3py.phonon3.imag_self_energy import ImagSelfEnergy
from phono3py.phonon3.interaction import Interaction
from phono3py.phonon.grid import get_grid_points_by_rotations, get_ir_grid_points
unit_to_WmK = (
(THz * Angstrom) ** 2 / (Angstrom**3) * EV / THz / (2 * np.pi)
@ -81,6 +81,7 @@ class HeatCapacityMixIn:
"Use attribute, Conductivity.mode_heat_capacities "
"instead of Conductivity.get_mode_heat_capacities().",
DeprecationWarning,
stacklevel=2,
)
return self.mode_heat_capacities
@ -129,6 +130,7 @@ class ConductivityMixIn(HeatCapacityMixIn):
warnings.warn(
"Use attribute, Conductivity.kappa " "instead of Conductivity.get_kappa().",
DeprecationWarning,
stacklevel=2,
)
return self.kappa
@ -143,6 +145,7 @@ class ConductivityMixIn(HeatCapacityMixIn):
"Use attribute, Conductivity.mode_kappa "
"instead of Conductivity.get_mode_kappa().",
DeprecationWarning,
stacklevel=2,
)
return self.mode_kappa
@ -165,6 +168,7 @@ class ConductivityMixIn(HeatCapacityMixIn):
"Use attribute, Conductivity.group_velocities "
"instead of Conductivity.get_group_velocities().",
DeprecationWarning,
stacklevel=2,
)
return self.group_velocities
@ -179,6 +183,7 @@ class ConductivityMixIn(HeatCapacityMixIn):
"Use attribute, Conductivity.gv_by_gv "
"instead of Conductivity.get_gv_by_gv().",
DeprecationWarning,
stacklevel=2,
)
return self.gv_by_gv
@ -413,6 +418,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.mesh_numbers "
"instead of Conductivity.get_mesh_numbers().",
DeprecationWarning,
stacklevel=2,
)
return self.mesh_numbers
@ -440,6 +446,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.frequencies "
"instead of Conductivity.get_frequencies().",
DeprecationWarning,
stacklevel=2,
)
return self.frequencies
@ -458,6 +465,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.qpoints "
"instead of Conductivity.get_qpoints().",
DeprecationWarning,
stacklevel=2,
)
return self.qpoints
@ -480,6 +488,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.grid_points "
"instead of Conductivity.get_grid_points().",
DeprecationWarning,
stacklevel=2,
)
return self.grid_points
@ -494,6 +503,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.grid_weights "
"instead of Conductivity.get_grid_weights().",
DeprecationWarning,
stacklevel=2,
)
return self.grid_weights
@ -513,6 +523,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.temperatures "
"instead of Conductivity.get_temperatures().",
DeprecationWarning,
stacklevel=2,
)
return self.temperatures
@ -522,6 +533,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.temperatures "
"instead of Conductivity.set_temperatures().",
DeprecationWarning,
stacklevel=2,
)
self.temperatures = temperatures
@ -540,6 +552,7 @@ class ConductivityBase(ABC):
warnings.warn(
"Use attribute, Conductivity.gamma " "instead of Conductivity.get_gamma().",
DeprecationWarning,
stacklevel=2,
)
return self.gamma
@ -548,6 +561,7 @@ class ConductivityBase(ABC):
warnings.warn(
"Use attribute, Conductivity.gamma " "instead of Conductivity.set_gamma().",
DeprecationWarning,
stacklevel=2,
)
self.gamma = gamma
@ -567,6 +581,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.gamma_isotope "
"instead of Conductivity.get_gamma_isotope().",
DeprecationWarning,
stacklevel=2,
)
return self.gamma_isotope
@ -576,6 +591,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.gamma_isotope "
"instead of Conductivity.set_gamma_isotope().",
DeprecationWarning,
stacklevel=2,
)
self.gamma_isotope = gamma_iso
@ -590,6 +606,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.sigmas "
"instead of Conductivity.get_sigmas().",
DeprecationWarning,
stacklevel=2,
)
return self.sigmas
@ -604,6 +621,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.sigma_cutoff_width "
"instead of Conductivity.get_sigma_cutoff_width().",
DeprecationWarning,
stacklevel=2,
)
return self.sigma_cutoff_width
@ -618,6 +636,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.grid_point_count "
"instead of Conductivity.get_grid_point_count().",
DeprecationWarning,
stacklevel=2,
)
return self.grid_point_count
@ -632,6 +651,7 @@ class ConductivityBase(ABC):
"Use attribute, Conductivity.averaged_pp_interaction "
"instead of Conductivity.get_averaged_pp_interaction().",
DeprecationWarning,
stacklevel=2,
)
return self.averaged_pp_interaction

View File

@ -56,9 +56,9 @@ from phono3py.conductivity.wigner import (
get_conversion_factor_WTE,
)
from phono3py.file_IO import read_pp_from_hdf5
from phono3py.phonon.grid import get_grid_points_by_rotations
from phono3py.phonon3.collision_matrix import CollisionMatrix
from phono3py.phonon3.interaction import Interaction, all_bands_exist
from phono3py.phonon.grid import get_grid_points_by_rotations
class ConductivityLBTEBase(ConductivityBase):
@ -163,6 +163,7 @@ class ConductivityLBTEBase(ConductivityBase):
"Use attribute, Conductivity_LBTE.collision_matrix "
"instead of Conductivity_LBTE.get_collision_matrix().",
DeprecationWarning,
stacklevel=2,
)
return self.collision_matrix
@ -172,6 +173,7 @@ class ConductivityLBTEBase(ConductivityBase):
"Use attribute, Conductivity_LBTE.collision_matrix "
"instead of Conductivity_LBTE.set_collision_matrix().",
DeprecationWarning,
stacklevel=2,
)
self.collision_matrix = collision_matrix
@ -1271,6 +1273,7 @@ class ConductivityLBTE(ConductivityMixIn, ConductivityLBTEBase):
"Use attribute, Conductivity_LBTE.kappa_RTA "
"instead of Conductivity_LBTE.get_kappa_RTA().",
DeprecationWarning,
stacklevel=2,
)
return self.kappa_RTA
@ -1285,6 +1288,7 @@ class ConductivityLBTE(ConductivityMixIn, ConductivityLBTEBase):
"Use attribute, Conductivity_LBTE.mode_kappa_RTA "
"instead of Conductivity_LBTE.get_mode_kappa_RTA().",
DeprecationWarning,
stacklevel=2,
)
return self.mode_kappa_RTA

View File

@ -54,9 +54,9 @@ from phono3py.conductivity.wigner import (
)
from phono3py.file_IO import read_pp_from_hdf5
from phono3py.other.tetrahedron_method import get_tetrahedra_relative_grid_address
from phono3py.phonon.grid import get_grid_points_by_rotations
from phono3py.phonon3.imag_self_energy import ImagSelfEnergy, average_by_degeneracy
from phono3py.phonon3.interaction import Interaction, all_bands_exist
from phono3py.phonon.grid import get_grid_points_by_rotations
class ConductivityRTABase(ConductivityBase):
@ -921,7 +921,7 @@ class ConductivityKuboRTA(ConductivityKuboMixIn, ConductivityRTABase):
return
g = g_sum[i_band] + g_sum[j_band]
for i_pair, (a, b) in enumerate(
for i_pair, _ in enumerate(
([0, 0], [1, 1], [2, 2], [1, 2], [0, 2], [0, 1])
):
old_settings = np.seterr(all="raise")

View File

@ -34,7 +34,6 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import sys
from typing import TYPE_CHECKING, Optional, Union
@ -367,7 +366,7 @@ class ConductivityRTAWriter:
all_triplets = get_all_triplets(gp, interaction.bz_grid)
if all_bands_exist(interaction):
for j, sigma in enumerate(sigmas):
for sigma in sigmas:
write_gamma_detail_to_hdf5(
temperatures,
mesh,
@ -384,7 +383,7 @@ class ConductivityRTAWriter:
verbose=verbose,
)
else:
for j, sigma in enumerate(sigmas):
for sigma in sigmas:
for k, bi in enumerate(interaction.get_band_indices()):
write_gamma_detail_to_hdf5(
temperatures,
@ -871,7 +870,7 @@ class ShowCalcProgress:
("#%6s " + " %-10s" * 6)
% ("T(K)", "xx", "yy", "zz", "yz", "xz", "xy")
)
for j, (t, k) in enumerate(zip(temperatures, kappa[i])):
for t, k in zip(temperatures, kappa[i]):
print(("%7.1f " + " %10.3f" * 6) % ((t,) + tuple(k)))
print("")
@ -936,13 +935,13 @@ class ShowCalcProgress:
% (" \t T(K)", "xx", "yy", "zz", "yz", "xz", "xy")
)
if kappa_P_RTA is not None:
for j, (t, k) in enumerate(zip(temperatures, kappa_P_RTA[i])):
for t, k in zip(temperatures, kappa_P_RTA[i]):
print("K_P\t" + ("%7.1f " + " %10.3f" * 6) % ((t,) + tuple(k)))
print(" ")
for j, (t, k) in enumerate(zip(temperatures, kappa_C[i])):
for t, k in zip(temperatures, kappa_C[i]):
print("K_C\t" + ("%7.1f " + " %10.3f" * 6) % ((t,) + tuple(k)))
print(" ")
for j, (t, k) in enumerate(zip(temperatures, kappa_TOT_RTA[i])):
for t, k in zip(temperatures, kappa_TOT_RTA[i]):
print("K_T\t" + ("%7.1f " + " %10.3f" * 6) % ((t,) + tuple(k)))
print("")

View File

@ -40,7 +40,8 @@ import copy
import os
import pathlib
import sys
from typing import Optional
from dataclasses import asdict
from typing import Optional, Union
import numpy as np
from phonopy.cui.phonopy_script import file_exists, print_error
@ -52,6 +53,7 @@ from phonopy.harmonic.force_constants import (
)
from phonopy.interface.calculator import get_default_physical_units
from phonopy.interface.fc_calculator import fc_calculator_names
from phonopy.interface.pypolymlp import PypolymlpParams, parse_mlp_params
from phono3py import Phono3py
from phono3py.cui.show_log import show_phono3py_force_constants_settings
@ -64,6 +66,7 @@ from phono3py.file_IO import (
write_fc2_to_hdf5,
write_fc3_to_hdf5,
)
from phono3py.interface.fc_calculator import extract_fc2_fc3_calculators
from phono3py.interface.phono3py_yaml import Phono3pyYaml
from phono3py.phonon3.fc3 import (
set_permutation_symmetry_fc3,
@ -122,6 +125,11 @@ def create_phono3py_force_constants(
settings.cutoff_pair_distance,
fc_calculator,
fc_calculator_options,
settings.use_pypolymlp,
settings.mlp_params,
settings.displacement_distance,
settings.random_displacements,
settings.random_seed,
log_level,
)
@ -159,29 +167,19 @@ def create_phono3py_force_constants(
_read_phono3py_fc2(phono3py, symmetrize_fc2, input_filename, log_level)
else:
if phono3py.phonon_supercell_matrix is None:
if fc_calculator == "alm" and phono3py.fc2 is not None:
if log_level:
print("fc2 that was fit simultaneously with fc3 " "by ALM is used.")
else:
_create_phono3py_fc2(
phono3py,
ph3py_yaml,
symmetrize_fc2,
settings.is_compact_fc,
fc_calculator,
fc_calculator_options,
log_level,
)
force_filename = "FORCES_FC3"
else:
_create_phono3py_phonon_fc2(
phono3py,
ph3py_yaml,
symmetrize_fc2,
settings.is_compact_fc,
fc_calculator,
fc_calculator_options,
log_level,
)
force_filename = "FORCES_FC2"
_create_phono3py_fc2(
phono3py,
ph3py_yaml,
force_filename,
symmetrize_fc2,
settings.is_compact_fc,
fc_calculator,
fc_calculator_options,
log_level,
)
if output_filename is None:
filename = "fc2.hdf5"
else:
@ -249,7 +247,7 @@ def parse_forces(
# Try to read FORCES_FC* if type-2 and return dataset.
# None is returned unless type-2.
# can emit FileNotFoundError.
if dataset is None or dataset is not None and not forces_in_dataset(dataset):
if dataset is None or (dataset is not None and not forces_in_dataset(dataset)):
_dataset = read_type2_dataset(
natom, filename=force_filename, log_level=log_level
)
@ -321,8 +319,10 @@ def forces_in_dataset(dataset: dict) -> bool:
)
def displacements_in_dataset(dataset: dict) -> bool:
def displacements_in_dataset(dataset: Optional[dict]) -> bool:
"""Return whether displacements in dataset or not."""
if dataset is None:
return False
return "displacements" in dataset or "first_atoms" in dataset
@ -443,6 +443,11 @@ def _create_phono3py_fc3(
cutoff_pair_distance: Optional[float],
fc_calculator: Optional[str],
fc_calculator_options: Optional[str],
use_pypolymlp: bool,
mlp_params: Union[str, dict, PypolymlpParams],
displacement_distance: Optional[float],
number_of_snapshots: Optional[int],
random_seed: Optional[int],
log_level: int,
):
"""Read or calculate fc3.
@ -481,31 +486,175 @@ def _create_phono3py_fc3(
# from _get_type2_dataset
file_exists(e.filename, log_level)
phono3py.dataset = dataset
if use_pypolymlp:
phono3py.mlp_dataset = dataset
run_pypolymlp_to_compute_forces(
phono3py,
mlp_params,
displacement_distance=displacement_distance,
number_of_snapshots=number_of_snapshots,
random_seed=random_seed,
log_level=log_level,
)
else:
phono3py.dataset = dataset
phono3py.produce_fc3(
symmetrize_fc3r=symmetrize_fc3r,
is_compact_fc=is_compact_fc,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
fc_calculator=extract_fc2_fc3_calculators(fc_calculator, 3),
fc_calculator_options=extract_fc2_fc3_calculators(fc_calculator_options, 3),
)
def run_pypolymlp_to_compute_forces(
ph3py: Phono3py,
mlp_params: Union[str, dict, PypolymlpParams],
displacement_distance: Optional[float] = None,
number_of_snapshots: Optional[int] = None,
random_seed: Optional[int] = None,
log_level: int = 0,
):
"""Run pypolymlp to compute forces."""
if log_level:
print("-" * 29 + " pypolymlp start " + "-" * 30)
print("Pypolymlp is a generator of polynomial machine learning potentials.")
print("Please cite the paper: A. Seko, J. Appl. Phys. 133, 011101 (2023).")
print("Pypolymlp is developed at https://github.com/sekocha/pypolymlp.")
if mlp_params:
print("Parameters:")
for k, v in asdict(parse_mlp_params(mlp_params)).items():
if v is not None:
print(f" {k}: {v}")
if log_level > 1:
print("")
if log_level:
print("Developing MLPs by pypolymlp...", flush=True)
ph3py.develop_mlp(params=mlp_params)
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 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(
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,
)
if log_level:
print(
f"Evaluate forces in {ph3py.displacements.shape[0]} supercells "
"by pypolymlp",
flush=True,
)
if ph3py.mlp_dataset is None:
msg = "mlp_dataset has to be set before calling this method."
raise RuntimeError(msg)
if ph3py.supercells_with_displacements is None:
raise RuntimeError("Displacements are not set. Run generate_displacements.")
ph3py.evaluate_mlp()
def run_pypolymlp_to_compute_phonon_forces(
ph3py: Phono3py,
mlp_params: Optional[Union[str, dict, PypolymlpParams]] = None,
displacement_distance: Optional[float] = None,
number_of_snapshots: Optional[int] = None,
random_seed: Optional[int] = None,
log_level: int = 0,
):
"""Run pypolymlp to compute phonon forces."""
if ph3py.phonon_mlp_dataset is not None:
if log_level:
print("-" * 29 + " pypolymlp start " + "-" * 30)
print("Pypolymlp is a generator of polynomial machine learning potentials.")
print("Please cite the paper: A. Seko, J. Appl. Phys. 133, 011101 (2023).")
print("Pypolymlp is developed at https://github.com/sekocha/pypolymlp.")
if mlp_params:
print("Parameters:")
for k, v in asdict(parse_mlp_params(mlp_params)).items():
if v is not None:
print(f" {k}: {v}")
if log_level > 1:
print("")
if log_level:
print("Developing MLPs by pypolymlp...", flush=True)
ph3py.develop_phonon_mlp(params=mlp_params)
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 log_level:
print("Generate random displacements for fc2")
print(
f" Displacement distance: {_displacement_distance:.5f}".rstrip("0").rstrip(
"."
)
)
ph3py.generate_fc2_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.phonon_displacements.shape[0]} "
"supercells by pypolymlp",
flush=True,
)
ph3py.evaluate_phonon_mlp()
def _create_phono3py_fc2(
phono3py: Phono3py,
ph3py_yaml: Optional[Phono3pyYaml],
force_filename,
symmetrize_fc2,
is_compact_fc,
fc_calculator,
fc_calculator_options,
log_level,
):
"""Read forces and produce fc2.
force_filename is either "FORCES_FC2" or "FORCES_FC3".
"""
_ph3py_yaml = _get_default_ph3py_yaml(ph3py_yaml)
try:
dataset = parse_forces(
phono3py,
ph3py_yaml=_ph3py_yaml,
force_filename="FORCES_FC3",
force_filename=force_filename,
fc_type="fc2",
log_level=log_level,
)
@ -521,8 +670,8 @@ def _create_phono3py_fc2(
phono3py.produce_fc2(
symmetrize_fc2=symmetrize_fc2,
is_compact_fc=is_compact_fc,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
fc_calculator=extract_fc2_fc3_calculators(fc_calculator, 2),
fc_calculator_options=extract_fc2_fc3_calculators(fc_calculator_options, 2),
)
@ -534,42 +683,6 @@ def _get_default_ph3py_yaml(ph3py_yaml: Optional[Phono3pyYaml]):
return _ph3py_yaml
def _create_phono3py_phonon_fc2(
phono3py: Phono3py,
ph3py_yaml: Optional[Phono3pyYaml],
symmetrize_fc2: bool,
is_compact_fc: bool,
fc_calculator: Optional[str],
fc_calculator_options: Optional[str],
log_level: int,
):
_ph3py_yaml = _get_default_ph3py_yaml(ph3py_yaml)
try:
dataset = parse_forces(
phono3py,
ph3py_yaml=_ph3py_yaml,
force_filename="FORCES_FC2",
fc_type="phonon_fc2",
log_level=log_level,
)
except RuntimeError as e:
if log_level:
print(str(e))
print_error()
sys.exit(1)
except FileNotFoundError as e:
file_exists(e.filename, log_level)
phono3py.phonon_dataset = dataset
phono3py.produce_fc2(
symmetrize_fc2=symmetrize_fc2,
is_compact_fc=is_compact_fc,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
)
def _convert_unit_in_dataset(
dataset: dict,
distance_to_A: Optional[float] = None,

View File

@ -77,8 +77,18 @@ def create_phono3py_supercells(
cutoff_pair_distance=settings.cutoff_pair_distance,
is_plusminus=settings.is_plusminus_displacement,
is_diagonal=settings.is_diagonal_displacement,
number_of_snapshots=settings.random_displacements,
random_seed=settings.random_seed,
)
if settings.random_displacements_fc2:
phono3py.generate_fc2_displacements(
distance=distance,
is_plusminus=settings.is_plusminus_displacement,
number_of_snapshots=settings.random_displacements_fc2,
random_seed=settings.random_seed,
)
if log_level:
print("")
print('Unit cell was read from "%s".' % optional_structure_info[0])

View File

@ -49,12 +49,12 @@ from phonopy.structure.cells import determinant
from phono3py import Phono3py
from phono3py.cui.create_force_constants import (
displacements_in_dataset,
forces_in_dataset,
parse_forces,
read_type2_dataset,
run_pypolymlp_to_compute_forces,
)
from phono3py.file_IO import read_fc2_from_hdf5, read_fc3_from_hdf5
from phono3py.interface.fc_calculator import extract_fc2_fc3_calculators
from phono3py.interface.phono3py_yaml import Phono3pyYaml
from phono3py.phonon3.fc3 import show_drift_fc3
@ -86,6 +86,8 @@ def load(
symmetrize_fc: bool = True,
is_mesh_symmetry: bool = True,
is_compact_fc: bool = False,
use_pypolymlp: bool = False,
mlp_params: Optional[dict] = None,
use_grg: bool = False,
make_r0_average: bool = True,
symprec: float = 1e-5,
@ -236,6 +238,10 @@ def load(
True: (primitive, supecell, 3, 3) False: (supercell, supecell, 3, 3)
where 'supercell' and 'primitive' indicate number of atoms in these
cells. Default is False.
use_pypolymlp : bool, optional
Use pypolymlp for generating force constants. Default is False.
mlp_params : dict, optional
A set of parameters used by machine learning potentials.
use_grg : bool, optional
Use generalized regular grid when True. Default is False.
make_r0_average : bool, optional
@ -337,6 +343,7 @@ def load(
forces_fc3_filename=forces_fc3_filename,
forces_fc2_filename=forces_fc2_filename,
phono3py_yaml_filename=phono3py_yaml,
use_pypolymlp=use_pypolymlp,
log_level=log_level,
)
@ -348,6 +355,8 @@ def load(
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,
)
@ -370,6 +379,7 @@ def set_dataset_and_force_constants(
forces_fc2_filename: Optional[Union[os.PathLike, Sequence]] = None,
phono3py_yaml_filename: Optional[os.PathLike] = None,
cutoff_pair_distance: Optional[float] = None,
use_pypolymlp: bool = False,
log_level: int = 0,
) -> dict:
"""Set displacements, forces, and create force constants.
@ -387,7 +397,7 @@ def set_dataset_and_force_constants(
"""
read_fc = {"fc2": False, "fc3": False}
read_fc["fc3"] = _set_dataset_or_fc3(
read_fc["fc3"], dataset = _get_dataset_or_fc3(
ph3py,
ph3py_yaml=ph3py_yaml,
fc3_filename=fc3_filename,
@ -396,20 +406,20 @@ def set_dataset_and_force_constants(
cutoff_pair_distance=cutoff_pair_distance,
log_level=log_level,
)
read_fc["fc2"] = _set_dataset_phonon_dataset_or_fc2(
if not read_fc["fc3"]:
if use_pypolymlp:
ph3py.mlp_dataset = dataset
else:
ph3py.dataset = dataset
read_fc["fc2"], phonon_dataset = _get_dataset_phonon_dataset_or_fc2(
ph3py,
ph3py_yaml=ph3py_yaml,
fc2_filename=fc2_filename,
forces_fc2_filename=forces_fc2_filename,
log_level=log_level,
)
# Cases that dataset is in phono3py.yaml but not forces.
if ph3py.dataset is None:
if ph3py_yaml is not None and ph3py_yaml.dataset is not None:
ph3py.dataset = ph3py_yaml.dataset
if ph3py_yaml is not None and ph3py_yaml.phonon_dataset is not None:
ph3py.phonon_dataset = ph3py_yaml.phonon_dataset
if not read_fc["fc2"]:
ph3py.phonon_dataset = phonon_dataset
return read_fc
@ -418,9 +428,14 @@ def compute_force_constants_from_datasets(
ph3py: Phono3py,
read_fc: dict,
fc_calculator: Optional[str] = None,
fc_calculator_options: Optional[dict] = 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.
@ -435,36 +450,40 @@ def compute_force_constants_from_datasets(
fc2 : bool
"""
if not read_fc["fc3"] and ph3py.dataset:
fc3_calculator = extract_fc2_fc3_calculators(fc_calculator, 3)
fc2_calculator = extract_fc2_fc3_calculators(fc_calculator, 2)
if not read_fc["fc3"] and (ph3py.dataset or ph3py.mlp_dataset):
if ph3py.mlp_dataset and 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,
)
ph3py.produce_fc3(
symmetrize_fc3r=symmetrize_fc,
is_compact_fc=is_compact_fc,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
fc_calculator=fc3_calculator,
fc_calculator_options=extract_fc2_fc3_calculators(fc_calculator_options, 3),
)
if log_level and symmetrize_fc:
if log_level and symmetrize_fc and fc_calculator is None:
print("fc3 was symmetrized.")
if not read_fc["fc2"] and (ph3py.dataset or ph3py.phonon_dataset):
if (
ph3py.phonon_supercell_matrix is None
and fc_calculator == "alm"
and ph3py.fc2 is not None
):
if log_level:
print("fc2 that was fit simultaneously with fc3 by ALM is used.")
else:
ph3py.produce_fc2(
symmetrize_fc2=symmetrize_fc,
is_compact_fc=is_compact_fc,
fc_calculator=fc_calculator,
fc_calculator_options=fc_calculator_options,
)
if log_level and symmetrize_fc:
print("fc2 was symmetrized.")
ph3py.produce_fc2(
symmetrize_fc2=symmetrize_fc,
is_compact_fc=is_compact_fc,
fc_calculator=fc2_calculator,
fc_calculator_options=extract_fc2_fc3_calculators(fc_calculator_options, 2),
)
if log_level and symmetrize_fc and fc_calculator is None:
print("fc2 was symmetrized.")
def _set_dataset_or_fc3(
def _get_dataset_or_fc3(
ph3py: Phono3py,
ph3py_yaml: Optional[Phono3pyYaml] = None,
fc3_filename: Optional[os.PathLike] = None,
@ -472,19 +491,40 @@ def _set_dataset_or_fc3(
phono3py_yaml_filename: Optional[os.PathLike] = None,
cutoff_pair_distance: Optional[float] = None,
log_level: int = 0,
) -> bool:
) -> tuple[bool, dict]:
p2s_map = ph3py.primitive.p2s_map
read_fc3 = False
if fc3_filename is not None:
fc3 = read_fc3_from_hdf5(filename=fc3_filename, p2s_map=p2s_map)
_check_fc3_shape(ph3py, fc3, filename=fc3_filename)
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('fc3 was read from "%s".' % fc3_filename)
elif forces_fc3_filename is not None:
force_filename = forces_fc3_filename
_set_dataset_for_fc3(
print(f'fc3 was read from "{_fc3_filename}".')
elif (
ph3py_yaml is not None
and ph3py_yaml.dataset is not None
and forces_in_dataset(ph3py_yaml.dataset)
):
dataset = _get_dataset_for_fc3(
ph3py,
ph3py_yaml,
None,
phono3py_yaml_filename,
cutoff_pair_distance,
log_level,
)
elif forces_fc3_filename is not None or pathlib.Path("FORCES_FC3").exists():
if forces_fc3_filename is None:
force_filename = "FORCES_FC3"
else:
force_filename = forces_fc3_filename
dataset = _get_dataset_for_fc3(
ph3py,
ph3py_yaml,
force_filename,
@ -492,132 +532,74 @@ def _set_dataset_or_fc3(
cutoff_pair_distance,
log_level,
)
elif pathlib.Path("fc3.hdf5").exists():
fc3 = read_fc3_from_hdf5(filename="fc3.hdf5", p2s_map=p2s_map)
_check_fc3_shape(ph3py, fc3)
ph3py.fc3 = fc3
read_fc3 = True
if log_level:
print('fc3 was read from "fc3.hdf5".')
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
if not forces_in_dataset(dataset):
dataset = None
return read_fc3, dataset
def _set_dataset_phonon_dataset_or_fc2(
def _get_dataset_phonon_dataset_or_fc2(
ph3py: Phono3py,
ph3py_yaml: Optional[Phono3pyYaml] = None,
fc2_filename: Optional[os.PathLike] = None,
forces_fc2_filename: Optional[Union[os.PathLike, Sequence]] = None,
log_level: int = 0,
) -> bool:
) -> tuple[bool, dict, dict]:
phonon_p2s_map = ph3py.phonon_primitive.p2s_map
read_fc2 = False
if fc2_filename is not None:
fc2 = read_fc2_from_hdf5(filename=fc2_filename, p2s_map=phonon_p2s_map)
_check_fc2_shape(ph3py, fc2, filename=fc2_filename)
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('fc2 was read from "%s".' % fc2_filename)
elif forces_fc2_filename is not None:
force_filename = forces_fc2_filename
_set_dataset_for_fc2(
print(f'fc2 was read from "{fc2_filename}".')
elif (
ph3py_yaml is not None
and ph3py_yaml.phonon_dataset is not None
and forces_in_dataset(ph3py_yaml.phonon_dataset)
):
phonon_dataset = _get_dataset_for_fc2(
ph3py,
ph3py_yaml,
None,
"phonon_fc2",
log_level,
)
elif (
forces_fc2_filename is not None or pathlib.Path("FORCES_FC2").exists()
) and ph3py.phonon_supercell_matrix:
if forces_fc2_filename is None:
force_filename = forces_fc2_filename
else:
force_filename = forces_fc2_filename
phonon_dataset = _get_dataset_for_fc2(
ph3py,
ph3py_yaml,
force_filename,
"phonon_fc2",
log_level,
)
elif pathlib.Path("fc2.hdf5").exists():
fc2 = read_fc2_from_hdf5(filename="fc2.hdf5", p2s_map=phonon_p2s_map)
_check_fc2_shape(ph3py, fc2)
ph3py.fc2 = fc2
read_fc2 = True
if log_level:
print('fc2 was read from "fc2.hdf5".')
elif (
pathlib.Path("FORCES_FC2").exists()
and ph3py.phonon_supercell_matrix is not None
):
_set_dataset_for_fc2(
ph3py,
ph3py_yaml,
"FORCES_FC2",
"phonon_fc2",
log_level,
)
elif (
ph3py_yaml is not None
and ph3py_yaml.phonon_dataset is not None
and forces_in_dataset(ph3py_yaml.phonon_dataset)
):
_set_dataset_for_fc2(
ph3py,
ph3py_yaml,
None,
"phonon_fc2",
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_fc2(
ph3py,
ph3py_yaml,
None,
"fc2",
log_level,
)
elif (
pathlib.Path("FORCES_FC3").exists()
and ph3py.phonon_supercell_matrix is not None
):
# suppose fc3.hdf5 is read but fc2.hdf5 doesn't exist.
_set_dataset_for_fc2(
ph3py,
ph3py_yaml,
"FORCES_FC3",
"fc2",
log_level,
)
return read_fc2
if not forces_in_dataset(phonon_dataset):
phonon_dataset = None
return read_fc2, phonon_dataset
def _set_dataset_for_fc3(
def _get_dataset_for_fc3(
ph3py: Phono3py,
ph3py_yaml: Optional[Phono3pyYaml],
force_filename,
phono3py_yaml_filename,
cutoff_pair_distance,
log_level,
):
ph3py.dataset = parse_forces(
) -> dict:
dataset = parse_forces(
ph3py,
ph3py_yaml=ph3py_yaml,
cutoff_pair_distance=cutoff_pair_distance,
@ -626,9 +608,10 @@ def _set_dataset_for_fc3(
fc_type="fc3",
log_level=log_level,
)
return dataset
def _set_dataset_for_fc2(
def _get_dataset_for_fc2(
ph3py: Phono3py,
ph3py_yaml: Optional[Phono3pyYaml],
force_filename,
@ -642,10 +625,7 @@ def _set_dataset_for_fc2(
fc_type=fc_type,
log_level=log_level,
)
if fc_type == "phonon_fc2":
ph3py.phonon_dataset = dataset
else:
ph3py.dataset = dataset
return dataset
def _check_fc2_shape(ph3py: Phono3py, fc2, filename="fc2.hdf5"):

View File

@ -471,6 +471,15 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False):
parser.add_argument(
"--mesh", nargs="+", dest="mesh_numbers", default=None, help="Mesh numbers"
)
parser.add_argument(
"--mlp-params",
dest="mlp_params",
default=None,
help=(
"Parameters for machine learning potentials as comma separated "
"string with the style of key = values"
),
)
parser.add_argument(
"--mv",
"--mass-variances",
@ -516,7 +525,7 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False):
action="store_true",
default=False,
help="Deactivate summation of partial kappa at q-stars",
),
)
parser.add_argument(
"--nomeshsym",
dest="is_nomeshsym",
@ -618,6 +627,13 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False):
default=None,
help="Conversion factor for ph-ph interaction",
)
parser.add_argument(
"--pypolymlp",
dest="use_pypolymlp",
action="store_true",
default=False,
help="Use pypolymlp and symfc for generating force constants",
)
parser.add_argument(
"--qpoints",
nargs="+",
@ -640,6 +656,29 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False):
default=False,
help="Print out smallest information",
)
parser.add_argument(
"--random-seed",
dest="random_seed",
type=int,
default=None,
help="Random seed by a 32 bit unsigned integer",
)
parser.add_argument(
"--rd",
"--random-displacements",
dest="random_displacements",
type=int,
default=None,
help="Number of supercells with random displacements",
)
parser.add_argument(
"--rd-fc2",
"--random-displacements-fc2",
dest="random_displacements_fc2",
type=int,
default=None,
help="Number of phonon supercells with random displacements",
)
parser.add_argument(
"--read-collision",
dest="read_collision",

View File

@ -89,9 +89,9 @@ from phono3py.file_IO import (
write_phonon_to_hdf5,
)
from phono3py.interface.phono3py_yaml import Phono3pyYaml
from phono3py.phonon.grid import get_grid_point_from_address, get_ir_grid_points
from phono3py.phonon3.fc3 import show_drift_fc3
from phono3py.phonon3.gruneisen import run_gruneisen_parameters
from phono3py.phonon.grid import get_grid_point_from_address, get_ir_grid_points
from phono3py.version import __version__
# import logging
@ -160,11 +160,18 @@ def finalize_phono3py(
yaml_filename = filename
_physical_units = get_default_physical_units(phono3py.calculator)
write_force_sets = phono3py.mlp is not None
_write_displacements = write_displacements or phono3py.mlp is not None
ph3py_yaml = Phono3pyYaml(
configuration=confs_dict,
calculator=phono3py.calculator,
physical_units=_physical_units,
settings={"force_sets": False, "displacements": write_displacements},
settings={
"force_sets": write_force_sets,
"displacements": _write_displacements,
},
)
ph3py_yaml.set_phonon_info(phono3py)
with open(yaml_filename, "w") as w:
@ -528,6 +535,7 @@ def store_force_constants(
ph3py_yaml=ph3py_yaml,
phono3py_yaml_filename=phono3py_yaml_filename,
cutoff_pair_distance=settings.cutoff_pair_distance,
use_pypolymlp=settings.use_pypolymlp,
log_level=log_level,
)
try:
@ -538,6 +546,11 @@ def store_force_constants(
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:
@ -605,8 +618,8 @@ def _show_fc_calculator_not_found(log_level):
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."
"An external force calculator, e.g., symfc (--symfc_ or ALM (--alm), "
"has to be used to compute force constants."
)
print_error()
sys.exit(1)

View File

@ -89,6 +89,7 @@ class Phono3pySettings(Settings):
"pinv_solver": 0,
"pinv_method": 0,
"pp_conversion_factor": None,
"random_displacements_fc2": None,
"scattering_event_class": None, # scattering event class 1 or 2
"sigma_cutoff_width": None,
"solve_collective_phonon": False,
@ -276,6 +277,10 @@ class Phono3pySettings(Settings):
"""Set pp_conversion_factor."""
self._v["pp_conversion_factor"] = val
def set_random_displacements_fc2(self, val):
"""Set random_displacements_fc2."""
self._v["random_displacements_fc2"] = val
def set_read_collision(self, val):
"""Set read_collision."""
self._v["read_collision"] = val
@ -553,6 +558,11 @@ class Phono3pyConfParser(ConfParser):
if pp_conv_factor is not None:
self._confs["pp_conversion_factor"] = pp_conv_factor
if "random_displacements_fc2" in self._args:
rd_fc2 = self._args.random_displacements_fc2
if rd_fc2 is not None:
self._confs["random_displacements_fc2"] = rd_fc2
if "read_fc2" in self._args:
if self._args.read_fc2:
self._confs["read_fc2"] = ".true."
@ -695,6 +705,7 @@ class Phono3pyConfParser(ConfParser):
"pinv_method",
"pinv_solver",
"num_points_in_batch",
"random_displacements_fc2",
"scattering_event_class",
):
self.set_parameter(conf_key, int(confs[conf_key]))
@ -709,7 +720,7 @@ class Phono3pyConfParser(ConfParser):
# specials
if conf_key in ("create_forces_fc2", "create_forces_fc3"):
if type(confs[conf_key]) is str:
if isinstance(confs[conf_key], str):
fnames = confs[conf_key].split()
else:
fnames = confs[conf_key]
@ -943,6 +954,12 @@ class Phono3pyConfParser(ConfParser):
if "pp_conversion_factor" in params:
self._settings.set_pp_conversion_factor(params["pp_conversion_factor"])
# Random displacements for fc2
if "random_displacements_fc2" in params:
self._settings.set_random_displacements_fc2(
params["random_displacements_fc2"]
)
# Calculate real_self_energys
if "real_self_energy" in params:
self._settings.set_is_real_self_energy(params["real_self_energy"])

View File

@ -48,7 +48,8 @@ def show_general_settings(
):
"""Show general setting information."""
is_primitive_axes_auto = (
type(phono3py.primitive_matrix) is str and phono3py.primitive_matrix == "auto"
isinstance(phono3py.primitive_matrix, str)
and phono3py.primitive_matrix == "auto"
)
primitive_matrix = phono3py.primitive_matrix
supercell_matrix = phono3py.supercell_matrix
@ -106,7 +107,7 @@ def show_phono3py_cells(phono3py: Phono3py):
print_cell(phonon_primitive)
print("-" * 21 + " supercell for harmonic phonon " + "-" * 22)
print_cell(phonon_supercell, mapping=phonon_primitive.s2p_map)
print("-" * 76)
print("-" * 76, flush=True)
def show_phono3py_force_constants_settings(settings: Phono3pySettings):

View File

@ -37,8 +37,8 @@
import numpy as np
from phono3py.file_IO import write_grid_address_to_hdf5, write_ir_grid_points
from phono3py.phonon3.triplets import get_triplets_at_q
from phono3py.phonon.grid import get_ir_grid_points
from phono3py.phonon3.triplets import get_triplets_at_q
def write_grid_points(

View File

@ -57,7 +57,9 @@ def write_disp_fc3_yaml(dataset, supercell, filename="disp_fc3.yaml"):
This function should not be called from phono3py script from version 3.
"""
warnings.warn("write_disp_fc3_yaml() is deprecated.", DeprecationWarning)
warnings.warn(
"write_disp_fc3_yaml() is deprecated.", DeprecationWarning, stacklevel=2
)
w = open(filename, "w")
w.write("natom: %d\n" % dataset["natom"])
@ -155,7 +157,9 @@ def write_disp_fc2_yaml(dataset, supercell, filename="disp_fc2.yaml"):
This function should not be called from phono3py script from version 3.
"""
warnings.warn("write_disp_fc2_yaml() is deprecated.", DeprecationWarning)
warnings.warn(
"write_disp_fc2_yaml() is deprecated.", DeprecationWarning, stacklevel=2
)
w = open(filename, "w")
w.write("natom: %d\n" % dataset["natom"])
@ -251,7 +255,7 @@ def write_FORCES_FC3(disp_dataset, forces_fc3=None, fp=None, filename="FORCES_FC
else:
# for forces in forces_fc3[i]:
# w.write("%15.10f %15.10f %15.10f\n" % (tuple(forces)))
for j in range(natom):
for _ in range(natom):
w.write("%15.10f %15.10f %15.10f\n" % (0, 0, 0))
count += 1
@ -339,8 +343,8 @@ def write_fc2_to_hdf5(
):
try:
import h5py
except ImportError:
raise ModuleNotFoundError("You need to install python-h5py.")
except ImportError as exc:
raise ModuleNotFoundError("You need to install python-h5py.") from exc
with h5py.File(filename, "w") as w:
w.create_dataset(
@ -1480,7 +1484,9 @@ def parse_disp_fc2_yaml(filename="disp_fc2.yaml", return_cell=False):
This function should not be called from phono3py script from version 3.
"""
warnings.warn("parse_disp_fc2_yaml() is deprecated.", DeprecationWarning)
warnings.warn(
"parse_disp_fc2_yaml() is deprecated.", DeprecationWarning, stacklevel=2
)
dataset = _parse_yaml(filename)
natom = dataset["natom"]
@ -1507,7 +1513,9 @@ def parse_disp_fc3_yaml(filename="disp_fc3.yaml", return_cell=False):
This function should not be called from phono3py script from version 3.
"""
warnings.warn("parse_disp_fc3_yaml() is deprecated.", DeprecationWarning)
warnings.warn(
"parse_disp_fc3_yaml() is deprecated.", DeprecationWarning, stacklevel=2
)
dataset = _parse_yaml(filename)
natom = dataset["natom"]
@ -1547,7 +1555,7 @@ def parse_FORCES_FC2(disp_dataset, filename="FORCES_FC2", unit_conversion_factor
num_disp = len(disp_dataset["first_atoms"])
forces_fc2 = []
with open(filename, "r") as f2:
for i in range(num_disp):
for _ in range(num_disp):
forces = _parse_force_lines(f2, num_atom)
if forces is None:
return []
@ -1681,7 +1689,7 @@ def _parse_yaml(file_yaml):
So this is obsolete at v2 and later versions.
"""
warnings.warn("_parse_yaml() is deprecated.", DeprecationWarning)
warnings.warn("_parse_yaml() is deprecated.", DeprecationWarning, stacklevel=2)
import yaml
@ -1720,7 +1728,7 @@ def _write_cell_yaml(w, supercell):
These methods are also deprecated.
"""
warnings.warn("write_cell_yaml() is deprecated.", DeprecationWarning)
warnings.warn("write_cell_yaml() is deprecated.", DeprecationWarning, stacklevel=2)
w.write("lattice:\n")
for axis in supercell.get_cell():

View File

@ -34,7 +34,6 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
calculator_info = {
"abinit": {"option": {"name": "--abinit", "help": "Invoke Abinit mode"}},
# 'aims': {'option': {'name': "--aims",

View File

@ -36,7 +36,7 @@
from __future__ import annotations
from typing import Optional
from typing import Optional, Union
import numpy as np
from phonopy.structure.atoms import PhonopyAtoms
@ -118,8 +118,35 @@ def get_fc3(
orders=[2, 3],
is_compact_fc=is_compact_fc,
symmetry=symmetry,
options=fc_calculator_options,
log_level=log_level,
)
else:
msg = "Force constants calculator of %s was not found ." % fc_calculator
raise RuntimeError(msg)
def extract_fc2_fc3_calculators(fc_calculator: Optional[Union[str, dict]], order: int):
"""Extract fc_calculator and fc_calculator_options for fc2 and fc3.
fc_calculator : str
FC calculator. "|" separates fc2 and fc3. First and last
parts separated correspond to fc2 and fc3 calculators, respectively.
order : int = 2 or 3
2 and 3 indicate fc2 and fc3, respectively.
"""
if isinstance(fc_calculator, dict) or fc_calculator is None:
return fc_calculator
elif isinstance(fc_calculator, str):
if "|" in fc_calculator:
_fc_calculator = fc_calculator.split("|")[order - 2]
if _fc_calculator == "":
return None
return _fc_calculator
else:
if fc_calculator.strip() == "":
return None
return fc_calculator
else:
raise RuntimeError("fc_calculator should be str or dict.")

View File

@ -152,9 +152,9 @@ class Phono3pyYamlLoader(PhonopyYamlLoaderBase):
dataset = None
if "displacement_pairs" in self._yaml:
disp = self._yaml["displacement_pairs"][0]
if type(disp) is dict: # type1
if isinstance(disp, dict): # type1
dataset = self._parse_fc3_dataset_type1(len(self._data.supercell))
elif type(disp) is list: # type2
elif isinstance(disp, list): # type2
if "displacement" in disp[0]:
dataset = self._parse_force_sets_type2()
if "displacement_pair_info" in self._yaml:
@ -326,12 +326,13 @@ class Phono3pyYamlDumper(PhonopyYamlDumperBase):
"""
lines = []
if self._data.phonon_supercell_matrix is not None:
if self._data.phonon_dataset is not None:
lines += self._displacements_yaml_lines_2types(
self._data.phonon_dataset,
with_forces=with_forces,
key_prefix="phonon_",
)
lines.append("")
lines += self._displacements_yaml_lines_2types(
self._data.dataset, with_forces=with_forces
)
@ -507,7 +508,7 @@ def _displacements_yaml_lines_type1_info(dataset):
if "duplicates" in dataset and dataset["duplicates"]:
lines.append(" duplicated_supercell_ids: " "# 0 means perfect supercell")
# Backward compatibility for dict type
if type(dataset["duplicates"]) is dict:
if isinstance(dataset["duplicates"], dict):
for disp1_id, j in dataset["duplicates"].items():
lines.append(" - [ %d, %d ]" % (int(disp1_id), j))
else:
@ -580,7 +581,7 @@ def read_phono3py_yaml(
) -> Phono3pyYamlData:
"""Read phono3py.yaml like file."""
yaml_data = load_yaml(filename)
if type(yaml_data) is str:
if isinstance(yaml_data, str):
msg = f'Could not load "{filename}" properly.'
raise TypeError(msg)
return load_phono3py_yaml(
@ -597,7 +598,7 @@ def load_phono3py_yaml(
"""Return Phono3pyYamlData instance loading yaml data.
Parameters
-----------
----------
yaml_data : dict
"""

View File

@ -716,6 +716,7 @@ class GridMatrix:
warnings.warn(
"Non primitive cell input. Unable to use GR-grid.",
RuntimeWarning,
stacklevel=2,
)
return False

View File

@ -350,13 +350,11 @@ def _find_duplicates(direction_dataset):
duplucates = []
done = []
for i, direction1 in enumerate(direction_dataset):
for direction1 in direction_dataset:
n1 = direction1["number"]
for directions2 in direction1["second_atoms"]:
n2 = directions2["number"]
if (
n2 > n1 and (n2, n1) not in done and (n2, n1) in direction_sets
): # noqa E129
if n2 > n1 and (n2, n1) not in done and (n2, n1) in direction_sets: # noqa E129
done.append((n2, n1))
duplucates += _compare(
n1,
@ -368,14 +366,14 @@ def _find_duplicates(direction_dataset):
)
done = []
for i, direction1 in enumerate(direction_dataset):
for direction1 in direction_dataset:
n1 = direction1["number"]
for directions2 in direction1["second_atoms"]:
n2 = directions2["number"]
if n1 == n2 and n1 not in done:
done.append(n1)
duplucates += _compare_opposite(
n1, direction_sets[(n1, n1)], pair_idx[(n1, n1)]
direction_sets[(n1, n1)], pair_idx[(n1, n1)]
)
return duplucates
@ -393,10 +391,10 @@ def _compare(n1, n2, dset1, dset2, pidx1, pidx2):
return [[i, j] for (i, j) in duplucates if i > j]
def _compare_opposite(n1, dset1, pidx1):
def _compare_opposite(dset1, pidx1):
flip_sets = np.array(dset1)[:, [3, 4, 5, 0, 1, 2]]
duplucates = []
for i, d1 in enumerate(dset1):
for d1 in dset1:
eq_indices = np.where(np.abs(flip_sets + d1).sum(axis=1) == 0)[0]
if len(eq_indices) > 0:
duplucates += [[pidx1[j], 0] for j in eq_indices]

View File

@ -276,12 +276,12 @@ def set_permutation_symmetry_compact_fc3(fc3, primitive):
np.array(p2s_map, dtype="int_"),
np.array(nsym_list, dtype="int_"),
)
except ImportError:
except ImportError as exc:
text = (
"Import error at phono3c.permutation_symmetry_compact_fc3. "
"Corresponding python code is not implemented."
)
raise RuntimeError(text)
raise RuntimeError(text) from exc
def _copy_permutation_symmetry_fc3_elem(fc3, fc3_elem, a, b, c):
@ -339,29 +339,29 @@ def set_translational_invariance_compact_fc3(fc3, primitive: Primitive):
_set_translational_invariance_fc3_per_index(fc3, index=1)
_set_translational_invariance_fc3_per_index(fc3, index=2)
except ImportError:
except ImportError as exc:
text = (
"Import error at phono3c.tranpose_compact_fc3. "
"Corresponding python code is not implemented."
)
raise RuntimeError(text)
raise RuntimeError(text) from exc
def _set_translational_invariance_fc3_per_index(fc3, index=0):
for i in range(fc3.shape[(1 + index) % 3]):
for j in range(fc3.shape[(2 + index) % 3]):
for k, l, m in list(np.ndindex(3, 3, 3)):
for k, ll, m in list(np.ndindex(3, 3, 3)):
if index == 0:
fc3[:, i, j, k, l, m] -= (
np.sum(fc3[:, i, j, k, l, m]) / fc3.shape[0]
fc3[:, i, j, k, ll, m] -= (
np.sum(fc3[:, i, j, k, ll, m]) / fc3.shape[0]
)
elif index == 1:
fc3[j, :, i, k, l, m] -= (
np.sum(fc3[j, :, i, k, l, m]) / fc3.shape[1]
fc3[j, :, i, k, ll, m] -= (
np.sum(fc3[j, :, i, k, ll, m]) / fc3.shape[1]
)
elif index == 2:
fc3[i, j, :, k, l, m] -= (
np.sum(fc3[i, j, :, k, l, m]) / fc3.shape[2]
fc3[i, j, :, k, ll, m] -= (
np.sum(fc3[i, j, :, k, ll, m]) / fc3.shape[2]
)
@ -465,7 +465,7 @@ def _solve_fc3(
print("Displacements (in Angstrom):")
else:
print("One displacement (in Angstrom):")
for i, v in enumerate(displacements_first):
for v in displacements_first:
print(" [%7.4f %7.4f %7.4f]" % tuple(v))
sys.stdout.flush()
if verbose > 2:
@ -577,19 +577,19 @@ def show_drift_fc3(fc3, primitive=None, name="fc3"):
klm1 = [0, 0, 0]
klm2 = [0, 0, 0]
klm3 = [0, 0, 0]
for i, j, k, l, m in list(np.ndindex((num_atom, num_atom, 3, 3, 3))):
val1 = fc3[:, i, j, k, l, m].sum()
val2 = fc3[i, :, j, k, l, m].sum()
val3 = fc3[i, j, :, k, l, m].sum()
for i, j, k, ll, m in list(np.ndindex((num_atom, num_atom, 3, 3, 3))):
val1 = fc3[:, i, j, k, ll, m].sum()
val2 = fc3[i, :, j, k, ll, m].sum()
val3 = fc3[i, j, :, k, ll, m].sum()
if abs(val1) > abs(maxval1):
maxval1 = val1
klm1 = [k, l, m]
klm1 = [k, ll, m]
if abs(val2) > abs(maxval2):
maxval2 = val2
klm2 = [k, l, m]
klm2 = [k, ll, m]
if abs(val3) > abs(maxval3):
maxval3 = val3
klm3 = [k, l, m]
klm3 = [k, ll, m]
else:
try:
import phono3py._phono3py as phono3c
@ -614,29 +614,29 @@ def show_drift_fc3(fc3, primitive=None, name="fc3"):
phono3c.transpose_compact_fc3(
fc3, permutations, s2pp_map, p2s_map, nsym_list, 0
) # dim[0] <--> dim[1]
for i, j, k, l, m in np.ndindex((num_patom, num_satom, 3, 3, 3)):
val1 = fc3[i, :, j, k, l, m].sum()
for i, j, k, ll, m in np.ndindex((num_patom, num_satom, 3, 3, 3)):
val1 = fc3[i, :, j, k, ll, m].sum()
if abs(val1) > abs(maxval1):
maxval1 = val1
klm1 = [k, l, m]
klm1 = [k, ll, m]
phono3c.transpose_compact_fc3(
fc3, permutations, s2pp_map, p2s_map, nsym_list, 0
) # dim[0] <--> dim[1]
for i, j, k, l, m in np.ndindex((num_patom, num_satom, 3, 3, 3)):
val2 = fc3[i, :, j, k, l, m].sum()
val3 = fc3[i, j, :, k, l, m].sum()
for i, j, k, ll, m in np.ndindex((num_patom, num_satom, 3, 3, 3)):
val2 = fc3[i, :, j, k, ll, m].sum()
val3 = fc3[i, j, :, k, ll, m].sum()
if abs(val2) > abs(maxval2):
maxval2 = val2
klm2 = [k, l, m]
klm2 = [k, ll, m]
if abs(val3) > abs(maxval3):
maxval3 = val3
klm3 = [k, l, m]
except ImportError:
klm3 = [k, ll, m]
except ImportError as exc:
text = (
"Import error at phono3c.tranpose_compact_fc3. "
"Corresponding python code is not implemented."
)
raise RuntimeError(text)
raise RuntimeError(text) from exc
text = "Max drift of %s: " % name
text += "%f (%s%s%s) " % (maxval1, "xyz"[klm1[0]], "xyz"[klm1[1]], "xyz"[klm1[2]])

View File

@ -270,9 +270,7 @@ class Gruneisen:
):
f.write("- nqpoint: %d\n" % len(path))
f.write(" phonon:\n")
for i, (q, d, g_at_q, freqs_at_q) in enumerate(
zip(path, distances, gs, fs)
): # noqa E125
for q, d, g_at_q, freqs_at_q in zip(path, distances, gs, fs):
f.write(" - q-position: [ %10.7f, %10.7f, %10.7f ]\n" % tuple(q))
f.write(" distance: %10.7f\n" % d)
f.write(" band:\n")
@ -415,7 +413,7 @@ class Gruneisen:
for j in range(3):
for k in range(3):
for ll in range(3):
for m in range(3):
for _ in range(3):
dPhidu[nu, pi, i, j, k, ll] = (
fc3[p2s[nu], pi, :, i, j, :] * Y[:, :, k, ll]
).sum()

View File

@ -46,9 +46,9 @@ from phono3py.file_IO import (
write_gamma_detail_to_hdf5,
write_imag_self_energy_at_grid_point,
)
from phono3py.phonon.func import bose_einstein
from phono3py.phonon3.interaction import Interaction
from phono3py.phonon3.triplets import get_triplets_integration_weights
from phono3py.phonon.func import bose_einstein
class ImagSelfEnergy:
@ -170,6 +170,7 @@ class ImagSelfEnergy:
"Use attribute, ImagSelfEnergy.imag_self_energy "
"instead of ImagSelfEnergy.get_imag_self_energy().",
DeprecationWarning,
stacklevel=2,
)
return self.imag_self_energy
@ -200,6 +201,7 @@ class ImagSelfEnergy:
"Use attribute, ImagSelfEnergy.detailed_imag_self_energy "
"instead of ImagSelfEnergy.get_detailed_imag_self_energy().",
DeprecationWarning,
stacklevel=2,
)
return self.detailed_imag_self_energy
@ -222,6 +224,7 @@ class ImagSelfEnergy:
"Use attribute, ImagSelfEnergy.unit_conversion_factor "
"instead of ImagSelfEnergy.get_unit_conversion_factor().",
DeprecationWarning,
stacklevel=2,
)
return self.unit_conversion_factor
@ -268,6 +271,7 @@ class ImagSelfEnergy:
"Use attribute, ImagSelfEnergy.frequency_points "
"instead of ImagSelfEnergy.set_frequency_points().",
DeprecationWarning,
stacklevel=2,
)
self.frequency_points = frequency_points
@ -289,6 +293,7 @@ class ImagSelfEnergy:
"Use attribute, ImagSelfEnergy.temperature "
"instead of ImagSelfEnergy.set_temperature().",
DeprecationWarning,
stacklevel=2,
)
self.temperature = temperature

View File

@ -45,15 +45,15 @@ from phonopy.structure.cells import Primitive, compute_all_sg_permutations
from phonopy.structure.symmetry import Symmetry
from phonopy.units import AMU, EV, Angstrom, Hbar, THz, VaspToTHz
from phono3py.phonon3.real_to_reciprocal import RealToReciprocal
from phono3py.phonon3.reciprocal_to_normal import ReciprocalToNormal
from phono3py.phonon3.triplets import get_nosym_triplets_at_q, get_triplets_at_q
from phono3py.phonon.grid import (
BZGrid,
get_grid_points_by_rotations,
get_ir_grid_points,
)
from phono3py.phonon.solver import run_phonon_solver_c, run_phonon_solver_py
from phono3py.phonon3.real_to_reciprocal import RealToReciprocal
from phono3py.phonon3.reciprocal_to_normal import ReciprocalToNormal
from phono3py.phonon3.triplets import get_nosym_triplets_at_q, get_triplets_at_q
class Interaction:
@ -222,6 +222,7 @@ class Interaction:
"Use attribute, Interaction.interaction_strength "
"instead of Interaction.get_interaction_strength().",
DeprecationWarning,
stacklevel=2,
)
return self.interaction_strength
@ -243,6 +244,7 @@ class Interaction:
"Use attribute, Interaction.mesh_numbers "
"instead of Interaction.get_mesh_numbers().",
DeprecationWarning,
stacklevel=2,
)
return self.mesh_numbers
@ -261,6 +263,7 @@ class Interaction:
warnings.warn(
"Use attribute, Interaction.fc3 " "instead of Interaction.get_fc3().",
DeprecationWarning,
stacklevel=2,
)
return self.fc3
@ -275,6 +278,7 @@ class Interaction:
"Use attribute, Interaction.dynamical_matrix "
"instead of Interaction.get_dynamical_matrix().",
DeprecationWarning,
stacklevel=2,
)
return self.dynamical_matrix
@ -289,6 +293,7 @@ class Interaction:
"Use attribute, Interaction.primitive "
"instead of Interaction.get_primitive().",
DeprecationWarning,
stacklevel=2,
)
return self.primitive
@ -338,6 +343,7 @@ class Interaction:
"Use attribute, Interaction.band_indices "
"instead of Interaction.get_band_indices().",
DeprecationWarning,
stacklevel=2,
)
return self.band_indices
@ -373,6 +379,7 @@ class Interaction:
"Use attribute, Interaction.nac_q_direction "
"instead of Interaction.get_nac_q_direction().",
DeprecationWarning,
stacklevel=2,
)
return self.nac_q_direction
@ -382,6 +389,7 @@ class Interaction:
"Use attribute, Interaction.nac_q_direction "
"instead of Interaction.set_nac_q_direction().",
DeprecationWarning,
stacklevel=2,
)
self.nac_q_direction = nac_q_direction
@ -402,6 +410,7 @@ class Interaction:
"Use attribute, Interaction.zero_value_positions "
"instead of Interaction.get_zero_value_positions().",
DeprecationWarning,
stacklevel=2,
)
return self.zero_value_positions
@ -436,6 +445,7 @@ class Interaction:
"Use attribute, Interaction.frequency_factor_to_THz ",
"instead of Interaction.get_frequency_factor_to_THz().",
DeprecationWarning,
stacklevel=2,
)
return self.frequency_factor_to_THz
@ -450,6 +460,7 @@ class Interaction:
"Use attribute, Interaction.lapack_zheev_uplo "
"instead of Interaction.get_lapack_zheev_uplo().",
DeprecationWarning,
stacklevel=2,
)
return self.lapack_zheev_uplo
@ -464,6 +475,7 @@ class Interaction:
"Use attribute, Interaction.cutoff_frequency "
"instead of Interaction.get_cutoff_frequency().",
DeprecationWarning,
stacklevel=2,
)
return self.cutoff_frequency
@ -520,6 +532,7 @@ class Interaction:
"Use attribute, Interaction.averaged_interaction "
"instead of Interaction.get_averaged_interaction().",
DeprecationWarning,
stacklevel=2,
)
return self.averaged_interaction
@ -540,6 +553,7 @@ class Interaction:
"Use attribute, Interaction.unit_conversion_factor "
"instead of Interaction.get_unit_conversion_factor().",
DeprecationWarning,
stacklevel=2,
)
return self.unit_conversion_factor
@ -554,6 +568,7 @@ class Interaction:
"Use attribute, Interaction.constant_averaged_interaction "
"instead of Interaction.get_constant_averaged_interaction().",
DeprecationWarning,
stacklevel=2,
)
return self.constant_averaged_interaction

View File

@ -42,14 +42,14 @@ from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, get_dynamical_mat
from phonopy.structure.cells import Primitive, Supercell
from phonopy.units import VaspToTHz
from phono3py.phonon.func import bose_einstein
from phono3py.phonon.grid import BZGrid, get_grid_point_from_address
from phono3py.phonon.solver import run_phonon_solver_c
from phono3py.phonon3.triplets import (
get_nosym_triplets_at_q,
get_triplets_at_q,
get_triplets_integration_weights,
)
from phono3py.phonon.func import bose_einstein
from phono3py.phonon.grid import BZGrid, get_grid_point_from_address
from phono3py.phonon.solver import run_phonon_solver_c
class JointDos:
@ -129,7 +129,7 @@ class JointDos:
def get_joint_dos(self):
"""Return joint-density-of-states."""
warnings.warn("Use attribute, joint_dos", DeprecationWarning)
warnings.warn("Use attribute, joint_dos", DeprecationWarning, stacklevel=2)
return self.joint_dos
@property
@ -143,7 +143,9 @@ class JointDos:
def get_frequency_points(self):
"""Return frequency points."""
warnings.warn("Use attribute, frequency_points", DeprecationWarning)
warnings.warn(
"Use attribute, frequency_points", DeprecationWarning, stacklevel=2
)
return self.frequency_points
def get_phonons(self):
@ -157,7 +159,7 @@ class JointDos:
def get_primitive(self):
"""Return primitive cell."""
warnings.warn("Use attribute, primitive", DeprecationWarning)
warnings.warn("Use attribute, primitive", DeprecationWarning, stacklevel=2)
return self.primitive
@property
@ -172,7 +174,7 @@ class JointDos:
def get_mesh_numbers(self):
"""Return mesh numbers by three integer values."""
warnings.warn("Use attribute, mesh_numbers", DeprecationWarning)
warnings.warn("Use attribute, mesh_numbers", DeprecationWarning, stacklevel=2)
return self.mesh
@property
@ -189,7 +191,9 @@ class JointDos:
def set_nac_q_direction(self, nac_q_direction=None):
"""Set q-direction for NAC."""
warnings.warn("Use attribute, nac_q_direction", DeprecationWarning)
warnings.warn(
"Use attribute, nac_q_direction", DeprecationWarning, stacklevel=2
)
self.nac_q_direction = nac_q_direction
@property
@ -209,6 +213,7 @@ class JointDos:
warnings.warn(
"Use attribute, JointDOS.sigma instead of JointDOS.set_sigma()",
DeprecationWarning,
stacklevel=2,
)
self.sigma = sigma
@ -401,14 +406,16 @@ class JointDos:
def _run_py_with_g_at_temperature(self, jdos, i):
g = self._g
n = self._occupations
for k, l in list(np.ndindex(g.shape[3:])):
for k, ll in list(np.ndindex(g.shape[3:])):
weights = np.where(
np.logical_or(n[:, 0, k] < 0, n[:, 1, l] < 0), 0, self._weights_at_q
np.logical_or(n[:, 0, k] < 0, n[:, 1, ll] < 0), 0, self._weights_at_q
)
jdos[i, 1] += np.dot(
(n[:, 0, k] + n[:, 1, l] + 1) * g[0, :, i, k, l], weights
(n[:, 0, k] + n[:, 1, ll] + 1) * g[0, :, i, k, ll], weights
)
jdos[i, 0] += np.dot(
(n[:, 0, k] - n[:, 1, ll]) * g[1, :, i, k, ll], weights
)
jdos[i, 0] += np.dot((n[:, 0, k] - n[:, 1, l]) * g[1, :, i, k, l], weights)
def _init_dynamical_matrix(self):
self._dm = get_dynamical_matrix(

View File

@ -44,9 +44,9 @@ from phono3py.file_IO import (
write_real_self_energy_at_grid_point,
write_real_self_energy_to_hdf5,
)
from phono3py.phonon.func import bose_einstein
from phono3py.phonon3.imag_self_energy import get_frequency_points
from phono3py.phonon3.interaction import Interaction
from phono3py.phonon.func import bose_einstein
class RealSelfEnergy:
@ -247,8 +247,8 @@ class RealSelfEnergy:
)
def _run_py_with_band_indices(self):
for i, (triplet, w, interaction) in enumerate(
zip(self._triplets_at_q, self._weights_at_q, self._pp_strength)
for triplet, w, interaction in zip(
self._triplets_at_q, self._weights_at_q, self._pp_strength
):
freqs = self._frequencies[triplet]
for j, bi in enumerate(self._band_indices):
@ -286,22 +286,22 @@ class RealSelfEnergy:
def _run_py_with_frequency_points(self):
for k, fpoint in enumerate(self._frequency_points):
for i, (triplet, w, interaction) in enumerate(
zip(self._triplets_at_q, self._weights_at_q, self._pp_strength)
for triplet, w, interaction in zip(
self._triplets_at_q, self._weights_at_q, self._pp_strength
):
freqs = self._frequencies[triplet]
for j, bi in enumerate(self._band_indices):
for j, _ in enumerate(self._band_indices):
if self._temperature > 0:
self._real_self_energies[
k, j
] += self._real_self_energies_at_bands(
j, fpoint, freqs, interaction, w
self._real_self_energies[k, j] += (
self._real_self_energies_at_bands(
j, fpoint, freqs, interaction, w
)
)
else:
self._real_self_energies[
k, j
] += self._real_self_energies_at_bands_0K(
j, fpoint, freqs, interaction, w
self._real_self_energies[k, j] += (
self._real_self_energies_at_bands_0K(
j, fpoint, freqs, interaction, w
)
)
self._real_self_energies *= self._unit_conversion
@ -442,7 +442,7 @@ class ImagToReal:
fpoints = []
coef = self._df / np.pi
i_zero = (len(self._im_part) - 1) // 2
for i, im_part_at_i in enumerate(self._im_part):
for i, _ in enumerate(self._im_part):
if i < i_zero:
continue
fpoint = self._all_frequency_points[i] + self._df / 2

View File

@ -214,7 +214,7 @@ class SpectralFunction:
def run(self):
"""Calculate spectral function over grid points."""
for gp_index in self:
for _ in self:
pass
def __iter__(self):
@ -354,7 +354,7 @@ class SpectralFunction:
if self._log_level:
print("* Spectral function")
frequencies = self._pp.get_phonons()[0]
for j, temp in enumerate(self._temperatures):
for j, _ in enumerate(self._temperatures):
for k, bi in enumerate(self._pp.band_indices):
freq = frequencies[grid_point, bi]
gammas = self._gammas[sigma_i, j, i, k]

View File

@ -109,9 +109,10 @@ def get_triplets_at_q(
)
triplets_at_q, weights = _get_BZ_triplets_at_q(grid_point, bz_grid, map_triplets)
assert (
np.prod(bz_grid.D_diag) == weights.sum()
), "Num grid points %d, sum of weight %d" % (np.prod(bz_grid.D_diag), weights.sum())
assert np.prod(bz_grid.D_diag) == weights.sum(), (
"Num grid points %d, sum of weight %d"
% (np.prod(bz_grid.D_diag), weights.sum())
)
return triplets_at_q, weights, map_triplets, map_q

View File

@ -34,4 +34,4 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
__version__ = "3.1.2"
__version__ = "3.2.0"

View File

@ -1,14 +1,19 @@
[build-system]
requires = ["setuptools", "wheel", "numpy"]
#requires = ["setuptools", "wheel", "numpy", "oldest-supported-numpy"]
#build-backend = "setuptools.build_meta"
[tool.flake8]
max-line-length = 88
extend-ignore = "E203,W503"
[tool.black]
[tool.ruff]
line-length = 88
lint.select = [
"F", # Flake8
"B", # Black
"I", # isort
"E", # pycodestyle-errors
"D", # pydocstyle
]
lint.extend-ignore = [
"D417",
"D100",
]
[tool.isort]
profile = "black"
[tool.ruff.lint.pydocstyle]
convention = "numpy"

View File

@ -2,4 +2,4 @@ numpy >= 1.17.0
PyYAML >= 5.3
matplotlib >= 2.2.2
h5py >= 3.0
phonopy >=2.24,<2.25
phonopy >=2.25,<2.26

View File

@ -11,7 +11,7 @@ epsilon = 1.0e-8
def get_options():
# Arg-parser
"""Parse command line options."""
parser = argparse.ArgumentParser(description="Plot collision matrix eigenvalues")
parser.add_argument(
"--temperature",
@ -33,6 +33,7 @@ def get_options():
def get_t_index(temperatures, args):
"""Return temperature index."""
if len(temperatures) > 29:
t_index = 30
else:
@ -45,6 +46,7 @@ def get_t_index(temperatures, args):
def plot_one(ax, coleigs, temperatures, args):
"""Plot collision matrix eigenvalues at one temperature."""
t_index = get_t_index(temperatures, args)
coleigs_p = coleigs[t_index].copy()
coleigs_n = coleigs[t_index].copy()
@ -56,6 +58,7 @@ def plot_one(ax, coleigs, temperatures, args):
def plot_one_file(ax, args):
"""Plot collision matrix eigenvalues at one temperature from file."""
filename = args.filenames[0]
if os.path.isfile(filename):
with h5py.File(filename, "r") as f:
@ -68,6 +71,7 @@ def plot_one_file(ax, args):
def plot_more(ax, coleigs, temperatures, args):
"""Update plot by collision matrix eigenvalues from one file."""
t_index = get_t_index(temperatures[0], args)
y = [np.abs(v[t_index]) for v in coleigs]
ax.semilogy(np.transpose(y), ".", markersize=5)
@ -75,6 +79,7 @@ def plot_more(ax, coleigs, temperatures, args):
def plot_more_files(ax, args):
"""Plot collision matrix eigenvalues from multiple files."""
temperatures = []
coleigs = []
for filename in args.filenames:
@ -89,6 +94,7 @@ def plot_more_files(ax, args):
def plot(args: argparse.Namespace):
"""Plot collision matrix eigenvalues."""
import matplotlib.pyplot as plt
_, ax = plt.subplots()
@ -108,6 +114,7 @@ def plot(args: argparse.Namespace):
def write_dat(args: argparse.Namespace):
"""Write collision matrix eigenvalues to a file in gnuplot style."""
with open("coleigs.dat", "w") as w:
for filename in args.filenames:
with h5py.File(filename) as f:
@ -125,6 +132,7 @@ def write_dat(args: argparse.Namespace):
def main(args: argparse.Namespace):
"""Run phono3py-coleigplot."""
if args.savetxt:
write_dat(args)
else:

View File

@ -12,6 +12,7 @@ epsilon = 1.0e-8
def collect_data(gamma, weights, frequencies, cutoff, max_freq):
"""Collect data for making input of Gaussian-KDE."""
freqs = []
mode_prop = []
for w, freq, g in zip(weights, frequencies, gamma):
@ -37,8 +38,7 @@ def collect_data(gamma, weights, frequencies, cutoff, max_freq):
def run_KDE(x, y, nbins, x_max=None, y_max=None, density_ratio=0.1):
"""Running Gaussian-KDE by scipy"""
"""Run Gaussian-KDE by scipy."""
x_min = 0
if x_max is None:
_x_max = np.rint(x.max() * 1.1)
@ -95,6 +95,7 @@ def plot(
point_size=5,
title=None,
):
"""Plot lifetime distribution."""
xmax = np.max(x)
ymax = np.max(y)
x_cut = []
@ -159,7 +160,7 @@ def plot(
def get_options():
# Arg-parser
"""Parse command-line arguments."""
parser = argparse.ArgumentParser(
description="Plot property density with gaussian KDE"
)
@ -206,7 +207,7 @@ def get_options():
"Number of bins in which data are assigned, "
"i.e., determining resolution of plot"
),
),
)
parser.add_argument(
"--no-points", dest="no_points", action="store_true", help="Do not show points"
)
@ -246,9 +247,7 @@ def get_options():
def main(args):
#
# Matplotlib setting
#
"""Run phono3py-kdeplot."""
import matplotlib
matplotlib.use("Agg")

View File

@ -188,12 +188,12 @@ def _get_extensions(build_dir):
found_libs[key] = line.split()[3].split(";")
if f"{key} flags" in line and len(line.split()) > 3:
found_flags[key] = line.split()[3].split(";")
for key, value in found_libs.items():
for _, value in found_libs.items():
found_extra_link_args += value
for element in value:
if "libmkl" in element:
use_mkl_lapacke = True
for key, value in found_flags.items():
for _, value in found_flags.items():
found_extra_compile_args += value
if use_mkl_lapacke:
params["define_macros"].append(("MKL_LAPACKE", None))
@ -326,7 +326,7 @@ def main(build_dir):
"matplotlib>=2.2.2",
"h5py>=3.0",
"spglib>=2.0",
"phonopy>=2.24,<2.25",
"phonopy>=2.25,<2.26",
],
provides=["phono3py"],
scripts=scripts_phono3py,

View File

@ -5,6 +5,8 @@ from __future__ import annotations
from pathlib import Path
import numpy as np
import pytest
from phonopy.interface.pypolymlp import PypolymlpParams
from phono3py import Phono3py
@ -166,3 +168,41 @@ def test_type2_forces_energies_setter_Si(si_111_222_rd: Phono3py):
ph3.phonon_forces = ph3_in.phonon_forces + 1
np.testing.assert_allclose(ph3_in.forces + 1, ph3.forces)
np.testing.assert_allclose(ph3_in.phonon_forces + 1, ph3.phonon_forces)
def test_use_pypolymlp_mgo(mgo_222rd_444rd: Phono3py):
"""Test use_pypolymlp in produce_fc3."""
pytest.importorskip("pypolymlp")
ph3_in = mgo_222rd_444rd
ph3 = Phono3py(
ph3_in.unitcell,
supercell_matrix=ph3_in.supercell_matrix,
phonon_supercell_matrix=ph3_in.phonon_supercell_matrix,
primitive_matrix=ph3_in.primitive_matrix,
log_level=2,
)
ph3.mlp_dataset = {
"displacements": ph3_in.displacements[:10],
"forces": ph3_in.forces[:10],
"supercell_energies": ph3_in.supercell_energies[:10],
}
ph3.phonon_dataset = ph3_in.phonon_dataset
ph3.nac_params = ph3_in.nac_params
ph3.displacements = ph3_in.displacements[:100]
atom_energies = {"Mg": -0.00896717, "O": -0.95743902}
params = PypolymlpParams(gtinv_maxl=(4, 4), atom_energies=atom_energies)
ph3.generate_displacements(distance=0.001, is_plusminus=True)
ph3.develop_mlp(params=params)
ph3.evaluate_mlp()
ph3.produce_fc3(fc_calculator="symfc")
ph3.produce_fc2(fc_calculator="symfc")
ph3.mesh_numbers = 30
ph3.init_phph_interaction()
ph3.run_thermal_conductivity(temperatures=[300])
assert (
pytest.approx(63.0018546, abs=1e-1) == ph3.thermal_conductivity.kappa[0, 0, 0]
)

View File

@ -111,7 +111,6 @@ def test_kappa_RTA_si_nosym(si_pbesol: Phono3py, si_pbesol_nosym: Phono3py):
def test_kappa_RTA_si_nomeshsym(si_pbesol: Phono3py, si_pbesol_nomeshsym: Phono3py):
"""Test RTA without considering mesh symmetry by Si."""
if si_pbesol_nomeshsym._make_r0_average:
ref_kappa_RTA_si_nomeshsym = [81.147, 81.147, 81.147, 0.000, 0.000, 0.000]
else:

View File

@ -92,7 +92,6 @@ def test_kappa_RTA_si_with_sigma_iso(si_pbesol: Phono3py):
def test_kappa_RTA_si_nosym(si_pbesol: Phono3py, si_pbesol_nosym: Phono3py):
"""Test RTA without considering symmetry by Si."""
if si_pbesol_nosym._make_r0_average:
ref_kappa_P_RTA_si_nosym = [39.396, 39.222, 39.368, -0.096, -0.022, 0.026]
ref_kappa_C_si_nosym = [0.009, 0.009, 0.009, 0.000, 0.000, 0.000]

View File

@ -415,7 +415,6 @@ def nacl_pbe_cutoff_fc3(request) -> Phono3py:
count += 1
ph3.dataset = dataset
ph3.produce_fc3()
# ph3.produce_fc3(symmetrize_fc3r=True)
return ph3
@ -497,6 +496,17 @@ def si_111_222_rd() -> Phono3py:
return phono3py.load(yaml_filename, produce_fc=False, log_level=1)
@pytest.fixture(scope="session")
def mgo_222rd_444rd() -> Phono3py:
"""Return Phono3py class instance of MgO-2x2x2-4x4x4 RD-RD.
4 and 400 supercells for fc2 and fc3, respectively.
"""
yaml_filename = cwd / "phono3py_params_MgO-222rd-444rd.yaml.xz"
return phono3py.load(yaml_filename, produce_fc=False, log_level=1)
@pytest.fixture(scope="session")
def ph_nacl() -> Phonopy:
"""Return Phonopy class instance of NaCl 2x2x2."""

View File

@ -45,6 +45,7 @@ class MockArgs:
return (getattr(self, field.name) for field in fields(self))
def __contains__(self, item):
"""Implement in operator."""
return item in (field.name for field in fields(self))

View File

@ -298,6 +298,7 @@ def test_GammaDOSsmearing(nacl_pbe: Phono3py):
def test_run_prop_dos(si_pbesol: Phono3py):
"""Test of run_prop_dos."""
ph3 = si_pbesol
ph3.mesh_numbers = [7, 7, 7]
ph3.init_phph_interaction()

Binary file not shown.

View File

@ -5,8 +5,8 @@ import pytest
from phono3py import Phono3py
from phono3py.api_jointdos import Phono3pyJointDos
from phono3py.phonon3.joint_dos import JointDos
from phono3py.phonon.grid import BZGrid
from phono3py.phonon3.joint_dos import JointDos
si_freq_points = [
0.0000000,

View File

@ -7,12 +7,12 @@ from phonopy.structure.atoms import PhonopyAtoms
from phonopy.structure.symmetry import Symmetry
from phono3py import Phono3py
from phono3py.phonon.grid import BZGrid, get_grid_point_from_address
from phono3py.phonon3.triplets import (
_get_BZ_triplets_at_q,
_get_triplets_reciprocal_mesh_at_q,
get_triplets_at_q,
)
from phono3py.phonon.grid import BZGrid, get_grid_point_from_address
def test_get_triplets_at_q_type1(si_pbesol_111):

View File

@ -13,11 +13,6 @@ from phono3py.sscha.sscha import (
get_sscha_matrices,
)
try:
ModuleNotFoundError
except NameError:
ModuleNotFoundError = ImportError
si_pbesol_upsilon0_0 = [[3.849187e02, 0, 0], [0, 3.849187e02, 0], [0, 0, 3.849187e02]]
si_pbesol_upsilon1_34 = [
[1.886404, -1.549705, -1.126055],