mirror of https://github.com/phonopy/phono3py.git
Merge branch 'develop' into publish-gh-pages
This commit is contained in:
commit
f488d850ce
|
@ -11,7 +11,7 @@ repos:
|
||||||
exclude: ^example/AlN-LDA/
|
exclude: ^example/AlN-LDA/
|
||||||
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.12.1
|
rev: v0.12.4
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: [ "--fix", "--show-fixes" ]
|
args: [ "--fix", "--show-fixes" ]
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## Jul-22-2025: Version 3.18.0
|
||||||
|
|
||||||
|
- Changed `Phono3py.run_imag_self_energy()` to return `ImagSelfEnergyValues`.
|
||||||
|
- Traditional force constants symmetrizer now applies translational and
|
||||||
|
permutation symmetries alternately 3 times in succession (previously once).
|
||||||
|
|
||||||
## Jul-5-2025: Version 3.17.1
|
## Jul-5-2025: Version 3.17.1
|
||||||
|
|
||||||
- Fix direct-solution crashing when executed via command line
|
- Fix direct-solution crashing when executed via command line
|
||||||
|
|
|
@ -758,8 +758,8 @@ where the averaged phonon-phonon interaction that is read from
|
||||||
`kappa-mxxx(-sx-sdx).hdf5` file is used if it exists in the file. Therefore the
|
`kappa-mxxx(-sx-sdx).hdf5` file is used if it exists in the file. Therefore the
|
||||||
averaged phonon-phonon interaction has to be stored before using this option
|
averaged phonon-phonon interaction has to be stored before using this option
|
||||||
(see {ref}`--full-pp <full_pp_option>`). The calculation result **overwrites**
|
(see {ref}`--full-pp <full_pp_option>`). The calculation result **overwrites**
|
||||||
`kappa-mxxx(-sx-sdx).hdf5` file. Therefore to use this option together with `-o`
|
`kappa-mxxx(-sx-sdx).hdf5` file. Therefore the original
|
||||||
option is strongly recommended.
|
`kappa-mxxx(-sx-sdx).hdf5` file should be backed up.
|
||||||
|
|
||||||
First, run full conductivity calculation,
|
First, run full conductivity calculation,
|
||||||
|
|
||||||
|
@ -1224,10 +1224,6 @@ set. Other filters (`lzf` or integer values of 0 to 9) may be used, see h5py
|
||||||
documentation
|
documentation
|
||||||
(<http://docs.h5py.org/en/stable/high/dataset.html#filter-pipeline>).
|
(<http://docs.h5py.org/en/stable/high/dataset.html#filter-pipeline>).
|
||||||
|
|
||||||
### `-o`, `-i`, `--io`
|
|
||||||
|
|
||||||
These options are deprecated.
|
|
||||||
|
|
||||||
<!-- (output_filename_option)=
|
<!-- (output_filename_option)=
|
||||||
### `-o` (command option only)
|
### `-o` (command option only)
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,9 @@ copyright = "2015, Atsushi Togo"
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = "3.17"
|
version = "3.18"
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = "3.17.1"
|
release = "3.18.0"
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# AlN lattice thermal conductivity calculation from dataset for pypolymlp
|
||||||
|
|
||||||
|
## Computational setting of VASP calculations
|
||||||
|
|
||||||
|
For supercell forces and energies
|
||||||
|
|
||||||
|
- Supercell 4x4x2 of wurtzite unit cell
|
||||||
|
- Random directional displacements of 0.03 Angstrom
|
||||||
|
- PBE-sol
|
||||||
|
- 520 eV cutoff energy
|
||||||
|
- Gamma centered 2x2x2 kpoint mesh
|
||||||
|
- LREAL = .FALSE.
|
||||||
|
- ADDGRID = .TRUE.
|
||||||
|
|
||||||
|
For parameters of non-analytical term correction,
|
||||||
|
|
||||||
|
- PBE-sol
|
||||||
|
- 520 eV cutoff energy
|
||||||
|
- Gamma centered 7x7x4 kpoint mesh
|
||||||
|
- LEPSION = .TRUE.
|
||||||
|
- LREAL = .FALSE.
|
||||||
|
|
||||||
|
These data are stored in `phonopy_params_mp-661.yaml.xz`.
|
||||||
|
|
||||||
|
## Example of lattice thermal conductivity calculation
|
||||||
|
|
||||||
|
MLPs by pypolymlp are developed by
|
||||||
|
|
||||||
|
```bash
|
||||||
|
% phono3py-load phonopy_params_mp-661.yaml.xz --pypolymlp -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Dataset with 180 supercells is used for training and 20 for the test. This
|
||||||
|
calculation will take 5-10 minutes depending on computer resource.
|
||||||
|
`pypolymlp.yaml` is made by this command.
|
||||||
|
|
||||||
|
Force constants are calculated by
|
||||||
|
|
||||||
|
```bash
|
||||||
|
% phono3py-load phonopy_params_mp-661.yaml.xz --pypolymlp --relax-atomic-positions -d
|
||||||
|
```
|
||||||
|
|
||||||
|
With the `--relax-atomic-positions` option, internal atomic positions in unit
|
||||||
|
cell are optimized by pypolymlp. The displacement-force dataset is stored in
|
||||||
|
`phono3py_mlp_eval_dataset.yaml`. Force constants are symmetried using symfc,
|
||||||
|
but the phono3py's traditional symmetrizer can be used with the option
|
||||||
|
`--fc-calculator traditional`. The symmetry constraints applied by this
|
||||||
|
traditional symmetrizer is weaker, but the calculation demands less memory
|
||||||
|
space.
|
||||||
|
|
||||||
|
Lattice thermal conductivity is calculated by
|
||||||
|
|
||||||
|
```bash
|
||||||
|
% phono3py-load phonopy_params_mp-661.yaml.xz --mesh 40 --br
|
||||||
|
```
|
||||||
|
|
||||||
|
Steps written above are performed in one-shot by
|
||||||
|
|
||||||
|
```bash
|
||||||
|
% phono3py-load phonopy_params_mp-661.yaml.xz --pypolymlp --relax-atomic-positions -d --mesh 40 --br
|
||||||
|
```
|
||||||
|
|
||||||
|
The lattice thermal conductivity calculated at 300 K will be around k_xx=252 and k_zz=232.
|
Binary file not shown.
|
@ -34,8 +34,16 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
from phono3py.api_isotope import Phono3pyIsotope # noqa F401
|
from phono3py.api_isotope import Phono3pyIsotope
|
||||||
from phono3py.api_jointdos import Phono3pyJointDos # noqa F401
|
from phono3py.api_jointdos import Phono3pyJointDos
|
||||||
from phono3py.api_phono3py import Phono3py # noqa F401
|
from phono3py.api_phono3py import Phono3py
|
||||||
from phono3py.cui.load import load # noqa F401
|
from phono3py.cui.load import load
|
||||||
from phono3py.version import __version__ # noqa F401
|
from phono3py.version import __version__
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Phono3pyIsotope",
|
||||||
|
"Phono3pyJointDos",
|
||||||
|
"Phono3py",
|
||||||
|
"load",
|
||||||
|
"__version__",
|
||||||
|
]
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from phono3py.other.isotope import Isotope
|
from phono3py.other.isotope import Isotope
|
||||||
|
from phono3py.phonon.grid import BZGrid
|
||||||
|
|
||||||
|
|
||||||
class Phono3pyIsotope:
|
class Phono3pyIsotope:
|
||||||
|
@ -81,7 +82,7 @@ class Phono3pyIsotope:
|
||||||
return self._iso.dynamical_matrix
|
return self._iso.dynamical_matrix
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def grid(self):
|
def grid(self) -> BZGrid:
|
||||||
"""Return BZGrid class instance."""
|
"""Return BZGrid class instance."""
|
||||||
return self._iso.bz_grid
|
return self._iso.bz_grid
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,10 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
from phonopy.structure.cells import Primitive, Supercell
|
from phonopy.structure.cells import Primitive, Supercell
|
||||||
from phonopy.structure.symmetry import Symmetry
|
from phonopy.structure.symmetry import Symmetry
|
||||||
|
@ -116,7 +119,7 @@ class Phono3pyJointDos:
|
||||||
self.initialize(mesh)
|
self.initialize(mesh)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def grid(self):
|
def grid(self) -> BZGrid | None:
|
||||||
"""Return BZGrid class instance."""
|
"""Return BZGrid class instance."""
|
||||||
return self._bz_grid
|
return self._bz_grid
|
||||||
|
|
||||||
|
@ -293,7 +296,7 @@ class Phono3pyJointDos:
|
||||||
print('JDOS is written into "%s".' % filename)
|
print('JDOS is written into "%s".' % filename)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dynamical_matrix(self):
|
def dynamical_matrix(self) -> DynamicalMatrix:
|
||||||
"""Return DynamicalMatrix class instance."""
|
"""Return DynamicalMatrix class instance."""
|
||||||
return self._jdos.dynamical_matrix
|
return self._jdos.dynamical_matrix
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,14 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import dataclasses
|
||||||
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import Literal, Optional, Union, cast
|
from typing import Literal, cast
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.typing import NDArray
|
from numpy.typing import ArrayLike, NDArray
|
||||||
from phonopy.harmonic.displacement import (
|
from phonopy.harmonic.displacement import (
|
||||||
directions_to_displacement_dataset,
|
directions_to_displacement_dataset,
|
||||||
get_least_displacements,
|
get_least_displacements,
|
||||||
|
@ -59,7 +61,11 @@ from phonopy.interface.mlp import PhonopyMLP
|
||||||
from phonopy.interface.pypolymlp import (
|
from phonopy.interface.pypolymlp import (
|
||||||
PypolymlpParams,
|
PypolymlpParams,
|
||||||
)
|
)
|
||||||
from phonopy.interface.symfc import SymfcFCSolver, symmetrize_by_projector
|
from phonopy.interface.symfc import (
|
||||||
|
SymfcFCSolver,
|
||||||
|
parse_symfc_options,
|
||||||
|
symmetrize_by_projector,
|
||||||
|
)
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
from phonopy.structure.atoms import PhonopyAtoms
|
from phonopy.structure.atoms import PhonopyAtoms
|
||||||
from phonopy.structure.cells import (
|
from phonopy.structure.cells import (
|
||||||
|
@ -75,7 +81,10 @@ from phonopy.structure.symmetry import Symmetry
|
||||||
|
|
||||||
from phono3py.conductivity.init_direct_solution import get_thermal_conductivity_LBTE
|
from phono3py.conductivity.init_direct_solution import get_thermal_conductivity_LBTE
|
||||||
from phono3py.conductivity.init_rta import get_thermal_conductivity_RTA
|
from phono3py.conductivity.init_rta import get_thermal_conductivity_RTA
|
||||||
from phono3py.interface.fc_calculator import FC3Solver
|
from phono3py.interface.fc_calculator import (
|
||||||
|
FC3Solver,
|
||||||
|
extract_fc2_fc3_calculators_options,
|
||||||
|
)
|
||||||
from phono3py.interface.phono3py_yaml import Phono3pyYaml
|
from phono3py.interface.phono3py_yaml import Phono3pyYaml
|
||||||
from phono3py.phonon.grid import BZGrid
|
from phono3py.phonon.grid import BZGrid
|
||||||
from phono3py.phonon3.dataset import forces_in_dataset
|
from phono3py.phonon3.dataset import forces_in_dataset
|
||||||
|
@ -103,6 +112,16 @@ from phono3py.phonon3.spectral_function import run_spectral_function
|
||||||
from phono3py.version import __version__
|
from phono3py.version import __version__
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class ImagSelfEnergyValues:
|
||||||
|
"""Parameters for imaginary self-energy calculation."""
|
||||||
|
|
||||||
|
frequency_points: NDArray | None
|
||||||
|
gammas: NDArray
|
||||||
|
scattering_event_class: int | None = None
|
||||||
|
detailed_gammas: Sequence | None = None
|
||||||
|
|
||||||
|
|
||||||
class Phono3py:
|
class Phono3py:
|
||||||
"""Phono3py main class.
|
"""Phono3py main class.
|
||||||
|
|
||||||
|
@ -147,19 +166,19 @@ class Phono3py:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
unitcell: PhonopyAtoms,
|
unitcell: PhonopyAtoms,
|
||||||
supercell_matrix=None,
|
supercell_matrix: ArrayLike | None = None,
|
||||||
primitive_matrix=None,
|
primitive_matrix: str | ArrayLike | None = None,
|
||||||
phonon_supercell_matrix=None,
|
phonon_supercell_matrix: ArrayLike | None = None,
|
||||||
cutoff_frequency=1e-4,
|
cutoff_frequency: float = 1e-4,
|
||||||
frequency_factor_to_THz=None,
|
frequency_factor_to_THz: float | None = None,
|
||||||
is_symmetry=True,
|
is_symmetry: bool = True,
|
||||||
is_mesh_symmetry=True,
|
is_mesh_symmetry: bool = True,
|
||||||
use_grg=False,
|
use_grg: bool = False,
|
||||||
SNF_coordinates="reciprocal",
|
SNF_coordinates: str = "reciprocal",
|
||||||
make_r0_average: bool = True,
|
make_r0_average: bool = True,
|
||||||
symprec=1e-5,
|
symprec: float = 1e-5,
|
||||||
calculator: Optional[str] = None,
|
calculator: str | None = None,
|
||||||
log_level=0,
|
log_level: int = 0,
|
||||||
):
|
):
|
||||||
"""Init method.
|
"""Init method.
|
||||||
|
|
||||||
|
@ -232,7 +251,7 @@ class Phono3py:
|
||||||
self._make_r0_average = make_r0_average
|
self._make_r0_average = make_r0_average
|
||||||
|
|
||||||
self._cutoff_frequency = cutoff_frequency
|
self._cutoff_frequency = cutoff_frequency
|
||||||
self._calculator: Optional[str] = calculator
|
self._calculator = calculator
|
||||||
self._log_level = log_level
|
self._log_level = log_level
|
||||||
|
|
||||||
# Create supercell and primitive cell
|
# Create supercell and primitive cell
|
||||||
|
@ -240,8 +259,7 @@ class Phono3py:
|
||||||
self._supercell_matrix = np.array(
|
self._supercell_matrix = np.array(
|
||||||
shape_supercell_matrix(supercell_matrix), dtype="int64", order="C"
|
shape_supercell_matrix(supercell_matrix), dtype="int64", order="C"
|
||||||
)
|
)
|
||||||
pmat = self._determine_primitive_matrix(primitive_matrix)
|
self._primitive_matrix = self._determine_primitive_matrix(primitive_matrix)
|
||||||
self._primitive_matrix = pmat
|
|
||||||
self._nac_params = None
|
self._nac_params = None
|
||||||
if phonon_supercell_matrix is not None:
|
if phonon_supercell_matrix is not None:
|
||||||
self._phonon_supercell_matrix = np.array(
|
self._phonon_supercell_matrix = np.array(
|
||||||
|
@ -260,9 +278,7 @@ class Phono3py:
|
||||||
self._build_phonon_supercell()
|
self._build_phonon_supercell()
|
||||||
self._build_phonon_primitive_cell()
|
self._build_phonon_primitive_cell()
|
||||||
|
|
||||||
self._sigmas = [
|
self._sigmas = [None]
|
||||||
None,
|
|
||||||
]
|
|
||||||
self._sigma_cutoff = None
|
self._sigma_cutoff = None
|
||||||
|
|
||||||
# Grid
|
# Grid
|
||||||
|
@ -277,18 +293,17 @@ class Phono3py:
|
||||||
self._search_phonon_supercell_symmetry()
|
self._search_phonon_supercell_symmetry()
|
||||||
|
|
||||||
# Displacements and supercells
|
# Displacements and supercells
|
||||||
self._supercells_with_displacements = None
|
self._dataset: dict | None = None
|
||||||
self._dataset = None
|
self._phonon_dataset: dict | None = None
|
||||||
self._phonon_dataset = None
|
self._supercells_with_displacements: list | None = None
|
||||||
self._phonon_supercells_with_displacements = None
|
self._phonon_supercells_with_displacements: list | None = None
|
||||||
|
|
||||||
# Thermal conductivity
|
# Thermal conductivity
|
||||||
# conductivity_RTA or conductivity_LBTE class instance
|
# conductivity_RTA or conductivity_LBTE class instance
|
||||||
self._thermal_conductivity = None
|
self._thermal_conductivity = None
|
||||||
|
|
||||||
# Imaginary part of self energy at frequency points
|
# Imaginary part of self energy at frequency points
|
||||||
self._gammas = None
|
self._ise_params = None
|
||||||
self._scattering_event_class = None
|
|
||||||
|
|
||||||
# Frequency shift (real part of bubble diagram)
|
# Frequency shift (real part of bubble diagram)
|
||||||
self._real_self_energy = None
|
self._real_self_energy = None
|
||||||
|
@ -305,9 +320,9 @@ class Phono3py:
|
||||||
|
|
||||||
# MLP
|
# MLP
|
||||||
self._mlp = None
|
self._mlp = None
|
||||||
self._mlp_dataset = None
|
self._mlp_dataset: dict | None = None
|
||||||
self._phonon_mlp = None
|
self._phonon_mlp = None
|
||||||
self._phonon_mlp_dataset = None
|
self._phonon_mlp_dataset: dict | None = None
|
||||||
|
|
||||||
# Setup interaction
|
# Setup interaction
|
||||||
self._interaction = None
|
self._interaction = None
|
||||||
|
@ -326,7 +341,7 @@ class Phono3py:
|
||||||
return __version__
|
return __version__
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def calculator(self) -> Optional[str]:
|
def calculator(self) -> str | None:
|
||||||
"""Return calculator interface name.
|
"""Return calculator interface name.
|
||||||
|
|
||||||
str
|
str
|
||||||
|
@ -424,7 +439,7 @@ class Phono3py:
|
||||||
self._sigmas.append(None)
|
self._sigmas.append(None)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sigma_cutoff(self) -> Optional[float]:
|
def sigma_cutoff(self) -> float | None:
|
||||||
"""Setter and getter of Smearing cutoff width.
|
"""Setter and getter of Smearing cutoff width.
|
||||||
|
|
||||||
This is given as a multiple of the standard deviation.
|
This is given as a multiple of the standard deviation.
|
||||||
|
@ -441,7 +456,7 @@ class Phono3py:
|
||||||
self._sigma_cutoff = sigma_cutoff
|
self._sigma_cutoff = sigma_cutoff
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nac_params(self) -> Optional[dict]:
|
def nac_params(self) -> dict | None:
|
||||||
"""Setter and getter of parameters for non-analytical term correction.
|
"""Setter and getter of parameters for non-analytical term correction.
|
||||||
|
|
||||||
dict
|
dict
|
||||||
|
@ -465,7 +480,7 @@ class Phono3py:
|
||||||
self._init_dynamical_matrix()
|
self._init_dynamical_matrix()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dynamical_matrix(self) -> Optional[DynamicalMatrix]:
|
def dynamical_matrix(self) -> DynamicalMatrix | None:
|
||||||
"""Return DynamicalMatrix instance.
|
"""Return DynamicalMatrix instance.
|
||||||
|
|
||||||
This is not dynamical matrices but the instance of DynamicalMatrix
|
This is not dynamical matrices but the instance of DynamicalMatrix
|
||||||
|
@ -582,10 +597,10 @@ class Phono3py:
|
||||||
return self._phonon_supercell_matrix
|
return self._phonon_supercell_matrix
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primitive_matrix(self) -> NDArray:
|
def primitive_matrix(self) -> NDArray | None:
|
||||||
"""Return transformation matrix to primitive cell from unit cell.
|
"""Return transformation matrix to primitive cell from unit cell.
|
||||||
|
|
||||||
ndarray
|
ndarray or None
|
||||||
Primitive matrix with respect to unit cell.
|
Primitive matrix with respect to unit cell.
|
||||||
shape=(3, 3), dtype='double', order='C'
|
shape=(3, 3), dtype='double', order='C'
|
||||||
|
|
||||||
|
@ -605,7 +620,7 @@ class Phono3py:
|
||||||
return self._frequency_factor_to_THz
|
return self._frequency_factor_to_THz
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dataset(self) -> Optional[dict]:
|
def dataset(self) -> dict | None:
|
||||||
"""Setter and getter of displacement-force dataset.
|
"""Setter and getter of displacement-force dataset.
|
||||||
|
|
||||||
dict
|
dict
|
||||||
|
@ -667,7 +682,7 @@ class Phono3py:
|
||||||
self._phonon_supercells_with_displacements = None
|
self._phonon_supercells_with_displacements = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def phonon_dataset(self) -> Optional[dict]:
|
def phonon_dataset(self) -> dict | None:
|
||||||
"""Setter and getter of displacement-force dataset for fc2.
|
"""Setter and getter of displacement-force dataset for fc2.
|
||||||
|
|
||||||
dict
|
dict
|
||||||
|
@ -712,7 +727,7 @@ class Phono3py:
|
||||||
self._phonon_supercells_with_displacements = None
|
self._phonon_supercells_with_displacements = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mlp_dataset(self) -> Optional[dict]:
|
def mlp_dataset(self) -> dict | None:
|
||||||
"""Return displacement-force dataset.
|
"""Return displacement-force dataset.
|
||||||
|
|
||||||
The supercell matrix is equal to that of usual displacement-force
|
The supercell matrix is equal to that of usual displacement-force
|
||||||
|
@ -728,7 +743,7 @@ class Phono3py:
|
||||||
self._mlp_dataset = mlp_dataset
|
self._mlp_dataset = mlp_dataset
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def phonon_mlp_dataset(self) -> Optional[dict]:
|
def phonon_mlp_dataset(self) -> dict | None:
|
||||||
"""Return phonon displacement-force dataset.
|
"""Return phonon displacement-force dataset.
|
||||||
|
|
||||||
The phonon supercell matrix is equal to that of usual displacement-force
|
The phonon supercell matrix is equal to that of usual displacement-force
|
||||||
|
@ -803,7 +818,7 @@ class Phono3py:
|
||||||
self._phonon_supercell.masses = s_masses
|
self._phonon_supercell.masses = s_masses
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supercells_with_displacements(self) -> list[PhonopyAtoms]:
|
def supercells_with_displacements(self) -> list[PhonopyAtoms | None]:
|
||||||
"""Return supercells with displacements.
|
"""Return supercells with displacements.
|
||||||
|
|
||||||
list of PhonopyAtoms
|
list of PhonopyAtoms
|
||||||
|
@ -813,6 +828,7 @@ class Phono3py:
|
||||||
"""
|
"""
|
||||||
if self._supercells_with_displacements is None:
|
if self._supercells_with_displacements is None:
|
||||||
self._build_supercells_with_displacements()
|
self._build_supercells_with_displacements()
|
||||||
|
assert self._supercells_with_displacements is not None
|
||||||
return self._supercells_with_displacements
|
return self._supercells_with_displacements
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -834,7 +850,7 @@ class Phono3py:
|
||||||
return self._phonon_supercells_with_displacements
|
return self._phonon_supercells_with_displacements
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mesh_numbers(self):
|
def mesh_numbers(self) -> NDArray | None:
|
||||||
"""Setter and getter of sampling mesh numbers in reciprocal space."""
|
"""Setter and getter of sampling mesh numbers in reciprocal space."""
|
||||||
if self._bz_grid is None:
|
if self._bz_grid is None:
|
||||||
return None
|
return None
|
||||||
|
@ -842,7 +858,7 @@ class Phono3py:
|
||||||
return self._bz_grid.D_diag
|
return self._bz_grid.D_diag
|
||||||
|
|
||||||
@mesh_numbers.setter
|
@mesh_numbers.setter
|
||||||
def mesh_numbers(self, mesh_numbers: Union[int, float, Sequence, NDArray]):
|
def mesh_numbers(self, mesh_numbers: float | ArrayLike):
|
||||||
self._set_mesh_numbers(mesh_numbers)
|
self._set_mesh_numbers(mesh_numbers)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -882,7 +898,7 @@ class Phono3py:
|
||||||
"""
|
"""
|
||||||
dataset = self._dataset
|
dataset = self._dataset
|
||||||
|
|
||||||
if self._dataset is None:
|
if dataset is None:
|
||||||
raise RuntimeError("displacement dataset is not set.")
|
raise RuntimeError("displacement dataset is not set.")
|
||||||
|
|
||||||
if "first_atoms" in dataset:
|
if "first_atoms" in dataset:
|
||||||
|
@ -1077,7 +1093,9 @@ class Phono3py:
|
||||||
@property
|
@property
|
||||||
def detailed_gammas(self):
|
def detailed_gammas(self):
|
||||||
"""Return detailed gamma."""
|
"""Return detailed gamma."""
|
||||||
return self._detailed_gammas
|
if self._ise_params is None:
|
||||||
|
raise RuntimeError("Imaginary self energy parameters are not set.")
|
||||||
|
return self._ise_params.detailed_gammas
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def grid(self):
|
def grid(self):
|
||||||
|
@ -1091,12 +1109,12 @@ class Phono3py:
|
||||||
|
|
||||||
def init_phph_interaction(
|
def init_phph_interaction(
|
||||||
self,
|
self,
|
||||||
nac_q_direction=None,
|
nac_q_direction: ArrayLike | None = None,
|
||||||
constant_averaged_interaction=None,
|
constant_averaged_interaction: float | None = None,
|
||||||
frequency_scale_factor=None,
|
frequency_scale_factor: float | None = None,
|
||||||
symmetrize_fc3q: bool = False,
|
symmetrize_fc3q: bool = False,
|
||||||
lapack_zheev_uplo="L",
|
lapack_zheev_uplo: Literal["L", "U"] = "L",
|
||||||
openmp_per_triplets=None,
|
openmp_per_triplets: bool | None = None,
|
||||||
):
|
):
|
||||||
"""Initialize ph-ph interaction calculation.
|
"""Initialize ph-ph interaction calculation.
|
||||||
|
|
||||||
|
@ -1250,7 +1268,7 @@ class Phono3py:
|
||||||
self,
|
self,
|
||||||
distance: float | None = None,
|
distance: float | None = None,
|
||||||
cutoff_pair_distance: float | None = None,
|
cutoff_pair_distance: float | None = None,
|
||||||
is_plusminus: bool | str = "auto",
|
is_plusminus: bool | Literal["auto"] = "auto",
|
||||||
is_diagonal: bool = True,
|
is_diagonal: bool = True,
|
||||||
number_of_snapshots: int | Literal["auto"] | None = None,
|
number_of_snapshots: int | Literal["auto"] | None = None,
|
||||||
random_seed: int | None = None,
|
random_seed: int | None = None,
|
||||||
|
@ -1395,12 +1413,12 @@ class Phono3py:
|
||||||
|
|
||||||
def generate_fc2_displacements(
|
def generate_fc2_displacements(
|
||||||
self,
|
self,
|
||||||
distance: Optional[float] = None,
|
distance: float | None = None,
|
||||||
is_plusminus: str = "auto",
|
is_plusminus: bool | Literal["auto"] = "auto",
|
||||||
is_diagonal: bool = False,
|
is_diagonal: bool = False,
|
||||||
number_of_snapshots: Optional[Union[int, Literal["auto"]]] = None,
|
number_of_snapshots: int | Literal["auto"] | None = None,
|
||||||
random_seed: Optional[int] = None,
|
random_seed: int | None = None,
|
||||||
max_distance: Optional[float] = None,
|
max_distance: float | None = None,
|
||||||
):
|
):
|
||||||
"""Generate displacement dataset in phonon supercell for fc2.
|
"""Generate displacement dataset in phonon supercell for fc2.
|
||||||
|
|
||||||
|
@ -1541,9 +1559,13 @@ class Phono3py:
|
||||||
|
|
||||||
if fc_calculator == "traditional" or fc_calculator is None:
|
if fc_calculator == "traditional" or fc_calculator is None:
|
||||||
if symmetrize_fc3r:
|
if symmetrize_fc3r:
|
||||||
self.symmetrize_fc3(
|
fc3_calc_opts = extract_fc2_fc3_calculators_options(
|
||||||
use_symfc_projector=use_symfc_projector and fc_calculator is None
|
fc_calculator_options, 3
|
||||||
)
|
)
|
||||||
|
if use_symfc_projector and fc_calculator is None:
|
||||||
|
self.symmetrize_fc3(use_symfc_projector=True, options=fc3_calc_opts)
|
||||||
|
else:
|
||||||
|
self.symmetrize_fc3(options=fc3_calc_opts)
|
||||||
elif fc_calculator == "symfc":
|
elif fc_calculator == "symfc":
|
||||||
symfc_solver = cast(SymfcFCSolver, fc_solver.fc_solver)
|
symfc_solver = cast(SymfcFCSolver, fc_solver.fc_solver)
|
||||||
fc3_nonzero_elems = symfc_solver.get_nonzero_atomic_indices_fc3()
|
fc3_nonzero_elems = symfc_solver.get_nonzero_atomic_indices_fc3()
|
||||||
|
@ -1566,36 +1588,76 @@ class Phono3py:
|
||||||
self._fc2 = fc2
|
self._fc2 = fc2
|
||||||
if fc_calculator == "traditional" or fc_calculator is None:
|
if fc_calculator == "traditional" or fc_calculator is None:
|
||||||
if symmetrize_fc3r:
|
if symmetrize_fc3r:
|
||||||
self.symmetrize_fc2(
|
fc2_calc_opts = extract_fc2_fc3_calculators_options(
|
||||||
use_symfc_projector=use_symfc_projector
|
fc_calculator_options, 2
|
||||||
and fc_calculator is None
|
|
||||||
)
|
)
|
||||||
|
if use_symfc_projector and fc_calculator is None:
|
||||||
|
self.symmetrize_fc2(
|
||||||
|
use_symfc_projector=True, options=fc2_calc_opts
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.symmetrize_fc2(options=fc2_calc_opts)
|
||||||
|
|
||||||
def symmetrize_fc3(self, use_symfc_projector: bool = False):
|
def symmetrize_fc3(
|
||||||
"""Symmetrize fc3 by symfc projector or traditional approach."""
|
self,
|
||||||
|
use_symfc_projector: bool = False,
|
||||||
|
options: str | None = None,
|
||||||
|
):
|
||||||
|
"""Symmetrize fc3 by symfc projector or traditional approach.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
use_symfc_projector : bool, optional
|
||||||
|
If True, the force constants are symmetrized by symfc projector
|
||||||
|
instead of traditional approach.
|
||||||
|
options : str or None, optional
|
||||||
|
For symfc projector:
|
||||||
|
"use_mkl=true" calls sparse_dot_mkl (required to install it).
|
||||||
|
For traditional symmetrization:
|
||||||
|
"level=N" applies translational and permutation symmetries
|
||||||
|
alternately N times in succession. Default is 3.
|
||||||
|
|
||||||
|
"""
|
||||||
if self._fc3 is None:
|
if self._fc3 is None:
|
||||||
raise RuntimeError("fc3 is not set. Call produce_fc3 first.")
|
raise RuntimeError("fc3 is not set. Call produce_fc3 first.")
|
||||||
|
|
||||||
if use_symfc_projector:
|
if use_symfc_projector:
|
||||||
if self._log_level:
|
if self._log_level:
|
||||||
print("Symmetrizing fc3 by symfc projector.", flush=True)
|
print("Symmetrizing fc3 by symfc projector.", flush=True)
|
||||||
|
if options is None:
|
||||||
|
_options = None
|
||||||
|
else:
|
||||||
|
_options = parse_symfc_options(options, 3)
|
||||||
self._fc3 = symmetrize_by_projector(
|
self._fc3 = symmetrize_by_projector(
|
||||||
self._supercell,
|
self._supercell,
|
||||||
self._fc3,
|
self._fc3,
|
||||||
3,
|
3,
|
||||||
primitive=self._primitive,
|
primitive=self._primitive,
|
||||||
|
options=_options,
|
||||||
log_level=self._log_level,
|
log_level=self._log_level,
|
||||||
show_credit=True,
|
show_credit=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
level = 3
|
||||||
|
if options is not None:
|
||||||
|
for option in options.split(","):
|
||||||
|
if "level" in option.lower():
|
||||||
|
try:
|
||||||
|
level = int(option.split("=")[1].split()[0])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
break
|
||||||
if self._log_level:
|
if self._log_level:
|
||||||
print("Symmetrizing fc3 by traditional approach.", flush=True)
|
print(
|
||||||
if self._fc3.shape[0] == self._fc3.shape[1]:
|
f"Symmetrizing fc3 by traditional approach (N={level}).", flush=True
|
||||||
set_translational_invariance_fc3(self._fc3)
|
)
|
||||||
set_permutation_symmetry_fc3(self._fc3)
|
for _ in range(level):
|
||||||
else:
|
if self._fc3.shape[0] == self._fc3.shape[1]:
|
||||||
set_translational_invariance_compact_fc3(self._fc3, self._primitive)
|
set_translational_invariance_fc3(self._fc3)
|
||||||
set_permutation_symmetry_compact_fc3(self._fc3, self._primitive)
|
set_permutation_symmetry_fc3(self._fc3)
|
||||||
|
else:
|
||||||
|
set_translational_invariance_compact_fc3(self._fc3, self._primitive)
|
||||||
|
set_permutation_symmetry_compact_fc3(self._fc3, self._primitive)
|
||||||
|
|
||||||
def produce_fc2(
|
def produce_fc2(
|
||||||
self,
|
self,
|
||||||
|
@ -1657,11 +1719,30 @@ class Phono3py:
|
||||||
|
|
||||||
if symmetrize_fc2 and (fc_calculator is None or fc_calculator == "traditional"):
|
if symmetrize_fc2 and (fc_calculator is None or fc_calculator == "traditional"):
|
||||||
self.symmetrize_fc2(
|
self.symmetrize_fc2(
|
||||||
use_symfc_projector=use_symfc_projector and fc_calculator is None
|
use_symfc_projector=use_symfc_projector and fc_calculator is None,
|
||||||
|
options=fc_calculator_options,
|
||||||
)
|
)
|
||||||
|
|
||||||
def symmetrize_fc2(self, use_symfc_projector: bool = False):
|
def symmetrize_fc2(
|
||||||
"""Symmetrize fc2 by symfc projector or traditional approach."""
|
self,
|
||||||
|
use_symfc_projector: bool = False,
|
||||||
|
options: str | None = None,
|
||||||
|
):
|
||||||
|
"""Symmetrize fc2 by symfc projector or traditional approach.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
use_symfc_projector : bool, optional
|
||||||
|
If True, the force constants are symmetrized by symfc projector
|
||||||
|
instead of traditional approach.
|
||||||
|
options : str or None, optional
|
||||||
|
For symfc projector:
|
||||||
|
"use_mkl=true" calls sparse_dot_mkl (required to install it).
|
||||||
|
For traditional symmetrization:
|
||||||
|
"level=N" applies translational and permutation symmetries
|
||||||
|
alternately N times in succession. Default is 3.
|
||||||
|
|
||||||
|
"""
|
||||||
if self._fc2 is None:
|
if self._fc2 is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"fc2 is not set. Call produce_fc3 or produce_fc2 (phonon_fc2) first."
|
"fc2 is not set. Call produce_fc3 or produce_fc2 (phonon_fc2) first."
|
||||||
|
@ -1678,21 +1759,38 @@ class Phono3py:
|
||||||
if use_symfc_projector:
|
if use_symfc_projector:
|
||||||
if self._log_level:
|
if self._log_level:
|
||||||
print("Symmetrizing fc2 by symfc projector.", flush=True)
|
print("Symmetrizing fc2 by symfc projector.", flush=True)
|
||||||
|
if options is None:
|
||||||
|
_options = None
|
||||||
|
else:
|
||||||
|
_options = parse_symfc_options(options, 2)
|
||||||
self._fc2 = symmetrize_by_projector(
|
self._fc2 = symmetrize_by_projector(
|
||||||
supercell,
|
supercell,
|
||||||
self._fc2,
|
self._fc2,
|
||||||
2,
|
2,
|
||||||
primitive=primitive,
|
primitive=primitive,
|
||||||
|
options=_options,
|
||||||
log_level=self._log_level,
|
log_level=self._log_level,
|
||||||
show_credit=True,
|
show_credit=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
level = 3
|
||||||
|
if options is not None:
|
||||||
|
for option in options.split(","):
|
||||||
|
if "level" in option.lower():
|
||||||
|
try:
|
||||||
|
level = int(option.split("=")[1].split()[0])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
break
|
||||||
if self._log_level:
|
if self._log_level:
|
||||||
print("Symmetrizing fc2 by traditional approach.", flush=True)
|
print(
|
||||||
if self._fc2.shape[0] == self._fc2.shape[1]:
|
f"Symmetrizing fc2 by traditional approach (N={level}).", flush=True
|
||||||
symmetrize_force_constants(self._fc2)
|
)
|
||||||
else:
|
for _ in range(level):
|
||||||
symmetrize_compact_force_constants(self._fc2, primitive)
|
if self._fc2.shape[0] == self._fc2.shape[1]:
|
||||||
|
symmetrize_force_constants(self._fc2)
|
||||||
|
else:
|
||||||
|
symmetrize_compact_force_constants(self._fc2, primitive)
|
||||||
|
|
||||||
def cutoff_fc3_by_zero(self, cutoff_distance, fc3=None):
|
def cutoff_fc3_by_zero(self, cutoff_distance, fc3=None):
|
||||||
"""Set zero to fc3 elements out of cutoff distance.
|
"""Set zero to fc3 elements out of cutoff distance.
|
||||||
|
@ -1753,7 +1851,7 @@ class Phono3py:
|
||||||
write_gamma_detail=False,
|
write_gamma_detail=False,
|
||||||
keep_gamma_detail=False,
|
keep_gamma_detail=False,
|
||||||
output_filename=None,
|
output_filename=None,
|
||||||
):
|
) -> ImagSelfEnergyValues:
|
||||||
"""Calculate imaginary part of self-energy of bubble diagram (Gamma).
|
"""Calculate imaginary part of self-energy of bubble diagram (Gamma).
|
||||||
|
|
||||||
Pi = Delta - i Gamma.
|
Pi = Delta - i Gamma.
|
||||||
|
@ -1818,7 +1916,6 @@ class Phono3py:
|
||||||
else:
|
else:
|
||||||
self._temperatures = temperatures
|
self._temperatures = temperatures
|
||||||
self._grid_points = grid_points
|
self._grid_points = grid_points
|
||||||
self._scattering_event_class = scattering_event_class
|
|
||||||
vals = get_imag_self_energy(
|
vals = get_imag_self_energy(
|
||||||
self._interaction,
|
self._interaction,
|
||||||
grid_points,
|
grid_points,
|
||||||
|
@ -1836,25 +1933,34 @@ class Phono3py:
|
||||||
log_level=self._log_level,
|
log_level=self._log_level,
|
||||||
)
|
)
|
||||||
if keep_gamma_detail:
|
if keep_gamma_detail:
|
||||||
(self._frequency_points, self._gammas, self._detailed_gammas) = vals
|
self._ise_params = ImagSelfEnergyValues(
|
||||||
|
frequency_points=vals[0],
|
||||||
|
gammas=vals[1],
|
||||||
|
scattering_event_class=scattering_event_class,
|
||||||
|
detailed_gammas=vals[2],
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self._frequency_points, self._gammas = vals
|
self._ise_params = ImagSelfEnergyValues(
|
||||||
|
frequency_points=vals[0], gammas=vals[1]
|
||||||
|
)
|
||||||
|
|
||||||
if write_txt:
|
if write_txt:
|
||||||
self._write_imag_self_energy(output_filename=output_filename)
|
self._write_imag_self_energy(output_filename=output_filename)
|
||||||
|
|
||||||
return vals
|
return self._ise_params
|
||||||
|
|
||||||
def _write_imag_self_energy(self, output_filename=None):
|
def _write_imag_self_energy(self, output_filename=None):
|
||||||
|
if self._ise_params is None:
|
||||||
|
raise RuntimeError("Imaginary self-energy is not calculated.")
|
||||||
write_imag_self_energy(
|
write_imag_self_energy(
|
||||||
self._gammas,
|
self._ise_params.gammas,
|
||||||
self.mesh_numbers,
|
self.mesh_numbers,
|
||||||
self._grid_points,
|
self._grid_points,
|
||||||
self._band_indices,
|
self._band_indices,
|
||||||
self._frequency_points,
|
self._ise_params.frequency_points,
|
||||||
self._temperatures,
|
self._temperatures,
|
||||||
self._sigmas,
|
self._sigmas,
|
||||||
scattering_event_class=self._scattering_event_class,
|
scattering_event_class=self._ise_params.scattering_event_class,
|
||||||
output_filename=output_filename,
|
output_filename=output_filename,
|
||||||
is_mesh_symmetry=self._is_mesh_symmetry,
|
is_mesh_symmetry=self._is_mesh_symmetry,
|
||||||
log_level=self._log_level,
|
log_level=self._log_level,
|
||||||
|
@ -2039,16 +2145,16 @@ class Phono3py:
|
||||||
def run_thermal_conductivity(
|
def run_thermal_conductivity(
|
||||||
self,
|
self,
|
||||||
is_LBTE: bool = False,
|
is_LBTE: bool = False,
|
||||||
temperatures: Optional[Sequence] = None,
|
temperatures: Sequence | None = None,
|
||||||
is_isotope: bool = False,
|
is_isotope: bool = False,
|
||||||
mass_variances: Optional[Sequence] = None,
|
mass_variances: Sequence | None = None,
|
||||||
grid_points: Optional[Sequence[int]] = None,
|
grid_points: ArrayLike | None = None,
|
||||||
boundary_mfp: Optional[float] = None, # in micrometer
|
boundary_mfp: float | None = None, # in micrometer
|
||||||
solve_collective_phonon: bool = False,
|
solve_collective_phonon: bool = False,
|
||||||
use_ave_pp: bool = False,
|
use_ave_pp: bool = False,
|
||||||
is_reducible_collision_matrix: bool = False,
|
is_reducible_collision_matrix: bool = False,
|
||||||
is_kappa_star: bool = True,
|
is_kappa_star: bool = True,
|
||||||
gv_delta_q: Optional[float] = None, # for group velocity
|
gv_delta_q: float | None = None, # for group velocity
|
||||||
is_full_pp: bool = False,
|
is_full_pp: bool = False,
|
||||||
pinv_cutoff: float = 1.0e-8, # for pseudo-inversion of collision matrix
|
pinv_cutoff: float = 1.0e-8, # for pseudo-inversion of collision matrix
|
||||||
pinv_method: int = 0, # for pseudo-inversion of collision matrix
|
pinv_method: int = 0, # for pseudo-inversion of collision matrix
|
||||||
|
@ -2056,18 +2162,18 @@ class Phono3py:
|
||||||
write_gamma: bool = False,
|
write_gamma: bool = False,
|
||||||
read_gamma: bool = False,
|
read_gamma: bool = False,
|
||||||
is_N_U: bool = False,
|
is_N_U: bool = False,
|
||||||
conductivity_type: Optional[str] = None,
|
conductivity_type: str | None = None,
|
||||||
write_kappa: bool = False,
|
write_kappa: bool = False,
|
||||||
write_gamma_detail: bool = False,
|
write_gamma_detail: bool = False,
|
||||||
write_collision: bool = False,
|
write_collision: bool = False,
|
||||||
read_collision: bool = False,
|
read_collision: str | Sequence | None = None,
|
||||||
write_pp: bool = False,
|
write_pp: bool = False,
|
||||||
read_pp: bool = False,
|
read_pp: bool = False,
|
||||||
write_LBTE_solution: bool = False,
|
write_LBTE_solution: bool = False,
|
||||||
compression: str = "gzip",
|
compression: str = "gzip",
|
||||||
input_filename: Optional[str] = None,
|
input_filename: str | None = None,
|
||||||
output_filename: Optional[str] = None,
|
output_filename: str | None = None,
|
||||||
log_level: Optional[int] = None,
|
log_level: int | None = None,
|
||||||
):
|
):
|
||||||
"""Run thermal conductivity calculation.
|
"""Run thermal conductivity calculation.
|
||||||
|
|
||||||
|
@ -2174,9 +2280,9 @@ class Phono3py:
|
||||||
is written into a file. With multiple `sigmas` specified,
|
is written into a file. With multiple `sigmas` specified,
|
||||||
respective files are created. Be careful that this file can be
|
respective files are created. Be careful that this file can be
|
||||||
huge.
|
huge.
|
||||||
read_collision : bool, optional, default is False
|
read_collision : str | Sequence, optional, default is None.
|
||||||
Direct solution only (`is_LBTE=True`). With True, collision matrix
|
Direct solution only (`is_LBTE=True`). With specified, collision
|
||||||
is read from a file.
|
matrix is read from a file.
|
||||||
write_pp : bool, optional, default is False
|
write_pp : bool, optional, default is False
|
||||||
With True, phonon-phonon interaction strength is written into
|
With True, phonon-phonon interaction strength is written into
|
||||||
files at each grid point. This option assumes single value is in
|
files at each grid point. This option assumes single value is in
|
||||||
|
@ -2294,7 +2400,9 @@ class Phono3py:
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(
|
def save(
|
||||||
self, filename: str = "phono3py_params.yaml", settings: dict | None = None
|
self,
|
||||||
|
filename: str | os.PathLike = "phono3py_params.yaml",
|
||||||
|
settings: dict | None = None,
|
||||||
):
|
):
|
||||||
"""Save parameters in Phono3py instants into file.
|
"""Save parameters in Phono3py instants into file.
|
||||||
|
|
||||||
|
@ -2348,14 +2456,14 @@ class Phono3py:
|
||||||
test_size=test_size,
|
test_size=test_size,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_mlp(self, filename: Optional[str] = None):
|
def save_mlp(self, filename: str | None = None):
|
||||||
"""Save machine learning potential."""
|
"""Save machine learning potential."""
|
||||||
if self._mlp is None:
|
if self._mlp is None:
|
||||||
raise RuntimeError("MLP is not developed yet.")
|
raise RuntimeError("MLP is not developed yet.")
|
||||||
|
|
||||||
self._mlp.save(filename=filename)
|
self._mlp.save(filename=filename)
|
||||||
|
|
||||||
def load_mlp(self, filename: Optional[str] = None):
|
def load_mlp(self, filename: str | os.PathLike | None = None):
|
||||||
"""Load machine learning potential."""
|
"""Load machine learning potential."""
|
||||||
self._mlp = PhonopyMLP(log_level=self._log_level)
|
self._mlp = PhonopyMLP(log_level=self._log_level)
|
||||||
self._mlp.load(filename=filename)
|
self._mlp.load(filename=filename)
|
||||||
|
@ -2385,7 +2493,7 @@ class Phono3py:
|
||||||
|
|
||||||
def develop_phonon_mlp(
|
def develop_phonon_mlp(
|
||||||
self,
|
self,
|
||||||
params: Optional[Union[PypolymlpParams, dict, str]] = None,
|
params: PypolymlpParams | dict | str | None = None,
|
||||||
test_size: float = 0.1,
|
test_size: float = 0.1,
|
||||||
):
|
):
|
||||||
"""Develop MLP for fc2.
|
"""Develop MLP for fc2.
|
||||||
|
@ -2412,14 +2520,14 @@ class Phono3py:
|
||||||
test_size=test_size,
|
test_size=test_size,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_phonon_mlp(self, filename: Optional[str] = None):
|
def save_phonon_mlp(self, filename: str | os.PathLike | None = None):
|
||||||
"""Save machine learning potential."""
|
"""Save machine learning potential."""
|
||||||
if self._mlp is None:
|
if self._phonon_mlp is None:
|
||||||
raise RuntimeError("MLP is not developed yet.")
|
raise RuntimeError("MLP is not developed yet.")
|
||||||
|
|
||||||
self._phonon_mlp.save(filename=filename)
|
self._phonon_mlp.save(filename=filename)
|
||||||
|
|
||||||
def load_phonon_mlp(self, filename: Optional[str] = None):
|
def load_phonon_mlp(self, filename: str | None = None):
|
||||||
"""Load machine learning potential."""
|
"""Load machine learning potential."""
|
||||||
self._phonon_mlp = PhonopyMLP(log_level=self._log_level)
|
self._phonon_mlp = PhonopyMLP(log_level=self._log_level)
|
||||||
self._phonon_mlp.load(filename=filename)
|
self._phonon_mlp.load(filename=filename)
|
||||||
|
@ -2437,8 +2545,10 @@ class Phono3py:
|
||||||
constants.
|
constants.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self._mlp is None and self._phonon_mlp is None:
|
if self._mlp is None:
|
||||||
raise RuntimeError("MLP is not developed yet.")
|
raise RuntimeError("MLP is not developed yet.")
|
||||||
|
if self._phonon_mlp is None:
|
||||||
|
raise RuntimeError("Phonon MLP is not developed yet.")
|
||||||
|
|
||||||
if self.phonon_supercells_with_displacements is None:
|
if self.phonon_supercells_with_displacements is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
|
@ -2575,15 +2685,22 @@ class Phono3py:
|
||||||
return supercells
|
return supercells
|
||||||
|
|
||||||
def _build_supercells_with_displacements(self):
|
def _build_supercells_with_displacements(self):
|
||||||
|
assert self._dataset is not None
|
||||||
|
|
||||||
magmoms = self._supercell.magnetic_moments
|
magmoms = self._supercell.magnetic_moments
|
||||||
masses = self._supercell.masses
|
masses = self._supercell.masses
|
||||||
numbers = self._supercell.numbers
|
numbers = self._supercell.numbers
|
||||||
lattice = self._supercell.cell
|
lattice = self._supercell.cell
|
||||||
|
|
||||||
supercells = self._build_phonon_supercells_with_displacements(
|
# One displacement supercells
|
||||||
self._supercell, self._dataset
|
supercells = cast(
|
||||||
|
list[PhonopyAtoms | None],
|
||||||
|
self._build_phonon_supercells_with_displacements(
|
||||||
|
self._supercell, self._dataset
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Two displacement supercells
|
||||||
if "first_atoms" in self._dataset:
|
if "first_atoms" in self._dataset:
|
||||||
for disp1 in self._dataset["first_atoms"]:
|
for disp1 in self._dataset["first_atoms"]:
|
||||||
disp_cart1 = disp1["displacement"]
|
disp_cart1 = disp1["displacement"]
|
||||||
|
@ -2621,7 +2738,9 @@ class Phono3py:
|
||||||
|
|
||||||
return get_primitive(supercell, t_mat, self._symprec, store_dense_svecs=True)
|
return get_primitive(supercell, t_mat, self._symprec, store_dense_svecs=True)
|
||||||
|
|
||||||
def _determine_primitive_matrix(self, primitive_matrix):
|
def _determine_primitive_matrix(
|
||||||
|
self, primitive_matrix: str | ArrayLike | None
|
||||||
|
) -> NDArray | None:
|
||||||
pmat = get_primitive_matrix(primitive_matrix, symprec=self._symprec)
|
pmat = get_primitive_matrix(primitive_matrix, symprec=self._symprec)
|
||||||
if isinstance(pmat, str) and pmat == "auto":
|
if isinstance(pmat, str) and pmat == "auto":
|
||||||
return guess_primitive_matrix(self._unitcell, symprec=self._symprec)
|
return guess_primitive_matrix(self._unitcell, symprec=self._symprec)
|
||||||
|
@ -2630,7 +2749,7 @@ class Phono3py:
|
||||||
|
|
||||||
def _set_mesh_numbers(
|
def _set_mesh_numbers(
|
||||||
self,
|
self,
|
||||||
mesh: Union[int, float, Sequence, NDArray],
|
mesh: float | ArrayLike,
|
||||||
):
|
):
|
||||||
# initialization related to mesh
|
# initialization related to mesh
|
||||||
self._interaction = None
|
self._interaction = None
|
||||||
|
@ -2661,7 +2780,8 @@ class Phono3py:
|
||||||
nac_params=self._nac_params,
|
nac_params=self._nac_params,
|
||||||
)
|
)
|
||||||
freqs, _, _ = self.get_phonon_data()
|
freqs, _, _ = self.get_phonon_data()
|
||||||
gp_Gamma = self._bz_grid.gp_Gamma
|
gp_Gamma = self._interaction.bz_grid.gp_Gamma
|
||||||
|
assert freqs is not None
|
||||||
if np.sum(freqs[gp_Gamma] < self._cutoff_frequency) < 3:
|
if np.sum(freqs[gp_Gamma] < self._cutoff_frequency) < 3:
|
||||||
for i, f in enumerate(freqs[gp_Gamma, :3]):
|
for i, f in enumerate(freqs[gp_Gamma, :3]):
|
||||||
if not (f < self._cutoff_frequency):
|
if not (f < self._cutoff_frequency):
|
||||||
|
@ -2717,6 +2837,9 @@ class Phono3py:
|
||||||
def _set_forces_energies(
|
def _set_forces_energies(
|
||||||
self, values, target: Literal["forces", "supercell_energies"]
|
self, values, target: Literal["forces", "supercell_energies"]
|
||||||
):
|
):
|
||||||
|
if self._dataset is None:
|
||||||
|
raise RuntimeError("Dataset is not available.")
|
||||||
|
|
||||||
if "first_atoms" in self._dataset: # type-1
|
if "first_atoms" in self._dataset: # type-1
|
||||||
count = 0
|
count = 0
|
||||||
for disp1 in self._dataset["first_atoms"]:
|
for disp1 in self._dataset["first_atoms"]:
|
||||||
|
@ -2800,13 +2923,11 @@ class Phono3py:
|
||||||
is_plusminus: bool = False,
|
is_plusminus: bool = False,
|
||||||
random_seed: int | None = None,
|
random_seed: int | None = None,
|
||||||
max_distance: float | None = None,
|
max_distance: float | None = None,
|
||||||
):
|
) -> dict:
|
||||||
if random_seed is not None and random_seed >= 0 and random_seed < 2**32:
|
if random_seed is not None and random_seed >= 0 and random_seed < 2**32:
|
||||||
_random_seed = random_seed
|
_random_seed = random_seed
|
||||||
dataset = {"random_seed": _random_seed}
|
|
||||||
else:
|
else:
|
||||||
_random_seed = None
|
_random_seed = None
|
||||||
dataset = {}
|
|
||||||
d = get_random_displacements_dataset(
|
d = get_random_displacements_dataset(
|
||||||
number_of_snapshots,
|
number_of_snapshots,
|
||||||
number_of_atoms,
|
number_of_atoms,
|
||||||
|
@ -2815,7 +2936,10 @@ class Phono3py:
|
||||||
is_plusminus=is_plusminus,
|
is_plusminus=is_plusminus,
|
||||||
max_distance=max_distance,
|
max_distance=max_distance,
|
||||||
)
|
)
|
||||||
dataset["displacements"] = d
|
if _random_seed is None:
|
||||||
|
dataset = {"displacements": d}
|
||||||
|
else:
|
||||||
|
dataset = {"random_seed": _random_seed, "displacements": d}
|
||||||
return dataset
|
return dataset
|
||||||
|
|
||||||
def _check_mlp_dataset(self, mlp_dataset: dict):
|
def _check_mlp_dataset(self, mlp_dataset: dict):
|
||||||
|
|
|
@ -41,7 +41,7 @@ from abc import ABC, abstractmethod
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.typing import NDArray
|
from numpy.typing import ArrayLike, NDArray
|
||||||
from phonopy.phonon.group_velocity import GroupVelocity
|
from phonopy.phonon.group_velocity import GroupVelocity
|
||||||
from phonopy.phonon.thermal_properties import mode_cv
|
from phonopy.phonon.thermal_properties import mode_cv
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
@ -419,12 +419,12 @@ class ConductivityBase(ABC):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
interaction: Interaction,
|
interaction: Interaction,
|
||||||
grid_points: np.ndarray | None = None,
|
grid_points: ArrayLike | None = None,
|
||||||
temperatures: list | np.ndarray | None = None,
|
temperatures: ArrayLike | None = None,
|
||||||
sigmas: list | np.ndarray | None = None,
|
sigmas: ArrayLike | None = None,
|
||||||
sigma_cutoff: float | None = None,
|
sigma_cutoff: float | None = None,
|
||||||
is_isotope=False,
|
is_isotope=False,
|
||||||
mass_variances: list | np.ndarray | None = None,
|
mass_variances: ArrayLike | None = None,
|
||||||
boundary_mfp: float | None = None,
|
boundary_mfp: float | None = None,
|
||||||
is_kappa_star: bool = True,
|
is_kappa_star: bool = True,
|
||||||
is_full_pp: bool = False,
|
is_full_pp: bool = False,
|
||||||
|
|
|
@ -36,9 +36,10 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Optional, Union
|
import os
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike
|
||||||
|
|
||||||
from phono3py.conductivity.base import ConductivityComponents
|
from phono3py.conductivity.base import ConductivityComponents
|
||||||
from phono3py.conductivity.direct_solution_base import (
|
from phono3py.conductivity.direct_solution_base import (
|
||||||
|
@ -54,20 +55,20 @@ class ConductivityLBTE(ConductivityLBTEBase):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
interaction: Interaction,
|
interaction: Interaction,
|
||||||
grid_points: Optional[np.ndarray] = None,
|
grid_points: ArrayLike | None = None,
|
||||||
temperatures: Optional[Union[list, np.ndarray]] = None,
|
temperatures: ArrayLike | None = None,
|
||||||
sigmas: Optional[Union[list, np.ndarray]] = None,
|
sigmas: ArrayLike | None = None,
|
||||||
sigma_cutoff: Optional[float] = None,
|
sigma_cutoff: float | None = None,
|
||||||
is_isotope: bool = False,
|
is_isotope: bool = False,
|
||||||
mass_variances: Optional[Union[list, np.ndarray]] = None,
|
mass_variances: ArrayLike | None = None,
|
||||||
boundary_mfp: Optional[float] = None, # in micrometer
|
boundary_mfp: float | None = None, # in micrometer
|
||||||
solve_collective_phonon: bool = False,
|
solve_collective_phonon: bool = False,
|
||||||
is_reducible_collision_matrix: bool = False,
|
is_reducible_collision_matrix: bool = False,
|
||||||
is_kappa_star: bool = True,
|
is_kappa_star: bool = True,
|
||||||
gv_delta_q: Optional[float] = None,
|
gv_delta_q: float | None = None,
|
||||||
is_full_pp: bool = False,
|
is_full_pp: bool = False,
|
||||||
read_pp: bool = False,
|
read_pp: bool = False,
|
||||||
pp_filename: Optional[float] = None,
|
pp_filename: str | os.PathLike | None = None,
|
||||||
pinv_cutoff: float = 1.0e-8,
|
pinv_cutoff: float = 1.0e-8,
|
||||||
pinv_solver: int = 0,
|
pinv_solver: int = 0,
|
||||||
pinv_method: int = 0,
|
pinv_method: int = 0,
|
||||||
|
|
|
@ -36,12 +36,14 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import Optional, Union
|
from typing import Optional
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike
|
||||||
from phonopy.phonon.degeneracy import degenerate_sets
|
from phonopy.phonon.degeneracy import degenerate_sets
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
|
||||||
|
@ -63,19 +65,19 @@ class ConductivityLBTEBase(ConductivityBase):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
interaction: Interaction,
|
interaction: Interaction,
|
||||||
grid_points: Optional[np.ndarray] = None,
|
grid_points: ArrayLike | None = None,
|
||||||
temperatures: Optional[Union[list, np.ndarray]] = None,
|
temperatures: ArrayLike | None = None,
|
||||||
sigmas: Optional[Union[list, np.ndarray]] = None,
|
sigmas: ArrayLike | None = None,
|
||||||
sigma_cutoff: Optional[float] = None,
|
sigma_cutoff: float | None = None,
|
||||||
is_isotope: bool = False,
|
is_isotope: bool = False,
|
||||||
mass_variances: Optional[Union[list, np.ndarray]] = None,
|
mass_variances: ArrayLike | None = None,
|
||||||
boundary_mfp: Optional[float] = None, # in micrometer
|
boundary_mfp: float | None = None, # in micrometer
|
||||||
solve_collective_phonon: bool = False,
|
solve_collective_phonon: bool = False,
|
||||||
is_reducible_collision_matrix: bool = False,
|
is_reducible_collision_matrix: bool = False,
|
||||||
is_kappa_star: bool = True,
|
is_kappa_star: bool = True,
|
||||||
is_full_pp: bool = False,
|
is_full_pp: bool = False,
|
||||||
read_pp: bool = False,
|
read_pp: bool = False,
|
||||||
pp_filename: Optional[float] = None,
|
pp_filename: str | os.PathLike | None = None,
|
||||||
pinv_cutoff: float = 1.0e-8,
|
pinv_cutoff: float = 1.0e-8,
|
||||||
pinv_solver: int = 0,
|
pinv_solver: int = 0,
|
||||||
pinv_method: int = 0,
|
pinv_method: int = 0,
|
||||||
|
|
|
@ -34,8 +34,14 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
from typing import Optional, Union
|
from collections.abc import Sequence
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from numpy.typing import ArrayLike
|
||||||
|
|
||||||
from phono3py.conductivity.base import get_unit_to_WmK
|
from phono3py.conductivity.base import get_unit_to_WmK
|
||||||
from phono3py.conductivity.direct_solution import ConductivityLBTE
|
from phono3py.conductivity.direct_solution import ConductivityLBTE
|
||||||
|
@ -59,32 +65,32 @@ cond_LBTE_type = Union[ConductivityLBTE, ConductivityWignerLBTE]
|
||||||
|
|
||||||
def get_thermal_conductivity_LBTE(
|
def get_thermal_conductivity_LBTE(
|
||||||
interaction: Interaction,
|
interaction: Interaction,
|
||||||
temperatures=None,
|
temperatures: Sequence | None = None,
|
||||||
sigmas=None,
|
sigmas: Sequence | None = None,
|
||||||
sigma_cutoff=None,
|
sigma_cutoff: float | None = None,
|
||||||
is_isotope=False,
|
is_isotope: bool = False,
|
||||||
mass_variances=None,
|
mass_variances: Sequence | None = None,
|
||||||
grid_points=None,
|
grid_points: ArrayLike | None = None,
|
||||||
boundary_mfp=None, # in micrometer
|
boundary_mfp: float | None = None, # in micrometer
|
||||||
solve_collective_phonon=False,
|
solve_collective_phonon: bool = False,
|
||||||
is_reducible_collision_matrix=False,
|
is_reducible_collision_matrix: bool = False,
|
||||||
is_kappa_star=True,
|
is_kappa_star: bool = True,
|
||||||
gv_delta_q=None,
|
gv_delta_q: float | None = None,
|
||||||
is_full_pp=False,
|
is_full_pp: bool = False,
|
||||||
conductivity_type=None,
|
conductivity_type: str | None = None,
|
||||||
pinv_cutoff=1.0e-8,
|
pinv_cutoff: float = 1.0e-8,
|
||||||
pinv_solver=0, # default: dsyev in lapacke
|
pinv_solver: int = 0, # default: dsyev in lapacke
|
||||||
pinv_method=0, # default: abs(eig) < cutoff
|
pinv_method: int = 0, # default: abs(eig) < cutoff
|
||||||
write_collision=False,
|
write_collision: bool = False,
|
||||||
read_collision=False,
|
read_collision: str | Sequence | None = None,
|
||||||
write_kappa=False,
|
write_kappa: bool = False,
|
||||||
write_pp=False,
|
write_pp: bool = False,
|
||||||
read_pp=False,
|
read_pp: bool = False,
|
||||||
write_LBTE_solution=False,
|
write_LBTE_solution: bool = False,
|
||||||
compression="gzip",
|
compression: str = "gzip",
|
||||||
input_filename=None,
|
input_filename: str | os.PathLike | None = None,
|
||||||
output_filename=None,
|
output_filename: str | os.PathLike | None = None,
|
||||||
log_level=0,
|
log_level: int = 0,
|
||||||
):
|
):
|
||||||
"""Calculate lattice thermal conductivity by direct solution."""
|
"""Calculate lattice thermal conductivity by direct solution."""
|
||||||
if temperatures is None:
|
if temperatures is None:
|
||||||
|
@ -292,9 +298,9 @@ class ConductivityLBTEWriter:
|
||||||
volume: float,
|
volume: float,
|
||||||
is_reducible_collision_matrix: bool = False,
|
is_reducible_collision_matrix: bool = False,
|
||||||
write_LBTE_solution: bool = False,
|
write_LBTE_solution: bool = False,
|
||||||
pinv_solver: Optional[int] = None,
|
pinv_solver: int | None = None,
|
||||||
compression: str = "gzip",
|
compression: str = "gzip",
|
||||||
filename: Optional[str] = None,
|
filename: str | os.PathLike | None = None,
|
||||||
log_level: int = 0,
|
log_level: int = 0,
|
||||||
):
|
):
|
||||||
"""Write kappa related properties into a hdf5 file."""
|
"""Write kappa related properties into a hdf5 file."""
|
||||||
|
@ -473,7 +479,7 @@ class ConductivityLBTEWriter:
|
||||||
|
|
||||||
def _set_collision_from_file(
|
def _set_collision_from_file(
|
||||||
lbte: ConductivityLBTEBase,
|
lbte: ConductivityLBTEBase,
|
||||||
indices="all",
|
indices: str | Sequence | None = "all",
|
||||||
is_reducible_collision_matrix=False,
|
is_reducible_collision_matrix=False,
|
||||||
filename=None,
|
filename=None,
|
||||||
log_level=0,
|
log_level=0,
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ def parse_forces(
|
||||||
without writing calculator name in it.
|
without writing calculator name in it.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
filename_read_from: str | None = None
|
filename_read_from = None
|
||||||
dataset = None
|
dataset = None
|
||||||
|
|
||||||
if phono3py.phonon_supercell is None or fc_type == "fc3":
|
if phono3py.phonon_supercell is None or fc_type == "fc3":
|
||||||
|
@ -170,7 +170,9 @@ def _read_FORCES_FC3_or_FC2(
|
||||||
print(f'{n_disp} snapshots were found in "{filename}".')
|
print(f'{n_disp} snapshots were found in "{filename}".')
|
||||||
return _dataset
|
return _dataset
|
||||||
|
|
||||||
# Type-1
|
# Try reading type-1 dataset
|
||||||
|
if dataset is None:
|
||||||
|
raise RuntimeError("Type-1 displacement dataset is not given.")
|
||||||
if fc_type == "fc3":
|
if fc_type == "fc3":
|
||||||
parse_FORCES_FC3(dataset, filename)
|
parse_FORCES_FC3(dataset, filename)
|
||||||
else:
|
else:
|
||||||
|
@ -183,18 +185,9 @@ def _read_FORCES_FC3_or_FC2(
|
||||||
return dataset
|
return dataset
|
||||||
|
|
||||||
|
|
||||||
def run_pypolymlp_to_compute_forces(
|
def develop_pypolymlp(
|
||||||
ph3py: Phono3py,
|
ph3py: Phono3py,
|
||||||
mlp_params: str | dict | PypolymlpParams | None = None,
|
mlp_params: str | dict | PypolymlpParams | None = None,
|
||||||
displacement_distance: float | None = None,
|
|
||||||
number_of_snapshots: int | Literal["auto"] | None = None,
|
|
||||||
number_estimation_factor: int | None = None,
|
|
||||||
random_seed: int | None = None,
|
|
||||||
prepare_dataset: bool = False,
|
|
||||||
fc_calculator: str | None = None,
|
|
||||||
fc_calculator_options: str | None = None,
|
|
||||||
cutoff_pair_distance: float | None = None,
|
|
||||||
symfc_memory_size: float | None = None,
|
|
||||||
mlp_filename: str | os.PathLike | None = None,
|
mlp_filename: str | os.PathLike | None = None,
|
||||||
log_level: int = 0,
|
log_level: int = 0,
|
||||||
):
|
):
|
||||||
|
@ -219,12 +212,12 @@ def run_pypolymlp_to_compute_forces(
|
||||||
".xz",
|
".xz",
|
||||||
".gz",
|
".gz",
|
||||||
".bz2",
|
".bz2",
|
||||||
"lzma",
|
".lzma",
|
||||||
]:
|
]:
|
||||||
continue
|
continue
|
||||||
if log_level:
|
if log_level:
|
||||||
print(f'Load MLPs from "{mlp_filename}".')
|
print(f'Load MLPs from "{_mlp_filename}".')
|
||||||
ph3py.load_mlp(mlp_filename)
|
ph3py.load_mlp(_mlp_filename)
|
||||||
mlp_loaded = True
|
mlp_loaded = True
|
||||||
if log_level and mlp_filename == "phono3py.pmlp":
|
if log_level and mlp_filename == "phono3py.pmlp":
|
||||||
print(f'Loading MLPs from "{_mlp_filename}" is obsolete.')
|
print(f'Loading MLPs from "{_mlp_filename}" is obsolete.')
|
||||||
|
@ -253,58 +246,71 @@ def run_pypolymlp_to_compute_forces(
|
||||||
if log_level:
|
if log_level:
|
||||||
print("-" * 30 + " pypolymlp end " + "-" * 31, flush=True)
|
print("-" * 30 + " pypolymlp end " + "-" * 31, flush=True)
|
||||||
|
|
||||||
if prepare_dataset:
|
|
||||||
if displacement_distance is None:
|
def generate_displacements_and_evaluate_pypolymlp(
|
||||||
_displacement_distance = 0.01
|
ph3py: Phono3py,
|
||||||
|
displacement_distance: float | None = None,
|
||||||
|
number_of_snapshots: int | Literal["auto"] | None = None,
|
||||||
|
number_estimation_factor: int | None = None,
|
||||||
|
random_seed: int | None = None,
|
||||||
|
fc_calculator: str | None = None,
|
||||||
|
fc_calculator_options: str | None = None,
|
||||||
|
cutoff_pair_distance: float | None = None,
|
||||||
|
symfc_memory_size: float | None = None,
|
||||||
|
log_level: int = 0,
|
||||||
|
):
|
||||||
|
"""Generate displacements and evaluate forces by pypolymlp."""
|
||||||
|
if displacement_distance is None:
|
||||||
|
_displacement_distance = 0.01
|
||||||
|
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:
|
else:
|
||||||
_displacement_distance = displacement_distance
|
print("Generate displacements")
|
||||||
|
print(
|
||||||
if log_level:
|
f" Displacement distance: {_displacement_distance:.5f}".rstrip("0").rstrip(
|
||||||
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(".")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cutoff_pair_distance = determine_cutoff_pair_distance(
|
|
||||||
fc_calculator=fc_calculator,
|
|
||||||
fc_calculator_options=fc_calculator_options,
|
|
||||||
cutoff_pair_distance=cutoff_pair_distance,
|
|
||||||
symfc_memory_size=symfc_memory_size,
|
|
||||||
random_displacements=number_of_snapshots,
|
|
||||||
supercell=ph3py.supercell,
|
|
||||||
primitive=ph3py.primitive,
|
|
||||||
symmetry=ph3py.symmetry,
|
|
||||||
log_level=log_level,
|
|
||||||
)
|
|
||||||
ph3py.generate_displacements(
|
|
||||||
distance=_displacement_distance,
|
|
||||||
cutoff_pair_distance=cutoff_pair_distance,
|
|
||||||
is_plusminus=True,
|
|
||||||
number_of_snapshots=number_of_snapshots,
|
|
||||||
random_seed=random_seed,
|
|
||||||
number_estimation_factor=number_estimation_factor,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if log_level:
|
cutoff_pair_distance = determine_cutoff_pair_distance(
|
||||||
print(
|
fc_calculator=fc_calculator,
|
||||||
f"Evaluate forces in {ph3py.displacements.shape[0]} supercells "
|
fc_calculator_options=fc_calculator_options,
|
||||||
"by pypolymlp",
|
cutoff_pair_distance=cutoff_pair_distance,
|
||||||
flush=True,
|
symfc_memory_size=symfc_memory_size,
|
||||||
)
|
random_displacements=number_of_snapshots,
|
||||||
|
supercell=ph3py.supercell,
|
||||||
|
primitive=ph3py.primitive,
|
||||||
|
symmetry=ph3py.symmetry,
|
||||||
|
log_level=log_level,
|
||||||
|
)
|
||||||
|
ph3py.generate_displacements(
|
||||||
|
distance=_displacement_distance,
|
||||||
|
cutoff_pair_distance=cutoff_pair_distance,
|
||||||
|
is_plusminus=True,
|
||||||
|
number_of_snapshots=number_of_snapshots,
|
||||||
|
random_seed=random_seed,
|
||||||
|
number_estimation_factor=number_estimation_factor,
|
||||||
|
)
|
||||||
|
|
||||||
if ph3py.supercells_with_displacements is None:
|
if log_level:
|
||||||
raise RuntimeError("Displacements are not set. Run generate_displacements.")
|
print(
|
||||||
|
f"Evaluate forces in {ph3py.displacements.shape[0]} supercells "
|
||||||
|
"by pypolymlp",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
ph3py.evaluate_mlp()
|
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(
|
def run_pypolymlp_to_compute_phonon_forces(
|
||||||
|
|
|
@ -200,17 +200,15 @@ def create_FORCES_FC2_from_FORCE_SETS(log_level):
|
||||||
|
|
||||||
|
|
||||||
def create_FORCE_SETS_from_FORCES_FCx(
|
def create_FORCE_SETS_from_FORCES_FCx(
|
||||||
phonon_smat, input_filename: Optional[str], cell_filename: Optional[str], log_level
|
phonon_smat, cell_filename: Optional[str], log_level
|
||||||
):
|
):
|
||||||
"""Convert FORCES_FC3 or FORCES_FC2 to FORCE_SETS."""
|
"""Convert FORCES_FC3 or FORCES_FC2 to FORCE_SETS."""
|
||||||
if cell_filename is not None and is_file_phonopy_yaml(
|
if cell_filename is not None and is_file_phonopy_yaml(
|
||||||
cell_filename, keyword="phono3py"
|
cell_filename, keyword="phono3py"
|
||||||
):
|
):
|
||||||
disp_filename = cell_filename
|
disp_filename = cell_filename
|
||||||
elif input_filename is None:
|
|
||||||
disp_filename = "phono3py_disp.yaml"
|
|
||||||
else:
|
else:
|
||||||
disp_filename = f"phono3py_disp.{input_filename}.yaml"
|
disp_filename = "phono3py_disp.yaml"
|
||||||
if phonon_smat is not None:
|
if phonon_smat is not None:
|
||||||
forces_filename = "FORCES_FC2"
|
forces_filename = "FORCES_FC2"
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -229,6 +229,7 @@ def _read_files(args: argparse.Namespace) -> tuple[h5py.File, PhonopyAtoms | Non
|
||||||
cell_info = collect_cell_info(
|
cell_info = collect_cell_info(
|
||||||
supercell_matrix=np.eye(3, dtype=int),
|
supercell_matrix=np.eye(3, dtype=int),
|
||||||
phonopy_yaml_cls=Phono3pyYaml,
|
phonopy_yaml_cls=Phono3pyYaml,
|
||||||
|
load_phonopy_yaml=True,
|
||||||
)
|
)
|
||||||
cell_filename = cell_info.optional_structure_info[0]
|
cell_filename = cell_info.optional_structure_info[0]
|
||||||
print(f'# Crystal structure was read from "{cell_filename}".')
|
print(f'# Crystal structure was read from "{cell_filename}".')
|
||||||
|
|
|
@ -51,12 +51,13 @@ from phonopy.structure.cells import determinant
|
||||||
|
|
||||||
from phono3py import Phono3py
|
from phono3py import Phono3py
|
||||||
from phono3py.cui.create_force_constants import (
|
from phono3py.cui.create_force_constants import (
|
||||||
|
develop_pypolymlp,
|
||||||
parse_forces,
|
parse_forces,
|
||||||
run_pypolymlp_to_compute_forces,
|
|
||||||
)
|
)
|
||||||
from phono3py.file_IO import read_fc2_from_hdf5, read_fc3_from_hdf5
|
from phono3py.file_IO import read_fc2_from_hdf5, read_fc3_from_hdf5
|
||||||
from phono3py.interface.fc_calculator import (
|
from phono3py.interface.fc_calculator import (
|
||||||
extract_fc2_fc3_calculators,
|
extract_fc2_fc3_calculators,
|
||||||
|
extract_fc2_fc3_calculators_options,
|
||||||
update_cutoff_fc_calculator_options,
|
update_cutoff_fc_calculator_options,
|
||||||
)
|
)
|
||||||
from phono3py.interface.phono3py_yaml import Phono3pyYaml
|
from phono3py.interface.phono3py_yaml import Phono3pyYaml
|
||||||
|
@ -292,6 +293,7 @@ def load(
|
||||||
elif phono3py_yaml is not None:
|
elif phono3py_yaml is not None:
|
||||||
ph3py_yaml = Phono3pyYaml()
|
ph3py_yaml = Phono3pyYaml()
|
||||||
ph3py_yaml.read(phono3py_yaml)
|
ph3py_yaml.read(phono3py_yaml)
|
||||||
|
assert ph3py_yaml.unitcell is not None
|
||||||
cell = ph3py_yaml.unitcell.copy()
|
cell = ph3py_yaml.unitcell.copy()
|
||||||
_calculator = ph3py_yaml.calculator
|
_calculator = ph3py_yaml.calculator
|
||||||
smat = ph3py_yaml.supercell_matrix
|
smat = ph3py_yaml.supercell_matrix
|
||||||
|
@ -366,14 +368,13 @@ def load(
|
||||||
)
|
)
|
||||||
|
|
||||||
if use_pypolymlp and ph3py.fc3 is None and forces_in_dataset(ph3py.dataset):
|
if use_pypolymlp and ph3py.fc3 is None and forces_in_dataset(ph3py.dataset):
|
||||||
|
assert ph3py.dataset is not None
|
||||||
ph3py.mlp_dataset = ph3py.dataset
|
ph3py.mlp_dataset = ph3py.dataset
|
||||||
ph3py.dataset = None
|
ph3py.dataset = None
|
||||||
|
|
||||||
if produce_fc:
|
if produce_fc:
|
||||||
if ph3py.fc3 is None and use_pypolymlp:
|
if ph3py.fc3 is None and use_pypolymlp:
|
||||||
run_pypolymlp_to_compute_forces(
|
develop_pypolymlp(ph3py, mlp_params=mlp_params, log_level=log_level)
|
||||||
ph3py, mlp_params=mlp_params, log_level=log_level
|
|
||||||
)
|
|
||||||
|
|
||||||
compute_force_constants_from_datasets(
|
compute_force_constants_from_datasets(
|
||||||
ph3py,
|
ph3py,
|
||||||
|
@ -432,12 +433,11 @@ def compute_force_constants_from_datasets(
|
||||||
"""
|
"""
|
||||||
fc3_calculator = extract_fc2_fc3_calculators(fc_calculator, 3)
|
fc3_calculator = extract_fc2_fc3_calculators(fc_calculator, 3)
|
||||||
fc2_calculator = extract_fc2_fc3_calculators(fc_calculator, 2)
|
fc2_calculator = extract_fc2_fc3_calculators(fc_calculator, 2)
|
||||||
fc3_calc_opts = extract_fc2_fc3_calculators(fc_calculator_options, 3)
|
fc3_calc_opts = extract_fc2_fc3_calculators_options(fc_calculator_options, 3)
|
||||||
fc3_calc_opts = update_cutoff_fc_calculator_options(
|
fc3_calc_opts = update_cutoff_fc_calculator_options(
|
||||||
fc3_calc_opts, cutoff_pair_distance
|
fc3_calc_opts, cutoff_pair_distance
|
||||||
)
|
)
|
||||||
fc2_calc_opts = extract_fc2_fc3_calculators(fc_calculator_options, 2)
|
fc2_calc_opts = extract_fc2_fc3_calculators_options(fc_calculator_options, 2)
|
||||||
exist_fc2 = ph3py.fc2 is not None
|
|
||||||
if ph3py.fc3 is None and forces_in_dataset(ph3py.dataset):
|
if ph3py.fc3 is None and forces_in_dataset(ph3py.dataset):
|
||||||
ph3py.produce_fc3(
|
ph3py.produce_fc3(
|
||||||
symmetrize_fc3r=symmetrize_fc,
|
symmetrize_fc3r=symmetrize_fc,
|
||||||
|
@ -447,7 +447,7 @@ def compute_force_constants_from_datasets(
|
||||||
use_symfc_projector=load_phono3py_yaml,
|
use_symfc_projector=load_phono3py_yaml,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not exist_fc2:
|
if ph3py.fc2 is None or fc3_calculator != fc2_calculator:
|
||||||
if (
|
if (
|
||||||
ph3py.phonon_supercell_matrix is None and forces_in_dataset(ph3py.dataset)
|
ph3py.phonon_supercell_matrix is None and forces_in_dataset(ph3py.dataset)
|
||||||
) or (
|
) or (
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from phonopy.cui.phonopy_argparse import fix_deprecated_option_names
|
from phonopy.cui.phonopy_argparse import fix_deprecated_option_names
|
||||||
|
@ -56,7 +58,7 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--alm",
|
"--alm",
|
||||||
dest="use_alm",
|
dest="use_alm",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help=("Use ALM for generating 2nd and 3rd force constants in one fitting"),
|
help=("Use ALM for generating 2nd and 3rd force constants in one fitting"),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -178,7 +180,7 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--create-force-sets",
|
"--create-force-sets",
|
||||||
dest="force_sets_mode",
|
dest="force_sets_mode",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Create phonopy FORCE_SETS from FORCES_FC2",
|
help="Create phonopy FORCE_SETS from FORCES_FC2",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -186,7 +188,7 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--collective-phonon",
|
"--collective-phonon",
|
||||||
dest="solve_collective_phonon",
|
dest="solve_collective_phonon",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Solve collective phonons",
|
help="Solve collective phonons",
|
||||||
)
|
)
|
||||||
if load_phono3py_yaml:
|
if load_phono3py_yaml:
|
||||||
|
@ -278,14 +280,14 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--fc2",
|
"--fc2",
|
||||||
dest="read_fc2",
|
dest="read_fc2",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Read second order force constants",
|
help="Read second order force constants",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--fc3",
|
"--fc3",
|
||||||
dest="read_fc3",
|
dest="read_fc3",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Read third order force constants",
|
help="Read third order force constants",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -336,7 +338,7 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--fs2f2",
|
"--fs2f2",
|
||||||
"--force-sets-to-forces-fc2",
|
"--force-sets-to-forces-fc2",
|
||||||
dest="force_sets_to_forces_fc2_mode",
|
dest="force_sets_to_forces_fc2_mode",
|
||||||
default=False,
|
default=None,
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Create FORCES_FC2 from FORCE_SETS",
|
help="Create FORCES_FC2 from FORCE_SETS",
|
||||||
)
|
)
|
||||||
|
@ -344,7 +346,7 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--full-pp",
|
"--full-pp",
|
||||||
dest="is_full_pp",
|
dest="is_full_pp",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help=(
|
help=(
|
||||||
"Calculate full ph-ph interaction for RTA conductivity."
|
"Calculate full ph-ph interaction for RTA conductivity."
|
||||||
"This may be activated when full elements of ph-ph interaction "
|
"This may be activated when full elements of ph-ph interaction "
|
||||||
|
@ -381,14 +383,14 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--generalized-regular-grid",
|
"--generalized-regular-grid",
|
||||||
dest="use_grg",
|
dest="use_grg",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Use generalized regular grid.",
|
help="Use generalized regular grid.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--gruneisen",
|
"--gruneisen",
|
||||||
dest="is_gruneisen",
|
dest="is_gruneisen",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Calculate phonon Gruneisen parameter",
|
help="Calculate phonon Gruneisen parameter",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -404,21 +406,11 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
default=None,
|
default=None,
|
||||||
help="hdf5 compression filter (default: gzip)",
|
help="hdf5 compression filter (default: gzip)",
|
||||||
)
|
)
|
||||||
if not load_phono3py_yaml:
|
|
||||||
parser.add_argument(
|
|
||||||
"-i", dest="input_filename", default=None, help="Input filename extension"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--io",
|
|
||||||
dest="input_output_filename",
|
|
||||||
default=None,
|
|
||||||
help="Input and output filename extension",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--ion-clamped",
|
"--ion-clamped",
|
||||||
dest="ion_clamped",
|
dest="ion_clamped",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help=(
|
help=(
|
||||||
"Atoms are clamped under applied strain in Gruneisen parameter calculation"
|
"Atoms are clamped under applied strain in Gruneisen parameter calculation"
|
||||||
),
|
),
|
||||||
|
@ -427,35 +419,35 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--ise",
|
"--ise",
|
||||||
dest="is_imag_self_energy",
|
dest="is_imag_self_energy",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Calculate imaginary part of self energy",
|
help="Calculate imaginary part of self energy",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--isotope",
|
"--isotope",
|
||||||
dest="is_isotope",
|
dest="is_isotope",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Isotope scattering lifetime",
|
help="Isotope scattering lifetime",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--jdos",
|
"--jdos",
|
||||||
dest="is_joint_dos",
|
dest="is_joint_dos",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Calculate joint density of states",
|
help="Calculate joint density of states",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--kubo",
|
"--kubo",
|
||||||
dest="is_kubo_kappa",
|
dest="is_kubo_kappa",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Choose Kubo lattice thermal conductivity.",
|
help="Choose Kubo lattice thermal conductivity.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--lbte",
|
"--lbte",
|
||||||
dest="is_lbte",
|
dest="is_lbte",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="Calculate thermal conductivity LBTE with Chaput's method",
|
help="Calculate thermal conductivity LBTE with Chaput's method",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -544,7 +536,7 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
"--nomeshsym",
|
"--nomeshsym",
|
||||||
dest="is_nomeshsym",
|
dest="is_nomeshsym",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=None,
|
||||||
help="No symmetrization of triplets is made.",
|
help="No symmetrization of triplets is made.",
|
||||||
)
|
)
|
||||||
if load_phono3py_yaml:
|
if load_phono3py_yaml:
|
||||||
|
@ -593,10 +585,6 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
default=None,
|
default=None,
|
||||||
help="Output yaml filename instead of default filename of phono3py.yaml",
|
help="Output yaml filename instead of default filename of phono3py.yaml",
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
parser.add_argument(
|
|
||||||
"-o", dest="output_filename", default=None, help="Output filename extension"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--pa",
|
"--pa",
|
||||||
"--primitive-axis",
|
"--primitive-axis",
|
||||||
|
@ -739,6 +727,13 @@ def get_parser(load_phono3py_yaml: bool = False):
|
||||||
default=None,
|
default=None,
|
||||||
help="Solve reducible collision matrix",
|
help="Solve reducible collision matrix",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--relax-atomic-positions",
|
||||||
|
dest="relax_atomic_positions",
|
||||||
|
action="store_true",
|
||||||
|
default=None,
|
||||||
|
help="Relax atomic positions using polynomial MLPs",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--rse",
|
"--rse",
|
||||||
dest="is_real_self_energy",
|
dest="is_real_self_energy",
|
||||||
|
|
|
@ -40,12 +40,11 @@ import argparse
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import Optional, cast
|
from typing import cast
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.typing import NDArray
|
from numpy.typing import ArrayLike, NDArray
|
||||||
from phonopy.api_phonopy import Phonopy
|
from phonopy.api_phonopy import Phonopy
|
||||||
from phonopy.cui.phonopy_argparse import show_deprecated_option_warnings
|
from phonopy.cui.phonopy_argparse import show_deprecated_option_warnings
|
||||||
from phonopy.cui.phonopy_script import (
|
from phonopy.cui.phonopy_script import (
|
||||||
|
@ -58,17 +57,27 @@ from phonopy.cui.phonopy_script import (
|
||||||
store_nac_params,
|
store_nac_params,
|
||||||
)
|
)
|
||||||
from phonopy.cui.settings import PhonopySettings
|
from phonopy.cui.settings import PhonopySettings
|
||||||
from phonopy.exception import CellNotFoundError, ForceCalculatorRequiredError
|
from phonopy.exception import (
|
||||||
|
CellNotFoundError,
|
||||||
|
ForceCalculatorRequiredError,
|
||||||
|
PypolymlpRelaxationError,
|
||||||
|
)
|
||||||
from phonopy.file_IO import is_file_phonopy_yaml
|
from phonopy.file_IO import is_file_phonopy_yaml
|
||||||
|
from phonopy.harmonic.dynamical_matrix import DynamicalMatrixGL
|
||||||
from phonopy.harmonic.force_constants import show_drift_force_constants
|
from phonopy.harmonic.force_constants import show_drift_force_constants
|
||||||
from phonopy.interface.calculator import get_calculator_physical_units
|
from phonopy.interface.calculator import get_calculator_physical_units
|
||||||
|
from phonopy.interface.pypolymlp import get_change_in_positions, relax_atomic_positions
|
||||||
from phonopy.interface.symfc import estimate_symfc_cutoff_from_memsize
|
from phonopy.interface.symfc import estimate_symfc_cutoff_from_memsize
|
||||||
from phonopy.phonon.band_structure import get_band_qpoints
|
from phonopy.phonon.band_structure import get_band_qpoints
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
from phonopy.structure.atoms import PhonopyAtoms
|
||||||
from phonopy.structure.cells import isclose as cells_isclose
|
from phonopy.structure.cells import isclose as cells_isclose
|
||||||
|
|
||||||
from phono3py import Phono3py, Phono3pyIsotope, Phono3pyJointDos
|
from phono3py import Phono3py, Phono3pyIsotope, Phono3pyJointDos
|
||||||
from phono3py.cui.create_force_constants import run_pypolymlp_to_compute_forces
|
from phono3py.cui.create_force_constants import (
|
||||||
|
develop_pypolymlp,
|
||||||
|
generate_displacements_and_evaluate_pypolymlp,
|
||||||
|
)
|
||||||
from phono3py.cui.create_force_sets import (
|
from phono3py.cui.create_force_sets import (
|
||||||
create_FORCE_SETS_from_FORCES_FCx,
|
create_FORCE_SETS_from_FORCES_FCx,
|
||||||
create_FORCES_FC2_from_FORCE_SETS,
|
create_FORCES_FC2_from_FORCE_SETS,
|
||||||
|
@ -192,7 +201,6 @@ def _finalize_phono3py(
|
||||||
|
|
||||||
def _get_run_mode(settings: Phono3pySettings):
|
def _get_run_mode(settings: Phono3pySettings):
|
||||||
"""Extract run mode from settings."""
|
"""Extract run mode from settings."""
|
||||||
run_mode = None
|
|
||||||
if settings.is_gruneisen:
|
if settings.is_gruneisen:
|
||||||
run_mode = "gruneisen"
|
run_mode = "gruneisen"
|
||||||
elif settings.is_joint_dos:
|
elif settings.is_joint_dos:
|
||||||
|
@ -215,6 +223,8 @@ def _get_run_mode(settings: Phono3pySettings):
|
||||||
run_mode = "displacements"
|
run_mode = "displacements"
|
||||||
elif settings.write_phonon:
|
elif settings.write_phonon:
|
||||||
run_mode = "phonon"
|
run_mode = "phonon"
|
||||||
|
else:
|
||||||
|
run_mode = "force constants"
|
||||||
return run_mode
|
return run_mode
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,7 +245,7 @@ def _start_phono3py(**argparse_control) -> tuple[argparse.Namespace, int]:
|
||||||
# Title
|
# Title
|
||||||
if log_level:
|
if log_level:
|
||||||
print_phono3py()
|
print_phono3py()
|
||||||
import phono3py._phono3py as phono3c
|
import phono3py._phono3py as phono3c # type: ignore[import]
|
||||||
|
|
||||||
max_threads = phono3c.omp_max_threads()
|
max_threads = phono3c.omp_max_threads()
|
||||||
if max_threads > 0:
|
if max_threads > 0:
|
||||||
|
@ -313,33 +323,6 @@ def _read_phono3py_settings(
|
||||||
return settings, confs_dict, cell_filename
|
return settings, confs_dict, cell_filename
|
||||||
|
|
||||||
|
|
||||||
def _get_input_output_filenames_from_args(args: argparse.Namespace):
|
|
||||||
"""Return strings inserted to input and output filenames."""
|
|
||||||
if args.input_filename is not None:
|
|
||||||
warnings.warn(
|
|
||||||
"-i option is deprecated and will be removed soon.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
input_filename = args.input_filename
|
|
||||||
if args.output_filename is not None:
|
|
||||||
warnings.warn(
|
|
||||||
"-o option is deprecated and will be removed soon.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
output_filename = args.output_filename
|
|
||||||
if args.input_output_filename is not None:
|
|
||||||
warnings.warn(
|
|
||||||
"--io option is deprecated and will be removed soon.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
input_filename = args.input_output_filename
|
|
||||||
output_filename = args.input_output_filename
|
|
||||||
return input_filename, output_filename
|
|
||||||
|
|
||||||
|
|
||||||
def _get_default_values(settings: Phono3pySettings):
|
def _get_default_values(settings: Phono3pySettings):
|
||||||
"""Set default values."""
|
"""Set default values."""
|
||||||
# Brillouin zone integration: Tetrahedron (default) or smearing method
|
# Brillouin zone integration: Tetrahedron (default) or smearing method
|
||||||
|
@ -454,7 +437,7 @@ def _check_supercell_in_yaml(
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def _init_phono3py(
|
def _init_phono3py_with_cell_info(
|
||||||
settings: Phono3pySettings,
|
settings: Phono3pySettings,
|
||||||
cell_info: Phono3pyCellInfoResult,
|
cell_info: Phono3pyCellInfoResult,
|
||||||
interface_mode: str | None,
|
interface_mode: str | None,
|
||||||
|
@ -462,28 +445,54 @@ def _init_phono3py(
|
||||||
log_level: int,
|
log_level: int,
|
||||||
) -> tuple[Phono3py, dict]:
|
) -> tuple[Phono3py, dict]:
|
||||||
"""Initialize phono3py and update settings by default values."""
|
"""Initialize phono3py and update settings by default values."""
|
||||||
physical_units = get_calculator_physical_units(interface_mode)
|
|
||||||
distance_to_A = physical_units["distance_to_A"]
|
|
||||||
|
|
||||||
# Change unit of lattice parameters to angstrom
|
|
||||||
unitcell = cell_info.unitcell.copy()
|
|
||||||
if distance_to_A is not None:
|
|
||||||
lattice = unitcell.cell
|
|
||||||
lattice *= distance_to_A
|
|
||||||
unitcell.cell = lattice
|
|
||||||
|
|
||||||
# updated_settings keys
|
# updated_settings keys
|
||||||
# ('sigmas', 'temperature_points', 'temperatures',
|
# ('sigmas', 'temperature_points', 'temperatures',
|
||||||
# 'frequency_factor_to_THz', 'num_frequency_points',
|
# 'frequency_factor_to_THz', 'num_frequency_points',
|
||||||
# 'frequency_step', 'frequency_scale_factor',
|
# 'frequency_step', 'frequency_scale_factor',
|
||||||
# 'cutoff_frequency')
|
# 'cutoff_frequency')
|
||||||
|
phono3py, updated_settings, distance_to_A = _init_phono3py(
|
||||||
|
settings,
|
||||||
|
cell_info.unitcell.copy(),
|
||||||
|
supercell_matrix=cell_info.supercell_matrix,
|
||||||
|
primitive_matrix=cell_info.primitive_matrix,
|
||||||
|
phonon_supercell_matrix=cell_info.phonon_supercell_matrix,
|
||||||
|
interface_mode=interface_mode,
|
||||||
|
symprec=symprec,
|
||||||
|
log_level=log_level,
|
||||||
|
)
|
||||||
|
_check_supercell_in_yaml(cell_info, phono3py, distance_to_A, log_level)
|
||||||
|
|
||||||
|
return phono3py, updated_settings
|
||||||
|
|
||||||
|
|
||||||
|
def _init_phono3py(
|
||||||
|
settings: Phono3pySettings,
|
||||||
|
unitcell: PhonopyAtoms,
|
||||||
|
supercell_matrix: ArrayLike | None = None,
|
||||||
|
primitive_matrix: ArrayLike | None = None,
|
||||||
|
phonon_supercell_matrix: ArrayLike | None = None,
|
||||||
|
interface_mode: str | None = None,
|
||||||
|
symprec: float = 1e-5,
|
||||||
|
log_level: int = 0,
|
||||||
|
) -> tuple[Phono3py, dict, float | None]:
|
||||||
|
"""Initialize phono3py and update settings by default values."""
|
||||||
|
if interface_mode is not None:
|
||||||
|
physical_units = get_calculator_physical_units(interface_mode)
|
||||||
|
distance_to_A = physical_units["distance_to_A"]
|
||||||
|
assert distance_to_A is not None
|
||||||
|
lattice = unitcell.cell
|
||||||
|
lattice *= distance_to_A
|
||||||
|
unitcell.cell = lattice
|
||||||
|
else:
|
||||||
|
distance_to_A = None
|
||||||
|
|
||||||
updated_settings = _get_default_values(settings)
|
updated_settings = _get_default_values(settings)
|
||||||
|
|
||||||
phono3py = Phono3py(
|
phono3py = Phono3py(
|
||||||
unitcell,
|
unitcell,
|
||||||
cell_info.supercell_matrix,
|
supercell_matrix,
|
||||||
primitive_matrix=cell_info.primitive_matrix,
|
primitive_matrix=primitive_matrix,
|
||||||
phonon_supercell_matrix=cell_info.phonon_supercell_matrix,
|
phonon_supercell_matrix=phonon_supercell_matrix,
|
||||||
cutoff_frequency=updated_settings["cutoff_frequency"],
|
cutoff_frequency=updated_settings["cutoff_frequency"],
|
||||||
frequency_factor_to_THz=updated_settings["frequency_factor_to_THz"],
|
frequency_factor_to_THz=updated_settings["frequency_factor_to_THz"],
|
||||||
is_symmetry=settings.is_symmetry,
|
is_symmetry=settings.is_symmetry,
|
||||||
|
@ -498,12 +507,12 @@ def _init_phono3py(
|
||||||
phono3py.sigmas = updated_settings["sigmas"]
|
phono3py.sigmas = updated_settings["sigmas"]
|
||||||
phono3py.sigma_cutoff = settings.sigma_cutoff_width
|
phono3py.sigma_cutoff = settings.sigma_cutoff_width
|
||||||
|
|
||||||
_check_supercell_in_yaml(cell_info, phono3py, distance_to_A, log_level)
|
return phono3py, updated_settings, distance_to_A
|
||||||
|
|
||||||
return phono3py, updated_settings
|
|
||||||
|
|
||||||
|
|
||||||
def _settings_to_grid_points(settings: Phono3pySettings, bz_grid: BZGrid):
|
def _settings_to_grid_points(
|
||||||
|
settings: Phono3pySettings, bz_grid: BZGrid
|
||||||
|
) -> ArrayLike | None:
|
||||||
"""Read or set grid point indices."""
|
"""Read or set grid point indices."""
|
||||||
if settings.grid_addresses is not None:
|
if settings.grid_addresses is not None:
|
||||||
grid_points = _grid_addresses_to_grid_points(settings.grid_addresses, bz_grid)
|
grid_points = _grid_addresses_to_grid_points(settings.grid_addresses, bz_grid)
|
||||||
|
@ -514,7 +523,7 @@ def _settings_to_grid_points(settings: Phono3pySettings, bz_grid: BZGrid):
|
||||||
return grid_points
|
return grid_points
|
||||||
|
|
||||||
|
|
||||||
def _grid_addresses_to_grid_points(grid_addresses: NDArray, bz_grid: BZGrid):
|
def _grid_addresses_to_grid_points(grid_addresses: NDArray, bz_grid: BZGrid) -> NDArray:
|
||||||
"""Return grid point indices from grid addresses."""
|
"""Return grid point indices from grid addresses."""
|
||||||
grid_points = [
|
grid_points = [
|
||||||
get_grid_point_from_address(ga, bz_grid.D_diag) for ga in grid_addresses
|
get_grid_point_from_address(ga, bz_grid.D_diag) for ga in grid_addresses
|
||||||
|
@ -527,9 +536,10 @@ def _create_supercells_with_displacements(
|
||||||
cell_info: Phono3pyCellInfoResult,
|
cell_info: Phono3pyCellInfoResult,
|
||||||
confs_dict: dict,
|
confs_dict: dict,
|
||||||
unitcell_filename: str,
|
unitcell_filename: str,
|
||||||
interface_mode: Optional[str],
|
interface_mode: str | None,
|
||||||
symprec: float,
|
symprec: float = 1e-5,
|
||||||
log_level: int,
|
output_yaml_filename: str | None = None,
|
||||||
|
log_level: int = 0,
|
||||||
):
|
):
|
||||||
"""Create supercells and write displacements."""
|
"""Create supercells and write displacements."""
|
||||||
if (
|
if (
|
||||||
|
@ -537,7 +547,7 @@ def _create_supercells_with_displacements(
|
||||||
or settings.random_displacements is not None
|
or settings.random_displacements is not None
|
||||||
or settings.random_displacements_fc2 is not None
|
or settings.random_displacements_fc2 is not None
|
||||||
):
|
):
|
||||||
phono3py = create_phono3py_supercells(
|
ph3py = create_phono3py_supercells(
|
||||||
cell_info,
|
cell_info,
|
||||||
settings,
|
settings,
|
||||||
symprec,
|
symprec,
|
||||||
|
@ -547,7 +557,7 @@ def _create_supercells_with_displacements(
|
||||||
|
|
||||||
if pathlib.Path("BORN").exists():
|
if pathlib.Path("BORN").exists():
|
||||||
store_nac_params(
|
store_nac_params(
|
||||||
cast(Phonopy, phono3py),
|
cast(Phonopy, ph3py),
|
||||||
cast(PhonopySettings, settings),
|
cast(PhonopySettings, settings),
|
||||||
cell_info.phono3py_yaml,
|
cell_info.phono3py_yaml,
|
||||||
unitcell_filename,
|
unitcell_filename,
|
||||||
|
@ -556,23 +566,123 @@ def _create_supercells_with_displacements(
|
||||||
)
|
)
|
||||||
|
|
||||||
if log_level:
|
if log_level:
|
||||||
if phono3py.supercell.magnetic_moments is None:
|
if ph3py.supercell.magnetic_moments is None:
|
||||||
print("Spacegroup: %s" % phono3py.symmetry.get_international_table())
|
print("Spacegroup: %s" % ph3py.symmetry.get_international_table())
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
"Number of symmetry operations in supercell: %d"
|
"Number of symmetry operations in supercell: %d"
|
||||||
% len(phono3py.symmetry.symmetry_operations["rotations"])
|
% len(ph3py.symmetry.symmetry_operations["rotations"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ph3py.save("phono3py_disp.yaml")
|
||||||
|
if log_level > 0:
|
||||||
|
print('Displacement dataset was written in "phono3py_disp.yaml".')
|
||||||
|
|
||||||
_finalize_phono3py(
|
_finalize_phono3py(
|
||||||
phono3py,
|
ph3py,
|
||||||
confs_dict,
|
confs_dict,
|
||||||
log_level,
|
log_level,
|
||||||
write_displacements=True,
|
filename=output_yaml_filename,
|
||||||
filename="phono3py_disp.yaml",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_pypolymlp(
|
||||||
|
ph3py: Phono3py,
|
||||||
|
settings: Phono3pySettings,
|
||||||
|
confs_dict: dict,
|
||||||
|
output_yaml_filename: str | None = None,
|
||||||
|
mlp_eval_filename: str = "phono3py_mlp_eval_dataset.yaml",
|
||||||
|
log_level: int = 0,
|
||||||
|
) -> Phono3py:
|
||||||
|
assert ph3py.mlp_dataset is None
|
||||||
|
if ph3py.dataset is not None: # If None, load mlp from polymlp.yaml.
|
||||||
|
ph3py.mlp_dataset = ph3py.dataset
|
||||||
|
ph3py.dataset = None
|
||||||
|
|
||||||
|
develop_pypolymlp(
|
||||||
|
ph3py,
|
||||||
|
mlp_params=settings.mlp_params,
|
||||||
|
log_level=log_level,
|
||||||
|
)
|
||||||
|
|
||||||
|
_ph3py = ph3py
|
||||||
|
if settings.relax_atomic_positions:
|
||||||
|
if log_level:
|
||||||
|
print("Relaxing atomic positions using polynomial MLPs...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
assert ph3py.mlp is not None
|
||||||
|
relaxed_unitcell = relax_atomic_positions(
|
||||||
|
ph3py.unitcell,
|
||||||
|
ph3py.mlp.mlp,
|
||||||
|
verbose=log_level > 1,
|
||||||
|
)
|
||||||
|
except (PypolymlpRelaxationError, ValueError) as e:
|
||||||
|
# ValueError can come from pypolymlp directly.
|
||||||
|
print_error_message(str(e))
|
||||||
|
if log_level:
|
||||||
|
print_error()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if log_level:
|
||||||
|
if relaxed_unitcell is None:
|
||||||
|
print("No relaxation was performed due to symmetry constraints.")
|
||||||
|
else:
|
||||||
|
get_change_in_positions(
|
||||||
|
relaxed_unitcell, ph3py.unitcell, verbose=log_level > 0
|
||||||
|
)
|
||||||
|
print("-" * 76)
|
||||||
|
|
||||||
|
if relaxed_unitcell is not None:
|
||||||
|
if log_level:
|
||||||
|
print(
|
||||||
|
"Relaxed crystal structures will be stored in "
|
||||||
|
f'"{output_yaml_filename}".'
|
||||||
|
)
|
||||||
|
_ph3py, _, _ = _init_phono3py(
|
||||||
|
settings,
|
||||||
|
relaxed_unitcell.copy(),
|
||||||
|
supercell_matrix=ph3py.supercell_matrix,
|
||||||
|
primitive_matrix=ph3py.primitive_matrix,
|
||||||
|
phonon_supercell_matrix=ph3py.phonon_supercell_matrix,
|
||||||
|
symprec=ph3py.symmetry.tolerance,
|
||||||
|
log_level=log_level,
|
||||||
|
)
|
||||||
|
if ph3py.mesh_numbers is not None:
|
||||||
|
assert settings.mesh_numbers is not None
|
||||||
|
_ph3py.mesh_numbers = settings.mesh_numbers
|
||||||
|
_ph3py.nac_params = ph3py.nac_params
|
||||||
|
_ph3py.mlp = ph3py.mlp
|
||||||
|
|
||||||
|
if settings.create_displacements or settings.random_displacements is not None:
|
||||||
|
generate_displacements_and_evaluate_pypolymlp(
|
||||||
|
_ph3py,
|
||||||
|
displacement_distance=settings.displacement_distance,
|
||||||
|
number_of_snapshots=settings.random_displacements,
|
||||||
|
number_estimation_factor=settings.rd_number_estimation_factor,
|
||||||
|
random_seed=settings.random_seed,
|
||||||
|
fc_calculator=settings.fc_calculator,
|
||||||
|
fc_calculator_options=settings.fc_calculator_options,
|
||||||
|
cutoff_pair_distance=settings.cutoff_pair_distance,
|
||||||
|
symfc_memory_size=settings.symfc_memory_size,
|
||||||
|
log_level=log_level,
|
||||||
|
)
|
||||||
|
if log_level:
|
||||||
|
print(f'Dataset generated using MLPs was written in "{mlp_eval_filename}".')
|
||||||
|
_ph3py.save(mlp_eval_filename)
|
||||||
|
else:
|
||||||
|
if log_level:
|
||||||
|
print(
|
||||||
|
"Generate displacements (--rd or -d) for proceeding to phonon "
|
||||||
|
"calculations."
|
||||||
|
)
|
||||||
|
_finalize_phono3py(
|
||||||
|
_ph3py, confs_dict, log_level=log_level, filename=output_yaml_filename
|
||||||
|
)
|
||||||
|
|
||||||
|
return _ph3py
|
||||||
|
|
||||||
|
|
||||||
def _produce_force_constants(
|
def _produce_force_constants(
|
||||||
ph3py: Phono3py,
|
ph3py: Phono3py,
|
||||||
settings: Phono3pySettings,
|
settings: Phono3pySettings,
|
||||||
|
@ -622,7 +732,8 @@ def _produce_force_constants(
|
||||||
except ForceCalculatorRequiredError as e:
|
except ForceCalculatorRequiredError as e:
|
||||||
if load_phono3py_yaml:
|
if load_phono3py_yaml:
|
||||||
if log_level:
|
if log_level:
|
||||||
print("Symfc will be used to handle general (or random) displacements.")
|
print(str(e))
|
||||||
|
print("Try symfc to handle general (or random) displacements.")
|
||||||
else:
|
else:
|
||||||
print_error_message(str(e))
|
print_error_message(str(e))
|
||||||
if log_level:
|
if log_level:
|
||||||
|
@ -690,7 +801,9 @@ def _produce_force_constants(
|
||||||
|
|
||||||
|
|
||||||
def _run_gruneisen_then_exit(
|
def _run_gruneisen_then_exit(
|
||||||
phono3py: Phono3py, settings: Phono3pySettings, output_filename: str, log_level: int
|
phono3py: Phono3py,
|
||||||
|
settings: Phono3pySettings,
|
||||||
|
log_level: int,
|
||||||
):
|
):
|
||||||
"""Run mode Grueneisen parameter calculation from fc3."""
|
"""Run mode Grueneisen parameter calculation from fc3."""
|
||||||
if (
|
if (
|
||||||
|
@ -703,6 +816,8 @@ def _run_gruneisen_then_exit(
|
||||||
print_error()
|
print_error()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
assert phono3py.fc2 is not None
|
||||||
|
assert phono3py.fc3 is not None
|
||||||
if len(phono3py.fc2) != len(phono3py.fc3):
|
if len(phono3py.fc2) != len(phono3py.fc3):
|
||||||
print("Supercells used for fc2 and fc3 have to be same.")
|
print("Supercells used for fc2 and fc3 have to be same.")
|
||||||
if log_level:
|
if log_level:
|
||||||
|
@ -734,7 +849,6 @@ def _run_gruneisen_then_exit(
|
||||||
ion_clamped=settings.ion_clamped,
|
ion_clamped=settings.ion_clamped,
|
||||||
factor=get_physical_units().DefaultToTHz,
|
factor=get_physical_units().DefaultToTHz,
|
||||||
symprec=phono3py.symmetry.tolerance,
|
symprec=phono3py.symmetry.tolerance,
|
||||||
output_filename=output_filename,
|
|
||||||
log_level=log_level,
|
log_level=log_level,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -747,7 +861,6 @@ def _run_jdos_then_exit(
|
||||||
phono3py: Phono3py,
|
phono3py: Phono3py,
|
||||||
settings: Phono3pySettings,
|
settings: Phono3pySettings,
|
||||||
updated_settings: dict,
|
updated_settings: dict,
|
||||||
output_filename: str | None,
|
|
||||||
log_level: int,
|
log_level: int,
|
||||||
):
|
):
|
||||||
"""Run joint-DOS calculation."""
|
"""Run joint-DOS calculation."""
|
||||||
|
@ -769,15 +882,15 @@ def _run_jdos_then_exit(
|
||||||
use_grg=settings.use_grg,
|
use_grg=settings.use_grg,
|
||||||
is_mesh_symmetry=settings.is_mesh_symmetry,
|
is_mesh_symmetry=settings.is_mesh_symmetry,
|
||||||
symprec=phono3py.symmetry.tolerance,
|
symprec=phono3py.symmetry.tolerance,
|
||||||
output_filename=output_filename,
|
|
||||||
log_level=log_level,
|
log_level=log_level,
|
||||||
)
|
)
|
||||||
|
|
||||||
if log_level > 0:
|
if log_level > 0:
|
||||||
dm = joint_dos.dynamical_matrix
|
dm = joint_dos.dynamical_matrix
|
||||||
if dm.is_nac() and dm.nac_method == "gonze":
|
if isinstance(dm, DynamicalMatrixGL):
|
||||||
dm.show_Gonze_nac_message()
|
dm.show_nac_message()
|
||||||
|
|
||||||
|
assert joint_dos.grid is not None
|
||||||
grid_points = _settings_to_grid_points(settings, joint_dos.grid)
|
grid_points = _settings_to_grid_points(settings, joint_dos.grid)
|
||||||
joint_dos.run(grid_points, write_jdos=True)
|
joint_dos.run(grid_points, write_jdos=True)
|
||||||
|
|
||||||
|
@ -819,8 +932,8 @@ def _run_isotope_then_exit(
|
||||||
)
|
)
|
||||||
if log_level > 0:
|
if log_level > 0:
|
||||||
dm = iso.dynamical_matrix
|
dm = iso.dynamical_matrix
|
||||||
if dm.is_nac() and dm.nac_method == "gonze":
|
if isinstance(dm, DynamicalMatrixGL):
|
||||||
dm.show_Gonze_nac_message()
|
dm.show_nac_message()
|
||||||
|
|
||||||
grid_points = _settings_to_grid_points(settings, iso.grid)
|
grid_points = _settings_to_grid_points(settings, iso.grid)
|
||||||
iso.run(grid_points)
|
iso.run(grid_points)
|
||||||
|
@ -834,14 +947,13 @@ def _init_phph_interaction(
|
||||||
phono3py: Phono3py,
|
phono3py: Phono3py,
|
||||||
settings: Phono3pySettings,
|
settings: Phono3pySettings,
|
||||||
updated_settings: dict,
|
updated_settings: dict,
|
||||||
input_filename: str | None,
|
|
||||||
output_filename: str | None,
|
|
||||||
log_level: int,
|
log_level: int,
|
||||||
):
|
):
|
||||||
"""Initialize ph-ph interaction and phonons on grid."""
|
"""Initialize ph-ph interaction and phonons on grid."""
|
||||||
if log_level:
|
if log_level:
|
||||||
print("Generating grid system ... ", end="", flush=True)
|
print("Generating grid system ... ", end="", flush=True)
|
||||||
phono3py.mesh_numbers = settings.mesh_numbers
|
assert phono3py.grid is not None
|
||||||
|
assert phono3py.mesh_numbers is not None
|
||||||
bz_grid = phono3py.grid
|
bz_grid = phono3py.grid
|
||||||
if log_level:
|
if log_level:
|
||||||
if bz_grid.grid_matrix is None:
|
if bz_grid.grid_matrix is None:
|
||||||
|
@ -872,7 +984,7 @@ def _init_phph_interaction(
|
||||||
if log_level:
|
if log_level:
|
||||||
print("-" * 27 + " Phonon calculations " + "-" * 28)
|
print("-" * 27 + " Phonon calculations " + "-" * 28)
|
||||||
dm = phono3py.dynamical_matrix
|
dm = phono3py.dynamical_matrix
|
||||||
if dm.is_nac() and dm.nac_method == "gonze":
|
if isinstance(dm, DynamicalMatrixGL):
|
||||||
dm.show_nac_message()
|
dm.show_nac_message()
|
||||||
print("Running harmonic phonon calculations...")
|
print("Running harmonic phonon calculations...")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
@ -891,7 +1003,6 @@ def _init_phph_interaction(
|
||||||
ir_grid_points=ir_grid_points,
|
ir_grid_points=ir_grid_points,
|
||||||
ir_grid_weights=ir_grid_weights,
|
ir_grid_weights=ir_grid_weights,
|
||||||
compression=settings.hdf5_compression,
|
compression=settings.hdf5_compression,
|
||||||
filename=output_filename,
|
|
||||||
)
|
)
|
||||||
if filename:
|
if filename:
|
||||||
if log_level:
|
if log_level:
|
||||||
|
@ -903,9 +1014,7 @@ def _init_phph_interaction(
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if settings.read_phonon:
|
if settings.read_phonon:
|
||||||
phonons = read_phonon_from_hdf5(
|
phonons = read_phonon_from_hdf5(phono3py.mesh_numbers, verbose=(log_level > 0))
|
||||||
phono3py.mesh_numbers, filename=input_filename, verbose=(log_level > 0)
|
|
||||||
)
|
|
||||||
if phonons is None:
|
if phonons is None:
|
||||||
print("Reading phonons failed.")
|
print("Reading phonons failed.")
|
||||||
if log_level:
|
if log_level:
|
||||||
|
@ -971,12 +1080,10 @@ def main(**argparse_control):
|
||||||
else:
|
else:
|
||||||
args, log_level = _start_phono3py(**argparse_control)
|
args, log_level = _start_phono3py(**argparse_control)
|
||||||
|
|
||||||
|
output_yaml_filename: str | None
|
||||||
if load_phono3py_yaml:
|
if load_phono3py_yaml:
|
||||||
input_filename = None
|
|
||||||
output_filename = None
|
|
||||||
output_yaml_filename = args.output_yaml_filename
|
output_yaml_filename = args.output_yaml_filename
|
||||||
else:
|
else:
|
||||||
(input_filename, output_filename) = _get_input_output_filenames_from_args(args)
|
|
||||||
output_yaml_filename = None
|
output_yaml_filename = None
|
||||||
|
|
||||||
settings, confs_dict, cell_filename = _read_phono3py_settings(
|
settings, confs_dict, cell_filename = _read_phono3py_settings(
|
||||||
|
@ -990,7 +1097,7 @@ def main(**argparse_control):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
if args.force_sets_mode:
|
if args.force_sets_mode:
|
||||||
create_FORCE_SETS_from_FORCES_FCx(
|
create_FORCE_SETS_from_FORCES_FCx(
|
||||||
settings.phonon_supercell_matrix, input_filename, cell_filename, log_level
|
settings.phonon_supercell_matrix, cell_filename, log_level
|
||||||
)
|
)
|
||||||
if log_level:
|
if log_level:
|
||||||
print_end_phono3py()
|
print_end_phono3py()
|
||||||
|
@ -1045,6 +1152,7 @@ def main(**argparse_control):
|
||||||
|
|
||||||
if run_mode is None:
|
if run_mode is None:
|
||||||
run_mode = _get_run_mode(settings)
|
run_mode = _get_run_mode(settings)
|
||||||
|
assert run_mode is not None
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
# Create supercells with displacements and then exit #
|
# Create supercells with displacements and then exit #
|
||||||
|
@ -1056,8 +1164,9 @@ def main(**argparse_control):
|
||||||
confs_dict,
|
confs_dict,
|
||||||
unitcell_filename,
|
unitcell_filename,
|
||||||
interface_mode,
|
interface_mode,
|
||||||
symprec,
|
symprec=symprec,
|
||||||
log_level,
|
output_yaml_filename=output_yaml_filename,
|
||||||
|
log_level=log_level,
|
||||||
)
|
)
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
|
@ -1068,7 +1177,7 @@ def main(**argparse_control):
|
||||||
# 'frequency_factor_to_THz', 'num_frequency_points',
|
# 'frequency_factor_to_THz', 'num_frequency_points',
|
||||||
# 'frequency_step', 'frequency_scale_factor',
|
# 'frequency_step', 'frequency_scale_factor',
|
||||||
# 'cutoff_frequency')
|
# 'cutoff_frequency')
|
||||||
ph3py, updated_settings = _init_phono3py(
|
ph3py, updated_settings = _init_phono3py_with_cell_info(
|
||||||
settings, cell_info, interface_mode, symprec, log_level
|
settings, cell_info, interface_mode, symprec, log_level
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1081,8 +1190,6 @@ def main(**argparse_control):
|
||||||
run_mode,
|
run_mode,
|
||||||
ph3py,
|
ph3py,
|
||||||
unitcell_filename,
|
unitcell_filename,
|
||||||
input_filename,
|
|
||||||
output_filename,
|
|
||||||
interface_mode,
|
interface_mode,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1131,6 +1238,7 @@ def main(**argparse_control):
|
||||||
"show_triplets_info",
|
"show_triplets_info",
|
||||||
)
|
)
|
||||||
run_modes_with_gp = ("imag_self_energy", "real_self_energy", "jdos", "isotope")
|
run_modes_with_gp = ("imag_self_energy", "real_self_energy", "jdos", "isotope")
|
||||||
|
|
||||||
if settings.mesh_numbers is None and run_mode in run_modes_with_mesh:
|
if settings.mesh_numbers is None and run_mode in run_modes_with_mesh:
|
||||||
print("")
|
print("")
|
||||||
print("Mesh numbers have to be specified.")
|
print("Mesh numbers have to be specified.")
|
||||||
|
@ -1151,11 +1259,20 @@ def main(**argparse_control):
|
||||||
print_error()
|
print_error()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
####################
|
||||||
|
# Set mesh numbers #
|
||||||
|
####################
|
||||||
|
if run_mode in run_modes_with_mesh:
|
||||||
|
assert settings.mesh_numbers is not None
|
||||||
|
# jdos and isotope modes need to set mesh numbers differently.
|
||||||
|
if run_mode not in ("jdos", "isotope"):
|
||||||
|
ph3py.mesh_numbers = settings.mesh_numbers
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# Write ir-grid points and grid addresses and then exit #
|
# Write ir-grid points and grid addresses and then exit #
|
||||||
#########################################################
|
#########################################################
|
||||||
if run_mode == "write_grid_info":
|
if run_mode == "write_grid_info":
|
||||||
ph3py.mesh_numbers = settings.mesh_numbers
|
assert ph3py.grid is not None
|
||||||
write_grid_points(
|
write_grid_points(
|
||||||
ph3py.primitive,
|
ph3py.primitive,
|
||||||
ph3py.grid,
|
ph3py.grid,
|
||||||
|
@ -1175,7 +1292,7 @@ def main(**argparse_control):
|
||||||
# Show reduced number of triplets at grid points and then exit #
|
# Show reduced number of triplets at grid points and then exit #
|
||||||
################################################################
|
################################################################
|
||||||
if run_mode == "show_triplets_info":
|
if run_mode == "show_triplets_info":
|
||||||
ph3py.mesh_numbers = settings.mesh_numbers
|
assert ph3py.grid is not None
|
||||||
grid_points = _settings_to_grid_points(settings, ph3py.grid)
|
grid_points = _settings_to_grid_points(settings, ph3py.grid)
|
||||||
show_num_triplets(
|
show_num_triplets(
|
||||||
ph3py.primitive,
|
ph3py.primitive,
|
||||||
|
@ -1228,48 +1345,23 @@ def main(**argparse_control):
|
||||||
# polynomial MLPs #
|
# polynomial MLPs #
|
||||||
###################
|
###################
|
||||||
if settings.use_pypolymlp:
|
if settings.use_pypolymlp:
|
||||||
assert ph3py.mlp_dataset is None
|
if ph3py.fc3 is None or (
|
||||||
if ph3py.dataset is not None: # If None, load mlp from polymlp.yaml.
|
ph3py.fc2 is None and ph3py.phonon_supercell_matrix is None
|
||||||
ph3py.mlp_dataset = ph3py.dataset
|
):
|
||||||
ph3py.dataset = None
|
# Note that ph3py is replaced when relax_atomic_positions is True.
|
||||||
|
ph3py = _run_pypolymlp(
|
||||||
prepare_dataset = (
|
ph3py,
|
||||||
settings.create_displacements or settings.random_displacements is not None
|
settings,
|
||||||
)
|
confs_dict,
|
||||||
run_pypolymlp_to_compute_forces(
|
output_yaml_filename=output_yaml_filename,
|
||||||
ph3py,
|
log_level=log_level,
|
||||||
mlp_params=settings.mlp_params,
|
|
||||||
displacement_distance=settings.displacement_distance,
|
|
||||||
number_of_snapshots=settings.random_displacements,
|
|
||||||
number_estimation_factor=settings.rd_number_estimation_factor,
|
|
||||||
random_seed=settings.random_seed,
|
|
||||||
fc_calculator=settings.fc_calculator,
|
|
||||||
fc_calculator_options=settings.fc_calculator_options,
|
|
||||||
cutoff_pair_distance=settings.cutoff_pair_distance,
|
|
||||||
symfc_memory_size=settings.symfc_memory_size,
|
|
||||||
prepare_dataset=prepare_dataset,
|
|
||||||
log_level=log_level,
|
|
||||||
)
|
|
||||||
|
|
||||||
if ph3py.dataset is not None:
|
|
||||||
mlp_eval_filename = "phono3py_mlp_eval_dataset.yaml"
|
|
||||||
if log_level:
|
|
||||||
print(
|
|
||||||
"Dataset generated using MLPs was written in "
|
|
||||||
f'"{mlp_eval_filename}".'
|
|
||||||
)
|
|
||||||
ph3py.save(mlp_eval_filename)
|
|
||||||
|
|
||||||
# pypolymlp dataset is stored in "polymlp.yaml" and stop here.
|
|
||||||
if not prepare_dataset:
|
|
||||||
if log_level:
|
|
||||||
print(
|
|
||||||
"Generate displacements (--rd or -d) for proceeding to phonon "
|
|
||||||
"calculations."
|
|
||||||
)
|
|
||||||
_finalize_phono3py(
|
|
||||||
ph3py, confs_dict, log_level, filename=output_yaml_filename
|
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
if log_level:
|
||||||
|
print(
|
||||||
|
"Pypolymlp was not developed or used because fc2 and fc3 "
|
||||||
|
"are available."
|
||||||
|
)
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
# Produce force constants #
|
# Produce force constants #
|
||||||
|
@ -1280,21 +1372,19 @@ def main(**argparse_control):
|
||||||
# Phonon Gruneisen parameter and then exit #
|
# Phonon Gruneisen parameter and then exit #
|
||||||
############################################
|
############################################
|
||||||
if settings.is_gruneisen:
|
if settings.is_gruneisen:
|
||||||
_run_gruneisen_then_exit(ph3py, settings, output_filename, log_level)
|
_run_gruneisen_then_exit(ph3py, settings, log_level)
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# Show settings #
|
# Show settings #
|
||||||
#################
|
#################
|
||||||
if log_level and run_mode is not None:
|
if log_level:
|
||||||
show_phono3py_settings(ph3py, settings, updated_settings, log_level)
|
show_phono3py_settings(ph3py, settings, updated_settings, log_level)
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
# Joint DOS and then exit #
|
# Joint DOS and then exit #
|
||||||
###########################
|
###########################
|
||||||
if run_mode == "jdos":
|
if run_mode == "jdos":
|
||||||
_run_jdos_then_exit(
|
_run_jdos_then_exit(ph3py, settings, updated_settings, log_level)
|
||||||
ph3py, settings, updated_settings, output_filename, log_level
|
|
||||||
)
|
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
# Mass variances for phonon-isotope scattering #
|
# Mass variances for phonon-isotope scattering #
|
||||||
|
@ -1324,13 +1414,11 @@ def main(**argparse_control):
|
||||||
########################################
|
########################################
|
||||||
# Initialize phonon-phonon interaction #
|
# Initialize phonon-phonon interaction #
|
||||||
########################################
|
########################################
|
||||||
if run_mode is not None:
|
if run_mode in run_modes_with_mesh:
|
||||||
_init_phph_interaction(
|
_init_phph_interaction(
|
||||||
ph3py,
|
ph3py,
|
||||||
settings,
|
settings,
|
||||||
updated_settings,
|
updated_settings,
|
||||||
input_filename,
|
|
||||||
output_filename,
|
|
||||||
log_level,
|
log_level,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1338,6 +1426,7 @@ def main(**argparse_control):
|
||||||
# Run imaginary part of self energy of bubble diagram #
|
# Run imaginary part of self energy of bubble diagram #
|
||||||
#######################################################
|
#######################################################
|
||||||
if run_mode == "imag_self_energy":
|
if run_mode == "imag_self_energy":
|
||||||
|
assert ph3py.grid is not None
|
||||||
ph3py.run_imag_self_energy(
|
ph3py.run_imag_self_energy(
|
||||||
_settings_to_grid_points(settings, ph3py.grid),
|
_settings_to_grid_points(settings, ph3py.grid),
|
||||||
updated_settings["temperature_points"],
|
updated_settings["temperature_points"],
|
||||||
|
@ -1347,13 +1436,13 @@ def main(**argparse_control):
|
||||||
scattering_event_class=settings.scattering_event_class,
|
scattering_event_class=settings.scattering_event_class,
|
||||||
write_txt=True,
|
write_txt=True,
|
||||||
write_gamma_detail=settings.write_gamma_detail,
|
write_gamma_detail=settings.write_gamma_detail,
|
||||||
output_filename=output_filename,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# Run frequency shift calculation of bubble diagram #
|
# Run frequency shift calculation of bubble diagram #
|
||||||
#####################################################
|
#####################################################
|
||||||
elif run_mode == "real_self_energy":
|
elif run_mode == "real_self_energy":
|
||||||
|
assert ph3py.grid is not None
|
||||||
ph3py.run_real_self_energy(
|
ph3py.run_real_self_energy(
|
||||||
_settings_to_grid_points(settings, ph3py.grid),
|
_settings_to_grid_points(settings, ph3py.grid),
|
||||||
updated_settings["temperature_points"],
|
updated_settings["temperature_points"],
|
||||||
|
@ -1361,13 +1450,13 @@ def main(**argparse_control):
|
||||||
num_frequency_points=updated_settings["num_frequency_points"],
|
num_frequency_points=updated_settings["num_frequency_points"],
|
||||||
write_txt=True,
|
write_txt=True,
|
||||||
write_hdf5=True,
|
write_hdf5=True,
|
||||||
output_filename=output_filename,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
# Run spectral function calculation of bubble diagram #
|
# Run spectral function calculation of bubble diagram #
|
||||||
#######################################################
|
#######################################################
|
||||||
elif run_mode == "spectral_function":
|
elif run_mode == "spectral_function":
|
||||||
|
assert ph3py.grid is not None
|
||||||
ph3py.run_spectral_function(
|
ph3py.run_spectral_function(
|
||||||
_settings_to_grid_points(settings, ph3py.grid),
|
_settings_to_grid_points(settings, ph3py.grid),
|
||||||
updated_settings["temperature_points"],
|
updated_settings["temperature_points"],
|
||||||
|
@ -1376,13 +1465,13 @@ def main(**argparse_control):
|
||||||
num_points_in_batch=updated_settings["num_points_in_batch"],
|
num_points_in_batch=updated_settings["num_points_in_batch"],
|
||||||
write_txt=True,
|
write_txt=True,
|
||||||
write_hdf5=True,
|
write_hdf5=True,
|
||||||
output_filename=output_filename,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# Run lattice thermal conductivity #
|
# Run lattice thermal conductivity #
|
||||||
####################################
|
####################################
|
||||||
elif run_mode == "conductivity-RTA" or run_mode == "conductivity-LBTE":
|
elif run_mode == "conductivity-RTA" or run_mode == "conductivity-LBTE":
|
||||||
|
assert ph3py.grid is not None
|
||||||
grid_points = _settings_to_grid_points(settings, ph3py.grid)
|
grid_points = _settings_to_grid_points(settings, ph3py.grid)
|
||||||
ph3py.run_thermal_conductivity(
|
ph3py.run_thermal_conductivity(
|
||||||
is_LBTE=settings.is_lbte,
|
is_LBTE=settings.is_lbte,
|
||||||
|
@ -1412,8 +1501,6 @@ def main(**argparse_control):
|
||||||
read_pp=settings.read_pp,
|
read_pp=settings.read_pp,
|
||||||
write_LBTE_solution=settings.write_LBTE_solution,
|
write_LBTE_solution=settings.write_LBTE_solution,
|
||||||
compression=settings.hdf5_compression,
|
compression=settings.hdf5_compression,
|
||||||
input_filename=input_filename,
|
|
||||||
output_filename=output_filename,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if log_level:
|
if log_level:
|
||||||
|
|
|
@ -38,6 +38,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from phonopy.cui.settings import ConfParser, Settings, fracval
|
from phonopy.cui.settings import ConfParser, Settings, fracval
|
||||||
|
@ -81,7 +82,7 @@ class Phono3pySettings(Settings):
|
||||||
self.is_symmetrize_fc3_q = False
|
self.is_symmetrize_fc3_q = False
|
||||||
self.is_symmetrize_fc3_r = False
|
self.is_symmetrize_fc3_r = False
|
||||||
self.is_tetrahedron_method = False
|
self.is_tetrahedron_method = False
|
||||||
self.lapack_zheev_uplo = "L"
|
self.lapack_zheev_uplo: Literal["L", "U"] = "L"
|
||||||
self.mass_variances = None
|
self.mass_variances = None
|
||||||
self.max_freepath = None
|
self.max_freepath = None
|
||||||
self.num_points_in_batch = None
|
self.num_points_in_batch = None
|
||||||
|
|
|
@ -34,9 +34,10 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import Optional, Union
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from phonopy.structure.cells import print_cell
|
from phonopy.structure.cells import print_cell
|
||||||
|
@ -46,13 +47,11 @@ from phono3py.cui.settings import Phono3pySettings
|
||||||
|
|
||||||
|
|
||||||
def show_general_settings(
|
def show_general_settings(
|
||||||
settings,
|
settings: Phono3pySettings,
|
||||||
run_mode,
|
run_mode: str,
|
||||||
phono3py,
|
phono3py: Phono3py,
|
||||||
cell_filename,
|
cell_filename: str,
|
||||||
input_filename,
|
interface_mode: str | None,
|
||||||
output_filename,
|
|
||||||
interface_mode,
|
|
||||||
):
|
):
|
||||||
"""Show general setting information."""
|
"""Show general setting information."""
|
||||||
is_primitive_axes_auto = (
|
is_primitive_axes_auto = (
|
||||||
|
@ -64,12 +63,13 @@ def show_general_settings(
|
||||||
phonon_supercell_matrix = phono3py.phonon_supercell_matrix
|
phonon_supercell_matrix = phono3py.phonon_supercell_matrix
|
||||||
|
|
||||||
print("-" * 29 + " General settings " + "-" * 29)
|
print("-" * 29 + " General settings " + "-" * 29)
|
||||||
if run_mode:
|
if settings.use_pypolymlp:
|
||||||
|
if settings.create_displacements or settings.random_displacements is not None:
|
||||||
|
print(f"Run mode: pypolymlp + {run_mode}")
|
||||||
|
else:
|
||||||
|
print("Run mode: pypolymlp")
|
||||||
|
else:
|
||||||
print(f"Run mode: {run_mode}")
|
print(f"Run mode: {run_mode}")
|
||||||
if output_filename:
|
|
||||||
print(f"Output filename is modified by {output_filename}.")
|
|
||||||
if input_filename:
|
|
||||||
print(f"Input filename is modified by {input_filename}.")
|
|
||||||
if settings.hdf5_compression:
|
if settings.hdf5_compression:
|
||||||
print(f"HDF5 data compression filter: {settings.hdf5_compression}")
|
print(f"HDF5 data compression filter: {settings.hdf5_compression}")
|
||||||
if interface_mode:
|
if interface_mode:
|
||||||
|
@ -82,19 +82,18 @@ def show_general_settings(
|
||||||
|
|
||||||
print_supercell_matrix(supercell_matrix, phonon_supercell_matrix)
|
print_supercell_matrix(supercell_matrix, phonon_supercell_matrix)
|
||||||
|
|
||||||
if is_primitive_axes_auto:
|
if primitive_matrix is not None:
|
||||||
print("Primitive matrix (Auto):")
|
if is_primitive_axes_auto:
|
||||||
for v in primitive_matrix:
|
print("Primitive matrix (Auto):")
|
||||||
print(f" {v}")
|
else:
|
||||||
elif primitive_matrix is not None:
|
print("Primitive matrix:")
|
||||||
print("Primitive matrix:")
|
|
||||||
for v in primitive_matrix:
|
for v in primitive_matrix:
|
||||||
print(f" {v}")
|
print(f" {v}")
|
||||||
|
|
||||||
|
|
||||||
def print_supercell_matrix(
|
def print_supercell_matrix(
|
||||||
supercell_matrix: Union[Sequence, np.ndarray],
|
supercell_matrix: Sequence | np.ndarray,
|
||||||
phonon_supercell_matrix: Optional[Union[Sequence, np.ndarray]] = None,
|
phonon_supercell_matrix: Sequence | np.ndarray | None = None,
|
||||||
):
|
):
|
||||||
"""Print supercell matrix."""
|
"""Print supercell matrix."""
|
||||||
if (np.diag(np.diag(supercell_matrix)) - supercell_matrix).any():
|
if (np.diag(np.diag(supercell_matrix)) - supercell_matrix).any():
|
||||||
|
|
|
@ -34,10 +34,12 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
from collections.abc import Sequence
|
from __future__ import annotations
|
||||||
from typing import Optional, Union
|
|
||||||
|
import os
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike
|
||||||
from phonopy.structure.atoms import PhonopyAtoms
|
from phonopy.structure.atoms import PhonopyAtoms
|
||||||
|
|
||||||
from phono3py.file_IO import write_grid_address_to_hdf5, write_ir_grid_points
|
from phono3py.file_IO import write_grid_address_to_hdf5, write_ir_grid_points
|
||||||
|
@ -48,13 +50,13 @@ from phono3py.phonon3.triplets import get_triplets_at_q
|
||||||
def write_grid_points(
|
def write_grid_points(
|
||||||
primitive: PhonopyAtoms,
|
primitive: PhonopyAtoms,
|
||||||
bz_grid: BZGrid,
|
bz_grid: BZGrid,
|
||||||
band_indices: Optional[Union[Sequence, np.ndarray]] = None,
|
band_indices: ArrayLike | None = None,
|
||||||
sigmas: Optional[Union[Sequence, np.ndarray]] = None,
|
sigmas: ArrayLike | None = None,
|
||||||
temperatures: Optional[Union[Sequence, np.ndarray]] = None,
|
temperatures: ArrayLike | None = None,
|
||||||
is_kappa_star: bool = True,
|
is_kappa_star: bool = True,
|
||||||
is_lbte: bool = False,
|
is_lbte: bool = False,
|
||||||
compression: Union[str, int] = "gzip",
|
compression: str | int = "gzip",
|
||||||
filename: bool = None,
|
filename: str | os.PathLike | None = None,
|
||||||
):
|
):
|
||||||
"""Write grid points into files."""
|
"""Write grid points into files."""
|
||||||
ir_grid_points, ir_grid_weights = _get_ir_grid_points(
|
ir_grid_points, ir_grid_weights = _get_ir_grid_points(
|
||||||
|
@ -109,8 +111,8 @@ def write_grid_points(
|
||||||
def show_num_triplets(
|
def show_num_triplets(
|
||||||
primitive: PhonopyAtoms,
|
primitive: PhonopyAtoms,
|
||||||
bz_grid: BZGrid,
|
bz_grid: BZGrid,
|
||||||
band_indices: Optional[Union[Sequence, np.ndarray]] = None,
|
band_indices: ArrayLike | None = None,
|
||||||
grid_points: Optional[Union[Sequence, np.ndarray]] = None,
|
grid_points: ArrayLike | None = None,
|
||||||
is_kappa_star: bool = True,
|
is_kappa_star: bool = True,
|
||||||
):
|
):
|
||||||
"""Show numbers of triplets at grid points."""
|
"""Show numbers of triplets at grid points."""
|
||||||
|
|
|
@ -54,6 +54,7 @@ from phonopy.file_IO import (
|
||||||
write_FORCE_SETS,
|
write_FORCE_SETS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from phono3py.phonon.grid import BZGrid
|
||||||
from phono3py.version import __version__
|
from phono3py.version import __version__
|
||||||
|
|
||||||
|
|
||||||
|
@ -483,9 +484,9 @@ def write_grid_address_to_hdf5(
|
||||||
grid_address,
|
grid_address,
|
||||||
mesh,
|
mesh,
|
||||||
grid_mapping_table,
|
grid_mapping_table,
|
||||||
bz_grid=None,
|
bz_grid: BZGrid | None = None,
|
||||||
compression: Union[str, int] = "gzip",
|
compression: str | int = "gzip",
|
||||||
filename=None,
|
filename: str | os.PathLike | None = None,
|
||||||
):
|
):
|
||||||
"""Write grid addresses to grid_address.hdf5."""
|
"""Write grid addresses to grid_address.hdf5."""
|
||||||
suffix = _get_filename_suffix(mesh, filename=filename)
|
suffix = _get_filename_suffix(mesh, filename=filename)
|
||||||
|
@ -1155,7 +1156,7 @@ def read_gamma_from_hdf5(
|
||||||
|
|
||||||
def read_collision_from_hdf5(
|
def read_collision_from_hdf5(
|
||||||
mesh,
|
mesh,
|
||||||
indices=None,
|
indices: str | Sequence = "all",
|
||||||
grid_point=None,
|
grid_point=None,
|
||||||
band_index=None,
|
band_index=None,
|
||||||
sigma=None,
|
sigma=None,
|
||||||
|
@ -1643,7 +1644,11 @@ def parse_disp_fc3_yaml(filename="disp_fc3.yaml", return_cell=False):
|
||||||
return new_dataset
|
return new_dataset
|
||||||
|
|
||||||
|
|
||||||
def parse_FORCES_FC2(disp_dataset, filename="FORCES_FC2", unit_conversion_factor=None):
|
def parse_FORCES_FC2(
|
||||||
|
disp_dataset: dict,
|
||||||
|
filename: str | os.PathLike = "FORCES_FC2",
|
||||||
|
unit_conversion_factor: float | None = None,
|
||||||
|
):
|
||||||
"""Parse type1 FORCES_FC2 file and store forces in disp_dataset."""
|
"""Parse type1 FORCES_FC2 file and store forces in disp_dataset."""
|
||||||
num_atom = disp_dataset["natom"]
|
num_atom = disp_dataset["natom"]
|
||||||
num_disp = len(disp_dataset["first_atoms"])
|
num_disp = len(disp_dataset["first_atoms"])
|
||||||
|
@ -1664,7 +1669,10 @@ def parse_FORCES_FC2(disp_dataset, filename="FORCES_FC2", unit_conversion_factor
|
||||||
|
|
||||||
|
|
||||||
def parse_FORCES_FC3(
|
def parse_FORCES_FC3(
|
||||||
disp_dataset, filename="FORCES_FC3", use_loadtxt=False, unit_conversion_factor=None
|
disp_dataset: dict,
|
||||||
|
filename: str | os.PathLike = "FORCES_FC3",
|
||||||
|
use_loadtxt: bool = False,
|
||||||
|
unit_conversion_factor: float | None = None,
|
||||||
):
|
):
|
||||||
"""Parse type1 FORCES_FC3 and store forces in disp_dataset."""
|
"""Parse type1 FORCES_FC3 and store forces in disp_dataset."""
|
||||||
num_atom = disp_dataset["natom"]
|
num_atom = disp_dataset["natom"]
|
||||||
|
|
|
@ -116,14 +116,15 @@ class FC3Solver(FCSolver):
|
||||||
|
|
||||||
def _get_displacements_and_forces(self):
|
def _get_displacements_and_forces(self):
|
||||||
"""Return displacements and forces for fc3."""
|
"""Return displacements and forces for fc3."""
|
||||||
|
assert self._dataset is not None
|
||||||
return get_displacements_and_forces_fc3(self._dataset)
|
return get_displacements_and_forces_fc3(self._dataset)
|
||||||
|
|
||||||
|
|
||||||
def extract_fc2_fc3_calculators(
|
def extract_fc2_fc3_calculators(
|
||||||
fc_calculator: Literal["traditional", "symfc", "alm"] | str | None,
|
fc_calculator: Literal["traditional", "symfc", "alm"] | str | None,
|
||||||
order: int,
|
order: int,
|
||||||
) -> Literal["traditional", "symfc", "alm"] | str | None:
|
) -> Literal["traditional", "symfc", "alm"] | None:
|
||||||
"""Extract fc_calculator and fc_calculator_options for fc2 and fc3.
|
"""Extract fc_calculator for fc2 and fc3.
|
||||||
|
|
||||||
fc_calculator : str
|
fc_calculator : str
|
||||||
FC calculator. "|" separates fc2 and fc3. First and last
|
FC calculator. "|" separates fc2 and fc3. First and last
|
||||||
|
@ -133,20 +134,51 @@ def extract_fc2_fc3_calculators(
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fc_calculator is None:
|
if fc_calculator is None:
|
||||||
return fc_calculator
|
return None
|
||||||
elif isinstance(fc_calculator, str):
|
|
||||||
if "|" in fc_calculator:
|
|
||||||
_fc_calculator = fc_calculator.split("|")[order - 2]
|
|
||||||
if _fc_calculator == "":
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
if fc_calculator.strip() == "":
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
_fc_calculator = fc_calculator
|
|
||||||
return _fc_calculator
|
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("fc_calculator should be str or None.")
|
_fc_calculator = _split_fc_calculator_str(fc_calculator, order)
|
||||||
|
if _fc_calculator is None:
|
||||||
|
return None
|
||||||
|
fc_calculator_lower = _fc_calculator.lower()
|
||||||
|
if fc_calculator_lower not in ("traditional", "symfc", "alm"):
|
||||||
|
raise ValueError(
|
||||||
|
f"Unknown fc_calculator: {_fc_calculator}. "
|
||||||
|
"Available calculators are 'traditional', 'symfc', and 'alm'."
|
||||||
|
)
|
||||||
|
return fc_calculator_lower
|
||||||
|
|
||||||
|
|
||||||
|
def extract_fc2_fc3_calculators_options(
|
||||||
|
fc_calculator_opts: str | None,
|
||||||
|
order: int,
|
||||||
|
) -> str | None:
|
||||||
|
"""Extract fc_calculator_options for fc2 and fc3.
|
||||||
|
|
||||||
|
fc_calculator_opts : str
|
||||||
|
FC calculator options. "|" 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 fc_calculator_opts is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
_fc_calculator_opts = _split_fc_calculator_str(fc_calculator_opts, order)
|
||||||
|
return _fc_calculator_opts
|
||||||
|
|
||||||
|
|
||||||
|
def _split_fc_calculator_str(fc_calculator: str, order: int) -> str | None:
|
||||||
|
if "|" in fc_calculator:
|
||||||
|
_fc_calculator = fc_calculator.split("|")[order - 2]
|
||||||
|
if _fc_calculator == "":
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
if fc_calculator.strip() == "":
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
_fc_calculator = fc_calculator
|
||||||
|
return _fc_calculator
|
||||||
|
|
||||||
|
|
||||||
def update_cutoff_fc_calculator_options(
|
def update_cutoff_fc_calculator_options(
|
||||||
|
@ -235,6 +267,11 @@ def determine_cutoff_pair_distance(
|
||||||
"available for symfc calculator."
|
"available for symfc calculator."
|
||||||
)
|
)
|
||||||
symfc_options = {"memsize": {3: _symfc_memory_size}}
|
symfc_options = {"memsize": {3: _symfc_memory_size}}
|
||||||
|
if supercell is None or primitive is None or symmetry is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"supercell, primitive, and symmetry are required to estimate "
|
||||||
|
"cutoff_pair_distance by memory size."
|
||||||
|
)
|
||||||
update_symfc_cutoff_by_memsize(
|
update_symfc_cutoff_by_memsize(
|
||||||
symfc_options, supercell, primitive, symmetry, verbose=log_level > 0
|
symfc_options, supercell, primitive, symmetry, verbose=log_level > 0
|
||||||
)
|
)
|
||||||
|
@ -283,7 +320,7 @@ def _get_cutoff_pair_distance(
|
||||||
cutoff_pair_distance,
|
cutoff_pair_distance,
|
||||||
)
|
)
|
||||||
symfc_options = parse_symfc_options(
|
symfc_options = parse_symfc_options(
|
||||||
extract_fc2_fc3_calculators(_fc_calculator_options, 3), 3
|
extract_fc2_fc3_calculators_options(_fc_calculator_options, 3), 3
|
||||||
)
|
)
|
||||||
|
|
||||||
_cutoff_pair_distance = cutoff_pair_distance
|
_cutoff_pair_distance = cutoff_pair_distance
|
||||||
|
|
|
@ -36,9 +36,8 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Optional, Union
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike
|
||||||
from phonopy.harmonic.dynamical_matrix import get_dynamical_matrix
|
from phonopy.harmonic.dynamical_matrix import get_dynamical_matrix
|
||||||
from phonopy.phonon.tetrahedron_mesh import get_tetrahedra_frequencies
|
from phonopy.phonon.tetrahedron_mesh import get_tetrahedra_frequencies
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
@ -58,9 +57,9 @@ from phono3py.phonon.solver import run_phonon_solver_c, run_phonon_solver_py
|
||||||
|
|
||||||
|
|
||||||
def get_mass_variances(
|
def get_mass_variances(
|
||||||
primitive: Optional[PhonopyAtoms] = None,
|
primitive: PhonopyAtoms | None = None,
|
||||||
symbols: Optional[Union[list[str], tuple[str]]] = None,
|
symbols: list[str] | tuple[str] | None = None,
|
||||||
isotope_data: Optional[dict] = None,
|
isotope_data: dict | None = None,
|
||||||
):
|
):
|
||||||
"""Calculate mass variances."""
|
"""Calculate mass variances."""
|
||||||
if primitive is not None:
|
if primitive is not None:
|
||||||
|
@ -93,14 +92,14 @@ class Isotope:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
mesh,
|
mesh: float | ArrayLike,
|
||||||
primitive,
|
primitive: Primitive,
|
||||||
mass_variances=None, # length of list is num_atom.
|
mass_variances=None, # length of list is num_atom.
|
||||||
isotope_data=None,
|
isotope_data=None,
|
||||||
band_indices=None,
|
band_indices=None,
|
||||||
sigma=None,
|
sigma=None,
|
||||||
bz_grid=None,
|
bz_grid: BZGrid | None = None,
|
||||||
frequency_factor_to_THz=None,
|
frequency_factor_to_THz: float | None = None,
|
||||||
use_grg=False,
|
use_grg=False,
|
||||||
symprec=1e-5,
|
symprec=1e-5,
|
||||||
cutoff_frequency=None,
|
cutoff_frequency=None,
|
||||||
|
@ -116,7 +115,6 @@ class Isotope:
|
||||||
self._mass_variances = np.array(mass_variances, dtype="double")
|
self._mass_variances = np.array(mass_variances, dtype="double")
|
||||||
self._primitive = primitive
|
self._primitive = primitive
|
||||||
self._sigma = sigma
|
self._sigma = sigma
|
||||||
self._bz_grid = bz_grid
|
|
||||||
self._symprec = symprec
|
self._symprec = symprec
|
||||||
if cutoff_frequency is None:
|
if cutoff_frequency is None:
|
||||||
self._cutoff_frequency = 0
|
self._cutoff_frequency = 0
|
||||||
|
@ -143,7 +141,7 @@ class Isotope:
|
||||||
else:
|
else:
|
||||||
self._band_indices = np.array(band_indices, dtype="int64")
|
self._band_indices = np.array(band_indices, dtype="int64")
|
||||||
|
|
||||||
if self._bz_grid is None:
|
if bz_grid is None:
|
||||||
primitive_symmetry = Symmetry(self._primitive, self._symprec)
|
primitive_symmetry = Symmetry(self._primitive, self._symprec)
|
||||||
self._bz_grid = BZGrid(
|
self._bz_grid = BZGrid(
|
||||||
self._mesh,
|
self._mesh,
|
||||||
|
@ -152,6 +150,8 @@ class Isotope:
|
||||||
use_grg=use_grg,
|
use_grg=use_grg,
|
||||||
store_dense_gp_map=True,
|
store_dense_gp_map=True,
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
self._bz_grid = bz_grid
|
||||||
|
|
||||||
def set_grid_point(self, grid_point):
|
def set_grid_point(self, grid_point):
|
||||||
"""Initialize grid points."""
|
"""Initialize grid points."""
|
||||||
|
@ -196,8 +196,9 @@ class Isotope:
|
||||||
return self._gamma
|
return self._gamma
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bz_grid(self):
|
def bz_grid(self) -> BZGrid:
|
||||||
"""Return BZgrid class instance."""
|
"""Return BZgrid class instance."""
|
||||||
|
assert self._bz_grid is not None
|
||||||
return self._bz_grid
|
return self._bz_grid
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -144,12 +144,12 @@ class BZGrid:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
mesh: Union[int, float, Sequence, np.ndarray],
|
mesh: float | ArrayLike,
|
||||||
reciprocal_lattice=None,
|
reciprocal_lattice: ArrayLike | None = None,
|
||||||
lattice=None,
|
lattice: ArrayLike | None = None,
|
||||||
symmetry_dataset: Optional[SpglibDataset] = None,
|
symmetry_dataset: SpglibDataset | None = None,
|
||||||
transformation_matrix: Optional[Union[Sequence, np.ndarray]] = None,
|
transformation_matrix: ArrayLike | None = None,
|
||||||
is_shift: Optional[Union[list, np.ndarray]] = None,
|
is_shift: ArrayLike | None = None,
|
||||||
is_time_reversal: bool = True,
|
is_time_reversal: bool = True,
|
||||||
use_grg: bool = False,
|
use_grg: bool = False,
|
||||||
force_SNF: bool = False,
|
force_SNF: bool = False,
|
||||||
|
|
|
@ -34,7 +34,14 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from phonopy.harmonic.dynamical_matrix import (
|
||||||
|
DynamicalMatrix,
|
||||||
|
DynamicalMatrixGL,
|
||||||
|
DynamicalMatrixNAC,
|
||||||
|
)
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
from phonopy.structure.cells import sparse_to_dense_svecs
|
from phonopy.structure.cells import sparse_to_dense_svecs
|
||||||
|
|
||||||
|
@ -81,8 +88,8 @@ def run_phonon_solver_c(
|
||||||
'U' or 'L' for lapack zheev solver. Default is 'L'.
|
'U' or 'L' for lapack zheev solver. Default is 'L'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import phono3py._phono3py as phono3c
|
import phono3py._phono3py as phono3c # type: ignore[import-untyped]
|
||||||
import phono3py._phononcalc as phononcalc
|
import phono3py._phononcalc as phononcalc # type: ignore[import-untyped]
|
||||||
|
|
||||||
if frequency_conversion_factor is None:
|
if frequency_conversion_factor is None:
|
||||||
_frequency_conversion_factor = get_physical_units().DefaultToTHz
|
_frequency_conversion_factor = get_physical_units().DefaultToTHz
|
||||||
|
@ -100,7 +107,7 @@ def run_phonon_solver_c(
|
||||||
dielectric,
|
dielectric,
|
||||||
) = _extract_params(dm)
|
) = _extract_params(dm)
|
||||||
|
|
||||||
if dm.is_nac() and dm.nac_method == "gonze":
|
if isinstance(dm, DynamicalMatrixGL):
|
||||||
gonze_nac_dataset = dm.Gonze_nac_dataset
|
gonze_nac_dataset = dm.Gonze_nac_dataset
|
||||||
if gonze_nac_dataset[0] is None:
|
if gonze_nac_dataset[0] is None:
|
||||||
dm.make_Gonze_nac_dataset()
|
dm.make_Gonze_nac_dataset()
|
||||||
|
@ -112,6 +119,7 @@ def run_phonon_solver_c(
|
||||||
G_list, # List of G points where d-d interactions are integrated.
|
G_list, # List of G points where d-d interactions are integrated.
|
||||||
Lambda,
|
Lambda,
|
||||||
) = gonze_nac_dataset # Convergence parameter
|
) = gonze_nac_dataset # Convergence parameter
|
||||||
|
assert Lambda is not None
|
||||||
fc = gonze_fc
|
fc = gonze_fc
|
||||||
use_GL_NAC = True
|
use_GL_NAC = True
|
||||||
else:
|
else:
|
||||||
|
@ -120,7 +128,7 @@ def run_phonon_solver_c(
|
||||||
dd_q0 = np.zeros(2) # dummy variable
|
dd_q0 = np.zeros(2) # dummy variable
|
||||||
G_list = np.zeros(3) # dummy variable
|
G_list = np.zeros(3) # dummy variable
|
||||||
Lambda = 0 # dummy variable
|
Lambda = 0 # dummy variable
|
||||||
if not dm.is_nac():
|
if not isinstance(dm, DynamicalMatrixNAC):
|
||||||
born = np.zeros((3, 3)) # dummy variable
|
born = np.zeros((3, 3)) # dummy variable
|
||||||
dielectric = np.zeros(3) # dummy variable
|
dielectric = np.zeros(3) # dummy variable
|
||||||
fc = dm.force_constants
|
fc = dm.force_constants
|
||||||
|
@ -168,7 +176,7 @@ def run_phonon_solver_c(
|
||||||
dd_q0,
|
dd_q0,
|
||||||
G_list,
|
G_list,
|
||||||
float(Lambda),
|
float(Lambda),
|
||||||
dm.is_nac() * 1,
|
isinstance(dm, DynamicalMatrixNAC) * 1,
|
||||||
is_nac_q_zero * 1,
|
is_nac_q_zero * 1,
|
||||||
use_GL_NAC * 1,
|
use_GL_NAC * 1,
|
||||||
lapack_zheev_uplo,
|
lapack_zheev_uplo,
|
||||||
|
@ -207,14 +215,14 @@ def run_phonon_solver_py(
|
||||||
dynamical_matrix.run(q)
|
dynamical_matrix.run(q)
|
||||||
dm = dynamical_matrix.dynamical_matrix
|
dm = dynamical_matrix.dynamical_matrix
|
||||||
eigvals, eigvecs = np.linalg.eigh(dm, UPLO=lapack_zheev_uplo)
|
eigvals, eigvecs = np.linalg.eigh(dm, UPLO=lapack_zheev_uplo)
|
||||||
eigvals = eigvals.real
|
eigvals = eigvals.real # type: ignore[no-untyped-call]
|
||||||
frequencies[gp] = (
|
frequencies[gp] = (
|
||||||
np.sqrt(np.abs(eigvals)) * np.sign(eigvals) * frequency_conversion_factor
|
np.sqrt(np.abs(eigvals)) * np.sign(eigvals) * frequency_conversion_factor
|
||||||
)
|
)
|
||||||
eigenvectors[gp] = eigvecs
|
eigenvectors[gp] = eigvecs
|
||||||
|
|
||||||
|
|
||||||
def _extract_params(dm):
|
def _extract_params(dm: DynamicalMatrix | DynamicalMatrixNAC):
|
||||||
svecs, multi = dm.primitive.get_smallest_vectors()
|
svecs, multi = dm.primitive.get_smallest_vectors()
|
||||||
if dm.primitive.store_dense_svecs:
|
if dm.primitive.store_dense_svecs:
|
||||||
_svecs = svecs
|
_svecs = svecs
|
||||||
|
@ -225,7 +233,7 @@ def _extract_params(dm):
|
||||||
masses = np.array(dm.primitive.masses, dtype="double")
|
masses = np.array(dm.primitive.masses, dtype="double")
|
||||||
rec_lattice = np.array(np.linalg.inv(dm.primitive.cell), dtype="double", order="C")
|
rec_lattice = np.array(np.linalg.inv(dm.primitive.cell), dtype="double", order="C")
|
||||||
positions = np.array(dm.primitive.positions, dtype="double", order="C")
|
positions = np.array(dm.primitive.positions, dtype="double", order="C")
|
||||||
if dm.is_nac():
|
if isinstance(dm, DynamicalMatrixNAC):
|
||||||
born = dm.born
|
born = dm.born
|
||||||
nac_factor = dm.nac_factor
|
nac_factor = dm.nac_factor
|
||||||
dielectric = dm.dielectric_constant
|
dielectric = dm.dielectric_constant
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from phonopy.harmonic.dynamical_matrix import DynamicalMatrixGL
|
||||||
from phonopy.phonon.group_velocity import GroupVelocity
|
from phonopy.phonon.group_velocity import GroupVelocity
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
|
||||||
|
@ -210,11 +211,7 @@ class VelocityOperator(GroupVelocity):
|
||||||
if np.linalg.norm(q) < np.linalg.norm(delta_q):
|
if np.linalg.norm(q) < np.linalg.norm(delta_q):
|
||||||
flag_gamma = True
|
flag_gamma = True
|
||||||
|
|
||||||
if (
|
if isinstance(dynmat, DynamicalMatrixGL) and flag_gamma:
|
||||||
(self._dynmat.is_nac())
|
|
||||||
and (self._dynmat.nac_method == "gonze")
|
|
||||||
and flag_gamma
|
|
||||||
):
|
|
||||||
dynmat.run(
|
dynmat.run(
|
||||||
q - delta_q, q_direction=(q - delta_q) / np.linalg.norm(q - delta_q)
|
q - delta_q, q_direction=(q - delta_q) / np.linalg.norm(q - delta_q)
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from phonopy.harmonic.displacement import (
|
from phonopy.harmonic.displacement import (
|
||||||
directions_axis,
|
directions_axis,
|
||||||
|
@ -131,7 +135,10 @@ def direction_to_displacement(
|
||||||
|
|
||||||
|
|
||||||
def get_third_order_displacements(
|
def get_third_order_displacements(
|
||||||
cell: PhonopyAtoms, symmetry: Symmetry, is_plusminus="auto", is_diagonal=False
|
cell: PhonopyAtoms,
|
||||||
|
symmetry: Symmetry,
|
||||||
|
is_plusminus: bool | Literal["auto"] = "auto",
|
||||||
|
is_diagonal: bool = False,
|
||||||
):
|
):
|
||||||
"""Create displacement dataset.
|
"""Create displacement dataset.
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,13 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import NDArray
|
||||||
from phonopy.harmonic.force_constants import (
|
from phonopy.harmonic.force_constants import (
|
||||||
distribute_force_constants,
|
distribute_force_constants,
|
||||||
get_nsym_list_and_s2pp,
|
get_nsym_list_and_s2pp,
|
||||||
|
@ -573,30 +576,50 @@ def cutoff_fc3_by_zero(fc3, supercell, cutoff_distance, p2s_map=None, symprec=1e
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def show_drift_fc3(fc3, primitive=None, name="fc3"):
|
def show_drift_fc3(
|
||||||
"""Show drift of fc3."""
|
fc3: NDArray, primitive: Primitive | None = None, name: str = "fc3", digit: int = 8
|
||||||
|
):
|
||||||
|
"""Show max drift of fc3."""
|
||||||
|
maxval1, maxval2, maxval3, xyz1, xyz2, xyz3 = get_drift_fc3(
|
||||||
|
fc3, primitive=primitive
|
||||||
|
)
|
||||||
|
text = f"Max drift of {name}: "
|
||||||
|
text += f"{maxval1:.{digit}f} ({'xyz'[xyz1[0]]}{'xyz'[xyz1[1]]}{'xyz'[xyz1[2]]}) "
|
||||||
|
text += f"{maxval2:.{digit}f} ({'xyz'[xyz2[0]]}{'xyz'[xyz2[1]]}{'xyz'[xyz2[2]]}) "
|
||||||
|
text += f"{maxval3:.{digit}f} ({'xyz'[xyz3[0]]}{'xyz'[xyz3[1]]}{'xyz'[xyz3[2]]})"
|
||||||
|
print(text)
|
||||||
|
|
||||||
|
|
||||||
|
def get_drift_fc3(
|
||||||
|
fc3: NDArray, primitive: Primitive | None = None
|
||||||
|
) -> tuple[float, float, float, list[int], list[int], list[int]]:
|
||||||
|
"""Return max drift of fc3."""
|
||||||
if fc3.shape[0] == fc3.shape[1]:
|
if fc3.shape[0] == fc3.shape[1]:
|
||||||
num_atom = fc3.shape[0]
|
num_atom = fc3.shape[0]
|
||||||
maxval1 = 0
|
maxval1 = 0
|
||||||
maxval2 = 0
|
maxval2 = 0
|
||||||
maxval3 = 0
|
maxval3 = 0
|
||||||
klm1 = [0, 0, 0]
|
xyz1 = [0, 0, 0]
|
||||||
klm2 = [0, 0, 0]
|
xyz2 = [0, 0, 0]
|
||||||
klm3 = [0, 0, 0]
|
xyz3 = [0, 0, 0]
|
||||||
for i, j, k, ll, m in list(np.ndindex((num_atom, num_atom, 3, 3, 3))):
|
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()
|
val1 = fc3[:, i, j, k, ll, m].sum()
|
||||||
val2 = fc3[i, :, j, k, ll, m].sum()
|
val2 = fc3[i, :, j, k, ll, m].sum()
|
||||||
val3 = fc3[i, j, :, k, ll, m].sum()
|
val3 = fc3[i, j, :, k, ll, m].sum()
|
||||||
if abs(val1) > abs(maxval1):
|
if abs(val1) > abs(maxval1):
|
||||||
maxval1 = val1
|
maxval1 = val1
|
||||||
klm1 = [k, ll, m]
|
xyz1 = [k, ll, m]
|
||||||
if abs(val2) > abs(maxval2):
|
if abs(val2) > abs(maxval2):
|
||||||
maxval2 = val2
|
maxval2 = val2
|
||||||
klm2 = [k, ll, m]
|
xyz2 = [k, ll, m]
|
||||||
if abs(val3) > abs(maxval3):
|
if abs(val3) > abs(maxval3):
|
||||||
maxval3 = val3
|
maxval3 = val3
|
||||||
klm3 = [k, ll, m]
|
xyz3 = [k, ll, m]
|
||||||
else:
|
else:
|
||||||
|
if primitive is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Primitive cell is required to get drift of compact fc3."
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
import phono3py._phono3py as phono3c
|
import phono3py._phono3py as phono3c
|
||||||
|
|
||||||
|
@ -614,9 +637,9 @@ def show_drift_fc3(fc3, primitive=None, name="fc3"):
|
||||||
maxval1 = 0
|
maxval1 = 0
|
||||||
maxval2 = 0
|
maxval2 = 0
|
||||||
maxval3 = 0
|
maxval3 = 0
|
||||||
klm1 = [0, 0, 0]
|
xyz1 = [0, 0, 0]
|
||||||
klm2 = [0, 0, 0]
|
xyz2 = [0, 0, 0]
|
||||||
klm3 = [0, 0, 0]
|
xyz3 = [0, 0, 0]
|
||||||
phono3c.transpose_compact_fc3(
|
phono3c.transpose_compact_fc3(
|
||||||
fc3, permutations, s2pp_map, p2s_map, nsym_list, 0
|
fc3, permutations, s2pp_map, p2s_map, nsym_list, 0
|
||||||
) # dim[0] <--> dim[1]
|
) # dim[0] <--> dim[1]
|
||||||
|
@ -624,7 +647,7 @@ def show_drift_fc3(fc3, primitive=None, name="fc3"):
|
||||||
val1 = fc3[i, :, j, k, ll, m].sum()
|
val1 = fc3[i, :, j, k, ll, m].sum()
|
||||||
if abs(val1) > abs(maxval1):
|
if abs(val1) > abs(maxval1):
|
||||||
maxval1 = val1
|
maxval1 = val1
|
||||||
klm1 = [k, ll, m]
|
xyz1 = [k, ll, m]
|
||||||
phono3c.transpose_compact_fc3(
|
phono3c.transpose_compact_fc3(
|
||||||
fc3, permutations, s2pp_map, p2s_map, nsym_list, 0
|
fc3, permutations, s2pp_map, p2s_map, nsym_list, 0
|
||||||
) # dim[0] <--> dim[1]
|
) # dim[0] <--> dim[1]
|
||||||
|
@ -633,10 +656,10 @@ def show_drift_fc3(fc3, primitive=None, name="fc3"):
|
||||||
val3 = fc3[i, j, :, k, ll, m].sum()
|
val3 = fc3[i, j, :, k, ll, m].sum()
|
||||||
if abs(val2) > abs(maxval2):
|
if abs(val2) > abs(maxval2):
|
||||||
maxval2 = val2
|
maxval2 = val2
|
||||||
klm2 = [k, ll, m]
|
xyz2 = [k, ll, m]
|
||||||
if abs(val3) > abs(maxval3):
|
if abs(val3) > abs(maxval3):
|
||||||
maxval3 = val3
|
maxval3 = val3
|
||||||
klm3 = [k, ll, m]
|
xyz3 = [k, ll, m]
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
text = (
|
text = (
|
||||||
"Import error at phono3c.tranpose_compact_fc3. "
|
"Import error at phono3c.tranpose_compact_fc3. "
|
||||||
|
@ -644,11 +667,7 @@ def show_drift_fc3(fc3, primitive=None, name="fc3"):
|
||||||
)
|
)
|
||||||
raise RuntimeError(text) from exc
|
raise RuntimeError(text) from exc
|
||||||
|
|
||||||
text = "Max drift of %s: " % name
|
return maxval1, maxval2, maxval3, xyz1, xyz2, xyz3
|
||||||
text += "%f (%s%s%s) " % (maxval1, "xyz"[klm1[0]], "xyz"[klm1[1]], "xyz"[klm1[2]])
|
|
||||||
text += "%f (%s%s%s) " % (maxval2, "xyz"[klm2[0]], "xyz"[klm2[1]], "xyz"[klm2[2]])
|
|
||||||
text += "%f (%s%s%s)" % (maxval3, "xyz"[klm3[0]], "xyz"[klm3[1]], "xyz"[klm3[2]])
|
|
||||||
print(text)
|
|
||||||
|
|
||||||
|
|
||||||
def _set_permutation_symmetry_fc3_elem_with_cutoff(fc3, fc3_done, a, b, c):
|
def _set_permutation_symmetry_fc3_elem_with_cutoff(fc3, fc3_done, a, b, c):
|
||||||
|
|
|
@ -37,7 +37,11 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from phonopy.harmonic.dynamical_matrix import get_dynamical_matrix
|
from phonopy.harmonic.dynamical_matrix import (
|
||||||
|
DynamicalMatrixGL,
|
||||||
|
DynamicalMatrixNAC,
|
||||||
|
get_dynamical_matrix,
|
||||||
|
)
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
from phonopy.structure.atoms import PhonopyAtoms
|
from phonopy.structure.atoms import PhonopyAtoms
|
||||||
from phonopy.structure.cells import Primitive
|
from phonopy.structure.cells import Primitive
|
||||||
|
@ -96,8 +100,8 @@ def run_gruneisen_parameters(
|
||||||
|
|
||||||
if log_level > 0:
|
if log_level > 0:
|
||||||
dm = gruneisen.dynamical_matrix
|
dm = gruneisen.dynamical_matrix
|
||||||
if dm.is_nac() and dm.nac_method == "gonze":
|
if isinstance(dm, DynamicalMatrixGL):
|
||||||
dm.show_Gonze_nac_message()
|
dm.show_nac_message()
|
||||||
|
|
||||||
if mesh is not None:
|
if mesh is not None:
|
||||||
gruneisen.set_sampling_mesh(mesh, rotations=rotations, is_gamma_center=True)
|
gruneisen.set_sampling_mesh(mesh, rotations=rotations, is_gamma_center=True)
|
||||||
|
@ -310,7 +314,7 @@ class Gruneisen:
|
||||||
gruneisen_parameters = []
|
gruneisen_parameters = []
|
||||||
frequencies = []
|
frequencies = []
|
||||||
for i, q in enumerate(qpoints):
|
for i, q in enumerate(qpoints):
|
||||||
if self._dm.is_nac():
|
if isinstance(self._dm, DynamicalMatrixNAC):
|
||||||
if (np.abs(q) < 1e-5).all(): # If q is almost at Gamma
|
if (np.abs(q) < 1e-5).all(): # If q is almost at Gamma
|
||||||
if self._run_mode == "band":
|
if self._run_mode == "band":
|
||||||
# Direction estimated from neighboring point
|
# Direction estimated from neighboring point
|
||||||
|
|
|
@ -34,11 +34,14 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from typing import List, Optional
|
from collections.abc import Sequence
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike, NDArray
|
||||||
from phonopy.phonon.degeneracy import degenerate_sets
|
from phonopy.phonon.degeneracy import degenerate_sets
|
||||||
from phonopy.physical_units import get_physical_units
|
from phonopy.physical_units import get_physical_units
|
||||||
|
|
||||||
|
@ -576,20 +579,20 @@ class ImagSelfEnergy:
|
||||||
|
|
||||||
def get_imag_self_energy(
|
def get_imag_self_energy(
|
||||||
interaction: Interaction,
|
interaction: Interaction,
|
||||||
grid_points,
|
grid_points: ArrayLike,
|
||||||
temperatures,
|
temperatures: ArrayLike,
|
||||||
sigmas=None,
|
sigmas: Sequence[float | None] | None = None,
|
||||||
frequency_points=None,
|
frequency_points: ArrayLike | None = None,
|
||||||
frequency_step=None,
|
frequency_step: float | None = None,
|
||||||
num_frequency_points=None,
|
num_frequency_points: int | None = None,
|
||||||
frequency_points_at_bands=False,
|
frequency_points_at_bands: bool = False,
|
||||||
num_points_in_batch=None,
|
num_points_in_batch: int | None = None,
|
||||||
scattering_event_class=None, # class 1 or 2
|
scattering_event_class: int | None = None, # class 1 or 2
|
||||||
write_gamma_detail=False,
|
write_gamma_detail: bool = False,
|
||||||
return_gamma_detail=False,
|
return_gamma_detail: bool = False,
|
||||||
output_filename=None,
|
output_filename: str | None = None,
|
||||||
log_level=0,
|
log_level: int = 0,
|
||||||
):
|
) -> tuple[NDArray | None, NDArray, Sequence]:
|
||||||
"""Imaginary-part of self-energy at frequency points.
|
"""Imaginary-part of self-energy at frequency points.
|
||||||
|
|
||||||
Band indices to be calculated at are found in Interaction instance.
|
Band indices to be calculated at are found in Interaction instance.
|
||||||
|
@ -599,12 +602,12 @@ def get_imag_self_energy(
|
||||||
interaction : Interaction
|
interaction : Interaction
|
||||||
Ph-ph interaction.
|
Ph-ph interaction.
|
||||||
grid_points : array_like
|
grid_points : array_like
|
||||||
Grid-point indices where imag-self-energeis are caclculated.
|
Grid-point indices where imag-self-energies are calculated.
|
||||||
dtype=int, shape=(grid_points,)
|
dtype=int, shape=(grid_points,)
|
||||||
temperatures : array_like
|
temperatures : array_like
|
||||||
Temperatures where imag-self-energies are calculated.
|
Temperatures where imag-self-energies are calculated.
|
||||||
dtype=float, shape=(temperatures,)
|
dtype=float, shape=(temperatures,)
|
||||||
sigmas : array_like, optional
|
sigmas : Sequence, optional
|
||||||
A set of sigmas. simgas=[None, ] means to use tetrahedron method,
|
A set of sigmas. simgas=[None, ] means to use tetrahedron method,
|
||||||
otherwise smearing method with real positive value of sigma.
|
otherwise smearing method with real positive value of sigma.
|
||||||
For example, sigmas=[None, 0.01, 0.03] is possible. Default is None,
|
For example, sigmas=[None, 0.01, 0.03] is possible. Default is None,
|
||||||
|
@ -671,9 +674,7 @@ def get_imag_self_energy(
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if sigmas is None:
|
if sigmas is None:
|
||||||
_sigmas = [
|
_sigmas = [None]
|
||||||
None,
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
_sigmas = sigmas
|
_sigmas = sigmas
|
||||||
|
|
||||||
|
@ -718,7 +719,7 @@ def get_imag_self_energy(
|
||||||
order="C",
|
order="C",
|
||||||
)
|
)
|
||||||
|
|
||||||
detailed_gamma: List[Optional[np.ndarray]] = []
|
detailed_gamma = []
|
||||||
|
|
||||||
ise = ImagSelfEnergy(
|
ise = ImagSelfEnergy(
|
||||||
interaction, with_detail=(write_gamma_detail or return_gamma_detail)
|
interaction, with_detail=(write_gamma_detail or return_gamma_detail)
|
||||||
|
@ -771,10 +772,7 @@ def get_imag_self_energy(
|
||||||
log_level,
|
log_level,
|
||||||
)
|
)
|
||||||
|
|
||||||
if return_gamma_detail:
|
return _frequency_points, gamma, detailed_gamma
|
||||||
return _frequency_points, gamma, detailed_gamma
|
|
||||||
else:
|
|
||||||
return _frequency_points, gamma
|
|
||||||
|
|
||||||
|
|
||||||
def _get_imag_self_energy_at_gp(
|
def _get_imag_self_energy_at_gp(
|
||||||
|
|
|
@ -34,4 +34,4 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
__version__ = "3.17.1"
|
__version__ = "3.18.0"
|
||||||
|
|
|
@ -16,7 +16,7 @@ dependencies = [
|
||||||
"matplotlib",
|
"matplotlib",
|
||||||
"h5py",
|
"h5py",
|
||||||
"spglib",
|
"spglib",
|
||||||
"phonopy>=2.41,<2.42",
|
"phonopy>=2.42,<2.43",
|
||||||
]
|
]
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
license-files = ["LICENSE"]
|
license-files = ["LICENSE"]
|
||||||
|
|
|
@ -6,9 +6,11 @@ from pathlib import Path
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
|
from phonopy.harmonic.force_constants import get_drift_force_constants
|
||||||
from phonopy.interface.pypolymlp import PypolymlpParams
|
from phonopy.interface.pypolymlp import PypolymlpParams
|
||||||
|
|
||||||
from phono3py import Phono3py
|
from phono3py import Phono3py
|
||||||
|
from phono3py.phonon3.fc3 import get_drift_fc3
|
||||||
|
|
||||||
cwd = Path(__file__).parent
|
cwd = Path(__file__).parent
|
||||||
|
|
||||||
|
@ -207,3 +209,63 @@ def test_use_pypolymlp_mgo(mgo_222rd_444rd: Phono3py):
|
||||||
assert (
|
assert (
|
||||||
pytest.approx(63.0018546, abs=1e-1) == ph3.thermal_conductivity.kappa[0, 0, 0]
|
pytest.approx(63.0018546, abs=1e-1) == ph3.thermal_conductivity.kappa[0, 0, 0]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("is_compact_fc", [True, False])
|
||||||
|
def test_symmetrize_fc_traditional(si_pbesol: Phono3py, is_compact_fc: bool):
|
||||||
|
"""Test symmetrize_fc3 and symmetrize_fc2 with traditional approach."""
|
||||||
|
ph3 = Phono3py(
|
||||||
|
si_pbesol.unitcell,
|
||||||
|
supercell_matrix=si_pbesol.supercell_matrix,
|
||||||
|
primitive_matrix=si_pbesol.primitive_matrix,
|
||||||
|
log_level=2,
|
||||||
|
)
|
||||||
|
ph3.dataset = si_pbesol.dataset
|
||||||
|
ph3.produce_fc3(is_compact_fc=is_compact_fc)
|
||||||
|
assert ph3.fc3 is not None
|
||||||
|
assert ph3.fc2 is not None
|
||||||
|
|
||||||
|
v1, v2, v3, _, _, _ = get_drift_fc3(ph3.fc3, primitive=ph3.primitive)
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
np.abs([v1, v2, v3]), [1.755065e-01, 1.749287e-01, 3.333333e-05], atol=1e-6
|
||||||
|
)
|
||||||
|
ph3.symmetrize_fc3(options="level=3")
|
||||||
|
v1_sym, v2_sym, v3_sym, _, _, _ = get_drift_fc3(ph3.fc3, primitive=ph3.primitive)
|
||||||
|
if is_compact_fc:
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
np.abs([v1_sym, v2_sym, v3_sym]), 1.217081e-05, atol=1e-6
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
np.abs([v1_sym, v2_sym, v3_sym]), 1.421085e-14, atol=1e-6
|
||||||
|
)
|
||||||
|
|
||||||
|
v1_sym, v2_sym, _, _ = get_drift_force_constants(ph3.fc2, primitive=ph3.primitive)
|
||||||
|
if is_compact_fc:
|
||||||
|
np.testing.assert_allclose(np.abs([v1_sym, v2_sym]), 1.0e-06, atol=1e-6)
|
||||||
|
else:
|
||||||
|
np.testing.assert_allclose(np.abs([v1_sym, v2_sym]), 1.0e-06, atol=1e-6)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("is_compact_fc", [True, False])
|
||||||
|
def test_symmetrize_fc_symfc(si_pbesol: Phono3py, is_compact_fc: bool):
|
||||||
|
"""Test symmetrize_fc3 and symmetrize_fc2 with symfc."""
|
||||||
|
pytest.importorskip("symfc")
|
||||||
|
|
||||||
|
ph3 = Phono3py(
|
||||||
|
si_pbesol.unitcell,
|
||||||
|
supercell_matrix=si_pbesol.supercell_matrix,
|
||||||
|
primitive_matrix=si_pbesol.primitive_matrix,
|
||||||
|
log_level=2,
|
||||||
|
)
|
||||||
|
ph3.dataset = si_pbesol.dataset
|
||||||
|
ph3.produce_fc3(is_compact_fc=is_compact_fc)
|
||||||
|
assert ph3.fc3 is not None
|
||||||
|
assert ph3.fc2 is not None
|
||||||
|
|
||||||
|
ph3.symmetrize_fc3(use_symfc_projector=True)
|
||||||
|
v1_sym, v2_sym, v3_sym, _, _, _ = get_drift_fc3(ph3.fc3, primitive=ph3.primitive)
|
||||||
|
np.testing.assert_allclose([v1_sym, v2_sym, v3_sym], 0, atol=1e-6)
|
||||||
|
ph3.symmetrize_fc2(use_symfc_projector=True)
|
||||||
|
v1_sym, v2_sym, _, _ = get_drift_force_constants(ph3.fc2, primitive=ph3.primitive)
|
||||||
|
np.testing.assert_allclose([v1_sym, v2_sym], 0, atol=1e-6)
|
||||||
|
|
|
@ -72,7 +72,7 @@ def test_cutoff_fc3_zero_compact_fc(nacl_pbe_compact_fc: Phono3py):
|
||||||
fc3 = ph.fc3.copy()
|
fc3 = ph.fc3.copy()
|
||||||
cutoff_fc3_by_zero(fc3, ph.supercell, 5, p2s_map=ph.primitive.p2s_map)
|
cutoff_fc3_by_zero(fc3, ph.supercell, 5, p2s_map=ph.primitive.p2s_map)
|
||||||
abs_delta = np.abs(ph.fc3 - fc3).sum()
|
abs_delta = np.abs(ph.fc3 - fc3).sum()
|
||||||
assert np.abs(164.359250 - abs_delta) < 1e-3
|
assert np.abs(164.350663 - abs_delta) < 1e-3
|
||||||
|
|
||||||
|
|
||||||
def test_fc3(si_pbesol_111: Phono3py):
|
def test_fc3(si_pbesol_111: Phono3py):
|
||||||
|
|
|
@ -25,7 +25,7 @@ def test_imag_self_energy_at_bands(si_pbesol: Phono3py):
|
||||||
[0.00382813, 0.0049497, 0.02727924, 0.01382784, 0.04133946, 0.02980282],
|
[0.00382813, 0.0049497, 0.02727924, 0.01382784, 0.04133946, 0.02980282],
|
||||||
]
|
]
|
||||||
for i, grgp in enumerate((1, 103)):
|
for i, grgp in enumerate((1, 103)):
|
||||||
_, gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
[
|
[
|
||||||
si_pbesol.grid.grg2bzg[grgp],
|
si_pbesol.grid.grg2bzg[grgp],
|
||||||
],
|
],
|
||||||
|
@ -35,7 +35,9 @@ def test_imag_self_energy_at_bands(si_pbesol: Phono3py):
|
||||||
frequency_points_at_bands=True,
|
frequency_points_at_bands=True,
|
||||||
)
|
)
|
||||||
# print(gammas.ravel())
|
# print(gammas.ravel())
|
||||||
np.testing.assert_allclose(gammas.ravel(), gammas_ref[i], rtol=0, atol=1e-2)
|
np.testing.assert_allclose(
|
||||||
|
ise_params.gammas.ravel(), gammas_ref[i], rtol=0, atol=1e-2
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_imag_self_energy_at_bands_detailed(si_pbesol: Phono3py):
|
def test_imag_self_energy_at_bands_detailed(si_pbesol: Phono3py):
|
||||||
|
@ -47,7 +49,7 @@ def test_imag_self_energy_at_bands_detailed(si_pbesol: Phono3py):
|
||||||
"""
|
"""
|
||||||
si_pbesol.mesh_numbers = [9, 9, 9]
|
si_pbesol.mesh_numbers = [9, 9, 9]
|
||||||
si_pbesol.init_phph_interaction()
|
si_pbesol.init_phph_interaction()
|
||||||
_, gammas, detailed_gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
si_pbesol.grid.grg2bzg[[1, 103]],
|
si_pbesol.grid.grg2bzg[[1, 103]],
|
||||||
[
|
[
|
||||||
300,
|
300,
|
||||||
|
@ -145,10 +147,14 @@ def test_imag_self_energy_at_bands_detailed(si_pbesol: Phono3py):
|
||||||
]
|
]
|
||||||
weights_103 = [2] * 364 + [1]
|
weights_103 = [2] * 364 + [1]
|
||||||
|
|
||||||
gammas_1_ref = gammas[:, :, 0].ravel()
|
gammas_1_ref = ise_params.gammas[:, :, 0].ravel()
|
||||||
gammas_103_ref = gammas[:, :, 1].ravel()
|
gammas_103_ref = ise_params.gammas[:, :, 1].ravel()
|
||||||
gammas_1 = np.dot(weights_1, detailed_gammas[0][0, 0].sum(axis=-1).sum(axis=-1))
|
gammas_1 = np.dot(
|
||||||
gammas_103 = np.dot(weights_103, detailed_gammas[1][0, 0].sum(axis=-1).sum(axis=-1))
|
weights_1, ise_params.detailed_gammas[0][0, 0].sum(axis=-1).sum(axis=-1)
|
||||||
|
)
|
||||||
|
gammas_103 = np.dot(
|
||||||
|
weights_103, ise_params.detailed_gammas[1][0, 0].sum(axis=-1).sum(axis=-1)
|
||||||
|
)
|
||||||
np.testing.assert_allclose(
|
np.testing.assert_allclose(
|
||||||
gammas_1[:2].sum(), gammas_1_ref[:2].sum(), rtol=0, atol=1e-2
|
gammas_1[:2].sum(), gammas_1_ref[:2].sum(), rtol=0, atol=1e-2
|
||||||
)
|
)
|
||||||
|
@ -477,7 +483,7 @@ def test_imag_self_energy_npoints(si_pbesol: Phono3py, with_given_freq_points: b
|
||||||
si_pbesol.mesh_numbers = [9, 9, 9]
|
si_pbesol.mesh_numbers = [9, 9, 9]
|
||||||
si_pbesol.init_phph_interaction()
|
si_pbesol.init_phph_interaction()
|
||||||
if with_given_freq_points:
|
if with_given_freq_points:
|
||||||
fpoints, gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
si_pbesol.grid.grg2bzg[[1, 103]],
|
si_pbesol.grid.grg2bzg[[1, 103]],
|
||||||
[
|
[
|
||||||
300,
|
300,
|
||||||
|
@ -485,7 +491,7 @@ def test_imag_self_energy_npoints(si_pbesol: Phono3py, with_given_freq_points: b
|
||||||
frequency_points=ref_freq_points,
|
frequency_points=ref_freq_points,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
fpoints, gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
si_pbesol.grid.grg2bzg[[1, 103]],
|
si_pbesol.grid.grg2bzg[[1, 103]],
|
||||||
[
|
[
|
||||||
300,
|
300,
|
||||||
|
@ -497,8 +503,12 @@ def test_imag_self_energy_npoints(si_pbesol: Phono3py, with_given_freq_points: b
|
||||||
# for line in gammas.reshape(-1, 10):
|
# for line in gammas.reshape(-1, 10):
|
||||||
# print("[", ",".join([f"{val:.8f}" for val in line]), "],")
|
# print("[", ",".join([f"{val:.8f}" for val in line]), "],")
|
||||||
|
|
||||||
np.testing.assert_allclose(ref_gammas, gammas.reshape(-1, 10), rtol=0, atol=1e-2)
|
np.testing.assert_allclose(
|
||||||
np.testing.assert_allclose(ref_freq_points, fpoints.ravel(), rtol=0, atol=1e-5)
|
ref_gammas, ise_params.gammas.reshape(-1, 10), rtol=0, atol=1e-2
|
||||||
|
)
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
ref_freq_points, ise_params.frequency_points.ravel(), rtol=0, atol=1e-5
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_imag_self_energy_npoints_with_sigma(si_pbesol: Phono3py):
|
def test_imag_self_energy_npoints_with_sigma(si_pbesol: Phono3py):
|
||||||
|
@ -820,7 +830,7 @@ def test_imag_self_energy_npoints_with_sigma(si_pbesol: Phono3py):
|
||||||
]
|
]
|
||||||
si_pbesol.mesh_numbers = [9, 9, 9]
|
si_pbesol.mesh_numbers = [9, 9, 9]
|
||||||
si_pbesol.init_phph_interaction()
|
si_pbesol.init_phph_interaction()
|
||||||
fpoints, gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
si_pbesol.grid.grg2bzg[[1, 103]],
|
si_pbesol.grid.grg2bzg[[1, 103]],
|
||||||
[
|
[
|
||||||
300,
|
300,
|
||||||
|
@ -832,8 +842,12 @@ def test_imag_self_energy_npoints_with_sigma(si_pbesol: Phono3py):
|
||||||
# for line in gammas.reshape(-1, 10):
|
# for line in gammas.reshape(-1, 10):
|
||||||
# print("[", ",".join([f"{val:.8f}" for val in line]), "],")
|
# print("[", ",".join([f"{val:.8f}" for val in line]), "],")
|
||||||
|
|
||||||
np.testing.assert_allclose(ref_gammas, gammas.reshape(-1, 10), rtol=0, atol=1e-2)
|
np.testing.assert_allclose(
|
||||||
np.testing.assert_allclose(ref_freq_points, fpoints.ravel(), rtol=0, atol=1e-5)
|
ref_gammas, ise_params.gammas.reshape(-1, 10), rtol=0, atol=1e-2
|
||||||
|
)
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
ref_freq_points, ise_params.frequency_points.ravel(), rtol=0, atol=1e-5
|
||||||
|
)
|
||||||
si_pbesol.sigmas = None
|
si_pbesol.sigmas = None
|
||||||
|
|
||||||
|
|
||||||
|
@ -884,7 +898,7 @@ def test_imag_self_energy_detailed(si_pbesol: Phono3py):
|
||||||
]
|
]
|
||||||
si_pbesol.mesh_numbers = [9, 9, 9]
|
si_pbesol.mesh_numbers = [9, 9, 9]
|
||||||
si_pbesol.init_phph_interaction()
|
si_pbesol.init_phph_interaction()
|
||||||
_, _, detailed_gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
si_pbesol.grid.grg2bzg[
|
si_pbesol.grid.grg2bzg[
|
||||||
[
|
[
|
||||||
1,
|
1,
|
||||||
|
@ -898,13 +912,16 @@ def test_imag_self_energy_detailed(si_pbesol: Phono3py):
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
",".join(
|
",".join(
|
||||||
[f"{val:.8f}" for val in detailed_gammas[0][0, 0].sum(axis=(1, 2, 3, 4))]
|
[
|
||||||
|
f"{val:.8f}"
|
||||||
|
for val in ise_params.detailed_gammas[0][0, 0].sum(axis=(1, 2, 3, 4))
|
||||||
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
np.testing.assert_allclose(
|
np.testing.assert_allclose(
|
||||||
ref_detailed_gamma,
|
ref_detailed_gamma,
|
||||||
detailed_gammas[0][0, 0].sum(axis=(1, 2, 3, 4)),
|
ise_params.detailed_gammas[0][0, 0].sum(axis=(1, 2, 3, 4)),
|
||||||
rtol=0,
|
rtol=0,
|
||||||
atol=1e-2,
|
atol=1e-2,
|
||||||
)
|
)
|
||||||
|
@ -1428,7 +1445,7 @@ def test_imag_self_energy_scat_classes(si_pbesol: Phono3py, scattering_class: in
|
||||||
|
|
||||||
si_pbesol.mesh_numbers = [9, 9, 9]
|
si_pbesol.mesh_numbers = [9, 9, 9]
|
||||||
si_pbesol.init_phph_interaction()
|
si_pbesol.init_phph_interaction()
|
||||||
_, gammas = si_pbesol.run_imag_self_energy(
|
ise_params = si_pbesol.run_imag_self_energy(
|
||||||
si_pbesol.grid.grg2bzg[[1, 103]],
|
si_pbesol.grid.grg2bzg[[1, 103]],
|
||||||
[
|
[
|
||||||
300,
|
300,
|
||||||
|
@ -1441,7 +1458,7 @@ def test_imag_self_energy_scat_classes(si_pbesol: Phono3py, scattering_class: in
|
||||||
|
|
||||||
np.testing.assert_allclose(
|
np.testing.assert_allclose(
|
||||||
gammas_classes[scattering_class - 1],
|
gammas_classes[scattering_class - 1],
|
||||||
gammas.ravel(),
|
ise_params.gammas.ravel(),
|
||||||
rtol=0,
|
rtol=0,
|
||||||
atol=1e-2,
|
atol=1e-2,
|
||||||
)
|
)
|
||||||
|
@ -1714,7 +1731,7 @@ def test_imag_self_energy_nacl_npoints(nacl_pbe: Phono3py):
|
||||||
|
|
||||||
nacl_pbe.mesh_numbers = [9, 9, 9]
|
nacl_pbe.mesh_numbers = [9, 9, 9]
|
||||||
nacl_pbe.init_phph_interaction()
|
nacl_pbe.init_phph_interaction()
|
||||||
fpoints, gammas = nacl_pbe.run_imag_self_energy(
|
ise_params = nacl_pbe.run_imag_self_energy(
|
||||||
nacl_pbe.grid.grg2bzg[[1, 103]],
|
nacl_pbe.grid.grg2bzg[[1, 103]],
|
||||||
[
|
[
|
||||||
300,
|
300,
|
||||||
|
@ -1724,8 +1741,12 @@ def test_imag_self_energy_nacl_npoints(nacl_pbe: Phono3py):
|
||||||
|
|
||||||
# print(",".join([f"{val:.8f}" for val in gammas.ravel()]))
|
# print(",".join([f"{val:.8f}" for val in gammas.ravel()]))
|
||||||
|
|
||||||
np.testing.assert_allclose(ref_gammas_nacl, gammas.ravel(), rtol=0, atol=2e-2)
|
np.testing.assert_allclose(
|
||||||
np.testing.assert_allclose(ref_freq_points_nacl, fpoints.ravel(), rtol=0, atol=1e-5)
|
ref_gammas_nacl, ise_params.gammas.ravel(), rtol=0, atol=2e-2
|
||||||
|
)
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
ref_freq_points_nacl, ise_params.frequency_points.ravel(), rtol=0, atol=1e-5
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_imag_self_energy_nacl_nac_npoints(nacl_pbe: Phono3py):
|
def test_imag_self_energy_nacl_nac_npoints(nacl_pbe: Phono3py):
|
||||||
|
@ -1876,13 +1897,15 @@ def test_imag_self_energy_nacl_nac_npoints(nacl_pbe: Phono3py):
|
||||||
|
|
||||||
nacl_pbe.mesh_numbers = [9, 9, 9]
|
nacl_pbe.mesh_numbers = [9, 9, 9]
|
||||||
nacl_pbe.init_phph_interaction(nac_q_direction=[1, 0, 0])
|
nacl_pbe.init_phph_interaction(nac_q_direction=[1, 0, 0])
|
||||||
fpoints, gammas = nacl_pbe.run_imag_self_energy(
|
ise_params = nacl_pbe.run_imag_self_energy(
|
||||||
[nacl_pbe.grid.gp_Gamma], [300], num_frequency_points=10
|
[nacl_pbe.grid.gp_Gamma], [300], num_frequency_points=10
|
||||||
)
|
)
|
||||||
|
|
||||||
# print(",".join([f"{val:.8f}" for val in gammas.ravel()]))
|
# print(",".join([f"{val:.8f}" for val in gammas.ravel()]))
|
||||||
|
|
||||||
np.testing.assert_allclose(
|
np.testing.assert_allclose(
|
||||||
ref_freq_points_nacl_nac, fpoints.ravel(), rtol=0, atol=1e-5
|
ref_freq_points_nacl_nac, ise_params.frequency_points.ravel(), rtol=0, atol=1e-5
|
||||||
|
)
|
||||||
|
np.testing.assert_allclose(
|
||||||
|
ref_gammas_nacl_nac, ise_params.gammas.ravel(), rtol=0, atol=2e-2
|
||||||
)
|
)
|
||||||
np.testing.assert_allclose(ref_gammas_nacl_nac, gammas.ravel(), rtol=0, atol=2e-2)
|
|
||||||
|
|
Loading…
Reference in New Issue