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); // printf("Data shift:%lu [%lu, %lu]\n", adrs_shift, i_sigma, i_temp);
// } // }
void py_get_interaction(nb::ndarray<> py_fc3_normal_squared, void py_get_interaction(
nb::ndarray<> py_g_zero, nb::ndarray<> py_frequencies, nb::ndarray<> py_fc3_normal_squared, nb::ndarray<> py_g_zero,
nb::ndarray<> py_eigenvectors, nb::ndarray<> py_frequencies, nb::ndarray<> py_eigenvectors,
nb::ndarray<> py_triplets, nb::ndarray<> py_triplets, nb::ndarray<> py_bz_grid_addresses,
nb::ndarray<> py_bz_grid_addresses, nb::ndarray<> py_D_diag, nb::ndarray<> py_Q, nb::ndarray<> py_fc3,
nb::ndarray<> py_D_diag, nb::ndarray<> py_Q, nb::ndarray<> py_fc3_nonzero_indices, nb::ndarray<> py_svecs,
nb::ndarray<> py_fc3, nb::ndarray<> py_svecs, nb::ndarray<> py_multi, nb::ndarray<> py_masses, nb::ndarray<> py_p2s_map,
nb::ndarray<> py_multi, nb::ndarray<> py_masses, nb::ndarray<> py_s2p_map, nb::ndarray<> py_band_indices,
nb::ndarray<> py_p2s_map, nb::ndarray<> py_s2p_map, int64_t symmetrize_fc3_q, int64_t make_r0_average,
nb::ndarray<> py_band_indices, int64_t symmetrize_fc3_q, nb::ndarray<> py_all_shortest, double cutoff_frequency,
int64_t make_r0_average, nb::ndarray<> py_all_shortest, int64_t openmp_per_triplets) {
double cutoff_frequency, int64_t openmp_per_triplets) {
Darray *fc3_normal_squared; Darray *fc3_normal_squared;
Darray *freqs; Darray *freqs;
_lapack_complex_double *eigvecs; _lapack_complex_double *eigvecs;
@ -72,6 +71,7 @@ void py_get_interaction(nb::ndarray<> py_fc3_normal_squared,
int64_t *D_diag; int64_t *D_diag;
int64_t (*Q)[3]; int64_t (*Q)[3];
double *fc3; double *fc3;
char *fc3_nonzero_indices;
double (*svecs)[3]; double (*svecs)[3];
int64_t (*multi)[2]; int64_t (*multi)[2];
double *masses; double *masses;
@ -100,6 +100,7 @@ void py_get_interaction(nb::ndarray<> py_fc3_normal_squared,
} else { } else {
is_compact_fc3 = 1; is_compact_fc3 = 1;
} }
fc3_nonzero_indices = (char *)py_fc3_nonzero_indices.data();
svecs = (double (*)[3])py_svecs.data(); svecs = (double (*)[3])py_svecs.data();
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
multi_dims[i] = py_multi.shape(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, ph3py_get_interaction(fc3_normal_squared, g_zero, freqs, eigvecs, triplets,
num_triplets, bz_grid_addresses, D_diag, Q, fc3, num_triplets, bz_grid_addresses, D_diag, Q, fc3,
is_compact_fc3, svecs, multi_dims, multi, masses, p2s, fc3_nonzero_indices, is_compact_fc3, svecs,
s2p, band_indices, symmetrize_fc3_q, make_r0_average, multi_dims, multi, masses, p2s, s2p, band_indices,
all_shortest, cutoff_frequency, openmp_per_triplets); symmetrize_fc3_q, make_r0_average, all_shortest,
cutoff_frequency, openmp_per_triplets);
free(fc3_normal_squared); free(fc3_normal_squared);
fc3_normal_squared = NULL; 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_triplets, nb::ndarray<> py_triplet_weights,
nb::ndarray<> py_bz_grid_addresses, nb::ndarray<> py_bz_map, 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, 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_fc3, nb::ndarray<> py_fc3_nonzero_indices,
nb::ndarray<> py_masses, nb::ndarray<> py_p2s_map, nb::ndarray<> py_s2p_map, 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, nb::ndarray<> py_band_indices, nb::ndarray<> py_temperatures_THz,
int64_t is_NU, int64_t symmetrize_fc3_q, int64_t make_r0_average, int64_t is_NU, int64_t symmetrize_fc3_q, int64_t make_r0_average,
nb::ndarray<> py_all_shortest, double cutoff_frequency, nb::ndarray<> py_all_shortest, double cutoff_frequency,
@ -147,6 +150,7 @@ void py_get_pp_collision(
int64_t *D_diag; int64_t *D_diag;
int64_t (*Q)[3]; int64_t (*Q)[3];
double *fc3; double *fc3;
char *fc3_nonzero_indices;
double (*svecs)[3]; double (*svecs)[3];
int64_t (*multi)[2]; int64_t (*multi)[2];
double *masses; double *masses;
@ -176,6 +180,7 @@ void py_get_pp_collision(
} else { } else {
is_compact_fc3 = 1; is_compact_fc3 = 1;
} }
fc3_nonzero_indices = (char *)py_fc3_nonzero_indices.data();
svecs = (double (*)[3])py_svecs.data(); svecs = (double (*)[3])py_svecs.data();
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
multi_dims[i] = py_multi.shape(i); multi_dims[i] = py_multi.shape(i);
@ -191,9 +196,10 @@ void py_get_pp_collision(
ph3py_get_pp_collision( ph3py_get_pp_collision(
gamma, relative_grid_address, frequencies, eigenvectors, triplets, gamma, relative_grid_address, frequencies, eigenvectors, triplets,
num_triplets, triplet_weights, bz_grid_addresses, bz_map, bz_grid_type, 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, D_diag, Q, fc3, fc3_nonzero_indices, is_compact_fc3, svecs, multi_dims,
s2p, band_indices, temperatures_THz, is_NU, symmetrize_fc3_q, multi, masses, p2s, s2p, band_indices, temperatures_THz, is_NU,
make_r0_average, all_shortest, cutoff_frequency, openmp_per_triplets); symmetrize_fc3_q, make_r0_average, all_shortest, cutoff_frequency,
openmp_per_triplets);
free(band_indices); free(band_indices);
band_indices = NULL; 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_frequencies, nb::ndarray<> py_eigenvectors,
nb::ndarray<> py_triplets, nb::ndarray<> py_triplet_weights, nb::ndarray<> py_triplets, nb::ndarray<> py_triplet_weights,
nb::ndarray<> py_bz_grid_addresses, nb::ndarray<> py_D_diag, 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_multi, nb::ndarray<> py_masses, nb::ndarray<> py_p2s_map,
nb::ndarray<> py_s2p_map, nb::ndarray<> py_band_indices, nb::ndarray<> py_s2p_map, nb::ndarray<> py_band_indices,
nb::ndarray<> py_temperatures_THz, int64_t is_NU, int64_t symmetrize_fc3_q, 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 *D_diag;
int64_t (*Q)[3]; int64_t (*Q)[3];
double *fc3; double *fc3;
char *fc3_nonzero_indices;
double (*svecs)[3]; double (*svecs)[3];
int64_t (*multi)[2]; int64_t (*multi)[2];
double *masses; double *masses;
@ -249,6 +257,7 @@ void py_get_pp_collision_with_sigma(
} else { } else {
is_compact_fc3 = 1; is_compact_fc3 = 1;
} }
fc3_nonzero_indices = (char *)py_fc3_nonzero_indices.data();
svecs = (double (*)[3])py_svecs.data(); svecs = (double (*)[3])py_svecs.data();
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
multi_dims[i] = py_multi.shape(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( ph3py_get_pp_collision_with_sigma(
gamma, sigma, sigma_cutoff, frequencies, eigenvectors, triplets, gamma, sigma, sigma_cutoff, frequencies, eigenvectors, triplets,
num_triplets, triplet_weights, bz_grid_addresses, D_diag, Q, fc3, num_triplets, triplet_weights, bz_grid_addresses, D_diag, Q, fc3,
is_compact_fc3, svecs, multi_dims, multi, masses, p2s, s2p, fc3_nonzero_indices, is_compact_fc3, svecs, multi_dims, multi, masses,
band_indices, temperatures_THz, is_NU, symmetrize_fc3_q, p2s, s2p, band_indices, temperatures_THz, is_NU, symmetrize_fc3_q,
make_r0_average, all_shortest, cutoff_frequency, openmp_per_triplets); make_r0_average, all_shortest, cutoff_frequency, openmp_per_triplets);
free(band_indices); 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 _lapack_complex_double *eigenvectors, const int64_t (*triplets)[3],
const int64_t num_triplets, const int64_t (*bz_grid_addresses)[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 D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3], const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const int64_t multi_dims[2], const int64_t (*multiplicity)[2], const double (*svecs)[3], const int64_t multi_dims[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map, const int64_t (*multiplicity)[2], const double *masses,
const int64_t *band_indices, const int64_t symmetrize_fc3_q, const int64_t *p2s_map, const int64_t *s2p_map, const int64_t *band_indices,
const int64_t make_r0_average, const char *all_shortest, const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const double cutoff_frequency, const int64_t openmp_per_triplets) { const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets) {
RecgridConstBZGrid *bzgrid; RecgridConstBZGrid *bzgrid;
AtomTriplets *atom_triplets; AtomTriplets *atom_triplets;
int64_t i, j; int64_t i, j;
@ -102,6 +103,7 @@ int64_t ph3py_get_interaction(
atom_triplets->s2p_map = s2p_map; atom_triplets->s2p_map = s2p_map;
atom_triplets->make_r0_average = make_r0_average; atom_triplets->make_r0_average = make_r0_average;
atom_triplets->all_shortest = all_shortest; atom_triplets->all_shortest = all_shortest;
atom_triplets->nonzero_indices = fc3_nonzero_indices;
itr_get_interaction(fc3_normal_squared, g_zero, frequencies, itr_get_interaction(fc3_normal_squared, g_zero, frequencies,
(lapack_complex_double *)eigenvectors, triplets, (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_grid_addresses)[3], /* thm */
const int64_t *bz_map, /* 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 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 int64_t multi_dims[2], const int64_t (*multiplicity)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map, const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const Larray *band_indices, const Darray *temperatures_THz, 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->s2p_map = s2p_map;
atom_triplets->make_r0_average = make_r0_average; atom_triplets->make_r0_average = make_r0_average;
atom_triplets->all_shortest = all_shortest; atom_triplets->all_shortest = all_shortest;
atom_triplets->nonzero_indices = fc3_nonzero_indices;
ppc_get_pp_collision(imag_self_energy, relative_grid_address, frequencies, ppc_get_pp_collision(imag_self_energy, relative_grid_address, frequencies,
(lapack_complex_double *)eigenvectors, triplets, (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 (*triplets)[3], const int64_t num_triplets,
const int64_t *triplet_weights, const int64_t (*bz_grid_addresses)[3], 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 D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3], const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const int64_t multi_dims[2], const int64_t (*multiplicity)[2], const double (*svecs)[3], const int64_t multi_dims[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map, const int64_t (*multiplicity)[2], const double *masses,
const Larray *band_indices, const Darray *temperatures_THz, const int64_t *p2s_map, const int64_t *s2p_map, const Larray *band_indices,
const int64_t is_NU, const int64_t symmetrize_fc3_q, const Darray *temperatures_THz, const int64_t is_NU,
const int64_t make_r0_average, const char *all_shortest, const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const double cutoff_frequency, const int64_t openmp_per_triplets) { const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets) {
RecgridConstBZGrid *bzgrid; RecgridConstBZGrid *bzgrid;
AtomTriplets *atom_triplets; AtomTriplets *atom_triplets;
int64_t i, j; int64_t i, j;
@ -232,6 +237,7 @@ int64_t ph3py_get_pp_collision_with_sigma(
atom_triplets->s2p_map = s2p_map; atom_triplets->s2p_map = s2p_map;
atom_triplets->make_r0_average = make_r0_average; atom_triplets->make_r0_average = make_r0_average;
atom_triplets->all_shortest = all_shortest; atom_triplets->all_shortest = all_shortest;
atom_triplets->nonzero_indices = fc3_nonzero_indices;
ppc_get_pp_collision_with_sigma( ppc_get_pp_collision_with_sigma(
imag_self_energy, sigma, sigma_cutoff, frequencies, 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 _lapack_complex_double *eigenvectors, const int64_t (*triplets)[3],
const int64_t num_triplets, const int64_t (*bz_grid_addresses)[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 D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3], const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const int64_t multi_dims[2], const int64_t (*multi)[2], const double (*svecs)[3], const int64_t multi_dims[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map, const int64_t (*multi)[2], const double *masses, const int64_t *p2s_map,
const int64_t *band_indices, const int64_t symmetrize_fc3_q, const int64_t *s2p_map, const int64_t *band_indices,
const int64_t make_r0_average, const char *all_shortest, const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const double cutoff_frequency, const int64_t openmp_per_triplets); const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets);
int64_t ph3py_get_pp_collision( int64_t ph3py_get_pp_collision(
double *imag_self_energy, double *imag_self_energy,
const int64_t relative_grid_address[24][4][3], /* thm */ 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_grid_addresses)[3], /* thm */
const int64_t *bz_map, /* 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 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 int64_t multi_dims[2], const int64_t (*multi)[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map, const double *masses, const int64_t *p2s_map, const int64_t *s2p_map,
const Larray *band_indices, const Darray *temperatures_THz, 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 (*triplets)[3], const int64_t num_triplets,
const int64_t *triplet_weights, const int64_t (*bz_grid_addresses)[3], 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 D_diag[3], const int64_t Q[3][3], const double *fc3,
const int64_t is_compact_fc3, const double (*svecs)[3], const char *fc3_nonzero_indices, const int64_t is_compact_fc3,
const int64_t multi_dims[2], const int64_t (*multi)[2], const double (*svecs)[3], const int64_t multi_dims[2],
const double *masses, const int64_t *p2s_map, const int64_t *s2p_map, const int64_t (*multi)[2], const double *masses, const int64_t *p2s_map,
const Larray *band_indices, const Darray *temperatures_THz, const int64_t *s2p_map, const Larray *band_indices,
const int64_t is_NU, const int64_t symmetrize_fc3_q, const Darray *temperatures_THz, const int64_t is_NU,
const int64_t make_r0_average, const char *all_shortest, const int64_t symmetrize_fc3_q, const int64_t make_r0_average,
const double cutoff_frequency, const int64_t openmp_per_triplets); const char *all_shortest, const double cutoff_frequency,
const int64_t openmp_per_triplets);
void ph3py_get_imag_self_energy_at_bands_with_g( void ph3py_get_imag_self_energy_at_bands_with_g(
double *imag_self_energy, const Darray *fc3_normal_squared, double *imag_self_energy, const Darray *fc3_normal_squared,
const double *frequencies, const int64_t (*triplets)[3], 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 pi0, const int64_t pi1, const int64_t pi2,
const int64_t leg_index) { const int64_t leg_index) {
int64_t i, j, k, l; 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; lapack_complex_double phase_factor;
double fc3_rec_real[27], fc3_rec_imag[27]; double fc3_rec_real[27], fc3_rec_imag[27];
@ -309,8 +309,11 @@ static void real_to_reciprocal_elements(
continue; continue;
} }
} }
adrs_shift = adrs_shift_atoms = i * num_satom * num_satom + j * num_satom + k;
i * 27 * num_satom * num_satom + j * 27 * num_satom + k * 27; if (!atom_triplets->nonzero_indices[adrs_shift_atoms]) {
continue;
}
adrs_shift_fc3 = adrs_shift_atoms * 27;
phase_factor = phase_factor =
phonoc_complex_prod(phase_factor1[j], phase_factor2[k]); 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++) { for (l = 0; l < 27; l++) {
fc3_rec_real[l] += fc3_rec_real[l] +=
lapack_complex_double_real(phase_factor) * lapack_complex_double_real(phase_factor) *
fc3[adrs_shift + l] * 3; fc3[adrs_shift_fc3 + l] * 3;
fc3_rec_imag[l] += fc3_rec_imag[l] +=
lapack_complex_double_imag(phase_factor) * lapack_complex_double_imag(phase_factor) *
fc3[adrs_shift + l] * 3; fc3[adrs_shift_fc3 + l] * 3;
} }
} else { } else {
for (l = 0; l < 27; l++) { for (l = 0; l < 27; l++) {
fc3_rec_real[l] += fc3_rec_real[l] +=
lapack_complex_double_real(phase_factor) * lapack_complex_double_real(phase_factor) *
fc3[adrs_shift + l]; fc3[adrs_shift_fc3 + l];
fc3_rec_imag[l] += fc3_rec_imag[l] +=
lapack_complex_double_imag(phase_factor) * 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; const int64_t *s2p_map;
int64_t make_r0_average; int64_t make_r0_average;
const char *all_shortest; const char *all_shortest;
const char *nonzero_indices; // for compact fc3
} AtomTriplets; } AtomTriplets;
void r2r_real_to_reciprocal(lapack_complex_double *fc3_reciprocal, 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. `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." msg = "Phono3py.mesh_numbers of instance has to be set."
raise RuntimeError(msg) raise RuntimeError(msg)
@ -1151,6 +1151,7 @@ class Phono3py:
self._bz_grid, self._bz_grid,
self._primitive_symmetry, self._primitive_symmetry,
fc3=self._fc3, fc3=self._fc3,
fc3_nonzero_indices=self._fc3_nonzero_indices,
band_indices=self._band_indices_flatten, band_indices=self._band_indices_flatten,
constant_averaged_interaction=constant_averaged_interaction, constant_averaged_interaction=constant_averaged_interaction,
frequency_factor_to_THz=self._frequency_factor_to_THz, frequency_factor_to_THz=self._frequency_factor_to_THz,

View File

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

View File

@ -509,7 +509,7 @@ def _load_fc3(
assert "fc3_nonzero_indices" in fc3 assert "fc3_nonzero_indices" in fc3
ph3py.fc3_nonzero_indices = fc3["fc3_nonzero_indices"] ph3py.fc3_nonzero_indices = fc3["fc3_nonzero_indices"]
if log_level: 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: else:
_check_fc3_shape(ph3py, fc3, filename=_fc3_filename) _check_fc3_shape(ph3py, fc3, filename=_fc3_filename)
ph3py.fc3 = fc3 ph3py.fc3 = fc3

View File

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