mirror of https://github.com/phonopy/phono3py.git
Merge branch 'rc'
This commit is contained in:
commit
6ae8b6641b
|
@ -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
|
||||
|
|
38
README.md
38
README.md
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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."
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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("")
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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"):
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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
|
||||
|
||||
"""
|
||||
|
|
|
@ -716,6 +716,7 @@ class GridMatrix:
|
|||
warnings.warn(
|
||||
"Non primitive cell input. Unable to use GR-grid.",
|
||||
RuntimeWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return False
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]])
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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")
|
||||
|
|
6
setup.py
6
setup.py
|
@ -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,
|
||||
|
|
|
@ -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]
|
||||
)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
@ -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,
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in New Issue