Branch data Line data Source code
1 : : !!****m* ABINIT/defs_elphon
2 : : !!
3 : : !! NAME
4 : : !! defs_elphon
5 : : !!
6 : : !! FUNCTION
7 : : !! This module contains the datastructures for elphon
8 : : !! the different (huge) matrices will either be allocated and
9 : : !! used, or be written to disk. All combinations should be feasible.
10 : : !!
11 : : !! COPYRIGHT
12 : : !! Copyright (C) 2004-2026 ABINIT group (MVer, MG)
13 : : !! This file is distributed under the terms of the
14 : : !! GNU General Public Licence, see ~abinit/COPYING
15 : : !! or http://www.gnu.org/copyleft/gpl.txt .
16 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
17 : : !!
18 : : !! NOTES
19 : : !! Contains the following datastructures:
20 : : !! 1) elph_type contains data and dimensions for the kpoints near the
21 : : !! fermi surface and the $g_{k k+q}$ matrix elements
22 : : !!
23 : : !! SOURCE
24 : :
25 : : #if defined HAVE_CONFIG_H
26 : : #include "config.h"
27 : : #endif
28 : :
29 : : #include "abi_common.h"
30 : :
31 : : module defs_elphon
32 : :
33 : : use defs_basis
34 : : use m_abicore
35 : : use m_errors
36 : : use m_xmpi
37 : : use m_krank
38 : : use m_crystal
39 : :
40 : : implicit none
41 : :
42 : : private
43 : : !!***
44 : :
45 : : public :: gam_mult_displ
46 : : public :: complete_gamma
47 : : public :: complete_gamma_tr
48 : : public :: mkqptequiv
49 : :
50 : : !----------------------------------------------------------------------
51 : : !!****t* defs_elphon/elph_kgrid_type
52 : : !! NAME
53 : : !! elph_kgrid_type
54 : : !!
55 : : !! FUNCTION
56 : : !! elph_kgrid_type contains k-point grid data and dimensions
57 : : !! this is a sub object of elph_type
58 : : !!
59 : : !! SOURCE
60 : :
61 : : type,public :: elph_kgrid_type
62 : :
63 : : integer :: nband ! number of bands for weights
64 : : integer :: nsppol ! number of spin pol for weights
65 : : integer :: nsym ! number of symmetry operations
66 : : integer :: nkpt ! number of k-points in full grid
67 : : integer :: nkptirr ! number of k-points in irreducible grid
68 : : integer :: new_nkptirr ! number of k-points in irreducible grid
69 : : integer :: my_nkpt ! number of k-points on present processor
70 : :
71 : : type(krank_t) :: krank ! ranking of all kpoints on phonon calculation grid, and inverse rank
72 : :
73 : : integer, allocatable :: irr2full(:) ! correspondence of irred kpoints to a full one
74 : : integer, allocatable :: full2irr(:,:) ! correspondence of full k to one irred kpoints through sym and timrev
75 : : integer, allocatable :: full2full(:,:,:) ! symmetry mapping of kpoints
76 : : integer, allocatable :: my_kpt(:) ! flag for k-points belonging to present proc (= me index of proc for each k-point)
77 : : integer, allocatable :: my_ikpt(:) ! flag for k-points belonging to present proc (= me index of proc for each k-point)
78 : : integer, allocatable :: irredtoGS(:) ! (nkptirr)
79 : : integer, allocatable :: new_irredtoGS(:) ! (new_nkptirr)
80 : :
81 : : real(dp),allocatable :: kpt(:,:) ! coordinates of the full kpoints from phonon calculation
82 : : real(dp),allocatable :: kptirr(:,:) ! irreducible k-points, for preliminary set up
83 : : real(dp),allocatable :: new_kptirr(:,:) ! irreducible k-points, for preliminary set up
84 : : real(dp),allocatable :: wtk(:,:,:) ! integration weights (see also gkk_intweight)
85 : : real(dp),allocatable :: wtq(:,:,:) ! integration weights (see also gkk_intweight)
86 : : real(dp),allocatable :: wtkirr(:) ! weights for irreducible kpoints, to sum over _whole_ BZ (not just Fermi Surface)
87 : : real(dp),allocatable :: new_wtkirr(:) ! weights for irreducible kpoints, to sum over _whole_ BZ (not just Fermi Surface)
88 : : real(dp),allocatable :: velocwtk(:,:,:,:) ! (nFSband,nkpt_fine,3,nsppol), v(k)*wtk
89 : : real(dp),allocatable :: vvelocwtk(:,:,:,:,:) ! (nFSband,nkpt_fine,3,3,nsppol), v(k)*v(k)*wtk
90 : :
91 : : end type elph_kgrid_type
92 : :
93 : : public :: elph_k_copy
94 : : public :: elph_k_procs
95 : : public :: elph_k_destroy
96 : : !!***
97 : :
98 : : !----------------------------------------------------------------------
99 : :
100 : : !!****t* defs_elphon/elph_type
101 : : !! NAME
102 : : !! elph_type
103 : : !!
104 : : !! FUNCTION
105 : : !! elph_type contains data and dimensions for the kpoints near the
106 : : !! fermi surface and the $g_{k k+q}$ matrix elements
107 : : !!
108 : : !! SOURCE
109 : :
110 : : type,public :: elph_type
111 : :
112 : : type(elph_kgrid_type) :: k_phon ! object for k-grid of phonon calculation
113 : : type(elph_kgrid_type) :: k_fine ! object for fine k-grid for FS integration
114 : :
115 : : integer :: natom,nbranch,nFSband,nband
116 : : integer :: minFSband,maxFSband !Index of lower and upper bands used for the FS integration
117 : :
118 : : integer :: ngkkband !Number of bands kept in final gkk matrix elements:
119 : : !either 1 if sum is performed immediately
120 : : !or = nband if all elements are kept based on flag ep_keepbands
121 : :
122 : : integer :: nenergy ! number of points in energy
123 : : ! space for the electron band energies
124 : : ! energies from
125 : : ! ef-nenergy*delta_e to
126 : : ! ef+nenergy*delta_e
127 : :
128 : : integer :: n_pair ! number of pairs considered
129 : :
130 : : integer :: nqpt_full !number of q in full BZ
131 : : integer :: nqptirred !number of irred q-points
132 : :
133 : :
134 : : integer :: unita2f,unit_gkk2,unit_gkk_rpt
135 : : integer :: unitgkq !units for file output
136 : :
137 : : integer :: gkqwrite
138 : : integer :: gkk2write
139 : : integer :: gkk_rptwrite
140 : :
141 : : integer :: ep_scalprod !flag to perform the scalar product
142 : : integer :: symgkq !flag to symmetrize gkq matrix elements
143 : : integer :: ep_keepbands !flag to sum over bands or not
144 : : integer :: ep_lova ! 1 for lova, and 0 for general
145 : : integer :: tuniformgrid !flag to expect uniform grid of q or not
146 : : integer :: prtbltztrp !flag to output BoltzTraP input files
147 : :
148 : : integer :: na2f !dimensions and increments for a2F function
149 : : integer :: nsppol ! number of spin polarization channels
150 : : integer :: nspinor ! number of spinorial components
151 : : integer :: telphint ! flag for integration over the FS with 0=tetrahedra 1=gaussians
152 : : integer :: ep_nspline ! scale factor for spline interpolation in RTA
153 : : integer :: ntemper ! number of temperature points
154 : : integer :: use_k_fine ! flag for using fine k-grids for eigenvalues and velocities. 0=no 1=yes
155 : : integer :: ep_int_gkk ! flag for interpolate gkk(1) or gamma (0)
156 : : integer :: ep_b_min ! first band taken into account in FS integration (if telphint==2)
157 : : integer :: ep_b_max ! last band taken into account in FS integration (if telphint==2)
158 : : integer :: kptrlatt(3,3) ! kpoint grid generating vectors, as in abinit
159 : : integer :: kptrlatt_fine(3,3) ! kpoint grid generating vectors, for fine grid used in FS integration
160 : :
161 : : real(dp) :: delta_e ! step in electronic energies, around Fermi level
162 : : real(dp) :: omega_min,omega_max
163 : : real(dp) :: a2fsmear,domega
164 : : real(dp) :: nelect ! number of electrons per unit cell, eventually with extra charges for carriers in semiconductors.
165 : : real(dp) :: occ_factor ! normalization for integrals over FS, for num of spins, spinors, etc...
166 : :
167 : : real(dp) :: mustar ! mustar parameter
168 : : real(dp) :: fermie ! Fermi energy (Ha), either comes from wfk file or from anaddb input file
169 : : real(dp) :: elphsmear ! smearing width for gaussian integration or buffer in energy for
170 : : ! calculations with tetrahedra (telphint=0)
171 : : real(dp) :: tempermin ! minimum temperature at which resistivity etc are calculated (in K)
172 : : real(dp) :: temperinc ! interval temperature grid on which resistivity etc are calculated (in K)
173 : :
174 : : character(len=fnlen) :: elph_base_name !base name for output files
175 : :
176 : : integer,allocatable :: qirredtofull(:) !mapping between the qpoints found in the GGK file
177 : : !and the array of qpoints generated by the code
178 : :
179 : : real(dp),allocatable :: wtq(:) !weight for each qpoint in the full grid spqt
180 : : !if a point is not in the IBZ ==> wtq=0
181 : : !MG we can also use indqpt
182 : :
183 : : real(dp),allocatable :: n0(:) !DOS at the Fermi level (states/Ha/spin)
184 : : real(dp),allocatable :: qpt_full(:,:) !special q points obtained by the Monkhorst & Pack method,
185 : : !in reduced coordinates
186 : :
187 : :
188 : : real(dp),allocatable :: gkk_intweight(:,:,:) ! (nFSband,nkpt_fine,nsppol)
189 : : !integration weights for gkk matrix elements on FS:
190 : : !if ep_keepbands == 0 all are 1
191 : : !if ep_keepbands == 1 then = to wtk_phon in elphon
192 : : !DOES NOT INCLUDE FACTOR OF 1/nkpt_phon
193 : :
194 : : real(dp),allocatable :: gkk_velocwtk(:,:,:) ! (nFSband,nkpt_fine,nsppol)
195 : :
196 : : real(dp),allocatable :: gkk_vvelocwtk(:,:,:) ! (nFSband,nkpt_fine,nsppol)
197 : :
198 : : real(dp),allocatable :: gkk_qpt(:,:,:,:,:,:) ! (2, ngkkband*ngkkband, nbranch*nbranch, nkpt_phon, nsppol, nqptirred)
199 : : !Now gkq contains gkk2 matrices on basic qpts,
200 : : !summed over bands if ngkkband==1
201 : :
202 : :
203 : : real(dp),allocatable :: gkk_rpt(:,:,:,:,:,:) ! (2, ngkkband**2, nbranch**2, nkpt_phon, nsppol, nrpt)
204 : : !For the moment, gkk_rpt in memory is out of the question
205 : : real(dp),allocatable :: gkk2(:,:,:,:,:,:) ! (nbranch, ngkkband,ngkkband, nkpt_phon, nkpt_phon, nsppol)
206 : :
207 : : real(dp),allocatable :: gamma_qpt(:,:,:,:) !gamma matrices integrated over kpoint coeff
208 : : ! and bands: still depends on qpt
209 : : ! dims= 2, nbranch**2, nsppol, nqpt
210 : : real(dp),allocatable :: gamma_rpt(:,:,:,:)
211 : : ! dims= 2, nbranch**2, nsppol, nrpt
212 : : !NOTE: choice to put nsppol before or after nqpt is a bit arbitrary
213 : : ! abinit uses nband,nkpt,nsppol, but here for convenience nkpt_phon,nsppol,nqpt
214 : : ! as interpolation is on qpt
215 : :
216 : : real(dp),allocatable :: phfrq(:,:) !phonon frequencies
217 : : real(dp),allocatable :: a2f(:,:,:) !a2f function
218 : :
219 : : real(dp),allocatable :: qgrid_data(:,:,:,:) !e-ph values calculated over the irreducible part of the q-grid:
220 : : !first entry = index of the q-point,
221 : : !second index = branch index
222 : : !the third slice contains the frequency, the linewidth and lambda(q,nu)
223 : : !for that particular phonon mode
224 : : ! dims= nqptirred,elph_ds%nbranch,nsppol,3
225 : :
226 : : end type elph_type
227 : :
228 : : public :: elph_ds_clean
229 : : !!***
230 : :
231 : : !----------------------------------------------------------------------
232 : :
233 : : !!****t* defs_elphon/elph_tr_type
234 : : !! NAME
235 : : !! elph_tr_type
236 : : !!
237 : : !! FUNCTION
238 : : !! elph_tr_ds contains the necessary data for the transport properties
239 : : !!
240 : : !! SOURCE
241 : :
242 : : type,public :: elph_tr_type
243 : :
244 : : integer :: ifltransport
245 : : integer :: unitgkq_trin,unitgkq_trout
246 : : integer :: gkqwrite,gkqexist
247 : : integer :: onegkksize
248 : :
249 : : character(len=fnlen) :: ddkfilename
250 : :
251 : : real(dp),allocatable :: dos_n0(:,:) ! (nT,nsppol) DOS at the Fermi level (states/Ha/spin) at input temperatures
252 : : real(dp),allocatable :: dos_n(:,:) ! (nE,nsppol) DOS at the selected energies (states/Ha/spin)
253 : : real(dp),allocatable :: en_all(:,:) ! (nE,nsppol) selected energies
254 : : real(dp),allocatable :: de_all(:,:) ! (nE,nsppol) differences between selected energies
255 : : real(dp),allocatable :: veloc_sq0(:,:,:) ! (3,nsppol,nT)
256 : : real(dp),allocatable :: veloc_sq(:,:,:) ! (3,nsppol,nE)
257 : :
258 : : real(dp),allocatable :: el_veloc(:,:,:,:) ! nkpt nband 3 nsppol
259 : : ! the 9 = 3x3 is for the full tensorial transport coefficients
260 : : real(dp),allocatable :: gamma_qpt_tr(:,:,:,:,:) ! 2 9 branches**2 nsppol qpt
261 : : real(dp),allocatable :: gamma_qpt_trin(:,:,:,:,:) !idem
262 : : real(dp),allocatable :: gamma_qpt_trout(:,:,:,:,:) !idem
263 : :
264 : : real(dp),allocatable :: gamma_rpt_tr(:,:,:,:,:,:,:) !idem
265 : : real(dp),allocatable :: gamma_rpt_trin(:,:,:,:,:) !idem
266 : : real(dp),allocatable :: gamma_rpt_trout(:,:,:,:,:) !idem
267 : :
268 : : real(dp),allocatable :: a2f_1d_tr(:,:,:,:,:,:) ! nfreq 9 nsppol 4 n_pair ntemp
269 : : real(dp),allocatable :: a2f_1d_trin(:,:,:)
270 : : real(dp),allocatable :: a2f_1d_trout(:,:,:)
271 : :
272 : : real(dp),allocatable :: FSelecveloc_sq(:,:) ! 3 nsppol
273 : :
274 : : real(dp),allocatable :: tmp_gkk_intweight(:,:,:,:)
275 : : real(dp),allocatable :: tmp_gkk_intweight1(:,:,:)
276 : : real(dp),allocatable :: tmp_gkk_intweight2(:,:,:)
277 : :
278 : : real(dp),allocatable :: tmp_velocwtk(:,:,:,:,:)
279 : : real(dp),allocatable :: tmp_velocwtk1(:,:,:,:)
280 : : real(dp),allocatable :: tmp_velocwtk2(:,:,:,:)
281 : :
282 : : real(dp),allocatable :: tmp_vvelocwtk(:,:,:,:,:,:)
283 : : real(dp),allocatable :: tmp_vvelocwtk1(:,:,:,:,:)
284 : : real(dp),allocatable :: tmp_vvelocwtk2(:,:,:,:,:)
285 : :
286 : : end type elph_tr_type
287 : :
288 : : public :: elph_tr_ds_clean
289 : : !!***
290 : :
291 : : !----------------------------------------------------------------------
292 : :
293 : : CONTAINS
294 : : !!***
295 : :
296 : : !----------------------------------------------------------------------
297 : :
298 : : !!****f* defs_elphon/elph_ds_clean
299 : : !!
300 : : !! NAME
301 : : !! elph_ds_clean
302 : : !!
303 : : !! FUNCTION
304 : : !! deallocate remaining arrays in the elph_ds datastructure
305 : : !!
306 : : !! INPUTS
307 : : !! elph_ds = elphon datastructure
308 : : !!
309 : : !! SOURCE
310 : :
311 : 15 : subroutine elph_ds_clean(elph_ds)
312 : :
313 : : !Arguments ------------------------------------
314 : : class(elph_type), intent(inout) :: elph_ds
315 : : ! *************************************************************************
316 : :
317 : : !@elph_type
318 [ + - ]: 15 : ABI_SFREE(elph_ds%qirredtofull)
319 [ + - ]: 15 : ABI_SFREE(elph_ds%wtq)
320 [ + - ]: 15 : ABI_SFREE(elph_ds%n0)
321 [ + - ]: 15 : ABI_SFREE(elph_ds%qpt_full)
322 [ + - ]: 15 : ABI_SFREE(elph_ds%gkk_intweight)
323 [ + + ]: 15 : ABI_SFREE(elph_ds%gkk_qpt)
324 [ - + ]: 15 : ABI_SFREE(elph_ds%gkk_rpt)
325 [ - + ]: 15 : ABI_SFREE(elph_ds%gkk2)
326 [ + - ]: 15 : ABI_SFREE(elph_ds%gamma_qpt)
327 [ + - ]: 15 : ABI_SFREE(elph_ds%gamma_rpt)
328 [ - + ]: 15 : ABI_SFREE(elph_ds%phfrq)
329 [ - + ]: 15 : ABI_SFREE(elph_ds%a2f)
330 [ + - ]: 15 : ABI_SFREE(elph_ds%qgrid_data)
331 : :
332 : 15 : call elph_k_destroy (elph_ds%k_phon)
333 : 15 : call elph_k_destroy (elph_ds%k_fine)
334 : :
335 : 15 : call elph_ds%k_fine%krank%free()
336 : :
337 : 15 : end subroutine elph_ds_clean
338 : : !!***
339 : :
340 : : !----------------------------------------------------------------------
341 : :
342 : : !!****f* defs_elphon/elph_tr_ds_clean
343 : : !!
344 : : !! NAME
345 : : !! elph_tr_ds_clean
346 : : !!
347 : : !! FUNCTION
348 : : !! deallocate remaining arrays in the elph_tr_ds datastructure
349 : : !!
350 : : !! INPUTS
351 : : !! elph_tr_ds = elphon transport datastructure
352 : : !!
353 : : !! SOURCE
354 : :
355 : 15 : subroutine elph_tr_ds_clean(elph_tr_ds)
356 : :
357 : : !Arguments ------------------------------------
358 : : class(elph_tr_type), intent(inout) :: elph_tr_ds
359 : : ! *************************************************************************
360 : :
361 : : !@elph_tr_type
362 [ + + ]: 15 : ABI_SFREE(elph_tr_ds%el_veloc)
363 [ + + ]: 15 : ABI_SFREE(elph_tr_ds%FSelecveloc_sq)
364 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%veloc_sq0)
365 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%veloc_sq)
366 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%dos_n0)
367 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%dos_n)
368 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%en_all)
369 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%de_all)
370 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%gamma_qpt_tr)
371 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%gamma_qpt_trin)
372 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%gamma_qpt_trout)
373 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%gamma_rpt_tr)
374 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%gamma_rpt_trin)
375 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%gamma_rpt_trout)
376 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%a2f_1d_tr)
377 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%a2f_1d_trin)
378 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%a2f_1d_trout)
379 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_gkk_intweight)
380 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_gkk_intweight1)
381 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_gkk_intweight2)
382 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_velocwtk)
383 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_velocwtk1)
384 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_velocwtk2)
385 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_vvelocwtk)
386 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_vvelocwtk1)
387 [ - + ]: 15 : ABI_SFREE(elph_tr_ds%tmp_vvelocwtk2)
388 : :
389 : 15 : end subroutine elph_tr_ds_clean
390 : : !!***
391 : :
392 : : !----------------------------------------------------------------------
393 : :
394 : : !!****f* defs_elphon/elph_k_copy
395 : : !!
396 : : !! NAME
397 : : !! elph_k_copy
398 : : !!
399 : : !! FUNCTION
400 : : !! allocate and copy arrays in the elph_k datastructure
401 : : !!
402 : : !! INPUTS
403 : : !! elph_k = elphon k-points datastructure
404 : : !!
405 : : !! NOTES
406 : : !!
407 : : !! SOURCE
408 : :
409 [ # # ]: 0 : subroutine elph_k_copy(elph_k_in, elph_k_out)
410 : :
411 : : !Arguments ------------------------------------
412 : : class(elph_kgrid_type), intent(in) :: elph_k_in
413 : : class(elph_kgrid_type), intent(out) :: elph_k_out
414 : : ! *************************************************************************
415 : :
416 : : !@elph_kgrid_type
417 : 0 : elph_k_out%nband = elph_k_in%nband
418 : 0 : elph_k_out%nsppol = elph_k_in%nsppol
419 : 0 : elph_k_out%nsym = elph_k_in%nsym
420 : :
421 : 0 : elph_k_out%nkpt = elph_k_in%nkpt
422 : 0 : elph_k_out%nkptirr = elph_k_in%nkptirr
423 : :
424 : 0 : elph_k_out%my_nkpt = elph_k_in%my_nkpt
425 : :
426 [ # # # # : 0 : ABI_MALLOC(elph_k_out%my_kpt,(elph_k_out%nkpt))
# # # # #
# # # #
# ]
427 [ # # # # : 0 : elph_k_out%my_kpt = elph_k_in%my_kpt
# # # # #
# # # ]
428 : :
429 [ # # # # : 0 : ABI_MALLOC(elph_k_out%my_ikpt,(elph_k_out%my_nkpt))
# # # # #
# # # #
# ]
430 [ # # # # : 0 : elph_k_out%my_ikpt = elph_k_in%my_ikpt
# # # # #
# # # ]
431 : :
432 [ # # # # : 0 : ABI_MALLOC(elph_k_out%kptirr,(3,elph_k_out%nkptirr))
# # # # #
# # # #
# ]
433 [ # # # # : 0 : elph_k_out%kptirr = elph_k_in%kptirr
# # # # #
# # # # #
# # # # #
# ]
434 [ # # # # : 0 : ABI_MALLOC(elph_k_out%wtkirr,(elph_k_out%nkptirr))
# # # # #
# # # #
# ]
435 [ # # # # : 0 : elph_k_out%wtkirr = elph_k_in%wtkirr
# # # # #
# # # ]
436 : :
437 [ # # # # : 0 : ABI_MALLOC(elph_k_out%wtk,(elph_k_out%nband,elph_k_out%nkpt,elph_k_out%nsppol))
# # # # #
# # # # #
# # # # #
# # # ]
438 [ # # # # : 0 : elph_k_out%wtk = elph_k_in%wtk
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
439 [ # # # # : 0 : ABI_MALLOC(elph_k_out%kpt,(3,elph_k_out%nkpt))
# # # # #
# # # #
# ]
440 [ # # # # : 0 : elph_k_out%kpt = elph_k_in%kpt
# # # # #
# # # # #
# # # # #
# ]
441 : :
442 [ # # # # : 0 : elph_k_out%krank = elph_k_in%krank%copy()
# # ]
443 : :
444 [ # # # # : 0 : ABI_MALLOC(elph_k_out%irr2full,(elph_k_out%nkptirr))
# # # # #
# # # #
# ]
445 [ # # # # : 0 : elph_k_out%irr2full = elph_k_in%irr2full
# # # # #
# # # ]
446 [ # # # # : 0 : ABI_MALLOC(elph_k_out%full2irr,(3,elph_k_out%nkpt))
# # # # #
# # # #
# ]
447 [ # # # # : 0 : elph_k_out%full2irr = elph_k_in%full2irr
# # # # #
# # # # #
# # # # #
# ]
448 [ # # # # : 0 : ABI_MALLOC(elph_k_out%full2full,(2,elph_k_out%nsym,elph_k_out%nkpt))
# # # # #
# # # # #
# # # # ]
449 [ # # # # : 0 : elph_k_out%full2full = elph_k_in%full2full
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
450 : :
451 [ # # # # : 0 : ABI_MALLOC(elph_k_out%irredtoGS,(elph_k_out%nkptirr))
# # # # #
# # # #
# ]
452 [ # # # # : 0 : elph_k_out%irredtoGS = elph_k_in%irredtoGS
# # # # #
# # # ]
453 : :
454 : 0 : end subroutine elph_k_copy
455 : : !!***
456 : :
457 : : !----------------------------------------------------------------------
458 : :
459 : : !!****f* defs_elphon/elph_k_destroy
460 : : !!
461 : : !! NAME
462 : : !! elph_k_destroy
463 : : !!
464 : : !! FUNCTION
465 : : !! deallocate arrays in the elph_k datastructure
466 : : !!
467 : : !! INPUTS
468 : : !! elph_k = elphon k-points datastructure
469 : : !!
470 : : !! SOURCE
471 : :
472 : 30 : subroutine elph_k_destroy(elph_k)
473 : :
474 : : !Arguments ------------------------------------
475 : : class(elph_kgrid_type), intent(inout) :: elph_k
476 : : ! *************************************************************************
477 : :
478 : : !@elph_kgrid_type
479 [ + - ]: 30 : ABI_SFREE(elph_k%irr2full)
480 [ + - ]: 30 : ABI_SFREE(elph_k%full2irr)
481 [ + - ]: 30 : ABI_SFREE(elph_k%full2full)
482 [ + - ]: 30 : ABI_SFREE(elph_k%irredtoGS)
483 [ - + ]: 30 : ABI_SFREE(elph_k%new_irredtoGS)
484 [ + - ]: 30 : ABI_SFREE(elph_k%kpt)
485 [ + - ]: 30 : ABI_SFREE(elph_k%kptirr)
486 [ - + ]: 30 : ABI_SFREE(elph_k%new_kptirr)
487 [ + - ]: 30 : ABI_SFREE(elph_k%my_kpt)
488 [ + - ]: 30 : ABI_SFREE(elph_k%my_ikpt)
489 [ + - ]: 30 : ABI_SFREE(elph_k%wtk)
490 [ - + ]: 30 : ABI_SFREE(elph_k%wtq)
491 [ + - ]: 30 : ABI_SFREE(elph_k%wtkirr)
492 [ - + ]: 30 : ABI_SFREE(elph_k%new_wtkirr)
493 [ - + ]: 30 : ABI_SFREE(elph_k%velocwtk)
494 [ - + ]: 30 : ABI_SFREE(elph_k%vvelocwtk)
495 : :
496 : 30 : call elph_k%krank%free()
497 : :
498 : 30 : end subroutine elph_k_destroy
499 : : !!***
500 : :
501 : : !----------------------------------------------------------------------
502 : :
503 : : !!****f* defs_elphon/elph_k_procs
504 : : !!
505 : : !! NAME
506 : : !! elph_k_procs
507 : : !!
508 : : !! FUNCTION
509 : : !! allocate kpt to processors, in the elph_k datastructure
510 : : !!
511 : : !! INPUTS
512 : : !! nproc = number of k-parallel processors
513 : : !! elph_k = elphon k-points datastructure
514 : : !!
515 : : !! NOTES
516 : : !!
517 : : !! SOURCE
518 : :
519 : 15 : subroutine elph_k_procs(nproc, elph_k)
520 : :
521 : : !Arguments ------------------------------------
522 : : !scalars
523 : : integer, intent(in) :: nproc
524 : : class(elph_kgrid_type), intent(inout) :: elph_k
525 : :
526 : : integer :: ikpt, me, ik_this_proc
527 : : ! *************************************************************************
528 : :
529 [ - + ]: 15 : ABI_SFREE (elph_k%my_kpt)
530 [ - + + - : 45 : ABI_MALLOC (elph_k%my_kpt, (elph_k%nkpt))
+ - + - -
+ - + -
+ ]
531 : :
532 [ + + ]: 1327 : elph_k%my_kpt = 0
533 : 15 : elph_k%my_nkpt = 0
534 : 15 : me = xmpi_comm_rank(xmpi_world)
535 [ + + ]: 1327 : do ikpt = 1, elph_k%nkpt
536 : 1312 : elph_k%my_kpt(ikpt) = MOD(ikpt-1, nproc)
537 [ + - ]: 1327 : if (elph_k%my_kpt(ikpt) == me) elph_k%my_nkpt = elph_k%my_nkpt + 1
538 : : end do
539 : :
540 : : ! create inverse mapping from ik_this_proc to ikpt
541 [ - + ]: 15 : ABI_SFREE (elph_k%my_ikpt)
542 [ - + + - : 45 : ABI_MALLOC (elph_k%my_ikpt, (elph_k%my_nkpt))
+ - + - -
+ - + -
+ ]
543 [ + + ]: 1327 : elph_k%my_ikpt = 0
544 : :
545 : 15 : ik_this_proc = 0
546 [ + + ]: 1327 : do ikpt = 1, elph_k%nkpt
547 [ + - ]: 1327 : if (elph_k%my_kpt(ikpt) == me) then
548 : 1312 : ik_this_proc = ik_this_proc + 1
549 : 1312 : elph_k%my_ikpt(ik_this_proc) = ikpt
550 : : end if
551 : : end do
552 [ - + ]: 15 : ABI_CHECK(ik_this_proc == elph_k%my_nkpt, 'found inconsistent k distribution in processors')
553 : :
554 : 15 : write (std_out,*) 'elph_k_procs : nkpt, distrib = ', elph_k%my_nkpt
555 : 15 : write (std_out,*) elph_k%my_kpt
556 : 15 : write (std_out,*) elph_k%my_ikpt
557 : :
558 : 15 : end subroutine elph_k_procs
559 : : !!***
560 : :
561 : : !----------------------------------------------------------------------
562 : :
563 : : !!****f* defs_elphon/gam_mult_displ
564 : : !!
565 : : !! NAME
566 : : !! gam_mult_displ
567 : : !!
568 : : !! FUNCTION
569 : : !! This routine takes the bare gamma matrices and multiplies them
570 : : !! by the displ_red matrices (related to the scalprod variable)
571 : : !!
572 : : !! INPUTS
573 : : !! nbranch = number of phonon branches (3*natom)
574 : : !! displ_red = phonon mode displacement vectors in reduced coordinates.
575 : : !! gam_bare = bare gamma matrices before multiplication
576 : : !!
577 : : !! OUTPUT
578 : : !! gam_now = output gamma matrices multiplied by displacement matrices
579 : : !!
580 : : !! SOURCE
581 : :
582 : 48368 : subroutine gam_mult_displ(nbranch, displ_red, gam_bare, gam_now)
583 : :
584 : : !Arguments -------------------------------
585 : : integer, intent(in) :: nbranch
586 : : real(dp), intent(in) :: displ_red(2,nbranch,nbranch)
587 : : real(dp), intent(in) :: gam_bare(2,nbranch,nbranch)
588 : : real(dp), intent(out) :: gam_now(2,nbranch,nbranch)
589 : :
590 : : !Local variables -------------------------
591 : 48368 : real(dp) :: zgemm_tmp_mat(2,nbranch,nbranch)
592 : : ! *********************************************************************
593 : :
594 [ + + + + : 4337936 : gam_now = zero
+ + ]
595 : :
596 : 48368 : call zgemm('c','n',nbranch,nbranch,nbranch,cone,displ_red,nbranch,gam_bare,nbranch,czero,zgemm_tmp_mat,nbranch)
597 : 48368 : call zgemm('n','n',nbranch,nbranch,nbranch,cone,zgemm_tmp_mat,nbranch,displ_red,nbranch,czero,gam_now,nbranch)
598 : :
599 : 48368 : end subroutine gam_mult_displ
600 : : !!***
601 : :
602 : : !!****f* ABINIT/complete_gamma
603 : : !!
604 : : !! NAME
605 : : !! complete_gamma
606 : : !!
607 : : !! FUNCTION
608 : : !! Use the set of special q points calculated by the Monkhorst & Pack Technique.
609 : : !! Check if all the information for the q points are present in the input gamma matrices.
610 : : !! Generate the gamma matrices (already summed over the FS) of the set of q points which
611 : : !! samples homogeneously the entire Brillouin zone.
612 : : !!
613 : : !! INPUTS
614 : : !! qpttoqpt = qpoint index mapping under symops
615 : : !!
616 : : !! OUTPUT
617 : : !! gamma_qpt = in/out: set of gamma matrix elements completed and symmetrized
618 : : !! gamma_qpt(2,nbranch**2,nsppol,nqpt_full)
619 : : !!
620 : : !! SOURCE
621 : :
622 : 19 : subroutine complete_gamma(Cryst,nbranch,nsppol,nqptirred,nqpt_full,ep_scalprod,qirredtofull,qpttoqpt,gamma_qpt)
623 : :
624 : : !Arguments ------------------------------------
625 : : !scalars
626 : : integer,intent(in) :: nsppol,nbranch,nqptirred,nqpt_full,ep_scalprod
627 : : type(crystal_t),intent(in) :: Cryst
628 : : !arrays
629 : : integer,intent(in) :: qirredtofull(nqptirred)
630 : : integer,intent(in) :: qpttoqpt(2,Cryst%nsym,nqpt_full)
631 : : real(dp), intent(inout) :: gamma_qpt(2,nbranch**2,nsppol,nqpt_full)
632 : :
633 : : !Local variables-------------------------------
634 : : !scalars
635 : : integer :: ibranch,ieqqpt,natom,nsym,iqpt,isppol,isym
636 : : integer :: itim,jbranch,neqqpt,iatom,ancestor_iatom,iqpt_fullbz
637 : : !arrays
638 : 38 : integer :: symmetrized_qpt(nqpt_full)
639 : 38 : integer :: gkk_flag(nbranch,nbranch,nsppol,nqpt_full)
640 : : real(dp) :: ss(3,3)
641 : 38 : real(dp) :: tmp_mat(2,nbranch,nbranch)
642 : 38 : real(dp) :: tmp_mat2(2,nbranch,nbranch)
643 : 38 : real(dp) :: ss_allatoms(2,nbranch,nbranch)
644 : : complex(dp) :: c_one, c_zero
645 : 19 : real(dp),allocatable :: gkk_qpt_new(:,:,:),gkk_qpt_tmp(:,:,:)
646 : : ! *********************************************************************
647 : :
648 : 19 : c_one = dcmplx(one,zero)
649 : 19 : c_zero = dcmplx(zero,zero)
650 : :
651 : 19 : natom = Cryst%natom
652 : 19 : nsym = Cryst%nsym
653 : :
654 : : !Generation of the gkk matrices relative to the q points
655 : : !of the set which samples the entire Brillouin zone
656 : :
657 : : !set up flags for gamma_qpt matrices we have
658 [ + + + + : 13163 : gkk_flag = -1
+ + + + ]
659 [ + + ]: 125 : do iqpt=1,nqptirred
660 : 106 : iqpt_fullbz = qirredtofull(iqpt)
661 [ + + + + : 1902 : gkk_flag(:,:,:,iqpt_fullbz) = 1
+ + ]
662 : : end do
663 : :
664 [ + + ]: 899 : symmetrized_qpt(:) = -1
665 : :
666 [ - + + - : 76 : ABI_MALLOC(gkk_qpt_new,(2,nbranch**2,nsppol))
- + + - +
- + - - +
- + ]
667 [ - + + - : 57 : ABI_MALLOC(gkk_qpt_tmp,(2,nbranch**2,nsppol))
- + + - -
+ + - ]
668 : :
669 [ + + ]: 899 : do iqpt=1,nqpt_full
670 : : !
671 : : ! Already symmetrized?
672 [ + + ]: 880 : if (symmetrized_qpt(iqpt) == 1) cycle
673 : :
674 [ + + + + : 4130 : gkk_qpt_new(:,:,:) = zero
+ + ]
675 : :
676 : : ! loop over qpoints equivalent to iqpt
677 : : neqqpt=0
678 : : ! do not use time reversal symmetry to complete the qpoints:
679 : : ! do not know what happens to the gamma matrices
680 : : ! 11/2011: MJV: time reversal is needed here if inversion is absent
681 : : ! - used in read_gkk and all reductions of q-points by symmetry.
682 : :
683 [ + + ]: 318 : do itim=1,2
684 [ + + ]: 9822 : do isym=1,nsym
685 : : ! ieqqpt is sent onto iqpt by itim/isym
686 : 9504 : ieqqpt = qpttoqpt(itim,isym,iqpt)
687 : :
688 : :
689 [ + + ]: 9504 : if (gkk_flag(1,1,1,ieqqpt) == -1) cycle
690 : : ! if we have information on this qpt
691 : : ! iqpt is equivalent to ieqqpt: get it from file or memory
692 [ + + + + : 121932 : gkk_qpt_tmp(:,:,:) = gamma_qpt(:,:,:,ieqqpt)
+ + ]
693 : :
694 : 3164 : neqqpt=neqqpt+1
695 : :
696 : : !
697 : : ! MJV note 02/2010:
698 : : ! the correspondence of symrel and symrec in the different cases, symmetrizing there
699 : : ! and back, has been fixed in the cases with and without scalprod (ie cartesian
700 : : ! and reduced real space coordinates) with respect to a calculation with no symmetries
701 : : ! I believe everything is settled, but still do not know why the 2 versions of the ss
702 : : ! matrices here use different rel/rec, instead of just being multiplied by the rprim gprim...
703 : : !
704 [ + + ]: 3164 : if (ep_scalprod==1) then
705 : : ! ss(ii,jj)=ss(ii,jj)+Cryst%rprimd(ii,kk)*Cryst%symrel(kk,ll,isym)*Cryst%gprimd(ll,jj)
706 [ + + + + : 63248 : ss(:,:) = MATMUL(Cryst%rprimd, MATMUL(Cryst%symrel(:,:,isym), Cryst%gprimd))
+ - - + +
- + - + -
+ - - + -
+ + + + +
+ + + + +
+ + - + -
+ + + + +
+ + - + -
+ - ]
707 : : else
708 : : ! ss(ii,jj) = Cryst%symrec(ii,jj,isym)
709 [ + + + + ]: 34996 : ss(:,:) = Cryst%symrec(:,:,isym)
710 : : end if
711 : :
712 [ + + + + : 124964 : ss_allatoms(:,:,:) = zero
+ + ]
713 [ + + ]: 6648 : do iatom=1,natom
714 : 3484 : ancestor_iatom = Cryst%indsym(4,isym,iatom)
715 [ + + + + ]: 48456 : ss_allatoms(1, (ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3, (iatom-1)*3+1:(iatom-1)*3+3) = ss(1:3,1:3)
716 : : end do
717 : :
718 : :
719 : : ! NOTE ssinv(ii,jj)=ssinv(ii,jj)+Cryst%gprimd(ii,kk)*rprimd(jj,ll)*Cryst%symrec(ll,kk,isym)
720 : :
721 [ + + ]: 6692 : do isppol=1,nsppol
722 : : ! multiply by the ss matrices
723 [ + + + + : 129676 : tmp_mat2(:,:,:) = zero
+ + ]
724 [ + + ]: 13264 : tmp_mat(:,:,:) = reshape(gkk_qpt_tmp(:,:,isppol),(/2,nbranch,nbranch/))
725 : :
726 : : call ZGEMM ('N','N',nbranch,nbranch,nbranch,&
727 : 3316 : & c_one,ss_allatoms,nbranch,tmp_mat,nbranch,c_zero,tmp_mat2,nbranch)
728 : :
729 : : call ZGEMM ('N','T',nbranch,nbranch,nbranch,&
730 : 3316 : & c_one,tmp_mat2,nbranch,ss_allatoms,nbranch,c_zero,tmp_mat,nbranch)
731 : :
732 : : ! add to gkk_qpt_new
733 [ + + ]: 23728 : do ibranch =1,nbranch
734 [ + + ]: 52708 : do jbranch =1,nbranch
735 : : gkk_qpt_new(:,(jbranch-1)*nbranch+ibranch,isppol) = &
736 [ + + ]: 126360 : & gkk_qpt_new(:,(jbranch-1)*nbranch+ibranch,isppol) + tmp_mat(:,jbranch,ibranch)
737 : : end do
738 : : end do
739 : : end do ! isppol
740 : : !
741 : : end do ! isym
742 : : end do ! itim
743 : : !
744 [ - + ]: 106 : ABI_CHECK(neqqpt>0,'no q-points found equivalent to iqpt ')
745 : : ! Divide by number of equivalent qpts found.
746 [ + + + + : 4130 : gkk_qpt_new(:,:,:) = gkk_qpt_new(:,:,:)/neqqpt
+ + ]
747 : :
748 : : ! copy the symmetrized version into all the equivalent qpoints, appropriately transformed
749 [ + + ]: 337 : do itim=1,2
750 [ + + ]: 10596 : do isym=1,nsym
751 : : ! ieqqpt is sent onto iqpt by itim/isym
752 : 9504 : ieqqpt = qpttoqpt(itim,isym,iqpt)
753 : :
754 [ + + ]: 9504 : if (symmetrized_qpt(ieqqpt) /= -1) cycle
755 [ + + + + : 27688 : gkk_qpt_tmp(:,:,:) = zero
+ + ]
756 : :
757 : : ! use symrec matrices to get inverse transform from isym^{-1}
758 [ + + ]: 880 : if (ep_scalprod==1) then
759 : : ! Use inverse of symop matrix here to get back to ieqqpt (inv+transpose is in symrec and in gprimd)
760 : : ! ss(ii,jj)=ss(ii,jj)+Cryst%rprimd(ii,kk)*Cryst%symrec(ll,kk,isym)*Cryst%gprimd(ll,jj)
761 [ + + + + : 4288 : ss(:,:) = MATMUL(Cryst%rprimd, MATMUL(TRANSPOSE(Cryst%symrec(:,:,isym)), Cryst%gprimd))
+ - - + +
- + - + -
+ - - + -
+ + + + +
+ + + + +
+ + - + -
+ + + + +
+ + - + -
+ - ]
762 : : else
763 : : ! ss(ii,jj) = Cryst%symrel(jj,ii,isym)
764 [ + + + + ]: 11024 : ss(:,:) = TRANSPOSE(Cryst%symrel(:,:,isym))
765 : : end if
766 : :
767 [ + + + + : 29296 : ss_allatoms(:,:,:) = zero
+ + ]
768 [ + + ]: 1784 : do iatom=1,natom
769 : 904 : ancestor_iatom = Cryst%indsym(4,isym,iatom)
770 [ + + + + ]: 12632 : ss_allatoms(1, (ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3, (iatom-1)*3+1:(iatom-1)*3+3) = ss(1:3,1:3)
771 : : end do
772 : :
773 : : ! ! Use inverse of symop matrix here to get back to ieqqpt
774 : : ! ssinv(ii,jj)=ssinv(ii,jj)+gprimd(ii,kk)*rprimd(jj,ll)*Cryst%symrel(kk,ll,isym)
775 : :
776 [ + + ]: 1768 : do isppol=1,nsppol
777 : : ! multiply by the ss^{-1} matrices
778 [ + + + + : 29544 : tmp_mat2(:,:,:) = zero
+ + ]
779 [ + + ]: 3552 : tmp_mat(:,:,:) = reshape(gkk_qpt_new(:,:,isppol),(/2,nbranch,nbranch/))
780 : :
781 : : call ZGEMM ('N','N',nbranch,nbranch,nbranch,&
782 : 888 : & c_one,ss_allatoms,nbranch,tmp_mat,nbranch,c_zero,tmp_mat2,nbranch)
783 : :
784 : : call ZGEMM ('N','T',nbranch,nbranch,nbranch,&
785 : 888 : & c_one,tmp_mat2,nbranch,ss_allatoms,nbranch,c_zero,tmp_mat,nbranch)
786 : :
787 : : ! FIXME: the following could just be a reshape
788 [ + + ]: 3624 : do ibranch =1,nbranch
789 [ + + ]: 12264 : do jbranch =1,nbranch
790 : : gkk_qpt_tmp(:,(jbranch-1)*nbranch+ibranch,isppol) =&
791 [ + + ]: 28656 : & tmp_mat(:,jbranch,ibranch)
792 : : end do
793 : : end do
794 [ + + + + : 11476 : if (gkk_flag (1,1,isppol,ieqqpt) == -1) gkk_flag (:,:,isppol,ieqqpt) = 0
+ + ]
795 : : end do ! end isppol do
796 : :
797 : : ! save symmetrized matrices for qpt ieqqpt
798 [ + + + + : 27688 : gamma_qpt(:,:,:,ieqqpt) = gkk_qpt_tmp(:,:,:)
+ + ]
799 : :
800 : 9716 : symmetrized_qpt(ieqqpt) = 1
801 : :
802 : : end do !isym
803 : : end do !itim
804 : : end do !iqpt
805 : :
806 [ - + ]: 19 : ABI_FREE(gkk_qpt_new)
807 [ - + ]: 19 : ABI_FREE(gkk_qpt_tmp)
808 : :
809 : 19 : end subroutine complete_gamma
810 : : !!***
811 : :
812 : : !!****f* ABINIT/complete_gamma_tr
813 : : !!
814 : : !! NAME
815 : : !! complete_gamma_tr
816 : : !!
817 : : !! FUNCTION
818 : : !! Use the set of special q points calculated by the Monkhorst & Pack Technique.
819 : : !! Check if all the information for the q points are present in
820 : : !! the input gamma transport matrices.
821 : : !! Generate the gamma transport matrices (already summed over the FS) of the set of q points which
822 : : !! samples homogeneously the entire Brillouin zone.
823 : : !!
824 : : !! INPUTS
825 : : !! crystal<crystal_t>=data type gathering info on the crystalline structure.
826 : : !! ep_scalprod= flag for scalar product of gkk with phonon displacement vectors
827 : : !! nbranch=number of phonon branches = 3*natom
828 : : !! nqptirred=nqpt irred BZ
829 : : !! nqpt_full=nqpt full BZ
830 : : !! nsppol=number of spins
831 : : !! qirredtofull= mapping irred to full qpoints
832 : : !! qpttoqpt = qpoint index mapping under symops
833 : : !!
834 : : !! OUTPUT
835 : : !! gamma_qpt_tr = in/out: set of gamma matrix elements completed and symmetrized
836 : : !! gamma_qpt_tr(2,9,nbranch*nbranch,nsppol,nqpt_full)
837 : : !!
838 : : !! SOURCE
839 : :
840 : 10 : subroutine complete_gamma_tr(crystal,ep_scalprod,nbranch,nqptirred,nqpt_full,nsppol,gamma_qpt_tr,qirredtofull,qpttoqpt)
841 : :
842 : : use m_linalg_interfaces
843 : :
844 : : !Arguments ------------------------------------
845 : : !scalars
846 : : integer, intent(in) :: nbranch,nqptirred,nqpt_full,nsppol, ep_scalprod
847 : : type(crystal_t),intent(in) :: crystal
848 : : !arrays
849 : : integer,intent(in) :: qpttoqpt(2,crystal%nsym,nqpt_full)
850 : : integer,intent(in) :: qirredtofull(nqptirred)
851 : : real(dp), intent(inout) :: gamma_qpt_tr(2,9,nbranch*nbranch,nsppol,nqpt_full)
852 : :
853 : : !Local variables-------------------------------
854 : : !scalars
855 : : integer :: ieqqpt,iqpt,isppol,isym
856 : : integer :: itim,neqqpt
857 : : integer :: iatom,ancestor_iatom
858 : : integer :: iqpt_fullbz,imode, itensor,reim
859 : : real(dp),parameter :: tol=2.d-8
860 : : !arrays
861 : 20 : integer :: symrel(3,3,crystal%nsym),symrec(3,3,crystal%nsym)
862 : 20 : integer :: symmetrized_qpt(nqpt_full)
863 : 20 : integer :: gkk_flag(nbranch,nbranch,nsppol,nqpt_full)
864 : : real(dp) :: gprimd(3,3),rprimd(3,3)
865 : : real(dp) :: ss(3,3), sscart(3,3)
866 : 20 : real(dp) :: tmp_mat(nbranch,nbranch)
867 : 20 : real(dp) :: tmp_mat2(nbranch,nbranch)
868 : : real(dp) :: tmp_tensor(3,3)
869 : : real(dp) :: tmp_tensor2(3,3)
870 : 20 : real(dp) :: ss_allatoms(nbranch,nbranch)
871 : 10 : real(dp),allocatable :: gkk_qpt_new(:,:,:,:),gkk_qpt_tmp(:,:,:,:)
872 : : ! *********************************************************************
873 : :
874 [ + + + + ]: 130 : gprimd = crystal%gprimd
875 [ + + + + ]: 130 : rprimd = crystal%rprimd
876 : :
877 [ + + + + : 4066 : symrec = crystal%symrec
+ + ]
878 [ + + + + : 4066 : symrel = crystal%symrel
+ + ]
879 : :
880 : : !Generation of the gkk matrices relative to the q points
881 : : !of the set which samples the entire Brillouin zone
882 : :
883 : : !set up flags for gamma_qpt matrices we have
884 [ + + + + : 2570 : gkk_flag = -1
+ + + + ]
885 [ + + ]: 46 : do iqpt=1,nqptirred
886 : 36 : iqpt_fullbz = qirredtofull(iqpt)
887 [ + + + + : 1234 : gkk_flag(:,:,:,iqpt_fullbz) = 1
+ + ]
888 : : end do
889 : :
890 [ + + ]: 90 : symmetrized_qpt(:) = -1
891 : : ! isppol=1
892 : :
893 [ - + + - : 40 : ABI_MALLOC(gkk_qpt_new,(2,9,nbranch*nbranch, nsppol))
- + + - +
- + - - +
- + ]
894 [ - + + - : 30 : ABI_MALLOC(gkk_qpt_tmp,(2,9,nbranch*nbranch, nsppol))
- + + - -
+ + - ]
895 : :
896 [ + + ]: 90 : do iqpt=1,nqpt_full
897 : :
898 : : ! Already symmetrized?
899 [ + + ]: 80 : if (symmetrized_qpt(iqpt) == 1) cycle
900 : :
901 [ + + + + : 27288 : gkk_qpt_new(:,:,:,:) = zero
+ + + + ]
902 : :
903 : : ! loop over qpoints equivalent to iqpt
904 : : neqqpt=0
905 : : ! do not use time reversal symmetry to complete the qpoints:
906 : : ! do not know what happens to the gamma matrices
907 : :
908 [ + + ]: 108 : do itim=1,2
909 [ + + ]: 2220 : do isym=1,crystal%nsym
910 : : ! ieqqpt is sent onto iqpt by itim/isym
911 : 2112 : ieqqpt = qpttoqpt(itim,isym,iqpt)
912 : :
913 [ + + ]: 2112 : if (gkk_flag(1,1,1,ieqqpt) == -1) cycle
914 : : ! if we have information on this qpt
915 : : ! iqpt is equivalent to ieqqpt: get it from file or memory
916 [ + + + + : 800832 : gkk_qpt_tmp(:,:,:,:) = gamma_qpt_tr(:,:,:,:,ieqqpt)
+ + + + ]
917 : :
918 : 1248 : neqqpt=neqqpt+1
919 : :
920 : : !
921 : : ! MJV note 02/2010:
922 : : ! the correspondence of symrel and symrec in the different cases, symmetrizing there
923 : : ! and back, has been fixed in the cases with and without scalprod (ie cartesian
924 : : ! and reduced real space coordinates) with respect to a calculation with no symmetries
925 : : ! I believe everything is settled, but still do not know why the 2 versions of the ss
926 : : ! matrices here use different rel/rec, instead of just being multiplied by the rprim gprim...
927 : : !
928 : : ! sscart(ii,jj)=sscart(ii,jj)+rprimd(ii,kk)*symrel(kk,ll,isym)*gprimd(ll,jj)
929 [ + + + + : 113568 : sscart(:,:) = MATMUL(rprimd, MATMUL(symrel(:,:,isym), gprimd))
+ + + + +
+ + + + +
+ + ]
930 [ + + ]: 1248 : if (ep_scalprod==1) then
931 : : ! ss(ii,jj)=ss(ii,jj)+rprimd(ii,kk)*symrel(kk,ll,isym)*gprimd(ll,jj)
932 [ + + + + : 85904 : ss(:,:) = MATMUL(rprimd, MATMUL(symrel(:,:,isym), gprimd))
+ + + + +
+ + + + +
+ + ]
933 : : else
934 : : ! ss(ii,jj) = symrec(ii,jj,isym)
935 [ + + + + ]: 3952 : ss(:,:) = symrec(:,:,isym)
936 : : end if
937 : :
938 [ + + + + ]: 35424 : ss_allatoms(:,:) = zero
939 [ + + ]: 3136 : do iatom=1,crystal%natom
940 : 1888 : ancestor_iatom = crystal%indsym(4,isym,iatom)
941 : : ss_allatoms((ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3,&
942 [ + + + + ]: 25792 : & (iatom-1)*3+1: (iatom-1)*3+3) = ss(1:3,1:3)
943 : : end do
944 : :
945 : :
946 : : ! NOTE ssinv(ii,jj)=ssinv(ii,jj)+gprimd(ii,kk)*rprimd(jj,ll)*symrec(ll,kk,isym)
947 : :
948 [ + + ]: 2568 : do isppol=1,nsppol
949 : :
950 : : ! for each tensor component, rotate the cartesian directions of phonon modes
951 [ + + ]: 12480 : do itensor = 1, 9
952 [ + + ]: 34944 : do reim=1,2 ! Real/Imaginary parts
953 : : ! Multiply by the ss matrices
954 [ + + + + ]: 637632 : tmp_mat2(:,:) = zero
955 [ + + ]: 67392 : tmp_mat(:,:) = reshape(gkk_qpt_tmp(reim,itensor,:,isppol),(/nbranch,nbranch/))
956 : 22464 : call DGEMM ('N','N',nbranch,nbranch,nbranch,one,ss_allatoms,nbranch,tmp_mat,nbranch,zero,tmp_mat2,nbranch)
957 : 22464 : call DGEMM ('N','T',nbranch,nbranch,nbranch,one,tmp_mat2,nbranch,ss_allatoms,nbranch,zero,tmp_mat,nbranch)
958 [ + + + + ]: 569376 : gkk_qpt_tmp(reim,itensor,:,isppol) = reshape (tmp_mat, (/nbranch*nbranch/))
959 : : enddo
960 : : end do ! itensor
961 : :
962 : : ! for each cartesian direction/phonon mode, rotate the tensor components
963 [ + + ]: 29760 : do imode = 1, nbranch*nbranch
964 [ + + ]: 86784 : do reim=1,2 ! Real/Imaginary parts
965 : 57024 : tmp_tensor2(:,:) = zero
966 : 57024 : tmp_tensor(:,:) = reshape(gkk_qpt_tmp(reim,:,imode,isppol),(/3,3/))
967 : 57024 : call DGEMM ('N','N',3,3,3,one,sscart,3,tmp_tensor,3,zero,tmp_tensor2,3)
968 : 57024 : call DGEMM ('N','T',3,3,3,one,tmp_tensor2,3,sscart,3,zero,tmp_tensor,3)
969 [ + + ]: 598752 : gkk_qpt_tmp(reim,:,imode,isppol) = reshape (tmp_tensor, (/9/)) ! modified by BX
970 : : enddo
971 : : end do ! imode
972 : :
973 : : ! add to gkk_qpt_new
974 [ + + + + : 800832 : gkk_qpt_new(:,:,:,isppol) = gkk_qpt_new(:,:,:,isppol) + gkk_qpt_tmp(:,:,:,isppol)
+ + ]
975 : :
976 : : end do ! end isppol do
977 : :
978 : : end do ! end isym do
979 : : end do ! end itim do
980 : :
981 [ - + ]: 36 : ABI_CHECK(neqqpt>0,'no q-points found equivalent to iqpt ')
982 : :
983 : : ! divide by number of equivalent qpts found
984 [ + + + + : 27288 : gkk_qpt_new = gkk_qpt_new/neqqpt
+ + + + ]
985 : :
986 : :
987 : : ! copy the symmetrized version into all the equivalent qpoints, appropriately transformed
988 [ + + ]: 118 : do itim=1,2
989 [ + + ]: 2264 : do isym=1,crystal%nsym
990 : : ! ieqqpt is sent onto iqpt by itim/isym
991 : 2112 : ieqqpt = qpttoqpt(itim,isym,iqpt)
992 : :
993 [ + + ]: 2112 : if (symmetrized_qpt(ieqqpt) /= -1) cycle
994 [ + + + + : 56608 : gkk_qpt_tmp = zero
+ + + + ]
995 : :
996 : : ! use symrec matrices to get inverse transform from isym^{-1}
997 : : ! Use inverse of symop matrix here to get back to ieqqpt (inv+transpose is in symrec and in gprimd)
998 : : ! sscart(ii,jj)=sscart(ii,jj)+rprimd(ii,kk)*symrec(ll,kk,isym)*gprimd(ll,jj)
999 : : ! sscart(ii,jj)=sscart(ii,jj)+rprimd(ii,kk)*symrec(ll,kk,isym)*gprimd(ll,jj)
1000 [ + + + + : 7280 : sscart(:,:) = MATMUL(rprimd, MATMUL(TRANSPOSE(symrec(:,:,isym)), gprimd))
+ + + + +
+ + + + +
+ + ]
1001 [ + + ]: 80 : if (ep_scalprod==1) then
1002 : : ! Use inverse of symop matrix here to get back to ieqqpt (inv+transpose is in symrec and in gprimd)
1003 : : ! ss(ii,jj)=ss(ii,jj)+rprimd(ii,kk)*symrec(ll,kk,isym)*gprimd(ll,jj)
1004 [ + + + + : 5824 : ss(:,:) = MATMUL(rprimd, MATMUL(TRANSPOSE(symrec(:,:,isym)), gprimd))
+ + + + +
+ + + + +
+ + ]
1005 : :
1006 : : else
1007 : : ! ss(ii,jj) = symrel(jj,ii,isym)
1008 [ + + + + ]: 208 : ss(:,:) = TRANSPOSE(symrel(:,:,isym))
1009 : : end if
1010 : :
1011 [ + + + + ]: 2480 : ss_allatoms(:,:) = zero
1012 [ + + ]: 208 : do iatom=1,crystal%natom
1013 : 128 : ancestor_iatom = crystal%indsym(4,isym,iatom)
1014 : : ss_allatoms((ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3,&
1015 [ + + + + ]: 1744 : & (iatom-1)*3+1: (iatom-1)*3+3) = ss(1:3,1:3)
1016 : : end do
1017 : :
1018 : : ! ! Use inverse of symop matrix here to get back to ieqqpt
1019 : : ! ssinv(ii,jj)=ssinv(ii,jj)+gprimd(ii,kk)*rprimd(jj,ll)*symrel(kk,ll,isym)
1020 : :
1021 [ + + ]: 160 : do isppol=1,nsppol
1022 [ + + ]: 800 : do itensor = 1, 9
1023 [ + + ]: 2240 : do reim=1,2 ! Real/Imaginary parts
1024 : : ! Multiply by the ss^{-1} matrices
1025 [ + + + + ]: 44640 : tmp_mat2(:,:) = zero
1026 [ + + ]: 4320 : tmp_mat(:,:) = reshape(gkk_qpt_new(reim,itensor,:,isppol),(/nbranch,nbranch/))
1027 : 1440 : call DGEMM ('N','N',nbranch,nbranch,nbranch,one,ss_allatoms,nbranch,tmp_mat,nbranch,zero,tmp_mat2,nbranch)
1028 : 1440 : call DGEMM ('N','T',nbranch,nbranch,nbranch,one,tmp_mat2,nbranch,ss_allatoms,nbranch,zero,tmp_mat,nbranch)
1029 [ + + + + ]: 39888 : gkk_qpt_tmp(reim,itensor,:,isppol) = reshape (tmp_mat, (/nbranch*nbranch/))
1030 : : enddo
1031 : : end do ! itensor
1032 : :
1033 : : ! for each cartesian direction/phonon mode, rotate the tensor components
1034 [ + + ]: 2096 : do imode = 1, nbranch*nbranch
1035 [ + + ]: 6128 : do reim=1,2 ! Real/Imaginary parts
1036 : 4032 : tmp_tensor2(:,:) = zero
1037 : 4032 : tmp_tensor(:,:) = reshape(gkk_qpt_tmp(reim,:,imode,isppol),(/3,3/))
1038 : 4032 : call DGEMM ('N','N',3,3,3,one,sscart,3,tmp_tensor,3,zero,tmp_tensor2,3)
1039 : 4032 : call DGEMM ('N','T',3,3,3,one,tmp_tensor2,3,sscart,3,zero,tmp_tensor,3)
1040 : : ! gkk_qpt_new(:,:,imode,isppol) = reshape (tmp_tensor, (/2,9/)) ! Modified by BX
1041 [ + + ]: 42336 : gkk_qpt_tmp(reim,:,imode,isppol) = reshape (tmp_tensor, (/9/)) ! Modified by BX
1042 : : enddo
1043 : : end do ! imode
1044 : :
1045 [ + + ]: 160 : if (gkk_flag (1,1,isppol,ieqqpt) == -1) then
1046 [ + + + + ]: 1292 : gkk_flag (:,:,isppol,ieqqpt) = 0
1047 : : end if
1048 : :
1049 : : end do ! end isppol do
1050 : :
1051 : :
1052 : : ! save symmetrized matrices for qpt ieqqpt
1053 [ + + + + : 56608 : gamma_qpt_tr(:,:,:,:,ieqqpt) = gkk_qpt_tmp(:,:,:,:)
+ + + + ]
1054 : :
1055 : 152 : symmetrized_qpt(ieqqpt) = 1
1056 : :
1057 : : end do ! end isym do
1058 : : end do ! end itim do
1059 : :
1060 : : end do
1061 : : !end iqpt do
1062 : :
1063 [ - + ]: 10 : ABI_FREE(gkk_qpt_new)
1064 [ - + ]: 10 : ABI_FREE(gkk_qpt_tmp)
1065 : :
1066 : 10 : end subroutine complete_gamma_tr
1067 : : !!***
1068 : :
1069 : : !----------------------------------------------------------------------
1070 : :
1071 : : !!****f* m_fstab/mkqptequiv
1072 : : !! NAME
1073 : : !! mkqptequiv
1074 : : !!
1075 : : !! FUNCTION
1076 : : !! This routine determines the equivalence between
1077 : : !! 1) qpoints and fermi surface kpoints
1078 : : !! 2) qpoints under symmetry operations
1079 : : !!
1080 : : !! INPUTS
1081 : : !! Cryst<crystal_t>=Info on unit cell and symmetries.
1082 : : !! kpt_phon = fermi surface kpoints
1083 : : !! nkpt_phon = number of kpoints in the full FS set
1084 : : !! nqpt = number of qpoints
1085 : : !! qpt_full = qpoint coordinates
1086 : : !!
1087 : : !! OUTPUT
1088 : : !! FSfullpqtofull = mapping of k + q onto k' for k and k' in full BZ
1089 : : !! qpttoqpt(itim,isym,iqpt) = qpoint index which transforms to iqpt under isym and with time reversal itim.
1090 : : !!
1091 : : !! NOTES
1092 : : !! REMOVED 3/6/2008: much too large matrix, and not used at present
1093 : : !! FStoqpt = mapping of kpoint pairs (1 irreducible and 1 full) to qpoints
1094 : : !!
1095 : : !! SOURCE
1096 : :
1097 : 15 : subroutine mkqptequiv(FSfullpqtofull,Cryst,kpt_phon,nkpt_phon,nqpt,qpttoqpt,qpt_full,mqtofull)
1098 : :
1099 : : !Arguments ------------------------------------
1100 : : !scalars
1101 : : integer,intent(in) :: nkpt_phon,nqpt
1102 : : type(crystal_t),intent(in) :: Cryst
1103 : : !arrays
1104 : : integer,intent(out) :: FSfullpqtofull(nkpt_phon,nqpt),qpttoqpt(2,Cryst%nsym,nqpt)
1105 : : integer,intent(out),optional :: mqtofull(nqpt)
1106 : : real(dp),intent(in) :: kpt_phon(3,nkpt_phon),qpt_full(3,nqpt)
1107 : :
1108 : : !Local variables-------------------------------
1109 : : !scalars
1110 : : integer :: ikpt_phon,iFSqpt,iqpt,isym,symrankkpt_phon
1111 : : !character(len=500) :: message
1112 : 15 : type(krank_t) :: krank
1113 : : !arrays
1114 : : real(dp) :: tmpkpt(3),gamma_kpt(3)
1115 : : ! *************************************************************************
1116 : :
1117 : 15 : call wrtout(std_out,' mkqptequiv : making rankkpt_phon and invrankkpt_phon',"COLL")
1118 : :
1119 : 15 : call krank%init(nkpt_phon, kpt_phon)
1120 : :
1121 [ + + + + ]: 10631 : FSfullpqtofull = -999
1122 : : gamma_kpt(:) = zero
1123 : :
1124 [ + + ]: 1327 : do ikpt_phon=1,nkpt_phon
1125 [ + + ]: 11823 : do iqpt=1,nqpt
1126 : : ! tmpkpt = jkpt = ikpt + qpt
1127 [ + + ]: 41984 : tmpkpt(:) = kpt_phon(:,ikpt_phon) + qpt_full(:,iqpt)
1128 : :
1129 : : ! which kpt is it among the full FS kpts?
1130 : 10496 : symrankkpt_phon = krank%get_rank(tmpkpt)
1131 : :
1132 : 10496 : FSfullpqtofull(ikpt_phon,iqpt) = krank%invrank(symrankkpt_phon)
1133 [ - + ]: 11808 : if (FSfullpqtofull(ikpt_phon, iqpt) == -1) then
1134 : 0 : ABI_ERROR("looks like no kpoint equiv to k+q !!!")
1135 : : end if
1136 : :
1137 : : end do
1138 : : end do
1139 : :
1140 [ - + ]: 15 : if (present(mqtofull)) then
1141 [ # # ]: 0 : do iqpt=1,nqpt
1142 [ # # ]: 0 : tmpkpt(:) = gamma_kpt(:) - qpt_full(:,iqpt)
1143 : :
1144 : : ! which kpt is it among the full FS kpts?
1145 : 0 : symrankkpt_phon = krank%get_rank(tmpkpt)
1146 : :
1147 : 0 : mqtofull(iqpt) = krank%invrank(symrankkpt_phon)
1148 [ # # ]: 0 : if (mqtofull(iqpt) == -1) then
1149 : 0 : ABI_ERROR("looks like no kpoint equiv to -q !!!")
1150 : : end if
1151 : : end do
1152 : : end if
1153 : :
1154 : 15 : call krank%free()
1155 : :
1156 : : ! start over with q grid
1157 : 15 : call wrtout(std_out,' mkqptequiv : FSfullpqtofull made. Do qpttoqpt',"COLL")
1158 : :
1159 : 15 : call krank%init(nqpt, qpt_full)
1160 : :
1161 [ + + + + : 15399 : qpttoqpt(:,:,:) = -1
+ + ]
1162 [ + + ]: 135 : do iFSqpt=1,nqpt
1163 [ + + ]: 5223 : do isym=1,Cryst%nsym
1164 : : tmpkpt(:) = Cryst%symrec(:,1,isym)*qpt_full(1,iFSqpt) &
1165 : : + Cryst%symrec(:,2,isym)*qpt_full(2,iFSqpt) &
1166 [ + + ]: 20352 : + Cryst%symrec(:,3,isym)*qpt_full(3,iFSqpt)
1167 : :
1168 : 5088 : symrankkpt_phon = krank%get_rank(tmpkpt)
1169 [ - + ]: 5088 : if (krank%invrank(symrankkpt_phon) == -1) then
1170 : 0 : ABI_ERROR("looks like no kpoint equiv to q by symmetry without time reversal!!!")
1171 : : end if
1172 : 5088 : qpttoqpt(1,isym,krank%invrank(symrankkpt_phon)) = iFSqpt
1173 : :
1174 [ + + ]: 20352 : tmpkpt = -tmpkpt
1175 : 5088 : symrankkpt_phon = krank%get_rank(tmpkpt)
1176 [ - + ]: 5088 : if (krank%invrank(symrankkpt_phon) == -1) then
1177 : 0 : ABI_ERROR('looks like no kpoint equiv to q by symmetry with time reversal!!!')
1178 : : end if
1179 : 5208 : qpttoqpt(2,isym,krank%invrank(symrankkpt_phon)) = iFSqpt
1180 : : end do
1181 : : end do
1182 : :
1183 : 15 : call krank%free()
1184 : :
1185 [ - + - + : 15 : end subroutine mkqptequiv
- + ]
1186 : : !!***
1187 : :
1188 [ # # # # : 504 : end module defs_elphon
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
1189 : : !!***
|