Run ph-ph interaction calculation with fc3-nonzero-indices

This commit is contained in:
Atsushi Togo 2025-06-06 13:05:44 +09:00
parent 748a9692aa
commit cbd410ac4c
12 changed files with 190 additions and 87 deletions

View File

@ -50,18 +50,17 @@ static Darray *convert_to_darray(nb::ndarray<> npyary) {
// printf("Data shift:%lu [%lu, %lu]\n", adrs_shift, i_sigma, i_temp);
// }
void py_get_interaction(nb::ndarray<> py_fc3_normal_squared,
nb::ndarray<> py_g_zero, nb::ndarray<> py_frequencies,
nb::ndarray<> py_eigenvectors,
nb::ndarray<> py_triplets,
nb::ndarray<> py_bz_grid_addresses,
nb::ndarray<> py_D_diag, nb::ndarray<> py_Q,
nb::ndarray<> py_fc3, nb::ndarray<> py_svecs,
nb::ndarray<> py_multi, nb::ndarray<> py_masses,
nb::ndarray<> py_p2s_map, nb::ndarray<> py_s2p_map,
nb::ndarray<> py_band_indices, int64_t symmetrize_fc3_q,
int64_t make_r0_average, nb::ndarray<> py_all_shortest,
double cutoff_frequency, int64_t openmp_per_triplets) {
void py_get_interaction(
nb::ndarray<> py_fc3_normal_squared, nb::ndarray<> py_g_zero,
nb::ndarray<> py_frequencies, nb::ndarray<> py_eigenvectors,
nb::ndarray<> py_triplets, nb::ndarray<> py_bz_grid_addresses,
nb::ndarray<> py_D_diag, nb::ndarray<> py_Q, nb::ndarray<> py_fc3,
nb::ndarray<> py_fc3_nonzero_indices, nb::ndarray<> py_svecs,
nb::ndarray<> py_multi, nb::ndarray<> py_masses, nb::ndarray<> py_p2s_map,
nb::ndarray<> py_s2p_map, nb::ndarray<> py_band_indices,
int64_t symmetrize_fc3_q, int64_t make_r0_average,
nb::ndarray<> py_all_shortest, double cutoff_frequency,
int64_t openmp_per_triplets) {
Darray *fc3_normal_squared;
Darray *freqs;
_lapack_complex_double *eigvecs;
@ -72,6 +71,7 @@ void py_get_interaction(nb::ndarray<> py_fc3_normal_squared,
int64_t *D_diag;
int64_t (*Q)[3];
double *fc3;
char *fc3_nonzero_indices;
double (*svecs)[3];
int64_t (*multi)[2];
double *masses;
@ -100,6 +100,7 @@ void py_get_interaction(nb::ndarray<> py_fc3_normal_squared,
} else {
is_compact_fc3 = 1;
}
fc3_nonzero_indices = (char *)py_fc3_nonzero_indices.data();
svecs = (double (*)[3])py_svecs.data();
for (i = 0; i < 2; i++) {
multi_dims[i] = py_multi.shape(i);
@ -113,9 +114,10 @@ void py_get_interaction(nb::ndarray<> py_fc3_normal_squared,
ph3py_get_interaction(fc3_normal_squared, g_zero, freqs, eigvecs, triplets,
num_triplets, bz_grid_addresses, D_diag, Q, fc3,
is_compact_fc3, svecs, multi_dims, multi, masses, p2s,
s2p, band_indices, symmetrize_fc3_q, make_r0_average,
all_shortest, cutoff_frequency, openmp_per_triplets);
fc3_nonzero_indices, is_compact_fc3, svecs,
multi_dims, multi, masses, p2s, s2p, band_indices,
symmetrize_fc3_q, make_r0_average, all_shortest,
cutoff_frequency, openmp_per_triplets);
free(fc3_normal_squared);
fc3_normal_squared = NULL;
@ -129,8 +131,9 @@ void py_get_pp_collision(
nb::ndarray<> py_triplets, nb::ndarray<> py_triplet_weights,
nb::ndarray<> py_bz_grid_addresses, nb::ndarray<> py_bz_map,
int64_t bz_grid_type, nb::ndarray<> py_D_diag, nb::ndarray<> py_Q,
nb::ndarray<> py_fc3, nb::ndarray<> py_svecs, nb::ndarray<> py_multi,
nb::ndarray<> py_masses, nb::ndarray<> py_p2s_map, nb::ndarray<> py_s2p_map,
nb::ndarray<> py_fc3, nb::ndarray<> py_fc3_nonzero_indices,
nb::ndarray<> py_svecs, nb::ndarray<> py_multi, nb::ndarray<> py_masses,
nb::ndarray<> py_p2s_map, nb::ndarray<> py_s2p_map,
nb::ndarray<> py_band_indices, nb::ndarray<> py_temperatures_THz,
int64_t is_NU, int64_t symmetrize_fc3_q, int64_t make_r0_average,
nb::ndarray<> py_all_shortest, double cutoff_frequency,
@ -147,6 +150,7 @@ void py_get_pp_collision(
int64_t *D_diag;
int64_t (*Q)[3];
double *fc3;
char *fc3_nonzero_indices;
double (*svecs)[3];
int64_t (*multi)[2];
double *masses;
@ -176,6 +180,7 @@ void py_get_pp_collision(
} else {
is_compact_fc3 = 1;
}
fc3_nonzero_indices = (char *)py_fc3_nonzero_indices.data();
svecs = (double (*)[3])py_svecs.data();
for (i = 0; i < 2; i++) {
multi_dims[i] = py_multi.shape(i);
@ -191,9 +196,10 @@ void py_get_pp_collision(
ph3py_get_pp_collision(
gamma, relative_grid_address, frequencies, eigenvectors, triplets,
num_triplets, triplet_weights, bz_grid_addresses, bz_map, bz_grid_type,
D_diag, Q, fc3, is_compact_fc3, svecs, multi_dims, multi, masses, p2s,
s2p, band_indices, temperatures_THz, is_NU, symmetrize_fc3_q,
make_r0_average, all_shortest, cutoff_frequency, openmp_per_triplets);
D_diag, Q, fc3, fc3_nonzero_indices, is_compact_fc3, svecs, multi_dims,
multi, masses, p2s, s2p, band_indices, temperatures_THz, is_NU,
symmetrize_fc3_q, make_r0_average, all_shortest, cutoff_frequency,
openmp_per_triplets);
free(band_indices);
band_indices = NULL;
@ -206,7 +212,8 @@ void py_get_pp_collision_with_sigma(
nb::ndarray<> py_frequencies, nb::ndarray<> py_eigenvectors,
nb::ndarray<> py_triplets, nb::ndarray<> py_triplet_weights,
nb::ndarray<> py_bz_grid_addresses, nb::ndarray<> py_D_diag,
nb::ndarray<> py_Q, nb::ndarray<> py_fc3, nb::ndarray<> py_svecs,
nb::ndarray<> py_Q, nb::ndarray<> py_fc3,
nb::ndarray<> py_fc3_nonzero_indices, nb::ndarray<> py_svecs,
nb::ndarray<> py_multi, nb::ndarray<> py_masses, nb::ndarray<> py_p2s_map,
nb::ndarray<> py_s2p_map, nb::ndarray<> py_band_indices,
nb::ndarray<> py_temperatures_THz, int64_t is_NU, int64_t symmetrize_fc3_q,
@ -222,6 +229,7 @@ void py_get_pp_collision_with_sigma(
int64_t *D_diag;
int64_t (*Q)[3];
double *fc3;
char *fc3_nonzero_indices;
double (*svecs)[3];
int64_t (*multi)[2];
double *masses;
@ -249,6 +257,7 @@ void py_get_pp_collision_with_sigma(
} else {
is_compact_fc3 = 1;
}
fc3_nonzero_indices = (char *)py_fc3_nonzero_indices.data();
svecs = (double (*)[3])py_svecs.data();
for (i = 0; i < 2; i++) {
multi_dims[i] = py_multi.shape(i);
@ -264,8 +273,8 @@ void py_get_pp_collision_with_sigma(
ph3py_get_pp_collision_with_sigma(
gamma, sigma, sigma_cutoff, frequencies, eigenvectors, triplets,
num_triplets, triplet_weights, bz_grid_addresses, D_diag, Q, fc3,
is_compact_fc3, svecs, multi_dims, multi, masses, p2s, s2p,
band_indices, temperatures_THz, is_NU, symmetrize_fc3_q,
fc3_nonzero_indices, is_compact_fc3, svecs, multi_dims, multi, masses,
p2s, s2p, band_indices, temperatures_THz, is_NU, symmetrize_fc3_q,
make_r0_average, all_shortest, cutoff_frequency, openmp_per_triplets);
free(band_indices);

View File

@ -63,12 +63,13 @@ int64_t ph3py_get_interaction(
const _lapack_complex_double *eigenvectors, const int64_t (*triplets)[3],
const int64_t num_triplets, const int64_t (*bz_grid_addresses)[3],
const int64_t D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3],
const int64_t multi_dims[2], const int64_t (*multiplicity)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const int64_t *band_indices, const int64_t symmetrize_fc3_q,
const int64_t make_r0_average, const char *all_shortest,
const double cutoff_frequency, const int64_t openmp_per_triplets) {
const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const double (*svecs)[3], const int64_t multi_dims[2],
const int64_t (*multiplicity)[2], const double *masses,
const int64_t *p2s_map, const int64_t *s2p_map, const int64_t *band_indices,
const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets) {
RecgridConstBZGrid *bzgrid;
AtomTriplets *atom_triplets;
int64_t i, j;
@ -102,6 +103,7 @@ int64_t ph3py_get_interaction(
atom_triplets->s2p_map = s2p_map;
atom_triplets->make_r0_average = make_r0_average;
atom_triplets->all_shortest = all_shortest;
atom_triplets->nonzero_indices = fc3_nonzero_indices;
itr_get_interaction(fc3_normal_squared, g_zero, frequencies,
(lapack_complex_double *)eigenvectors, triplets,
@ -127,7 +129,8 @@ int64_t ph3py_get_pp_collision(
const int64_t (*bz_grid_addresses)[3], /* thm */
const int64_t *bz_map, /* thm */
const int64_t bz_grid_type, const int64_t D_diag[3], const int64_t Q[3][3],
const double *fc3, const int64_t is_compact_fc3, const double (*svecs)[3],
const double *fc3, const char *fc3_nonzero_indices,
const int64_t is_compact_fc3, const double (*svecs)[3],
const int64_t multi_dims[2], const int64_t (*multiplicity)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const Larray *band_indices, const Darray *temperatures_THz,
@ -169,6 +172,7 @@ int64_t ph3py_get_pp_collision(
atom_triplets->s2p_map = s2p_map;
atom_triplets->make_r0_average = make_r0_average;
atom_triplets->all_shortest = all_shortest;
atom_triplets->nonzero_indices = fc3_nonzero_indices;
ppc_get_pp_collision(imag_self_energy, relative_grid_address, frequencies,
(lapack_complex_double *)eigenvectors, triplets,
@ -192,13 +196,14 @@ int64_t ph3py_get_pp_collision_with_sigma(
const int64_t (*triplets)[3], const int64_t num_triplets,
const int64_t *triplet_weights, const int64_t (*bz_grid_addresses)[3],
const int64_t D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3],
const int64_t multi_dims[2], const int64_t (*multiplicity)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const Larray *band_indices, const Darray *temperatures_THz,
const int64_t is_NU, const int64_t symmetrize_fc3_q,
const int64_t make_r0_average, const char *all_shortest,
const double cutoff_frequency, const int64_t openmp_per_triplets) {
const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const double (*svecs)[3], const int64_t multi_dims[2],
const int64_t (*multiplicity)[2], const double *masses,
const int64_t *p2s_map, const int64_t *s2p_map, const Larray *band_indices,
const Darray *temperatures_THz, const int64_t is_NU,
const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets) {
RecgridConstBZGrid *bzgrid;
AtomTriplets *atom_triplets;
int64_t i, j;
@ -232,6 +237,7 @@ int64_t ph3py_get_pp_collision_with_sigma(
atom_triplets->s2p_map = s2p_map;
atom_triplets->make_r0_average = make_r0_average;
atom_triplets->all_shortest = all_shortest;
atom_triplets->nonzero_indices = fc3_nonzero_indices;
ppc_get_pp_collision_with_sigma(
imag_self_energy, sigma, sigma_cutoff, frequencies,

View File

@ -53,12 +53,13 @@ int64_t ph3py_get_interaction(
const _lapack_complex_double *eigenvectors, const int64_t (*triplets)[3],
const int64_t num_triplets, const int64_t (*bz_grid_addresses)[3],
const int64_t D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3],
const int64_t multi_dims[2], const int64_t (*multi)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const int64_t *band_indices, const int64_t symmetrize_fc3_q,
const int64_t make_r0_average, const char *all_shortest,
const double cutoff_frequency, const int64_t openmp_per_triplets);
const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const double (*svecs)[3], const int64_t multi_dims[2],
const int64_t (*multi)[2], const double *masses, const int64_t *p2s_map,
const int64_t *s2p_map, const int64_t *band_indices,
const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets);
int64_t ph3py_get_pp_collision(
double *imag_self_energy,
const int64_t relative_grid_address[24][4][3], /* thm */
@ -68,7 +69,8 @@ int64_t ph3py_get_pp_collision(
const int64_t (*bz_grid_addresses)[3], /* thm */
const int64_t *bz_map, /* thm */
const int64_t bz_grid_type, const int64_t D_diag[3], const int64_t Q[3][3],
const double *fc3, const int64_t is_compact_fc3, const double (*svecs)[3],
const double *fc3, const char *fc3_nonzero_indices,
const int64_t is_compact_fc3, const double (*svecs)[3],
const int64_t multi_dims[2], const int64_t (*multi)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const Larray *band_indices, const Darray *temperatures_THz,
@ -81,13 +83,14 @@ int64_t ph3py_get_pp_collision_with_sigma(
const int64_t (*triplets)[3], const int64_t num_triplets,
const int64_t *triplet_weights, const int64_t (*bz_grid_addresses)[3],
const int64_t D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3],
const int64_t multi_dims[2], const int64_t (*multi)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const Larray *band_indices, const Darray *temperatures_THz,
const int64_t is_NU, const int64_t symmetrize_fc3_q,
const int64_t make_r0_average, const char *all_shortest,
const double cutoff_frequency, const int64_t openmp_per_triplets);
const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const double (*svecs)[3], const int64_t multi_dims[2],
const int64_t (*multi)[2], const double *masses, const int64_t *p2s_map,
const int64_t *s2p_map, const Larray *band_indices,
const Darray *temperatures_THz, const int64_t is_NU,
const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets);
void ph3py_get_imag_self_energy_at_bands_with_g(
double *imag_self_energy, const Darray *fc3_normal_squared,
const double *frequencies, const int64_t (*triplets)[3],

View File

@ -277,7 +277,7 @@ static void real_to_reciprocal_elements(
const int64_t pi0, const int64_t pi1, const int64_t pi2,
const int64_t leg_index) {
int64_t i, j, k, l;
int64_t num_satom, adrs_shift;
int64_t num_satom, adrs_shift_atoms, adrs_shift_fc3;
lapack_complex_double phase_factor;
double fc3_rec_real[27], fc3_rec_imag[27];
@ -309,8 +309,11 @@ static void real_to_reciprocal_elements(
continue;
}
}
adrs_shift =
i * 27 * num_satom * num_satom + j * 27 * num_satom + k * 27;
adrs_shift_atoms = i * num_satom * num_satom + j * num_satom + k;
if (!atom_triplets->nonzero_indices[adrs_shift_atoms]) {
continue;
}
adrs_shift_fc3 = adrs_shift_atoms * 27;
phase_factor =
phonoc_complex_prod(phase_factor1[j], phase_factor2[k]);
@ -320,19 +323,19 @@ static void real_to_reciprocal_elements(
for (l = 0; l < 27; l++) {
fc3_rec_real[l] +=
lapack_complex_double_real(phase_factor) *
fc3[adrs_shift + l] * 3;
fc3[adrs_shift_fc3 + l] * 3;
fc3_rec_imag[l] +=
lapack_complex_double_imag(phase_factor) *
fc3[adrs_shift + l] * 3;
fc3[adrs_shift_fc3 + l] * 3;
}
} else {
for (l = 0; l < 27; l++) {
fc3_rec_real[l] +=
lapack_complex_double_real(phase_factor) *
fc3[adrs_shift + l];
fc3[adrs_shift_fc3 + l];
fc3_rec_imag[l] +=
lapack_complex_double_imag(phase_factor) *
fc3[adrs_shift + l];
fc3[adrs_shift_fc3 + l];
}
}
}

View File

@ -48,6 +48,7 @@ typedef struct {
const int64_t *s2p_map;
int64_t make_r0_average;
const char *all_shortest;
const char *nonzero_indices; // for compact fc3
} AtomTriplets;
void r2r_real_to_reciprocal(lapack_complex_double *fc3_reciprocal,

View File

@ -1138,7 +1138,7 @@ class Phono3py:
`None` will choose one of them automatically.
"""
if self.mesh_numbers is None:
if self._bz_grid is None:
msg = "Phono3py.mesh_numbers of instance has to be set."
raise RuntimeError(msg)
@ -1151,6 +1151,7 @@ class Phono3py:
self._bz_grid,
self._primitive_symmetry,
fc3=self._fc3,
fc3_nonzero_indices=self._fc3_nonzero_indices,
band_indices=self._band_indices_flatten,
constant_averaged_interaction=constant_averaged_interaction,
frequency_factor_to_THz=self._frequency_factor_to_THz,

View File

@ -328,7 +328,6 @@ class ConductivityRTABase(ConductivityBase):
s2p,
masses,
) = self._pp.get_primitive_and_supercell_correspondence()
fc3 = self._pp.fc3
triplets_at_q, weights_at_q, _, _ = self._pp.get_triplets_at_q()
if None in self._sigmas:
@ -384,7 +383,8 @@ class ConductivityRTABase(ConductivityBase):
self._pp.bz_grid.store_dense_gp_map * 1 + 1,
self._pp.bz_grid.D_diag,
self._pp.bz_grid.Q,
fc3,
self._pp.fc3,
self._pp.fc3_nonzero_indices,
svecs,
multi,
masses,
@ -415,7 +415,8 @@ class ConductivityRTABase(ConductivityBase):
self._pp.bz_grid.addresses,
self._pp.bz_grid.D_diag,
self._pp.bz_grid.Q,
fc3,
self._pp.fc3,
self._pp.fc3_nonzero_indices,
svecs,
multi,
masses,

View File

@ -509,7 +509,7 @@ def _load_fc3(
assert "fc3_nonzero_indices" in fc3
ph3py.fc3_nonzero_indices = fc3["fc3_nonzero_indices"]
if log_level:
print(f'fc3 and nonzero indices were read from "{_fc3_filename}".')
print(f'fc3 and fc3 nonzero indices were read from "{_fc3_filename}".')
else:
_check_fc3_shape(ph3py, fc3, filename=_fc3_filename)
ph3py.fc3 = fc3

View File

@ -36,9 +36,10 @@
from __future__ import annotations
from collections.abc import Sequence
from typing import Literal, Optional
from typing import Literal
import numpy as np
from numpy.typing import NDArray
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, get_dynamical_matrix
from phonopy.physical_units import get_physical_units
from phonopy.structure.cells import Primitive, compute_all_sg_permutations
@ -93,8 +94,9 @@ class Interaction:
primitive: Primitive,
bz_grid: BZGrid,
primitive_symmetry: Symmetry,
fc3: np.ndarray | None = None,
band_indices: np.ndarray | Sequence | None = None,
fc3: NDArray | None = None,
fc3_nonzero_indices: NDArray | None = None,
band_indices: NDArray | Sequence | None = None,
constant_averaged_interaction: float | None = None,
frequency_factor_to_THz: float | None = None,
frequency_scale_factor: float | None = None,
@ -120,7 +122,7 @@ class Interaction:
self._frequency_scale_factor = frequency_scale_factor
if fc3 is not None:
self._set_fc3(fc3)
self._set_fc3(fc3, fc3_nonzero_indices=fc3_nonzero_indices)
# Unit to eV^2
if unit_conversion is None:
@ -180,9 +182,7 @@ class Interaction:
)
self._get_all_shortest()
def run(
self, lang: Literal["C", "Python"] = "C", g_zero: Optional[np.ndarray] = None
):
def run(self, lang: Literal["C", "Python"] = "C", g_zero: NDArray | None = None):
"""Run ph-ph interaction calculation."""
if self._phonon_all_done:
self.run_phonon_solver()
@ -209,7 +209,7 @@ class Interaction:
)
@property
def interaction_strength(self) -> np.ndarray | None:
def interaction_strength(self) -> NDArray | None:
"""Return ph-ph interaction strength.
Returns
@ -222,7 +222,7 @@ class Interaction:
return self._interaction_strength
@property
def mesh_numbers(self) -> np.ndarray:
def mesh_numbers(self) -> NDArray:
"""Return mesh numbers.
Returns
@ -239,10 +239,15 @@ class Interaction:
return self._is_mesh_symmetry
@property
def fc3(self) -> np.ndarray:
def fc3(self) -> NDArray:
"""Return fc3."""
return self._fc3
@property
def fc3_nonzero_indices(self) -> NDArray:
"""Return fc3_nonzero_indices."""
return self._fc3_nonzero_indices
@property
def dynamical_matrix(self) -> DynamicalMatrix | None:
"""Return DynamicalMatrix class instance."""
@ -273,10 +278,10 @@ class Interaction:
def get_triplets_at_q(
self,
) -> tuple[
np.ndarray | None,
np.ndarray | None,
np.ndarray | None,
np.ndarray | None,
NDArray | None,
NDArray | None,
NDArray | None,
NDArray | None,
]:
"""Return grid point triplets information.
@ -299,7 +304,7 @@ class Interaction:
return self._bz_grid
@property
def band_indices(self) -> np.ndarray:
def band_indices(self) -> NDArray:
"""Return band indices.
Returns
@ -316,7 +321,7 @@ class Interaction:
return self._nac_params
@property
def nac_q_direction(self) -> np.ndarray | None:
def nac_q_direction(self) -> NDArray | None:
"""Return q-direction used for NAC at q->0.
Direction of q-vector watching from Gamma point used for
@ -337,7 +342,7 @@ class Interaction:
self._nac_q_direction = np.array(nac_q_direction, copy=True, dtype="double")
@property
def zero_value_positions(self) -> np.ndarray | None:
def zero_value_positions(self) -> NDArray | None:
"""Return zero ph-ph interaction elements information.
Returns
@ -349,7 +354,7 @@ class Interaction:
def get_phonons(
self,
) -> tuple[np.ndarray | None, np.ndarray | None, np.ndarray | None]:
) -> tuple[NDArray | None, NDArray | None, NDArray | None]:
"""Return phonons on grid.
Returns
@ -407,7 +412,7 @@ class Interaction:
return self._make_r0_average
@property
def all_shortest(self) -> np.ndarray:
def all_shortest(self) -> NDArray:
"""Return boolean of make_r0_average.
This flag is used to activate averaging of fc3 transformation
@ -419,7 +424,7 @@ class Interaction:
return self._all_shortest
@property
def averaged_interaction(self) -> np.ndarray:
def averaged_interaction(self) -> NDArray:
"""Return sum over phonon triplets of interaction strength.
See Eq.(21) of PRB 91, 094306 (2015)
@ -439,7 +444,7 @@ class Interaction:
def get_primitive_and_supercell_correspondence(
self,
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[NDArray, NDArray, NDArray, NDArray, NDArray]:
"""Return atomic pair information."""
return (self._svecs, self._multi, self._p2s, self._s2p, self._masses)
@ -449,7 +454,7 @@ class Interaction:
return self._unit_conversion
@property
def constant_averaged_interaction(self) -> Optional[float]:
def constant_averaged_interaction(self) -> float | None:
"""Return constant averaged interaction."""
return self._constant_averaged_interaction
@ -817,7 +822,7 @@ class Interaction:
self._interaction_strength = None
self._g_zero = None
def _set_fc3(self, fc3):
def _set_fc3(self, fc3: NDArray, fc3_nonzero_indices: NDArray | None = None):
if (
isinstance(fc3, np.ndarray)
and fc3.dtype == np.dtype("double")
@ -834,7 +839,24 @@ class Interaction:
fc3 * self._frequency_scale_factor**2, dtype="double", order="C"
)
def _get_band_indices(self, band_indices) -> np.ndarray:
if fc3_nonzero_indices is None:
self._fc3_nonzero_indices = np.ones(
self._fc3.shape[:3], dtype="byte", order="C"
)
elif (
isinstance(fc3_nonzero_indices, np.ndarray)
and fc3_nonzero_indices.dtype == np.dtype("byte")
and fc3_nonzero_indices.flags.aligned
and fc3_nonzero_indices.flags.owndata
and fc3_nonzero_indices.flags.c_contiguous
):
self._fc3_nonzero_indices = fc3_nonzero_indices
else:
self._fc3_nonzero_indices = np.array(
fc3_nonzero_indices, dtype="byte", order="C"
)
def _get_band_indices(self, band_indices) -> NDArray:
num_band = len(self._primitive) * 3
if band_indices is None:
return np.arange(num_band, dtype="int64")
@ -877,6 +899,7 @@ class Interaction:
self._bz_grid.D_diag,
self._bz_grid.Q,
self._fc3,
self._fc3_nonzero_indices,
self._svecs,
self._multi,
self._masses,

View File

@ -276,6 +276,18 @@ def test_kappa_RTA_nacl(nacl_pbe: Phono3py):
np.testing.assert_allclose(ref_kappa_RTA, kappa, atol=0.5)
def test_kappa_RTA_mgo(
mgo_222rd_444rd_symfc: Phono3py, mgo_222rd_444rd_symfc_compact_fc: Phono3py
):
"""Test RTA by MgO cutoff 4."""
for ph3 in (mgo_222rd_444rd_symfc, mgo_222rd_444rd_symfc_compact_fc):
ref_kappa_RTA = [63.75, 63.75, 63.75, 0, 0, 0]
kappa = _get_kappa(ph3, [11, 11, 11]).ravel()
np.testing.assert_allclose(ref_kappa_RTA, kappa, atol=0.5)
kappa = _get_kappa(ph3, [11, 11, 11], is_full_pp=True).ravel()
np.testing.assert_allclose(ref_kappa_RTA, kappa, atol=0.5)
def test_kappa_RTA_nacl_with_sigma(nacl_pbe: Phono3py):
"""Test RTA with smearing method by NaCl."""
if nacl_pbe._make_r0_average:

View File

@ -566,6 +566,48 @@ def mgo_222rd_444rd() -> Phono3py:
return phono3py.load(yaml_filename, produce_fc=False, log_level=1)
@pytest.fixture(scope="session")
def mgo_222rd_444rd_symfc() -> Phono3py:
"""Return Phono3py instance of MgO-2x2x2-4x4x4 RD-RD.
* with symmetry
* full fc
* use symfc if available on test side
"""
pytest.importorskip("symfc")
yaml_filename = cwd / "phono3py_params_MgO-222rd-444rd.yaml.xz"
return phono3py.load(
yaml_filename,
is_compact_fc=False,
fc_calculator="symfc",
fc_calculator_options="|cutoff = 4",
log_level=1,
)
@pytest.fixture(scope="session")
def mgo_222rd_444rd_symfc_compact_fc() -> Phono3py:
"""Return Phono3py instance of MgO-2x2x2-4x4x4 RD-RD.
* with symmetry
* full fc
* use symfc if available on test side
"""
pytest.importorskip("symfc")
yaml_filename = cwd / "phono3py_params_MgO-222rd-444rd.yaml.xz"
return phono3py.load(
yaml_filename,
is_compact_fc=True,
fc_calculator="symfc",
fc_calculator_options="|cutoff = 4",
log_level=1,
)
@pytest.fixture(scope="session")
def ph_nacl() -> Phonopy:
"""Return Phonopy class instance of NaCl 2x2x2."""

View File

@ -301,6 +301,7 @@ def test_get_all_shortest(aln_lda: Phono3py):
"""Test Interaction._get_all_shortest."""
ph3 = aln_lda
ph3.mesh_numbers = 30
assert ph3.grid is not None
itr = Interaction(
ph3.primitive,
ph3.grid,
@ -339,6 +340,7 @@ def _get_irt(
make_r0_average: bool = False,
):
ph3.mesh_numbers = mesh
assert ph3.grid is not None
itr = Interaction(
ph3.primitive,
ph3.grid,