1 /* Copyright (C) 2021 Atsushi Togo */
2 /* All rights reserved. */
3 
4 /* This file is part of phonopy. */
5 
6 /* Redistribution and use in source and binary forms, with or without */
7 /* modification, are permitted provided that the following conditions */
8 /* are met: */
9 
10 /* * Redistributions of source code must retain the above copyright */
11 /*   notice, this list of conditions and the following disclaimer. */
12 
13 /* * Redistributions in binary form must reproduce the above copyright */
14 /*   notice, this list of conditions and the following disclaimer in */
15 /*   the documentation and/or other materials provided with the */
16 /*   distribution. */
17 
18 /* * Neither the name of the phonopy project nor the names of its */
19 /*   contributors may be used to endorse or promote products derived */
20 /*   from this software without specific prior written permission. */
21 
22 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26 /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28 /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30 /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31 /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32 /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33 /* POSSIBILITY OF SUCH DAMAGE. */
34 
35 #include "phono3py.h"
36 #include "lapack_wrapper.h"
37 #include "phonoc_array.h"
38 
39 #include "interaction.h"
40 #include "pp_collision.h"
41 #include "imag_self_energy_with_g.h"
42 #include "real_self_energy.h"
43 #include "collision_matrix.h"
44 #include "isotope.h"
45 #include "fc3.h"
46 #include "tetrahedron_method.h"
47 #include "triplet.h"
48 
49 #include <stdio.h>
50 
ph3py_get_interaction(Darray * fc3_normal_squared,const char * g_zero,const Darray * frequencies,const lapack_complex_double * eigenvectors,const size_t (* triplets)[3],const size_t num_triplets,const int * grid_address,const int * mesh,const double * fc3,const int is_compact_fc3,const double * shortest_vectors,const int svecs_dims[3],const int * multiplicity,const double * masses,const int * p2s_map,const int * s2p_map,const int * band_indices,const int symmetrize_fc3_q,const double cutoff_frequency)51 void ph3py_get_interaction(Darray *fc3_normal_squared,
52                            const char *g_zero,
53                            const Darray *frequencies,
54                            const lapack_complex_double *eigenvectors,
55                            const size_t (*triplets)[3],
56                            const size_t num_triplets,
57                            const int *grid_address,
58                            const int *mesh,
59                            const double *fc3,
60                            const int is_compact_fc3,
61                            const double *shortest_vectors,
62                            const int svecs_dims[3],
63                            const int *multiplicity,
64                            const double *masses,
65                            const int *p2s_map,
66                            const int *s2p_map,
67                            const int *band_indices,
68                            const int symmetrize_fc3_q,
69                            const double cutoff_frequency)
70 {
71   itr_get_interaction(fc3_normal_squared,
72                       g_zero,
73                       frequencies,
74                       eigenvectors,
75                       triplets,
76                       num_triplets,
77                       grid_address,
78                       mesh,
79                       fc3,
80                       is_compact_fc3,
81                       shortest_vectors,
82                       svecs_dims,
83                       multiplicity,
84                       masses,
85                       p2s_map,
86                       s2p_map,
87                       band_indices,
88                       symmetrize_fc3_q,
89                       cutoff_frequency);
90 }
91 
92 
ph3py_get_pp_collision(double * imag_self_energy,PHPYCONST int relative_grid_address[24][4][3],const double * frequencies,const lapack_complex_double * eigenvectors,const size_t (* triplets)[3],const size_t num_triplets,const int * triplet_weights,const int * grid_address,const size_t * bz_map,const int * mesh,const double * fc3,const int is_compact_fc3,const double * shortest_vectors,const int svecs_dims[3],const int * multiplicity,const double * masses,const int * p2s_map,const int * s2p_map,const Iarray * band_indices,const Darray * temperatures,const int is_NU,const int symmetrize_fc3_q,const double cutoff_frequency)93 void ph3py_get_pp_collision(double *imag_self_energy,
94                             PHPYCONST int relative_grid_address[24][4][3], /* thm */
95                             const double *frequencies,
96                             const lapack_complex_double *eigenvectors,
97                             const size_t (*triplets)[3],
98                             const size_t num_triplets,
99                             const int *triplet_weights,
100                             const int *grid_address, /* thm */
101                             const size_t *bz_map, /* thm */
102                             const int *mesh, /* thm */
103                             const double *fc3,
104                             const int is_compact_fc3,
105                             const double *shortest_vectors,
106                             const int svecs_dims[3],
107                             const int *multiplicity,
108                             const double *masses,
109                             const int *p2s_map,
110                             const int *s2p_map,
111                             const Iarray *band_indices,
112                             const Darray *temperatures,
113                             const int is_NU,
114                             const int symmetrize_fc3_q,
115                             const double cutoff_frequency)
116 {
117   ppc_get_pp_collision(imag_self_energy,
118                        relative_grid_address,
119                        frequencies,
120                        eigenvectors,
121                        triplets,
122                        num_triplets,
123                        triplet_weights,
124                        grid_address,
125                        bz_map,
126                        mesh,
127                        fc3,
128                        is_compact_fc3,
129                        shortest_vectors,
130                        svecs_dims,
131                        multiplicity,
132                        masses,
133                        p2s_map,
134                        s2p_map,
135                        band_indices,
136                        temperatures,
137                        is_NU,
138                        symmetrize_fc3_q,
139                        cutoff_frequency);
140 }
141 
142 
ph3py_get_pp_collision_with_sigma(double * imag_self_energy,const double sigma,const double sigma_cutoff,const double * frequencies,const lapack_complex_double * eigenvectors,const size_t (* triplets)[3],const size_t num_triplets,const int * triplet_weights,const int * grid_address,const int * mesh,const double * fc3,const int is_compact_fc3,const double * shortest_vectors,const int svecs_dims[3],const int * multiplicity,const double * masses,const int * p2s_map,const int * s2p_map,const Iarray * band_indices,const Darray * temperatures,const int is_NU,const int symmetrize_fc3_q,const double cutoff_frequency)143 void ph3py_get_pp_collision_with_sigma(
144   double *imag_self_energy,
145   const double sigma,
146   const double sigma_cutoff,
147   const double *frequencies,
148   const lapack_complex_double *eigenvectors,
149   const size_t (*triplets)[3],
150   const size_t num_triplets,
151   const int *triplet_weights,
152   const int *grid_address,
153   const int *mesh,
154   const double *fc3,
155   const int is_compact_fc3,
156   const double *shortest_vectors,
157   const int svecs_dims[3],
158   const int *multiplicity,
159   const double *masses,
160   const int *p2s_map,
161   const int *s2p_map,
162   const Iarray *band_indices,
163   const Darray *temperatures,
164   const int is_NU,
165   const int symmetrize_fc3_q,
166   const double cutoff_frequency)
167 {
168   ppc_get_pp_collision_with_sigma(imag_self_energy,
169                                   sigma,
170                                   sigma_cutoff,
171                                   frequencies,
172                                   eigenvectors,
173                                   triplets,
174                                   num_triplets,
175                                   triplet_weights,
176                                   grid_address,
177                                   mesh,
178                                   fc3,
179                                   is_compact_fc3,
180                                   shortest_vectors,
181                                   svecs_dims,
182                                   multiplicity,
183                                   masses,
184                                   p2s_map,
185                                   s2p_map,
186                                   band_indices,
187                                   temperatures,
188                                   is_NU,
189                                   symmetrize_fc3_q,
190                                   cutoff_frequency);
191 }
192 
193 
ph3py_get_imag_self_energy_at_bands_with_g(double * imag_self_energy,const Darray * fc3_normal_squared,const double * frequencies,const size_t (* triplets)[3],const int * triplet_weights,const double * g,const char * g_zero,const double temperature,const double cutoff_frequency,const int num_frequency_points,const int frequency_point_index)194 void ph3py_get_imag_self_energy_at_bands_with_g(
195   double *imag_self_energy,
196   const Darray *fc3_normal_squared,
197   const double *frequencies,
198   const size_t (*triplets)[3],
199   const int *triplet_weights,
200   const double *g,
201   const char *g_zero,
202   const double temperature,
203   const double cutoff_frequency,
204   const int num_frequency_points,
205   const int frequency_point_index)
206 {
207   ise_get_imag_self_energy_at_bands_with_g(imag_self_energy,
208                                            fc3_normal_squared,
209                                            frequencies,
210                                            triplets,
211                                            triplet_weights,
212                                            g,
213                                            g_zero,
214                                            temperature,
215                                            cutoff_frequency,
216                                            num_frequency_points,
217                                            frequency_point_index);
218 }
219 
220 
ph3py_get_detailed_imag_self_energy_at_bands_with_g(double * detailed_imag_self_energy,double * imag_self_energy_N,double * imag_self_energy_U,const Darray * fc3_normal_squared,const double * frequencies,const size_t (* triplets)[3],const int * triplet_weights,const int * grid_address,const double * g,const char * g_zero,const double temperature,const double cutoff_frequency)221 void ph3py_get_detailed_imag_self_energy_at_bands_with_g(
222   double *detailed_imag_self_energy,
223   double *imag_self_energy_N,
224   double *imag_self_energy_U,
225   const Darray *fc3_normal_squared,
226   const double *frequencies,
227   const size_t (*triplets)[3],
228   const int *triplet_weights,
229   const int *grid_address,
230   const double *g,
231   const char *g_zero,
232   const double temperature,
233   const double cutoff_frequency)
234 {
235   ise_get_detailed_imag_self_energy_at_bands_with_g(detailed_imag_self_energy,
236                                                     imag_self_energy_N,
237                                                     imag_self_energy_U,
238                                                     fc3_normal_squared,
239                                                     frequencies,
240                                                     triplets,
241                                                     triplet_weights,
242                                                     grid_address,
243                                                     g,
244                                                     g_zero,
245                                                     temperature,
246                                                     cutoff_frequency);
247 }
248 
249 
ph3py_get_real_self_energy_at_bands(double * real_self_energy,const Darray * fc3_normal_squared,const int * band_indices,const double * frequencies,const size_t (* triplets)[3],const int * triplet_weights,const double epsilon,const double temperature,const double unit_conversion_factor,const double cutoff_frequency)250 void ph3py_get_real_self_energy_at_bands(double *real_self_energy,
251                                          const Darray *fc3_normal_squared,
252                                          const int *band_indices,
253                                          const double *frequencies,
254                                          const size_t (*triplets)[3],
255                                          const int *triplet_weights,
256                                          const double epsilon,
257                                          const double temperature,
258                                          const double unit_conversion_factor,
259                                          const double cutoff_frequency)
260 {
261   rse_get_real_self_energy_at_bands(real_self_energy,
262                                     fc3_normal_squared,
263                                     band_indices,
264                                     frequencies,
265                                     triplets,
266                                     triplet_weights,
267                                     epsilon,
268                                     temperature,
269                                     unit_conversion_factor,
270                                     cutoff_frequency);
271 }
272 
273 
ph3py_get_real_self_energy_at_frequency_point(double * real_self_energy,const double frequency_point,const Darray * fc3_normal_squared,const int * band_indices,const double * frequencies,const size_t (* triplets)[3],const int * triplet_weights,const double epsilon,const double temperature,const double unit_conversion_factor,const double cutoff_frequency)274 void ph3py_get_real_self_energy_at_frequency_point(
275   double *real_self_energy,
276   const double frequency_point,
277   const Darray *fc3_normal_squared,
278   const int *band_indices,
279   const double *frequencies,
280   const size_t (*triplets)[3],
281   const int *triplet_weights,
282   const double epsilon,
283   const double temperature,
284   const double unit_conversion_factor,
285   const double cutoff_frequency)
286 {
287   rse_get_real_self_energy_at_frequency_point(real_self_energy,
288                                               frequency_point,
289                                               fc3_normal_squared,
290                                               band_indices,
291                                               frequencies,
292                                               triplets,
293                                               triplet_weights,
294                                               epsilon,
295                                               temperature,
296                                               unit_conversion_factor,
297                                               cutoff_frequency);
298 }
299 
300 
ph3py_get_collision_matrix(double * collision_matrix,const Darray * fc3_normal_squared,const double * frequencies,const size_t (* triplets)[3],const size_t * triplets_map,const size_t * map_q,const size_t * rotated_grid_points,const double * rotations_cartesian,const double * g,const size_t num_ir_gp,const size_t num_gp,const size_t num_rot,const double temperature,const double unit_conversion_factor,const double cutoff_frequency)301 void ph3py_get_collision_matrix(double *collision_matrix,
302                                 const Darray *fc3_normal_squared,
303                                 const double *frequencies,
304                                 const size_t (*triplets)[3],
305                                 const size_t *triplets_map,
306                                 const size_t *map_q,
307                                 const size_t *rotated_grid_points,
308                                 const double *rotations_cartesian,
309                                 const double *g,
310                                 const size_t num_ir_gp,
311                                 const size_t num_gp,
312                                 const size_t num_rot,
313                                 const double temperature,
314                                 const double unit_conversion_factor,
315                                 const double cutoff_frequency)
316 {
317   col_get_collision_matrix(collision_matrix,
318                            fc3_normal_squared,
319                            frequencies,
320                            triplets,
321                            triplets_map,
322                            map_q,
323                            rotated_grid_points,
324                            rotations_cartesian,
325                            g,
326                            num_ir_gp,
327                            num_gp,
328                            num_rot,
329                            temperature,
330                            unit_conversion_factor,
331                            cutoff_frequency);
332 }
333 
334 
ph3py_get_reducible_collision_matrix(double * collision_matrix,const Darray * fc3_normal_squared,const double * frequencies,const size_t (* triplets)[3],const size_t * triplets_map,const size_t * map_q,const double * g,const size_t num_gp,const double temperature,const double unit_conversion_factor,const double cutoff_frequency)335 void ph3py_get_reducible_collision_matrix(double *collision_matrix,
336                                           const Darray *fc3_normal_squared,
337                                           const double *frequencies,
338                                           const size_t (*triplets)[3],
339                                           const size_t *triplets_map,
340                                           const size_t *map_q,
341                                           const double *g,
342                                           const size_t num_gp,
343                                           const double temperature,
344                                           const double unit_conversion_factor,
345                                           const double cutoff_frequency)
346 {
347   col_get_reducible_collision_matrix(collision_matrix,
348                                      fc3_normal_squared,
349                                      frequencies,
350                                      triplets,
351                                      triplets_map,
352                                      map_q,
353                                      g,
354                                      num_gp,
355                                      temperature,
356                                      unit_conversion_factor,
357                                      cutoff_frequency);
358 }
359 
360 
ph3py_get_isotope_scattering_strength(double * gamma,const size_t grid_point,const double * mass_variances,const double * frequencies,const lapack_complex_double * eigenvectors,const size_t num_grid_points,const int * band_indices,const size_t num_band,const size_t num_band0,const double sigma,const double cutoff_frequency)361 void ph3py_get_isotope_scattering_strength(
362   double *gamma,
363   const size_t grid_point,
364   const double *mass_variances,
365   const double *frequencies,
366   const lapack_complex_double *eigenvectors,
367   const size_t num_grid_points,
368   const int *band_indices,
369   const size_t num_band,
370   const size_t num_band0,
371   const double sigma,
372   const double cutoff_frequency)
373 {
374   iso_get_isotope_scattering_strength(gamma,
375                                       grid_point,
376                                       mass_variances,
377                                       frequencies,
378                                       eigenvectors,
379                                       num_grid_points,
380                                       band_indices,
381                                       num_band,
382                                       num_band0,
383                                       sigma,
384                                       cutoff_frequency);
385 }
386 
387 
ph3py_get_thm_isotope_scattering_strength(double * gamma,const size_t grid_point,const size_t * ir_grid_points,const int * weights,const double * mass_variances,const double * frequencies,const lapack_complex_double * eigenvectors,const size_t num_ir_grid_points,const int * band_indices,const size_t num_band,const size_t num_band0,const double * integration_weights,const double cutoff_frequency)388 void ph3py_get_thm_isotope_scattering_strength
389 (double *gamma,
390  const size_t grid_point,
391  const size_t *ir_grid_points,
392  const int *weights,
393  const double *mass_variances,
394  const double *frequencies,
395  const lapack_complex_double *eigenvectors,
396  const size_t num_ir_grid_points,
397  const int *band_indices,
398  const size_t num_band,
399  const size_t num_band0,
400  const double *integration_weights,
401  const double cutoff_frequency)
402 {
403   iso_get_thm_isotope_scattering_strength(gamma,
404                                           grid_point,
405                                           ir_grid_points,
406                                           weights,
407                                           mass_variances,
408                                           frequencies,
409                                           eigenvectors,
410                                           num_ir_grid_points,
411                                           band_indices,
412                                           num_band,
413                                           num_band0,
414                                           integration_weights,
415                                           cutoff_frequency);
416 }
417 
ph3py_distribute_fc3(double * fc3,const int target,const int source,const int * atom_mapping,const size_t num_atom,const double * rot_cart)418 void ph3py_distribute_fc3(double *fc3,
419                           const int target,
420                           const int source,
421                           const int *atom_mapping,
422                           const size_t num_atom,
423                           const double *rot_cart)
424 {
425   fc3_distribute_fc3(fc3,
426                      target,
427                      source,
428                      atom_mapping,
429                      num_atom,
430                      rot_cart);
431 }
432 
433 
ph3py_rotate_delta_fc2(double (* fc3)[3][3][3],PHPYCONST double (* delta_fc2s)[3][3],const double * inv_U,PHPYCONST double (* site_sym_cart)[3][3],const int * rot_map_syms,const size_t num_atom,const size_t num_site_sym,const size_t num_disp)434 void ph3py_rotate_delta_fc2(double (*fc3)[3][3][3],
435                             PHPYCONST double (*delta_fc2s)[3][3],
436                             const double *inv_U,
437                             PHPYCONST double (*site_sym_cart)[3][3],
438                             const int *rot_map_syms,
439                             const size_t num_atom,
440                             const size_t num_site_sym,
441                             const size_t num_disp)
442 {
443   fc3_rotate_delta_fc2(fc3,
444                        delta_fc2s,
445                        inv_U,
446                        site_sym_cart,
447                        rot_map_syms,
448                        num_atom,
449                        num_site_sym,
450                        num_disp);
451 }
452 
453 
ph3py_set_permutation_symmetry_fc3(double * fc3,const size_t num_atom)454 void ph3py_set_permutation_symmetry_fc3(double *fc3, const size_t num_atom)
455 {
456   fc3_set_permutation_symmetry_fc3(fc3, num_atom);
457 }
458 
459 
ph3py_set_permutation_symmetry_compact_fc3(double * fc3,const int p2s[],const int s2pp[],const int nsym_list[],const int perms[],const size_t n_satom,const size_t n_patom)460 void ph3py_set_permutation_symmetry_compact_fc3(double * fc3,
461                                                 const int p2s[],
462                                                 const int s2pp[],
463                                                 const int nsym_list[],
464                                                 const int perms[],
465                                                 const size_t n_satom,
466                                                 const size_t n_patom)
467 {
468   fc3_set_permutation_symmetry_compact_fc3(fc3,
469                                            p2s,
470                                            s2pp,
471                                            nsym_list,
472                                            perms,
473                                            n_satom,
474                                            n_patom);
475 }
476 
ph3py_transpose_compact_fc3(double * fc3,const int p2s[],const int s2pp[],const int nsym_list[],const int perms[],const size_t n_satom,const size_t n_patom,const int t_type)477 void ph3py_transpose_compact_fc3(double * fc3,
478                                  const int p2s[],
479                                  const int s2pp[],
480                                  const int nsym_list[],
481                                  const int perms[],
482                                  const size_t n_satom,
483                                  const size_t n_patom,
484                                  const int t_type)
485 {
486   fc3_transpose_compact_fc3(fc3,
487                             p2s,
488                             s2pp,
489                             nsym_list,
490                             perms,
491                             n_satom,
492                             n_patom,
493                             t_type);
494 }
495 
496 
ph3py_get_triplets_reciprocal_mesh_at_q(size_t * map_triplets,size_t * map_q,int (* grid_address)[3],const size_t grid_point,const int mesh[3],const int is_time_reversal,const int num_rot,PHPYCONST int (* rotations)[3][3],const int swappable)497 size_t ph3py_get_triplets_reciprocal_mesh_at_q(size_t *map_triplets,
498                                                size_t *map_q,
499                                                int (*grid_address)[3],
500                                                const size_t grid_point,
501                                                const int mesh[3],
502                                                const int is_time_reversal,
503                                                const int num_rot,
504                                                PHPYCONST int (*rotations)[3][3],
505                                                const int swappable)
506 {
507   return tpl_get_triplets_reciprocal_mesh_at_q(map_triplets,
508                                                map_q,
509                                                grid_address,
510                                                grid_point,
511                                                mesh,
512                                                is_time_reversal,
513                                                num_rot,
514                                                rotations,
515                                                swappable);
516 }
517 
518 
ph3py_get_BZ_triplets_at_q(size_t (* triplets)[3],const size_t grid_point,PHPYCONST int (* bz_grid_address)[3],const size_t * bz_map,const size_t * map_triplets,const size_t num_map_triplets,const int mesh[3])519 size_t ph3py_get_BZ_triplets_at_q(size_t (*triplets)[3],
520                                   const size_t grid_point,
521                                   PHPYCONST int (*bz_grid_address)[3],
522                                   const size_t *bz_map,
523                                   const size_t *map_triplets,
524                                   const size_t num_map_triplets,
525                                   const int mesh[3])
526 {
527   return tpl_get_BZ_triplets_at_q(triplets,
528                                   grid_point,
529                                   bz_grid_address,
530                                   bz_map,
531                                   map_triplets,
532                                   num_map_triplets,
533                                   mesh);
534 }
535 
536 
ph3py_get_integration_weight(double * iw,char * iw_zero,const double * frequency_points,const size_t num_band0,PHPYCONST int relative_grid_address[24][4][3],const int mesh[3],PHPYCONST size_t (* triplets)[3],const size_t num_triplets,PHPYCONST int (* bz_grid_address)[3],const size_t * bz_map,const double * frequencies1,const size_t num_band1,const double * frequencies2,const size_t num_band2,const size_t tp_type,const int openmp_per_triplets,const int openmp_per_bands)537 void ph3py_get_integration_weight(double *iw,
538                                   char *iw_zero,
539                                   const double *frequency_points,
540                                   const size_t num_band0,
541                                   PHPYCONST int relative_grid_address[24][4][3],
542                                   const int mesh[3],
543                                   PHPYCONST size_t (*triplets)[3],
544                                   const size_t num_triplets,
545                                   PHPYCONST int (*bz_grid_address)[3],
546                                   const size_t *bz_map,
547                                   const double *frequencies1,
548                                   const size_t num_band1,
549                                   const double *frequencies2,
550                                   const size_t num_band2,
551                                   const size_t tp_type,
552                                   const int openmp_per_triplets,
553                                   const int openmp_per_bands)
554 {
555   tpl_get_integration_weight(iw,
556                              iw_zero,
557                              frequency_points,
558                              num_band0,
559                              relative_grid_address,
560                              mesh,
561                              triplets,
562                              num_triplets,
563                              bz_grid_address,
564                              bz_map,
565                              frequencies1,
566                              num_band1,
567                              frequencies2,
568                              num_band2,
569                              tp_type,
570                              openmp_per_triplets,
571                              openmp_per_bands);
572 }
573 
574 
ph3py_get_integration_weight_with_sigma(double * iw,char * iw_zero,const double sigma,const double sigma_cutoff,const double * frequency_points,const size_t num_band0,PHPYCONST size_t (* triplets)[3],const size_t num_triplets,const double * frequencies,const size_t num_band,const size_t tp_type)575 void ph3py_get_integration_weight_with_sigma(double *iw,
576                                              char *iw_zero,
577                                              const double sigma,
578                                              const double sigma_cutoff,
579                                              const double *frequency_points,
580                                              const size_t num_band0,
581                                              PHPYCONST size_t (*triplets)[3],
582                                              const size_t num_triplets,
583                                              const double *frequencies,
584                                              const size_t num_band,
585                                              const size_t tp_type)
586 {
587   tpl_get_integration_weight_with_sigma(iw,
588                                         iw_zero,
589                                         sigma,
590                                         sigma_cutoff,
591                                         frequency_points,
592                                         num_band0,
593                                         triplets,
594                                         num_triplets,
595                                         frequencies,
596                                         num_band,
597                                         tp_type);
598 }
599 
ph3py_symmetrize_collision_matrix(double * collision_matrix,const long num_column,const long num_temp,const long num_sigma)600 void ph3py_symmetrize_collision_matrix(double *collision_matrix,
601                                        const long num_column,
602                                        const long num_temp,
603                                        const long num_sigma)
604 {
605   double val;
606   long i, j, k, l, adrs_shift;
607 
608   for (i = 0; i < num_sigma; i++) {
609     for (j = 0; j < num_temp; j++) {
610       adrs_shift = (i * num_column * num_column * num_temp +
611                     j * num_column * num_column);
612       /* show_colmat_info(py_collision_matrix, i, j, adrs_shift); */
613 #pragma omp parallel for schedule(guided) private(l, val)
614       for (k = 0; k < num_column; k++) {
615         for (l = k + 1; l < num_column; l++) {
616           val = (collision_matrix[adrs_shift + k * num_column + l] +
617                  collision_matrix[adrs_shift + l * num_column + k]) / 2;
618           collision_matrix[adrs_shift + k * num_column + l] = val;
619           collision_matrix[adrs_shift + l * num_column + k] = val;
620         }
621       }
622     }
623   }
624 }
625 
626 
ph3py_expand_collision_matrix(double * collision_matrix,const size_t * rot_grid_points,const size_t * ir_grid_points,const long num_ir_gp,const long num_grid_points,const long num_rot,const long num_sigma,const long num_temp,const long num_band)627 void ph3py_expand_collision_matrix(double *collision_matrix,
628                                    const size_t *rot_grid_points,
629                                    const size_t *ir_grid_points,
630                                    const long num_ir_gp,
631                                    const long num_grid_points,
632                                    const long num_rot,
633                                    const long num_sigma,
634                                    const long num_temp,
635                                    const long num_band)
636 
637 {
638   long i, j, k, l, m, n, p, adrs_shift, adrs_shift_plus, ir_gp, gp_r;
639   long num_column, num_bgb;
640   long *multi;
641   double *colmat_copy;
642 
643   multi = (long*)malloc(sizeof(long) * num_ir_gp);
644   colmat_copy = NULL;
645 
646   num_column = num_grid_points * num_band;
647   num_bgb = num_band * num_grid_points * num_band;
648 
649 #pragma omp parallel for schedule(guided) private(j, ir_gp)
650   for (i = 0; i < num_ir_gp; i++) {
651     ir_gp = ir_grid_points[i];
652     multi[i] = 0;
653     for (j = 0; j < num_rot; j++) {
654       if (rot_grid_points[j * num_grid_points + ir_gp] == ir_gp) {
655         multi[i]++;
656       }
657     }
658   }
659 
660   for (i = 0; i < num_sigma; i++) {
661     for (j = 0; j < num_temp; j++) {
662       adrs_shift = (i * num_column * num_column * num_temp +
663                     j * num_column * num_column);
664 #pragma omp parallel for private(ir_gp, adrs_shift_plus, colmat_copy, l, gp_r, m, n, p)
665       for (k = 0; k < num_ir_gp; k++) {
666         ir_gp = ir_grid_points[k];
667         adrs_shift_plus = adrs_shift + ir_gp * num_bgb;
668         colmat_copy = (double*)malloc(sizeof(double) * num_bgb);
669         for (l = 0; l < num_bgb; l++) {
670           colmat_copy[l] = collision_matrix[adrs_shift_plus + l] / multi[k];
671           collision_matrix[adrs_shift_plus + l] = 0;
672         }
673         for (l = 0; l < num_rot; l++) {
674           gp_r = rot_grid_points[l * num_grid_points + ir_gp];
675           for (m = 0; m < num_band; m++) {
676             for (n = 0; n < num_grid_points; n++) {
677               for (p = 0; p < num_band; p++) {
678                 collision_matrix[
679                   adrs_shift + gp_r * num_bgb + m * num_grid_points * num_band
680                   + rot_grid_points[l * num_grid_points + n] * num_band + p] +=
681                   colmat_copy[m * num_grid_points * num_band + n * num_band + p];
682               }
683             }
684           }
685         }
686         free(colmat_copy);
687         colmat_copy = NULL;
688       }
689     }
690   }
691 
692   free(multi);
693   multi = NULL;
694 }
695 
696 
ph3py_get_neighboring_gird_points(size_t * relative_grid_points,const size_t * grid_points,PHPYCONST int (* relative_grid_address)[3],const int mesh[3],PHPYCONST int (* bz_grid_address)[3],const size_t * bz_map,const long num_grid_points,const long num_relative_grid_address)697 void ph3py_get_neighboring_gird_points(size_t *relative_grid_points,
698                                        const size_t *grid_points,
699                                        PHPYCONST int (*relative_grid_address)[3],
700                                        const int mesh[3],
701                                        PHPYCONST int (*bz_grid_address)[3],
702                                        const size_t *bz_map,
703                                        const long num_grid_points,
704                                        const long num_relative_grid_address)
705 {
706   long i;
707 
708 #pragma omp parallel for
709   for (i = 0; i < num_grid_points; i++) {
710     thm_get_dense_neighboring_grid_points
711       (relative_grid_points + i * num_relative_grid_address,
712        grid_points[i],
713        relative_grid_address,
714        num_relative_grid_address,
715        mesh,
716        bz_grid_address,
717        bz_map);
718   }
719 }
720 
721 
ph3py_set_integration_weights(double * iw,const double * frequency_points,const long num_band0,const long num_band,const long num_gp,PHPYCONST int (* relative_grid_address)[4][3],const int mesh[3],const size_t * grid_points,PHPYCONST int (* bz_grid_address)[3],const size_t * bz_map,const double * frequencies)722 void ph3py_set_integration_weights(double *iw,
723                                    const double *frequency_points,
724                                    const long num_band0,
725                                    const long num_band,
726                                    const long num_gp,
727                                    PHPYCONST int (*relative_grid_address)[4][3],
728                                    const int mesh[3],
729                                    const size_t *grid_points,
730                                    PHPYCONST int (*bz_grid_address)[3],
731                                    const size_t *bz_map,
732                                    const double *frequencies)
733 {
734   long i, j, k, bi;
735   size_t vertices[24][4];
736   double freq_vertices[24][4];
737 
738 #pragma omp parallel for private(j, k, bi, vertices, freq_vertices)
739   for (i = 0; i < num_gp; i++) {
740     for (j = 0; j < 24; j++) {
741       thm_get_dense_neighboring_grid_points(vertices[j],
742                                             grid_points[i],
743                                             relative_grid_address[j],
744                                             4,
745                                             mesh,
746                                             bz_grid_address,
747                                             bz_map);
748     }
749     for (bi = 0; bi < num_band; bi++) {
750       for (j = 0; j < 24; j++) {
751         for (k = 0; k < 4; k++) {
752           freq_vertices[j][k] = frequencies[vertices[j][k] * num_band + bi];
753         }
754       }
755       for (j = 0; j < num_band0; j++) {
756         iw[i * num_band0 * num_band + j * num_band + bi] =
757           thm_get_integration_weight(frequency_points[j], freq_vertices, 'I');
758       }
759     }
760   }
761 }
762